Harem(Hentai)Heroes Automatic

Open the menu in HaremHeroes(topright) to toggle AutoControlls. Supports AutoSalary, AutoQuest and AutoBattle. Messages are printed in local console.

  1. // ==UserScript==
  2. // @name Harem(Hentai)Heroes Automatic
  3. // @namespace JDscripts
  4. // @version 1.7
  5. // @description Open the menu in HaremHeroes(topright) to toggle AutoControlls. Supports AutoSalary, AutoQuest and AutoBattle. Messages are printed in local console.
  6. // @author JD
  7. // @match http*://nutaku.haremheroes.com/*
  8. // @match https://www.hentaiheroes.com/*
  9. // @require https://cdn.jsdelivr.net/js-cookie/2.2.0/js.cookie.js
  10. // @grant GM_addStyle
  11. // ==/UserScript==
  12.  
  13. GM_addStyle('/* The switch - the box around the slider */ .switch { position: relative; display: inline-block; width: 60px; height: 34px; } /* Hide default HTML checkbox */ .switch input {display:none;} /* The slider */ .slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; -webkit-transition: .4s; transition: .4s; } .slider:before { position: absolute; content: ""; height: 26px; width: 26px; left: 4px; bottom: 4px; background-color: white; -webkit-transition: .4s; transition: .4s; } input:checked + .slider { background-color: #2196F3; } input:focus + .slider { box-shadow: 0 0 1px #2196F3; } input:checked + .slider:before { -webkit-transform: translateX(26px); -ms-transform: translateX(26px); transform: translateX(26px); } /* Rounded sliders */ .slider.round { border-radius: 34px; } .slider.round:before { border-radius: 50%; }');
  14.  
  15. var proceedQuest = function () {
  16. //console.log("Starting auto quest.");
  17. var currentQuestMunuOption = $("nav div[rel='content'] a:has(.continue_quest)");
  18. if (currentQuestMunuOption === undefined || currentQuestMunuOption.attr("href") === undefined) {
  19. console.log("Could not find current quest menu button for verification. Probably it hasn't yet loaded.");
  20. return;
  21. }
  22. // Check if at correct page.
  23. if (currentQuestMunuOption.attr("href") !== window.location.pathname) {
  24. // Click on current quest to naviagte to it.
  25. console.log("Navigating to current quest.");
  26. sessionStorage.autoLoop = "false";
  27. window.location = window.location.origin + currentQuestMunuOption.attr("href");
  28. return;
  29. }
  30.  
  31. // Get the proceed button type
  32. var proceedButtonMatch = $("#controls button:not([style='display: none;'])");
  33. var proceedCostEnergy = Number($("#controls .cost span[cur='*']").text());
  34. var proceedCostMoney = Number($("#controls .cost span[cur='$']").text().trim().replace(',', ''));
  35. var proceedType = proceedButtonMatch.attr("act");
  36.  
  37. if (proceedButtonMatch.length === 0) console.log("Could not find resume button.");
  38. else if (proceedType === "free") {
  39. console.log("Proceeding for free.");
  40. proceedButtonMatch.click();
  41. }
  42. else if (proceedType === "pay") {
  43. var energyCurrent = Number($("span[hero='energy_quest']").text());
  44. var moneyCurrent = Number($("div[hero='soft_currency'] span").text().trim().replace(',', ''));
  45. if(proceedCostEnergy <= energyCurrent)
  46. {
  47. // We have energy.
  48. console.log("Spending "+proceedCostEnergy+" Energy to proceed.");
  49. }
  50. else
  51. {
  52. console.log("Quest requires "+proceedCostEnergy+" Energy to proceed.");
  53. sessionStorage.questRequirement = "*"+proceedCostEnergy;
  54. return;
  55. }
  56. if(proceedCostMoney <= moneyCurrent)
  57. {
  58. // We have money.
  59. console.log("Spending "+proceedCostMoney+" Money to proceed.");
  60. }
  61. else
  62. {
  63. console.log("Spending "+proceedCostEnergy+" Money to proceed.");
  64. sessionStorage.questRequirement = "$"+proceedCostMoney;
  65. return;
  66. }
  67. proceedButtonMatch.click();
  68. sessionStorage.autoLoop = "false";
  69. location.reload();
  70. }
  71. else if (proceedType === "use_item") {
  72. console.log("Proceeding by using X" + Number($("#controls .item span").text()) + " of the required item.");
  73. proceedButtonMatch.click();
  74. }
  75. else if (proceedType === "battle") {
  76. console.log("Proceeding to battle troll...");
  77. sessionStorage.questRequirement = "battle";
  78. // Proceed to battle troll.
  79. proceedButtonMatch.click();
  80. sessionStorage.autoLoop = "false";
  81. location.reload();
  82. }
  83. else if (proceedType === "end_archive") {
  84. console.log("Reached end of current archive. Proceeding to next archive.");
  85. sessionStorage.autoLoop = "false";
  86. proceedButtonMatch.click();
  87. }
  88. else if (proceedType === "end_play") {
  89. console.log("Reached end of current play. Proceeding to next play.");
  90. sessionStorage.autoLoop = "false";
  91. proceedButtonMatch.click();
  92. }
  93. else {
  94. console.log("Could not identify given resume button.");
  95. sessionStorage.questRequirement = "unknownQuestButton";
  96. }
  97. };
  98.  
  99. var getSalary = function () {
  100. try {
  101. if ($("#breadcrumbs span").last().text() === "Harem") {
  102. console.log("Detected Harem Screen. Fetching Salary");
  103. $("#harem_whole #harem_left .salary:not('.loads') button").each(function (index) {
  104. $(this).click();
  105. });
  106. document.cookie = "nextSalaryTime=;";
  107. }
  108. else {
  109. // Not at Harem screen then goto the Harem screen.
  110. console.log("Navigating to Harem window.");
  111. sessionStorage.autoLoop = "false";
  112. window.location = window.location.origin + $("nav div[rel='content'] a:has(.harem)").attr("href");
  113. return;
  114. }
  115. }
  116. catch (ex) {
  117. console.log("Could not collect salary... " + ex);
  118. }
  119. };
  120.  
  121. var doBossBattle = function()
  122. {
  123. var currentPower = Number($("span[hero='energy_fight']").text());
  124. if(currentPower < 1)
  125. {
  126. //console.log("No power for battle.");
  127. return;
  128. }
  129. // Battles the latest boss.
  130. // Navigate to latest boss.
  131. if(window.location.pathname.startsWith("/battle.html"))
  132. {
  133. // On the battle screen.
  134. doBattle();
  135. }
  136. else if(window.location.pathname.startsWith("/quest"))
  137. {
  138. // On some quest screen.
  139. // Goto this area's screen.
  140. console.log("Navigating to latest Troll.");
  141. sessionStorage.autoLoop = "false";
  142. window.location = window.location.origin + $("#breadcrumbs a[class='back']").last().attr("href");
  143. return;
  144. }
  145. else if(window.location.pathname.startsWith("/world"))
  146. {
  147. // On some world screen.
  148. // Click on the local Boss's battle button.
  149. console.log("Entering battle with this troll.");
  150. sessionStorage.autoLoop = "false";
  151. window.location = window.location.origin + $("#worldmap a[class='troll_world']").attr("href");
  152. return;
  153. }
  154. else{
  155. console.log("Navigating to latest Troll.");
  156. sessionStorage.autoLoop = "false";
  157. window.location = window.location.origin + $("nav div[rel='content'] a:has(.continue_quest)").attr("href");
  158. return;
  159. }
  160. };
  161.  
  162. var doBattle = function () {
  163. //console.log("Performing auto battle.");
  164. var currentPower = Number($("span[hero='energy_fight']").text());
  165. if(currentPower < 1)
  166. {
  167. //console.log("No power for battle.");
  168. return;
  169. }
  170. // Confirm if on correct screen.
  171. if ($("#breadcrumbs span").last().text() === "Battle") {
  172. // On battle page.
  173. //console.log("On Battle Page.");
  174. if ($("#arena[class='canvas']").length === 1) {
  175. // Oponent choose screen
  176. console.log("On opponent choose screen.");
  177. // Fight the first opponent in list.
  178. $(".opponents_arena .sub_block .grey_text_button:contains('Select')")[0].click();
  179. sessionStorage.autoLoop = "false";
  180. }
  181. else if ($("#battle[class='canvas']").length === 1) {
  182. // Battle screen
  183. //console.log("On battle screen.");
  184. var battleButton = $("#battle_middle button[rel='launch']");
  185. if(battleButton === undefined)return;
  186. if(battleButton.attr("price") === undefined){console.log("Could not detect battle button price. Maybe its not loaded yet.");return;}
  187. if(currentPower >= battleButton.attr("price"))
  188. {
  189. // We have the power.
  190. battleButton.click();
  191. // Skip
  192. setTimeout(function(){$("#battle_middle button[rel='skip']").click();},1000);
  193. setTimeout(function(){$("#battle_end div[style*='display: block;'] .blue_text_button").click();},2500);
  194.  
  195. if (sessionStorage.questRequirement === "battle") {
  196. // Battle Done.
  197. sessionStorage.questRequirement = "none";
  198. }
  199. }
  200. else
  201. {
  202. // We need more power.
  203. console.log("Battle requires "+battleButton.attr("price")+" power.");
  204. sessionStorage.battlePowerRequired = battleButton.attr("price");
  205. if(sessionStorage.questRequirement === "battle")sessionStorage.questRequirement = "P"+battleButton.attr("price");
  206. }
  207. }
  208. else {
  209. console.log("Could not identify battle screen.");
  210. if (sessionStorage.questRequirement === "battle") sessionStorage.questRequirement = "errorInAutoBattle";
  211. return;
  212. }
  213. }
  214. else
  215. {
  216. // Switch to the correct screen
  217. console.log("Switching to battle screen.");
  218. window.location = window.location.origin + $("nav div[rel='content'] a:has(.battle)").attr("href");
  219. sessionStorage.autoLoop = "false";
  220. return;
  221. }
  222. };
  223.  
  224. var updateData = function () {
  225. //console.log("updating UI");
  226. sessionStorage.autoSalary = document.getElementById("autoSalaryCheckbox").checked;
  227. sessionStorage.autoQuest = document.getElementById("autoQuestCheckbox").checked;
  228. sessionStorage.autoBattle = document.getElementById("autoBattleCheckbox").checked;
  229. };
  230.  
  231. var autoLoop = function () {
  232. updateData();
  233. var busy = false;
  234. var page = window.location.href;
  235. var currentPower = Number($("span[hero='energy_fight']").text());
  236. //console.log("sal="+sessionStorage.autoSalary);
  237. if (sessionStorage.autoSalary === "true" && busy === false) {
  238. if (Cookies.get("nextSalaryTime") === undefined) {
  239. console.log("Time to fetch salary.");
  240. getSalary();
  241. busy = true;
  242. }
  243. else if (Cookies.get("nextSalaryTime") === "") {
  244. console.log("Salary fetched. Getting next fetch time");
  245. if ($("nav div[rel='content'] a:has(.home)").attr("href") !== window.location.pathname) {
  246. console.log("Moving to home.");
  247. sessionStorage.autoLoop = "false";
  248. // Goto Home page.
  249. window.location = window.location.origin + $("nav div[rel='content'] a:has(.home)").attr("href");
  250. busy=true;
  251. return;
  252. }
  253. var closestTime = $("#collect_all_bar .in monospace m").first();
  254. closestTime = (Number(closestTime.text() + closestTime.next().text()) * 60 + Number(closestTime.next().next().text() + closestTime.next().next().next().text()));
  255. document.cookie = "nextSalaryTime=present;max-age=" + (closestTime < 0 ? 0 : closestTime);
  256. console.log("New fetch time stored in nextSalaryTime cookie.(+" + closestTime + " sec.)");
  257. busy = false;
  258. }
  259. }
  260. if (sessionStorage.autoQuest === "true" && busy === false) {
  261. if (sessionStorage.questRequirement === "battle") {
  262. //console.log("Quest requires battle.");
  263. doBossBattle();
  264. busy = true;
  265. }
  266. else if (sessionStorage.questRequirement[0] === '$') {
  267. if (Number(sessionStorage.questRequirement.substr(1)) < Number($("div[hero='soft_currency'] span").text().trim().replace(',', ''))) {
  268. // We have enough money... requirement fulfilled.
  269. console.log("Continuing quest, required money obtained.");
  270. sessionStorage.questRequirement = "none";
  271. proceedQuest();
  272. busy = true;
  273. }
  274. else {
  275. if(isNaN(sessionStorage.questRequirement.substr(1)))
  276. {
  277. sessionStorage.questRequirement = "none";
  278. console.log("Invalid money in session storage quest requirement !");
  279. }
  280. else{
  281. // Else we need more money.
  282. //console.log("Need money for quest, cannot continue. Turning ON AutoSalary.");
  283. sessionStorage.autoQuest = "true";
  284. }
  285. busy = false;
  286. }
  287. }
  288. else if (sessionStorage.questRequirement[0] === '*') {
  289. var energyNeeded = Number(sessionStorage.questRequirement.substr(1));
  290. var energyCurrent = Number($("span[hero='energy_quest']").text());
  291. if (energyNeeded <= energyCurrent) {
  292. // We have enough energy... requirement fulfilled.
  293. console.log("Continuing quest, required energy obtained.");
  294. sessionStorage.questRequirement = "none";
  295. proceedQuest();
  296. busy = true;
  297. }
  298. // Else we need energy, just wait.
  299. else {
  300. busy = false;
  301. //console.log("Replenishing energy for quest.(" + energyNeeded + " needed)");
  302. }
  303. }
  304. else if (sessionStorage.questRequirement[0] === 'P')
  305. {
  306. // Battle power required.
  307. var neededPower = Number(sessionStorage.questRequirement.substr(1));
  308. if(currentPower < neededPower)
  309. {
  310. console.log("Quest requires "+neededPower+" Battle Power for advancement. Waiting...");
  311. busy = false;
  312. }
  313. else
  314. {
  315. console.log("Battle Power obtained, resuming quest...");
  316. sessionStorage.questRequirement = "none";
  317. proceedQuest();
  318. busy = true;
  319. }
  320. }
  321. else if (sessionStorage.questRequirement === "unknownQuestButton") {
  322. console.log("AutoQuest disabled.AutoQuest cannot be performed due to unknown quest button. Please manually proceed the current quest screen.");
  323. document.getElementById("autoQuestCheckbox").checked = false;
  324. sessionStorage.autoQuest = "false";
  325. sessionStorage.questRequirement = "none";
  326. busy = false;
  327. }
  328. else if (sessionStorage.questRequirement === "errorInAutoBattle") {
  329. console.log("AutoQuest disabled.AutoQuest cannot be performed due errors in AutoBattle. Please manually proceed the current quest screen.");
  330. document.getElementById("autoQuestCheckbox").checked = false;
  331. sessionStorage.autoQuest = "false";
  332. sessionStorage.questRequirement = "none";
  333. busy = false;
  334. }
  335. else if(sessionStorage.questRequirement === "none")
  336. {
  337. //console.log("NONE req.");
  338. busy = true;
  339. proceedQuest();
  340. }
  341. else
  342. {
  343. console.log("Invalid quest requirement : "+sessionStorage.questRequirement);
  344. busy=false;
  345. }
  346. }else if(sessionStorage.autoQuest === "false"){sessionStorage.questRequirement = "none";}
  347.  
  348. if(sessionStorage.autoBattle === "true")
  349. {
  350. if(busy === false && currentPower >= Number(sessionStorage.battlePowerRequired) && currentPower > 0)
  351. {
  352. sessionStorage.battlePowerRequired = "0";
  353. busy = true;
  354. if(sessionStorage.autoQuest === "true")
  355. {
  356. if(sessionStorage.questRequirement[0] === 'P')
  357. {
  358. console.log("AutoBattle disabled for power collection for AutoQuest.");
  359. document.getElementById("autoBattleCheckbox").checked = false;
  360. sessionStorage.autoBattle = "false";
  361. busy = false;
  362. }
  363. else
  364. doBossBattle();
  365. }
  366. else
  367. doBossBattle();
  368. }
  369. }
  370. else{sessionStorage.battlePowerRequired = "0";}
  371.  
  372. if(busy === true && sessionStorage.userLink==="none")
  373. {
  374. sessionStorage.userLink = page;
  375. }
  376. else if(sessionStorage.userLink !=="none" && busy === false)
  377. {
  378. console.log("Restoring page "+sessionStorage.userLink);
  379. window.location = sessionStorage.userLink;
  380. sessionStorage.userLink = "none";
  381. }
  382.  
  383. if(isNaN(sessionStorage.autoLoopTimeMili)){
  384. console.log("AutoLoopTimeMili is not a number.");
  385. setDefaults();
  386. }
  387. else{
  388. if (sessionStorage.autoLoop === "true") setTimeout(autoLoop, Number(sessionStorage.autoLoopTimeMili));
  389. else console.log("autoLoop Disabled");
  390. }
  391. };
  392.  
  393. var setDefaults = function () {
  394. console.log("Setting Defaults.");
  395. sessionStorage.autoSalary = "false";
  396. sessionStorage.autoLoop = "true";
  397. sessionStorage.userLink = "none";
  398. sessionStorage.autoLoopTimeMili = "200";
  399. sessionStorage.autoQuest = "false";
  400. sessionStorage.autoBattle = "false";
  401. sessionStorage.battlePowerRequired = "0";
  402. sessionStorage.questRequirement = "none";
  403. sessionStorage.freshStart = "no";
  404. };
  405.  
  406. var start = function () {
  407. //console.log("script started");
  408. // Add UI buttons.
  409. var UIcontainer = $("#contains_all nav div[rel='content']");
  410. UIcontainer.html('<div style="position: absolute;right: -9.675%; padding: 10px;width: inherit;text-align: center;display:flex;flex-direction:column;"><span>AutoSal.</span><div><label class=\"switch\"><input id=\"autoSalaryCheckbox\" type=\"checkbox\"><span class=\"slider round\"></span></label></div><span>AutoQuest</span><div><label class=\"switch\"><input id=\"autoQuestCheckbox\" type=\"checkbox\"><span class=\"slider round\"></span></label></div><span>AutoBattle</span><div><label class=\"switch\"><input id=\"autoBattleCheckbox\" type=\"checkbox\"><span class=\"slider round\"></span></label></div></div>'+UIcontainer.html());
  411. document.getElementById("autoSalaryCheckbox").checked = sessionStorage.autoSalary === "true";
  412. document.getElementById("autoQuestCheckbox").checked = sessionStorage.autoQuest === "true";
  413. document.getElementById("autoBattleCheckbox").checked = sessionStorage.autoBattle === "true";
  414. sessionStorage.autoLoop = "true";
  415. if (typeof sessionStorage.freshStart == "undefined" || isNaN(Number(sessionStorage.autoLoopTimeMili))) {
  416. setDefaults();
  417. }
  418. autoLoop();
  419. };
  420. $("document").ready(start);