iradap

Resource Helper v2

Jun 28th, 2022 (edited)
956
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name         Resources helper
  3. // @namespace    http://tampermonkey.net/
  4. // @version      0.2
  5. // @description  Zaktualizowana wersja dodatku Czogiego na potrzeby Portu Verdent
  6. // @author       Iradap
  7. // @match        https://alkatria.pl/game
  8. // @grant        none
  9. // ==/UserScript==
  10.  
  11. //Timery surowców
  12. //Nazwa odnowa/wyczerpanie
  13.  
  14. //Palma 30s/75s
  15. //Dąb 60s/150s
  16. //Sosna 90s/180s
  17.  
  18. //Miedź 30s/75s
  19. //Żelazo 60s/150s
  20. //Srebro 90s/180s
  21.  
  22. //Łowisko N/A/120s
  23.  
  24. const resources = [];
  25. var awaitingForResponse = undefined;
  26. var timersController = undefined;
  27. const toolNames = {
  28.   Siek: "cutting",
  29.   Wędk: "fishing",
  30.   Noży: "gathering",
  31.   Kilo: "mining"
  32. };
  33. const respawnTimers = {
  34.   Pal: 1200,
  35.   Dęb: 1200,
  36.   Sos: 1200,
  37.   Klo: 1200,
  38.   Mie: 1200,
  39.   Żel: 1200,
  40.   Sre: 1200,
  41.   Zło: 1200
  42. };
  43. class TimersController {
  44.   constructor() {
  45.     this.lsName = "resourcesTimers";
  46.     this.timers = {};
  47.   }
  48.   removeTimer(x, y, type) {
  49.     this.removeLs(`${map.current_map},${x},${y},${type}`, 0);
  50.     delete this.timers[`${map.current_map},${x},${y},${type}`];
  51.   }
  52.   setTimer(timeout, x, y, type) {
  53.     this.timers[`${map.current_map},${x},${y},${type}`] = new Timer(
  54.       timeout,
  55.       x,
  56.       y,
  57.       type
  58.     );
  59.   }
  60.   getLs(name, val) {
  61.     const mainObj = JSON.parse(localStorage[this.lsName]);
  62.     if (!mainObj[name]) {
  63.       return val;
  64.     }
  65.     return mainObj[name];
  66.   }
  67.   setLs(name, val) {
  68.     const mainObj = JSON.parse(localStorage[this.lsName]);
  69.     mainObj[name] = val;
  70.     localStorage.setItem(this.lsName, JSON.stringify(mainObj));
  71.   }
  72.   removeLs(name) {
  73.     const mainObj = JSON.parse(localStorage[this.lsName]);
  74.     delete mainObj[name];
  75.     localStorage.setItem(this.lsName, JSON.stringify(mainObj));
  76.   }
  77.   checkLs() {
  78.     if (!localStorage[this.lsName]) {
  79.       localStorage.setItem(this.lsName, "{}");
  80.       return;
  81.     }
  82.     const timers = JSON.parse(localStorage[this.lsName]);
  83.     for (const [id, timer] of Object.entries(timers)) {
  84.       const cords = id.split(",");
  85.       cords.shift();
  86.       if (!timer) {
  87.         this.removeLs(...cords);
  88.         continue;
  89.       }
  90.  
  91.       const unix = Date.now();
  92.  
  93.       if (unix > timer) {
  94.         this.removeTimer(...cords);
  95.         continue;
  96.       }
  97.  
  98.       this.setTimer(timer - unix, ...cords);
  99.     }
  100.   }
  101. }
  102.  
  103. class Timer extends TimersController {
  104.   constructor(timer, x, y, type) {
  105.     super();
  106.     this.time = Date.now() + timer;
  107.     if (this.startTimer(x, y, type)) {
  108.       this.setLs(`${map.current_map},${x},${y},${type}`, this.time);
  109.     }
  110.   }
  111.   async startTimer(x, y, type) {
  112.     const tile = document.querySelector(`#tile_${x}-${y}`);
  113.     if (!tile) {
  114.       return false;
  115.     }
  116.     this.timer = document.createElement("p");
  117.     this.timer.style.textAlign = "center";
  118.     this.timer.style.top = tile.childElementCount === 0 ? "45%" : "55%";
  119.     this.timer.style.left = "25%";
  120.     this.timer.style.position = "absolute";
  121.     this.timer.style.textShadow = "2px 2px 5px Aqua";
  122.     tile.appendChild(this.timer);
  123.     while (this.time > Date.now()) {
  124.       this.timer.innerText = type + ":" + getTimer(this.time - Date.now());
  125.       await sleep(1000);
  126.     }
  127.     this.timer.remove();
  128.     if (tile.childElementCount === 1) {
  129.       tile.childNodes[0].style.top = "50%";
  130.     }
  131.     this.removeTimer(x, y, type);
  132.   }
  133. }
  134.  
  135. const getTimer = (unix) => {
  136.   let seconds = (~~(unix / 1000) % 60).toString();
  137.   let minutes = (~~(~~(unix / 1000) / 60) % 60).toString();
  138.   seconds = seconds.length === 2 ? seconds : "0" + seconds;
  139.   minutes = minutes.length === 2 ? minutes : "0" + minutes;
  140.  
  141.   return `${minutes}:${seconds}`;
  142. };
  143.  
  144. const oldParse = game.parseServerPacket;
  145. const oldLoad = map.loadMap;
  146. const oldSend = game.sendPacket;
  147.  
  148. const sleep = (ms) => {
  149.   return new Promise((resolve) => setTimeout(resolve, ms));
  150. };
  151.  
  152. const getDistance = (a, b) => {
  153.   return Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
  154. };
  155.  
  156. const equipTool = async (name) => {
  157.   if (document.querySelector(".player-equipment")) {
  158.     document.querySelector("#icon-character").click();
  159.     await sleep(100);
  160.     document.querySelector("#icon-character").click();
  161.   } else {
  162.     document.querySelector("#icon-character").click();
  163.   }
  164.   await sleep(300);
  165.  
  166.   const item = Array.from(
  167.     document.querySelector(".player-backpack").children
  168.   ).find((el) => {
  169.     if (el.dataset?.tipItem) {
  170.       const tip = el.dataset.tipItem;
  171.       return (
  172.         tip.includes("Doświadczonego") &&
  173.         tip.includes(name) &&
  174.         !tip.includes("Złam")
  175.       );
  176.     }
  177.   });
  178.   if (item) {
  179.     game.sendPacket("equip_item", {
  180.       from: item.dataset.slot,
  181.       type: "backpack"
  182.     });
  183.   }
  184.   document.querySelector("#icon-character").click();
  185.   return item !== undefined;
  186. };
  187.  
  188. const sortReesources = () => {
  189.   return resources.sort((a, b) => {
  190.     if (getDistance(window.player, a) < getDistance(window.player, b)) {
  191.       return -1;
  192.     } else if (getDistance(window.player, a) > getDistance(window.player, b)) {
  193.       return 1;
  194.     }
  195.     return 0;
  196.   });
  197. };
  198.  
  199. const isCloseEnough = (a, b) => {
  200.   const dist = getDistance(a, b);
  201.   return dist == 1
  202.     ? true
  203.     : dist === 2
  204.     ? Math.abs(a.x - b.x) <= 1 && Math.abs(a.y - b.y) <= 1
  205.     : false;
  206. };
  207.  
  208. window.document.addEventListener("keydown", (eventData) => {
  209.   if (eventData.code !== "Space") {
  210.     return;
  211.   }
  212.   var closestResource = sortReesources();
  213.  
  214.   const action = $(
  215.     "#tile_" + closestResource[0].x + "-" + closestResource[0].y + "_tip"
  216.   ).data("action");
  217.   if (action && action === player.current_element) {
  218.     player.current_element = "";
  219.     $("#my-character").html("");
  220.     return;
  221.   }
  222.  
  223.   closestResource = closestResource.filter((resource) => {
  224.     return (
  225.       !timersController.getLs(
  226.         `${map.current_map},${resource.x},${resource.y},E`,
  227.         0
  228.       ) &&
  229.       !timersController.getLs(
  230.         `${map.current_map},${resource.x},${resource.y},R`,
  231.         0
  232.       )
  233.     );
  234.   });
  235.   if (!closestResource.length) {
  236.     return;
  237.   }
  238.   closestResource = closestResource[0];
  239.  
  240.   if (
  241.     !closestResource ||
  242.     (!isCloseEnough(window.player, closestResource) &&
  243.       closestResource.action !== "fishing")
  244.   ) {
  245.     return;
  246.   }
  247.   if (getDistance(player, closestResource) > 3) {
  248.     return;
  249.   }
  250.   window.map.useElement(closestResource.x, closestResource.y);
  251. });
  252. const secondsToMili = (sec) => {
  253.   return sec * 1000;
  254. };
  255. game.parseServerPacket = async function (data) {
  256.   oldParse.apply(this, arguments);
  257.   if (data.code === 1016) {
  258.     if (data.message.includes("Musisz założyć")) {
  259.       const toolName = data.message.split(" ")[2].slice(0, 4);
  260.       const didEquip = await equipTool(toolName);
  261.       const closestTileOfTool = sortReesources().find((tile) => {
  262.         return (
  263.           tile.action === toolNames[toolName] ||
  264.           (window.player.current_element &&
  265.             tile.action === window.player.current_element)
  266.         );
  267.       });
  268.       if (didEquip) {
  269.         game.sendPacket(879, {
  270.           x: closestTileOfTool.x,
  271.           y: closestTileOfTool.y
  272.         });
  273.       }
  274.     }
  275.     if (
  276.       data.message === "Przedmiot został złamany" ||
  277.       data.message === "Niepowodzenie!"
  278.     ) {
  279.       if (awaitingForResponse) {
  280.         timersController.setTimer(
  281.           awaitingForResponse.timeout,
  282.           awaitingForResponse.x,
  283.           awaitingForResponse.y,
  284.           "E"
  285.         );
  286.         awaitingForResponse = undefined;
  287.       }
  288.     }
  289.   }
  290.   if (data.code === "exhaust_tile" && awaitingForResponse) {
  291.     if (data.x === awaitingForResponse.x && data.y === awaitingForResponse.y) {
  292.       timersController.setTimer(
  293.         awaitingForResponse.timeout,
  294.         awaitingForResponse.x,
  295.         awaitingForResponse.y,
  296.         "E"
  297.       );
  298.       const exhausted = resources.find((resource) => {
  299.         return resource.x === data.x && resource.y === data.y;
  300.       });
  301.       const respawn = respawnTimers[exhausted.name.split(" ")[1].slice(0, 3)];
  302.       if (respawn) {
  303.         timersController.setTimer(
  304.           secondsToMili(respawn),
  305.           exhausted.x,
  306.           exhausted.y,
  307.           "R"
  308.         );
  309.       }
  310.       awaitingForResponse = undefined;
  311.     }
  312.   }
  313. };
  314.  
  315. map.loadMap = function (data) {
  316.   oldLoad.apply(this, arguments);
  317.   for (const tile of data.tiles) {
  318.     if (!tile.action || tile.action === "healing") {
  319.       continue;
  320.     }
  321.     resources.push(tile);
  322.   }
  323.   timersController = new TimersController();
  324.   timersController.checkLs();
  325. };
  326.  
  327. game.sendPacket = function (code, data) {
  328.   oldSend.apply(this, arguments);
  329.   switch (code) {
  330.     case 879:
  331.       const tile = sortReesources().find((tile) => {
  332.         return data.x === tile.x && data.y === tile.y;
  333.       });
  334.       if (
  335.         tile.action === "fishing" &&
  336.         !timersController.getLs(`${map.current_map},${tile.x},${tile.y},E`, 0)
  337.       ) {
  338.         timersController.setTimer(tile.timeout, tile.x, tile.y, "E");
  339.         return;
  340.       }
  341.       if (tile) {
  342.         awaitingForResponse = tile;
  343.         setTimeout(() => {
  344.           awaitingForResponse = undefined;
  345.         }, 3000);
  346.       }
  347.       break;
  348.   }
  349. };
RAW Paste Data Copied