LWM Market Utility

Add Cost-per-battle to all market lots

  1. // ==UserScript==
  2. // @name LWM Market Utility
  3. // @author Prozyk
  4. // @description Add Cost-per-battle to all market lots
  5. // @match https://www.lordswm.com/auction.php?*\
  6. // @match https://www.lordswm.com/auction.php?*art_type*
  7. // @namespace https://greasyfork.org/users/722588
  8. // @version 0.0.1.20210113191835
  9. // ==/UserScript==
  10.  
  11.  
  12.  
  13.  
  14. //Put above inside Userscript definition if also want cpb on all *weapons* page, rather than only art_specific
  15. //Do at own risk, since it will initiate lot of requests to obtain all repair costs, might get admin's attention
  16.  
  17.  
  18.  
  19. // 1] Detect Table
  20. // 3] Catch Relevant Values: Price, Dura, Name
  21. // 4] Parse Repair Cost, store to name so don't have to recalculate
  22. // 5] Attach form asking repair rate
  23. // 6] Calculate CPB
  24. // 7] Add Cpb, Repair till, and number of battles in Columns
  25. // 8] Add sort abiility
  26. // 9] Make CPB sort option part of dropdown
  27.  
  28. // (Maybe)
  29. // Add generic CPB calculator above page
  30. // Contact Author with more ideas.
  31.  
  32.  
  33. console.log("Market Utility Script is On");
  34. var xpath = "//td[contains(text(),'Bids')]";
  35. var BidsElement = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
  36.  
  37. var table = BidsElement.parentNode.parentNode;
  38. var rows = table.childNodes;
  39. var settings = rows[0];
  40. var header = rows[1];
  41. var len = rows.length;
  42.  
  43. var smithEffi = 90;
  44. var smithCharge = 101;
  45.  
  46. var price = [];
  47. var dura_cur = [];
  48. var dura_max = [];
  49. var art_name = [];
  50. var repair_cost = [];
  51. var repair_cost_dict = {};
  52. var initiated = false;
  53.  
  54. var current_url = document.location.href;
  55.  
  56. var sleep_time = 10000;
  57. if (current_url.includes("art_type")) sleep_time = 2000;
  58.  
  59.  
  60. function extend_header(){
  61. var repair_header = document.createElement('td');
  62. repair_header.innerHTML = "<span align = center> Repair Cost </span> ";
  63. repair_header.setAttribute("width", "100");
  64. header.appendChild(repair_header);
  65.  
  66. var cpb_header = document.createElement('td');
  67. cpb_header.innerHTML = "<span align = center> CPB </span> ";
  68. cpb_header.setAttribute("width", "100");
  69. header.appendChild(cpb_header);
  70.  
  71. var final_header = document.createElement('td');
  72. final_header.innerHTML = "<span align = center> Repair Till </span> ";
  73. final_header.setAttribute("width", "100");
  74. header.appendChild(final_header);
  75.  
  76. var usage_header = document.createElement('td');
  77. usage_header.innerHTML = "<span align = center> Total Fights </span> ";
  78. usage_header.setAttribute("width", "100");
  79. header.appendChild(usage_header);
  80. }
  81. function add_cpb_form(){
  82. settings.childNodes[0].setAttribute('colspan', "2");
  83. settings.childNodes[1].setAttribute('align', "center");
  84. settings.childNodes[1].setAttribute('valign', "center");
  85. settings.childNodes[1].setAttribute('colspan', "3");
  86.  
  87. var myform = document.createElement('td');
  88. myform.setAttribute("align", "right");
  89. myform.setAttribute("valign", "center");
  90. myform.setAttribute("colspan", "4");
  91. var str = "<table align = center> <tr><td align = center> <b> Cost Per Battle</b> </td> </tr>";
  92. str += "<tr> <td align = center > Smith Efficiency :<input type=text id=smithEffi size = '4' value='90'>%</td></tr>";
  93. str += " <tr> <td align = center> Smith Charge <input type=text id=smithCharge size = '4' value='101'>%</td></tr>"
  94. str += "<tr><td align = center> <input type = button value = 'Calculate' id = 'calculate' </td> </tr></table> ";
  95. myform.innerHTML = str;
  96. settings.appendChild(myform);
  97.  
  98. document.getElementById('calculate').onclick = upgrade_table;
  99. document.getElementById('smithEffi').oninput = function(){
  100. smithEffi = document.getElementById('smithEffi').value
  101. };
  102. document.getElementById('smithCharge').oninput = function(){
  103. smithCharge = document.getElementById('smithCharge').value
  104. };
  105. }
  106. function parse_table(){
  107. var arts = new Set();
  108. for(var i = 2; i<len; i++){
  109. art_name[i] = rows[i].childNodes[0].textContent.split('-')[1].split('[')[0].trim();
  110. durability = rows[i].childNodes[0].textContent.split("Durability: ")[1];
  111. if (durability.includes("pcs")) durability = durability.substring(0, durability.length-6)
  112. dura_cur[i] = Number(durability.split('/')[0]);
  113. dura_max[i]= Number(durability.split('/')[1].split(" ")[0].match(/\d+/)[0]);
  114.  
  115. price[i] = Number(rows[i].childNodes[2].textContent.replaceAll(',', '').match(/\d+/)[0]);
  116. // console.log(rows[i].childNodes[2].textContent.replace(, price[i]);
  117. if(!arts.has(art_name[i])){
  118. get_repair_cost(i);
  119. arts.add(art_name[i]);
  120. }
  121. }
  122. console.log(arts);
  123. }
  124. function get_repair_cost(i){
  125. art_url = rows[i].childNodes[0].querySelectorAll('a')[1].href;
  126. var req = new XMLHttpRequest();
  127. req.open("GET", art_url, true);
  128. req.overrideMimeType('text/html; charset=windows-1251');
  129. req.send();
  130. req.onreadystatechange = function(){
  131. var text = req.responseText;
  132. repair_cost_dict[art_name[i]] = Number(text.split("Repairing")[1].replace(',', '').split('<td>')[2].split('</td>')[0]);
  133. console.log(art_name[i], repair_cost_dict[art_name[i]]);
  134. }
  135. }
  136. function set_repairs(){
  137.  
  138. new Promise(r => setTimeout(r, sleep_time)).then(() => {
  139. for(var i = 2; i<len; i++){
  140. repair_cost[i] = repair_cost_dict[art_name[i]];
  141. rows[i].innerHTML += "<td width=100> </td>".repeat(4);
  142. rows[i].childNodes[5].innerHTML = repair_cost[i];
  143. }
  144. });
  145. }
  146. function set_opt_cpb(){
  147. for(var i = 2; i<len; i++){
  148. var opt_cpb = cpb_calc(dura_cur[i], dura_max[i], price[i], repair_cost[i]);
  149. console.log(art_name[i], dura_cur[i], dura_max[i], price[i], repair_cost[i]);
  150. console.log(opt_cpb);
  151. // rows[i].childNodes[6].innerHTML = "Hello";
  152. rows[i].childNodes[6].innerHTML = opt_cpb[0];
  153. rows[i].childNodes[7].innerHTML = "0/" + opt_cpb[1];
  154. rows[i].childNodes[8].innerHTML = opt_cpb[2];
  155. }
  156. }
  157. function cpb_calc(currDura, maxDura, iniCost, repCost) {
  158. var tempMaxDura, tempDura, totDura, optDura, optFights;
  159. var iniCost, repCost;
  160. var se, sc;
  161. var totCostTillNow, costPerBattle = 0, minCPB;
  162. var i;
  163. var repCount = 1;
  164. //Assigning the values
  165.  
  166. se = smithEffi / 100;
  167. sc = smithCharge / 100;
  168. tempMaxDura = maxDura;
  169. tempDura = currDura;
  170. totDura = tempDura;
  171. totCostTillNow = iniCost;
  172. costPerBattle = totCostTillNow / totDura;
  173. minCPB = costPerBattle;
  174. optDura = tempMaxDura;
  175. optFights = totDura;
  176.  
  177.  
  178. for(i=1; i<=maxDura; i++)
  179. {
  180. totCostTillNow += parseFloat(repCost * sc);
  181. tempDura = parseInt(tempMaxDura * se);
  182. totDura += tempDura;
  183. costPerBattle = (totCostTillNow / parseFloat(totDura));
  184. tempMaxDura -= 1;
  185. if ( minCPB >= costPerBattle )
  186. {
  187. minCPB = costPerBattle;
  188. optDura = tempMaxDura;
  189. optFights = totDura;
  190. }
  191. }
  192. optOut = [eval(minCPB.toFixed(2)), optDura, optFights];
  193. return optOut;
  194. }
  195. function add_sort_form(){
  196. dropdown = document.getElementById("ss")
  197. var option = document.createElement("option");
  198. option.value = "304";
  199. option.textContent = "Cost per Battle: Ascending";
  200. dropdown.appendChild(option);
  201.  
  202. var option2 = document.createElement("option");
  203. option2.value = "0";
  204. option2.textContent = "Random Order";
  205. dropdown.appendChild(option2);
  206. dropdown.onchange = function(){
  207. if(dropdown.value != "304" && dropdown.value != "0") findsort(); //predefined by them
  208. else if (dropdown.value == "304") cpb_sort();
  209. }
  210. }
  211. function cpb_sort(){
  212. var sign_sort = -1;
  213. var NumberC = 6;
  214. var sorted = [];
  215. var m, t, p, f, i, j;
  216. for(i=2; i<len; i++){
  217. sorted[i] = [];
  218. for(j=0; j<9; j++){
  219. sorted[i][j] = rows[i].childNodes[j].innerHTML;
  220. }
  221. }
  222. while(true){
  223. f = 0;
  224. for(i=2; i<len-1; i++){
  225. m = sign_sort*Number(sorted[i][NumberC]);
  226. t = sign_sort*Number(sorted[i+1][NumberC]);
  227. if(m<t){
  228. f = 1;
  229. for(j=0; j<9; j++){
  230. p = sorted[i][j];
  231. sorted[i][j]=sorted[i+1][j];
  232. sorted[i+1][j] = p;
  233. }
  234. }
  235. }
  236. if(f == 0)break;
  237. }
  238. for(i=2; i<len ; i++){
  239. for(j=0; j<9; j++){
  240. rows[i].childNodes[j].innerHTML = sorted[i][j];
  241. }
  242. }
  243. }
  244.  
  245.  
  246.  
  247. function upgrade_table(){
  248.  
  249. if(!initiated){
  250. initiated = true;
  251. add_cpb_form();
  252. document.getElementById('calculate').disabled = true;
  253. extend_header();
  254. parse_table();
  255. set_repairs();
  256.  
  257. new Promise(r => setTimeout(r, sleep_time + 2000)).then(() => {
  258. set_opt_cpb();
  259. document.getElementById('calculate').disabled = false;
  260. add_sort_form();
  261. })
  262. }
  263. else{
  264. document.getElementById("ss").value = "0";
  265. set_opt_cpb();
  266. }
  267. }
  268.  
  269.  
  270. upgrade_table();
  271.  
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.