Premium Exchange - Buy Resources

Automatically buy resources up to a predefined amount of resources

Stan na 27-01-2020. Zobacz najnowsza wersja.

  1. // ==UserScript==
  2. // @name Premium Exchange - Buy Resources
  3. // @description Automatically buy resources up to a predefined amount of resources
  4. // @author FunnyPocketBook
  5. // @version 2.3
  6. // @include https://*/game.php*screen=market*
  7. // @namespace https://greasyfork.org/users/151096
  8. // ==/UserScript==
  9. const incoming = "Incoming"; // Change this accordingly to your language. In Portuguese it would be const incoming = "Entrada";
  10. const timeout = 200; // Time in ms between transactions. Too low and the game won't allow it
  11. let topUp, price, stack;
  12. let start = false; // Start script or stop script, default is stop
  13. let isBuying = false;
  14.  
  15. createInput();
  16.  
  17. function createInput() {
  18. "use strict";
  19. const userInputParent = document.getElementById("premium_exchange_form"); // Parent element
  20.  
  21. // Create input for setting how much res should be bought
  22. const divScript = document.createElement("div");
  23. divScript.setAttribute("id", "divScript");
  24. userInputParent.parentNode.insertBefore(divScript, userInputParent);
  25. document.getElementById("divScript").innerHTML = "<p>Top up warehouse to: <input id='topUpInput'> " +
  26. "<button id='topUpOk' class='btn'>OK</button><span id='topUpText'></span></p><p>Buy when price above: <input id='priceInput'> " +
  27. "<button id='priceOk' class='btn'>OK</button><span id='priceText'></span></p>" +
  28. "<p>Buy max this much at once: <input id='stackInput'> <button id='stackOk' class='btn'>OK</button><span id='stackText'></span></p>" +
  29. "<p>Buy the whole stock at once: <input type=\"checkbox\" name=\"buyStock\" id=\"buyStock\"></p><span style='color:red'>ATTENTION! This might deplete your Premium Points completely, as it buys everything that is available!</span>" +
  30. "<p>Buy resources:</p><p><input type=\"checkbox\" name=\"wood\" id=\"woodCheck\"> Wood <input type=\"checkbox\" " +
  31. "name=\"stone\" id=\"stoneCheck\"> Stone <input type=\"checkbox\" name=\"iron\" id=\"ironCheck\"> Iron</p>" +
  32. "<p><button id='start' class='btn'></button></p>";
  33. if (!start) {
  34. document.getElementById("start").innerHTML = "Start";
  35. } else {
  36. document.getElementById("start").innerHTML = "Stop";
  37. }
  38. if (localStorage.topUp) {
  39. document.getElementById("topUpInput").value = localStorage.topUp;
  40. topUp = localStorage.topUp;
  41. }
  42. if (localStorage.price) {
  43. document.getElementById("priceInput").value = localStorage.price;
  44. price = localStorage.price;
  45. }
  46. if (localStorage.stack) {
  47. document.getElementById("stackInput").value = localStorage.stack;
  48. stack = localStorage.stack;
  49. }
  50. }
  51.  
  52. document.getElementById("topUpOk").addEventListener("click", function () {
  53. topUp = document.getElementById("topUpInput").value;
  54. localStorage.topUp = topUp;
  55. document.getElementById("topUpText").innerHTML = "Top up to " + topUp;
  56. });
  57. document.getElementById("priceOk").addEventListener("click", function () {
  58. price = document.getElementById("priceInput").value;
  59. localStorage.price = price;
  60. document.getElementById("priceText").innerHTML = "Buy when price above " + price;
  61. });
  62. document.getElementById("stackOk").addEventListener("click", function () {
  63. stack = document.getElementById("stackInput").value;
  64. localStorage.stack = stack;
  65. document.getElementById("stackText").innerHTML = "Buy only " + stack + " resources at once";
  66. });
  67. document.getElementById("start").addEventListener("click", function () {
  68. if (start) {
  69. start = false;
  70. document.getElementById("start").innerHTML = "Start";
  71. } else {
  72. start = true;
  73. document.getElementById("start").innerHTML = "Stop";
  74. buyRes();
  75. }
  76. });
  77.  
  78. document.getElementById("topUpInput").addEventListener("keydown", clickOnKeyPress.bind(this, 13, "#topUpOk"));
  79. document.getElementById("priceInput").addEventListener("keydown", clickOnKeyPress.bind(this, 13, "#priceOk"));
  80. document.getElementById("stackInput").addEventListener("keydown", clickOnKeyPress.bind(this, 13, "#stackOk"));
  81.  
  82. /**
  83. *
  84. * @param wh Amount of resources in the warehouse
  85. * @param price Current price of the resource
  86. * @param stock Amount of resources in the premium exchange stock
  87. * @param inc Amount of incoming resources
  88. * @param input DOM Element of the text box
  89. * @param buy Amount of resources to buy
  90. * @constructor
  91. */
  92. function Resource(wh, price, stock, inc, input) {
  93. this.wh = wh;
  94. this.price = price;
  95. this.stock = stock;
  96. this.inc = inc;
  97. this.inputBuy = input;
  98. this.buy = 0;
  99. }
  100.  
  101. /**
  102. * Get all the info of the resources
  103. * @type {Resource}
  104. */
  105. let wood = new Resource(game_data.village.wood, parseInt(document.querySelector("#premium_exchange_rate_wood > div:nth-child(1)").innerText), parseInt(document.querySelector("#premium_exchange_stock_wood").innerText), 0, document.querySelector("#premium_exchange_buy_wood > div:nth-child(1) > input"));
  106. let iron = new Resource(game_data.village.iron, parseInt(document.querySelector("#premium_exchange_rate_iron > div:nth-child(1)").innerText), parseInt(document.querySelector("#premium_exchange_stock_iron").innerText), 0, document.querySelector("#premium_exchange_buy_iron > div:nth-child(1) > input"));
  107. let stone = new Resource(game_data.village.stone, parseInt(document.querySelector("#premium_exchange_rate_stone > div:nth-child(1)").innerText), parseInt(document.querySelector("#premium_exchange_stock_stone").innerText), 0, document.querySelector("#premium_exchange_buy_stone > div:nth-child(1) > input"));
  108. let warehouse = game_data.village.storage_max;
  109.  
  110.  
  111. if (start) {
  112. buyRes();
  113. }
  114. const interval = setInterval(function () {
  115. if (start && (!document.querySelector("#fader") || document.querySelector("#fader").style.display === "none")) {
  116. buyRes();
  117. }
  118. }, timeout);
  119.  
  120. function buyRes() {
  121. getRes();
  122.  
  123. // If buy everything is checked and warehouse + incoming resource of each resource is less than what the warehouse should be topped up to
  124. if (document.querySelector("#buyStock").checked || wood.wh + wood.inc < topUp || stone.wh + stone.inc < topUp || iron.wh + iron.inc < topUp) {
  125. if ((document.querySelector("#buyStock").checked && document.querySelector("#woodCheck").checked || wood.price > price && wood.wh + wood.inc < topUp && document.querySelector("#woodCheck").checked) && wood.stock > price) {
  126. // Buy wood
  127. wood.buy = topUp - wood.wh - wood.inc;
  128. // If for some reason, which shouldn't occur, the amount to buy goes below 0, adjust the amount to buy
  129. if (wood.buy <= 0) {
  130. wood.buy = wood.price - 2;
  131. }
  132. // Only buy a certain amount of resources (stack) at once so the price can be still seen
  133. if (wood.buy > stack) {
  134. wood.buy = stack;
  135. }
  136. if (wood.buy > wood.stock || document.querySelector("#buyStock").checked && wood.stock > 0) {
  137. wood.buy = wood.stock - 1;
  138. }
  139. //stone.inputBuy.value = "";
  140. //iron.inputBuy.value = "";
  141. //wood.buy = setZeroIfNaN(wood.buy);
  142. if (wood.buy === 0) {
  143. clearInterval(interval);
  144. console.log("wood:");
  145. console.log(wood);
  146. alert("This error message shouldn't pop up. Please open the console with CTRL+Shift+J and send a message to the developer via Discord, FunnyPocketBook#9373");
  147. return;
  148. }
  149. //wood.inputBuy.value = wood.buy;
  150. if (!isBuying) {
  151. buy("wood", wood.buy);
  152. }
  153. } else if (((document.querySelector("#buyStock").checked && document.querySelector("#stoneCheck").checked) || (stone.price > price && stone.wh + stone.inc < topUp && document.querySelector("#stoneCheck").checked) && stone.stock > price)) {
  154. // Buy stone
  155. stone.buy = topUp - stone.wh - stone.inc;
  156. if (stone.buy <= 0) {
  157. stone.buy = stone.price - 2;
  158. }
  159. if (stone.buy > stack) {
  160. stone.buy = stack;
  161. }
  162. if (stone.buy > stone.stock || document.querySelector("#buyStock").checked && stone.stock > 0) {
  163. stone.buy = stone.stock - 1;
  164. }
  165. //wood.inputBuy.value = "";
  166. //iron.inputBuy.value = "";
  167. //stone.buy = setZeroIfNaN(stone.buy);
  168. if (stone.buy === 0) {
  169. clearInterval(interval);
  170. console.log("stone:");
  171. console.log(stone);
  172. alert("This error message shouldn't pop up. Please open the console with CTRL+Shift+J and send a message to the developer via Discord, FunnyPocketBook#9373");
  173. return;
  174. }
  175. //stone.inputBuy.value = stone.buy;
  176. if (!isBuying) {
  177. buy("stone", stone.buy);
  178. }
  179. } else if ((document.querySelector("#buyStock").checked && document.querySelector("#ironCheck").checked || iron.price > price && iron.wh + iron.inc < topUp && document.querySelector("#ironCheck").checked) && iron.stock > price) {
  180. // Buy iron
  181. iron.buy = topUp - iron.wh - iron.inc;
  182. if (iron.buy <= 0) {
  183. iron.buy = iron.price - 2;
  184. }
  185. if (iron.buy > stack) {
  186. iron.buy = stack;
  187. }
  188. if (iron.buy > iron.stock || document.querySelector("#buyStock").checked && iron.stock > 0) {
  189. iron.buy = iron.stock - 1;
  190. }
  191. //wood.inputBuy.value = "";
  192. //stone.inputBuy.value = "";
  193. //iron.buy = setZeroIfNaN(iron.buy);
  194. if (iron.buy === 0) {
  195. clearInterval(interval);
  196. console.log("iron:");
  197. console.log(iron);
  198. alert("This error message shouldn't pop up. Please open the console with CTRL+Shift+J and send a message to the developer via Discord, FunnyPocketBook#9373");
  199. return;
  200. }
  201. //iron.inputBuy.value = iron.buy;
  202. if (!isBuying) {
  203. buy("iron", iron.buy);
  204. }
  205. }
  206. }
  207. }
  208.  
  209. function buy(res, amnt) {
  210. isBuying = true;
  211. let data = {};
  212. data["buy_" + res] = amnt;
  213. data.h = game_data.csrf;
  214. TribalWars.post("market", {ajaxaction: "exchange_begin"}, data, function(r) {
  215. if (r[0].error) {
  216. isBuying = false;
  217. return;
  218. }
  219. let rate_hash = r[0].rate_hash;
  220. let buy_amnt = r[0].amount;
  221. data["rate_" + res] = rate_hash;
  222. data["buy_" + res] = buy_amnt;
  223. data["mb"] = 1;
  224. data.h = game_data.csrf;
  225. TribalWars._ah = {
  226. TribalWarsTE: 1,
  227. }
  228. TribalWars.post("market", {ajaxaction: "exchange_confirm"}, data, function(r) {
  229. isBuying = false;
  230. if (r.success) {
  231. UI.SuccessMessage("Bought " + buy_amnt + " " + res + "!");
  232. console.log("Bought " + buy_amnt + " " + res + "!");
  233. $("#market_status_bar").replaceWith(r.data.status_bar);
  234. getRes();
  235. }
  236. })
  237. })
  238. }
  239. /**
  240. * Update resource objects
  241. */
  242. function getRes() {
  243. let parentInc;
  244. warehouse = game_data.village.storage_max;
  245. wood.wh = game_data.village.wood;
  246. stone.wh = game_data.village.stone;
  247. iron.wh = game_data.village.iron;
  248. wood.stock = parseInt(document.getElementById("premium_exchange_stock_wood").innerText);
  249. stone.stock = parseInt(document.getElementById("premium_exchange_stock_stone").innerText);
  250. iron.stock = parseInt(document.getElementById("premium_exchange_stock_iron").innerText);
  251. wood.price = parseInt(document.querySelector("#premium_exchange_rate_wood > div:nth-child(1)").innerText);
  252. stone.price = parseInt(document.querySelector("#premium_exchange_rate_stone > div:nth-child(1)").innerText);
  253. iron.price = parseInt(document.querySelector("#premium_exchange_rate_iron > div:nth-child(1)").innerText);
  254. try {
  255. if (document.querySelector("#market_status_bar > table:nth-child(2) > tbody > tr > th:nth-child(1)").innerHTML.split(" ")[0].replace(":", "") === incoming) {
  256. parentInc = document.querySelector("#market_status_bar > table:nth-child(2) > tbody > tr > th:nth-child(1)");
  257. }
  258. } catch (e) { }
  259. try {
  260. if (document.querySelector("#market_status_bar > table:nth-child(2) > tbody > tr > th:nth-child(2)").innerHTML.split(" ")[0].replace(":", "") === incoming) {
  261. parentInc = document.querySelector("#market_status_bar > table:nth-child(2) > tbody > tr > th:nth-child(2)");
  262. }
  263. } catch (e) { }
  264.  
  265. try {
  266. wood.inc = parseInt(setZeroIfNaN(parseInt(parentInc.querySelector(".wood").parentElement.innerText.replace(".", ""))));
  267. } catch (e) { }
  268. try {
  269. stone.inc = parseInt(setZeroIfNaN(parseInt(parentInc.querySelector(".stone").parentElement.innerText.replace(".", ""))));
  270. } catch (e) { }
  271. try {
  272. iron.inc = parseInt(setZeroIfNaN(parseInt(parentInc.querySelector(".iron").parentElement.innerText.replace(".", ""))));
  273. } catch (e) { }
  274. }
  275.  
  276. function clickOnKeyPress(key, selector) {
  277. "use strict";
  278. if (event.defaultPrevented) {
  279. return; // Should do nothing if the default action has been cancelled
  280. }
  281. let handled = false;
  282. if (event.key === key) {
  283. document.querySelector(selector).click();
  284. handled = true;
  285. } else if (event.keyIdentifier === key) {
  286. document.querySelector(selector).click();
  287. handled = true;
  288. } else if (event.keyCode === key) {
  289. document.querySelector(selector).click();
  290. handled = true;
  291. }
  292. if (handled) {
  293. event.preventDefault();
  294. }
  295. }
  296.  
  297. function setZeroIfNaN(x) {
  298. "use strict";
  299. if ((typeof x === 'number') && (x % 1 === 0)) {
  300. return x;
  301. } else {
  302. return 0;
  303. };
  304. }