Colony Helper

Add Farm/Mall/Storage auto-calc buttons if you need to buy them, also prev/next button to fast zipping and some stats

当前为 2018-08-24 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Colony Helper
  3. // @description Add Farm/Mall/Storage auto-calc buttons if you need to buy them, also prev/next button to fast zipping and some stats
  4. // @namespace bitbucket.org/Odahviing
  5. // @version 3.3
  6. // @include http://www.war-facts.com/view_colony.php*
  7. // @grant GM_getValue
  8. // @grant GM_setValue
  9. // ==/UserScript==
  10.  
  11. // Version history:
  12. // 1.0 Initial Basic Version
  13. // 1.1 Add warning in colony page for lack in malls
  14. // 1.2 Add the ability to buy malls from mail page (inner settings for mall)
  15. // 1.3 Some Bug Fix
  16. // 2.0 Add farm Option / Redesign Script
  17. // 2.1 Add warning if no input has been given
  18. // 2.21 Add buy storage option + Math fix
  19. // 3.0 Update to new UI, remove sync requests, rebuild function
  20. // 3.2 Add ability to load the print settings automatically
  21. // 3.21 - Auto load prints once a day.
  22. // 3.3 - More Bug Fix
  23.  
  24. var ColonyId = getQueryString(document.URL);
  25.  
  26. /* Global Settings */
  27. var doPrevNext = true;
  28. var checkMall = true;
  29. var checkFarm = true;
  30. var checkPrints = true;
  31. var checkStorage = true;
  32. var farmConstant = 0.18; // Don't have any idea what is the right number, but this number seems more or less right
  33. var storageLine = 80; // % of full before adding ability to buy
  34. var storageBuy = 50; // % to get while buying
  35. var multi = 1.1; // How much I want more then I need
  36.  
  37. /* Prints Id */
  38. var mallId;
  39. var peopleMall;
  40. var effMall;
  41. // --- //
  42. var farmId;
  43. var peopleFarm;
  44. var effFarm;
  45. // --- //
  46.  
  47. /* Main */
  48.  
  49. originalParseInt = parseInt;
  50. parseInt = function(str){if (!str.replace) return originalParseInt(str); else return originalParseInt(str.replace(/,/g, ""));}
  51. originalParseFloat = parseFloat;
  52. parseFloat = function(str){if (!str.replace) return originalParseFloat(str); else return originalParseFloat(str.replace(/,/g, ""));}
  53.  
  54. var mainDataBlock = document.getElementsByClassName('light padding5 tbborder');
  55. var population = extractValue(mainDataBlock[0], 'Population');
  56. var mallEffective;
  57. var farmEffective;
  58.  
  59. main();
  60.  
  61. function main() {
  62. loadSettings().then(function() {
  63. addButtons();
  64. addColonyPageData();
  65. });
  66. }
  67.  
  68. function addButtons() {
  69. if (doPrevNext == true)
  70. addPrevNext();
  71.  
  72. if (startupTest() == false)
  73. return false;
  74.  
  75. if (checkPrints == true)
  76. addUpdatePrintsButton();
  77.  
  78. if (checkMall == true)
  79. addMallButton();
  80.  
  81. if (checkFarm == true)
  82. addFarmButton();
  83.  
  84. if (checkStorage == true)
  85. addStorageButton();
  86. }
  87.  
  88. /* End Main */
  89.  
  90. /* Load Settings */
  91.  
  92. function addUpdatePrintsButton() {
  93. mainDataBlock[6].innerHTML = mainDataBlock[6].innerHTML + `<input type='button' id='updatebutton' value='Update Prints'>`;
  94. var mainbutton = document.getElementById('updatebutton');
  95. if (GM_getValue('colony-date') != getCurrentDate())
  96. mainbutton.style ="color:red";
  97. else
  98. mainbutton.style ="color:gray";
  99. mainbutton.className = 'darkbutton noleft';
  100. mainbutton.addEventListener("click", function(){updatePrints()}, false);
  101. }
  102.  
  103. function loadSettings() {
  104. return new Promise(function (fulfill) {
  105. var mallData = GM_getValue("mall");
  106. var farmData = GM_getValue("farm");
  107. var savedTime = GM_getValue('colony-date');
  108.  
  109. if (!mallData || !farmData || savedTime != getCurrentDate()) {
  110. updatePrints().then(function() {
  111. return fulfill();
  112. });
  113. }
  114. else
  115. {
  116. updateValues(mallData, farmData);
  117. console.log(`Prints Loaded\nMalls:${JSON.stringify(readRow(mallData))}\nFarms:${JSON.stringify(readRow(farmData))}`);
  118. return fulfill();
  119. }
  120. });
  121. }
  122.  
  123. function updatePrints() {
  124. return new Promise(function (fulfill) {
  125. getCurrentPrints(1, 11).then(function (farmData) { // load Farm
  126. getCurrentPrints(3, 8).then(function (mallData){ // load Mall
  127. let mallSavedValue = saveRow(mallData);
  128. let farmSavedValue = saveRow(farmData);
  129.  
  130. GM_setValue("mall", mallSavedValue);
  131. GM_setValue("farm", farmSavedValue);
  132. GM_setValue('colony-date', getCurrentDate());
  133. updateValues(mallSavedValue, farmSavedValue);
  134. console.log(`Prints Updated\nMalls:${JSON.stringify(mallData)}\nFarms:${JSON.stringify(farmData)}`);
  135. // location.reload();
  136. return fulfill();
  137. });
  138. });
  139. });
  140. }
  141.  
  142. function getCurrentDate()
  143. {
  144. var today = new Date();
  145. var dd = today.getDate();
  146. var mm = today.getMonth()+1; //January is 0!
  147. var yyyy = today.getFullYear();
  148. return `${mm}-${dd}-${yyyy}`;
  149. }
  150.  
  151. function updateValues(mallData, farmData) {
  152. let mallParseData = readRow(mallData);
  153. mallId = mallParseData.printId;
  154. peopleMall = mallParseData.workers;
  155. effMall = mallParseData.effect;
  156. let farmParseData = readRow(farmData);
  157. farmId = mallParseData.printId;
  158. peopleFarm = mallParseData.workers;
  159. effFarm = mallParseData.effect;
  160.  
  161. mallEffective = peopleMall * effMall / 100;
  162. farmEffective = peopleFarm * effFarm / 100;
  163. }
  164.  
  165. function readRow(value) {
  166. let tmp = value.split('&');
  167. return {printId: tmp[0], workers: tmp[1], effect: tmp[2]};
  168. }
  169.  
  170. function saveRow(value) {
  171. return `${value.printId}&${value.workers}&${value.effect}`;
  172. }
  173.  
  174. function getCurrentPrints(type, subtype) {
  175. return new Promise(function (fulfill){
  176. sendAjaxRequest('GET', `http://www.war-facts.com/blueprints.php?type=${type}&subtype=${subtype}`, true, true, null).then(function(html) {
  177. let div = document.createElement('div');
  178. div.innerHTML = html;
  179. let firstPrint = div.getElementsByClassName('overauto tbborder blueprint')[0];
  180. let firstCheckBox = firstPrint.getElementsByTagName('input')[1];
  181. let values = firstPrint.getElementsByTagName('span');
  182. return fulfill({printId: firstCheckBox.value, workers: values[1].innerHTML.split(' ')[0].trim(), effect: values[3].innerHTML.replace('%','').trim()});
  183. });
  184. });
  185. }
  186.  
  187. // End Load Settings */
  188.  
  189. /* Add General Stats */
  190.  
  191. function addColonyPageData() {
  192. let landValue = extractValue(mainDataBlock[1], 'Size');
  193. let allLines = document.getElementsByClassName('smalltext');
  194. let popGrowth = parseInt(allLines[1].innerHTML.split(' ')[1].replace('(+','').replace(')',''));
  195. let landGrowth = parseFloat(allLines[2].innerHTML.split('(')[1].replace('+','').replace('km²)',''));
  196.  
  197. allLines[1].innerHTML = allLines[1].innerHTML.replace('citizens ' , '') + ` - ${parseFloat(100 * popGrowth / population).toFixed(3)}%`;
  198. allLines[2].innerHTML = allLines[2].innerHTML.replace('km² ' , '') + ` - ${parseFloat(100 * landGrowth / landValue).toFixed(3)}%`;
  199. allLines[3].innerHTML = allLines[3].innerHTML.replace('citizens / km²','') + ` - Growth: ${(popGrowth/landGrowth).toFixed(2)}`;
  200. }
  201.  
  202. /* Finish General Stats */
  203.  
  204. /* Helping Functions */
  205.  
  206. function extractValue(row, text) {
  207. return parseInt(row.innerHTML.substring(row.innerHTML.indexOf(text + ':') + text.length + 1, row.innerHTML.indexOf('<', row.innerHTML.indexOf(text + ':'))).trim());
  208. }
  209.  
  210. function sendAjaxRequest(type, link, async, withResponse, params) {
  211. return new Promise(function (fulfill, reject){
  212. var xhttp = new XMLHttpRequest();
  213. xhttp.open(type, link , true);
  214. xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  215. xhttp.send(params);
  216.  
  217. xhttp.onreadystatechange = function () {
  218. if(xhttp.readyState === 4 && xhttp.status === 200) {
  219. if (withResponse == true)
  220. fulfill(xhttp.responseText);
  221. else
  222. fulfill();
  223. }
  224. };
  225. });
  226. }
  227.  
  228. function getQueryString(colonyURL) {
  229. var indexPoint = colonyURL.indexOf('?');
  230. if (indexPoint != -1)
  231. colonyURL = colonyURL.substring(indexPoint+1, colonyURL.length);
  232. return colonyURL.replace("colony=", "");
  233. }
  234.  
  235. function startupTest() {
  236. if (atleastOneBuyerisActive() == false) return false;
  237. if (peopleMall * peopleFarm == 0)
  238. {
  239. alert("You didn't update script settings for best blueprints, stopping..");
  240. return false;
  241. }
  242. return true;
  243. }
  244.  
  245. function atleastOneBuyerisActive() {return (checkMall || checkFarm || checkStorage);}
  246.  
  247. /* End Helping Functions */
  248.  
  249. /* Add Prev Button Functions */
  250.  
  251. function getPrevAndNext(currentColonyNumber) {
  252. var allColoniesFrame = document.getElementById("colonylist");
  253. var allColonies = allColoniesFrame.getElementsByClassName("colmenu_name");
  254. if (allColonies.length == 1)
  255. return [-1, -1];
  256.  
  257. for (var index = 0; index < allColonies.length; index ++)
  258. {
  259. var currentValue = getQueryString(allColonies[index].href);
  260. if (currentColonyNumber == currentValue)
  261. {
  262. if (index == 0)
  263. return [-1, getQueryString(allColonies[index+1].href)];
  264.  
  265. if (index == allColonies.length -1)
  266. return [getQueryString(allColonies[index-1].href), -1];
  267.  
  268. return [getQueryString(allColonies[index-1].href), getQueryString(allColonies[index+1].href)];
  269. }
  270. }
  271. }
  272.  
  273. function addPrevNext() {
  274. var prevNextValues = getPrevAndNext(ColonyId);
  275. var colonyText = document.getElementsByClassName("heading bold pagetitle");
  276. if (prevNextValues[1] != -1)
  277. colonyText[0].innerHTML = colonyText[0].innerHTML + "<span><a href='view_colony.php?colony=" + prevNextValues[1] + "'><font color='yellow'>&nbsp;&nbsp;&nbsp;Next</font></a></span>";
  278. if (prevNextValues[0] != -1)
  279. colonyText[0].innerHTML = "<span><a href='view_colony.php?colony=" + prevNextValues[0] + "'><font color='yellow'>Prev&nbsp;&nbsp;&nbsp;</font></a></span>" + colonyText[0].innerHTML;
  280. }
  281.  
  282. /* End Prev Button Functions */
  283.  
  284. /* Mall Functions */
  285.  
  286. function addMallButton() {
  287. let mallValue = extractValue(mainDataBlock[5], 'Malled people');
  288.  
  289. if (population * 1.1 > mallValue)
  290. {
  291. mainDataBlock[5].innerHTML = mainDataBlock[5].innerHTML.replace('Malled people', `<input type='button' id='mallbutton' value='Buy Malls'> for`);
  292. var mainbutton = document.getElementById('mallbutton');
  293. mainbutton.style ="color:red";
  294. mainbutton.className = 'darkbutton noleft';
  295. mainbutton.addEventListener("click", function(){buyMalls(population * multi, mallValue)}, false);
  296. }
  297. }
  298.  
  299. function buyMalls(people, malled) {
  300. var baseParams = "build=1&type=3&subtype=8";
  301. var missing = people - malled;
  302.  
  303. var toBuy = Math.ceil(missing / (mallEffective * 40));
  304. baseParams = baseParams + "&buildid=" + mallId + "&colony=" + ColonyId + "&amount=" + toBuy;
  305. sendAjaxRequest("POST", "build_facility.php", true, false, baseParams);
  306.  
  307. location.reload();
  308. }
  309.  
  310. /* End Mall Functions */
  311.  
  312. /* Farm Functions */
  313.  
  314. function addFarmButton() {
  315. var tempHolder = mainDataBlock[17].innerHTML;
  316. let foodStringValue = tempHolder.substring(tempHolder.indexOf('</a>') + 4, tempHolder.indexOf('<span>')).trim();
  317. let foodValue = parseInt(foodStringValue);
  318.  
  319. if (population * 1.5 > foodValue * 10)
  320. {
  321. var link = "/extras/colony_res.php?colony=" + ColonyId;
  322. var div = document.createElement('div');
  323.  
  324. sendAjaxRequest("GET", link, true, true, "").then(function (html){
  325. div.innerHTML = html;
  326. var allLines = div.getElementsByTagName('tr');
  327. var LowValue = allLines[11].getElementsByTagName('td')[1].innerHTML;
  328. var HighValue = allLines[11].getElementsByTagName('td')[2].innerHTML;
  329. var currentProduction = (parseInt(LowValue) * 0.7 + parseInt(HighValue) * 0.3);
  330. var resourcesGap = Math.ceil((population - currentProduction * 10) / 10);
  331. if (resourcesGap > 0)
  332. {
  333. // Just making sure I don't have to much
  334. if (foodValue < (population /10 - currentProduction) * 60)
  335. {
  336. mainDataBlock[17].innerHTML = "<input type='button' id='farmbutton' value='Buy Farms'>" + `${foodStringValue} Units`;
  337. var mainbutton = document.getElementById('farmbutton');
  338. mainbutton.style ="color:red";
  339. mainbutton.className = 'darkbutton noleft';
  340. mainbutton.addEventListener("click", function(){buyFarms(resourcesGap * multi)}, false);
  341. }
  342. }
  343. });
  344. }
  345. }
  346.  
  347. function buyFarms(gap) {
  348. // First taking data from the page
  349. var temp = mainDataBlock[3].innerHTML.split(" ")[1];
  350. var wealth = temp.substring(temp.indexOf('</a>') + 9).trim();
  351. var wages = document.getElementById('wages').value;
  352.  
  353. // Now lets see the %
  354. getFertSetting().then(function (farmFert) {
  355. var toBuy = Math.ceil(gap / Math.sqrt(wages/wealth) / Math.sqrt(farmFert * farmConstant) / farmEffective);
  356. var baseParams = "build=1&type=1&subtype=11";
  357. baseParams = baseParams + "&buildid=" + farmId + "&colony=" + ColonyId + "&amount=" + toBuy;
  358. sendAjaxRequest("POST", "build_facility.php", true, false, baseParams);
  359. location.reload();
  360. });
  361. }
  362.  
  363. function getFertSetting()
  364. {
  365. return new Promise(function (fulfill) {
  366. var farmFert = GM_getValue("farm" + ColonyId);
  367. if (farmFert == undefined)
  368. {
  369. console.log(`undefined`);
  370. var planetLink = document.getElementById('midcolumn').getElementsByClassName('openextra pointer')[0].title.trim();
  371. var div = document.createElement('div');
  372. sendAjaxRequest("GET", planetLink, false, true, "").then(function(html) {
  373. div.innerHTML = html;
  374. var allPlanetValues = div.getElementsByClassName('left tbborder light padding5 overauto box width50')
  375. farmFert = allPlanetValues[10].getElementsByTagName('div')[3].innerHTML.replace("%","");
  376. GM_setValue("farm" + ColonyId, farmFert);
  377. return fulfill(farmFert);
  378. });
  379. }
  380. return fulfill(farmFert);
  381. });
  382. }
  383.  
  384. /* End Farm Functions */
  385.  
  386. /* Storage Functions */
  387.  
  388. function addStorageButton() {
  389. var storageLeft = document.getElementsByClassName('storagetop')[0].innerHTML.split(' ')[0].replace(',','').replace(',','').replace(',','');
  390. var storageAll = document.getElementsByClassName('storagebottom')[0].innerHTML.split(' ')[0].replace(',','').replace(',','').replace(',','');
  391. var prec = Math.ceil((storageAll - storageLeft) * 100 / storageAll);
  392.  
  393. if (prec > storageLine)
  394. {
  395. var holder = document.getElementsByClassName('darkbutton noleft')[1];
  396. holder.innerHTML = "<font color='red'>" + holder.innerHTML + "</font>";
  397. holder.onclick = "";
  398. holder.addEventListener('click', function(){buyStorage(storageAll,storageLeft);}, false);
  399. }
  400. }
  401.  
  402. function buyStorage(overall, left) {
  403. var x = storageBuy / 100;
  404. var buy = Math.round((x * overall- left) / (1-x));
  405. var baseParams = "colony=" + ColonyId + "&addstorage=" + buy;
  406. sendAjaxRequest('POST', "view_colony.php", true, false, baseParams);
  407. location.reload();
  408. }
  409.  
  410. /* End Storage Functions */