hwm_mercenary.user.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. // ==UserScript==
  2. // @name HWM - Mercenary Guild
  3. // @namespace figey_hwm_
  4. // @description Auto complete MG quest, give up the cargo
  5. // @version 0.1.4
  6. // @run-at document-end
  7. // @grant GM_deleteValue
  8. // @grant GM_getValue
  9. // @grant GM_info
  10. // @grant GM_listValues
  11. // @grant GM_notification
  12. // @grant GM_setValue
  13. // @noframe
  14. // @require https://notabug.org/figey/localDataStorage/raw/8018b121fb20340d325f45999a308b02b8d761e1/localDataStorage-1.2.0.trim.js
  15. // @require https://notabug.org/figey/hwm_scripts/raw/59e98a179ba73cc408884238fa4c7c0285622194/src/core.js
  16. // @include /^https?:\/\/(www\.)?(heroeswm\.ru|lordswm\.com)\/home\.php.*/
  17. // @include /^https?:\/\/(www\.)?(heroeswm\.ru|lordswm\.com)\/map\.php.*/
  18. // @include /^https?:\/\/(www\.)?(heroeswm\.ru|lordswm\.com)\/mercenary_guild\.php.*/
  19. // ==/UserScript==
  20. /**
  21. * TODO
  22. * autoskip unwanted tasks
  23. */
  24. 'use strict';
  25. /**
  26. * Script settings
  27. */
  28. const scriptSettings = {
  29. 'mg_autocomplete': { name: 'Автосдача заданий', value: false, type: 'checkbox' },
  30. 'mg_autocargo': { name: 'Авто отдача груза', value: false, type: 'checkbox' },
  31. 'mg_skip' : {
  32. name: 'Пропускать задания(0=выкл)',
  33. value: {
  34. army: { name: 'Армии', level: 0, type: 'number' },
  35. invader: { name: 'Захватчики', level: 0, type: 'number' },
  36. monster: { name: 'Монстры', level: 0, type: 'number' },
  37. сonspirator: { name: 'Заговорщики', level: 0, type: 'number' },
  38. rogues: { name: 'Разбойники', level: 0, type: 'number' },
  39. squad: { name: 'Отряды', level: 0, type: 'number' },
  40. },
  41. type: 'list',
  42. }
  43. };
  44. /**
  45. * init
  46. */
  47. HWMMap.init();
  48. SettingsTab.init();
  49. const notify = new Notify(GM_info.script.name, 'https://dcdn1.heroeswm.ru/i/gn_face.png');
  50. const options = new GMSettings(scriptSettings);
  51. /**
  52. * Process quest status
  53. * @param quest quest status
  54. * @param xhr xhr was used or not
  55. */
  56. function questProgress(quest, xhr){
  57. const timerKey = 'timerMG';
  58. const map = ls.get('map');
  59. switch(quest.status){
  60. case 'new':
  61. if( xhr ){
  62. log.info('New quest availabe, reset MG timer');
  63. ls.set(timerKey, 0);
  64. }
  65. break;
  66. case 'old':
  67. if( xhr ){
  68. log.info('Old quest still in progress, reset MG timer');
  69. ls.set(timerKey, 0);
  70. }
  71. break;
  72. case 'done':
  73. notify.send({
  74. body: 'Задание успешно сдано\n' + quest.reward,
  75. tag: 'mercenary_quest',
  76. timeout: 15000,
  77. onclick: function(event){
  78. event.preventDefault();
  79. event.target.close();
  80. }
  81. });
  82. // refresh map data
  83. map.sectorMG = 0;
  84. ls.set('map', map);
  85. ls.set('mapTimestamp', Date.now());
  86. // set timer
  87. if( xhr ){
  88. log.info("Successful complete quest");
  89. ls.set(timerKey, Date.now() + 1000*60*quest.time);
  90. }
  91. break;
  92. case 'fail':
  93. notify.send({
  94. body: 'Задание было провалено',
  95. tag: 'mercenary_quest',
  96. timeout: 15000,
  97. onclick: function(event){
  98. event.preventDefault();
  99. event.target.close();
  100. }
  101. });
  102. // refresh map data
  103. map.sectorMG = 0;
  104. ls.set('map', map);
  105. ls.set('mapTimestamp', Date.now());
  106. // set timer
  107. if( xhr ){
  108. log.info("Quest was failed");
  109. ls.set(timerKey, Date.now() + 1000*60*quest.time);
  110. }
  111. break;
  112. case 'wait':
  113. if( xhr ){
  114. // correct timer if needed
  115. if( Math.abs(ls.get(timerKey) - ( Date.now() + 1000*60*quest.time ) ) > 1000*60 ){
  116. log.warn('Correcting MG timer');
  117. ls.set(timerKey, Date.now() + 1000*60*quest.time);
  118. }
  119. }
  120. break;
  121. default:
  122. log.error('Unknown status for mercenary quest');
  123. }
  124. };
  125. /**
  126. * Check if we can complete mercenary quest
  127. */
  128. const map = ls.get('map');
  129. const mgSectors = [2, 6, 16, 21];
  130. if( options.data['mg_autocomplete'].value && map && !map.move && map.sectorMG == -1 && mgSectors.includes(map.sector) ){
  131. // check if already on page
  132. if( location.pathname.match(/mercenary_guild\.php/) ){
  133. questProgress(mercenaryQuestStatus(document.body.innerHTML), false);
  134. // or use xhr to complete
  135. } else {
  136. const xhr = runXHR('GET', 'mercenary_guild.php', true);
  137. xhr.onload = function(){
  138. // react only on successful request
  139. if( xhr.status == 200 && xhr.responseURL.match(/mercenary_guild/) ){
  140. questProgress(mercenaryQuestStatus(xhr.responseText), true);
  141. }
  142. }
  143. }
  144. // fallback if dont have map data or we wait
  145. } else if( location.pathname.match(/mercenary_guild\.php/) ){
  146. questProgress(mercenaryQuestStatus(document.body.innerHTML), false);
  147. }
  148. /**
  149. * delivere the cargo if possible
  150. */
  151. const cargo = document.querySelector('a[href="/map.php?action=accept_merc_task3"]');
  152. if( options.data['mg_autocargo'].value && cargo ){
  153. const xhr = runXHR('GET', 'map.php?action=accept_merc_task3', true);
  154. xhr.onload = function(){
  155. if( xhr.status == 200
  156. && xhr.responseURL.match(/map\.php/) && xhr.responseText.match(/id="show_map"/)
  157. && xhr.responseText.match(/href="\/map\.php\?action=accept_merc_task3"/) == null
  158. ){
  159. notify.send({
  160. body: 'Груз успешно доставлен',
  161. tag: 'mercenary_cargo',
  162. timeout: 15000,
  163. onclick: function(event){
  164. event.preventDefault();
  165. parent.focus();
  166. window.focus();
  167. event.target.close();
  168. }
  169. });
  170. // update map info
  171. let m = ls.get('map');
  172. m.sectorMG = -1;
  173. ls.set('map', m);
  174. ls.set('mapTimestamp', Date.now());
  175. // hide cargo button
  176. const cargoTable = getParentByTagName(cargo, 'table', 1);
  177. if( cargoTable ){
  178. cargoTable.style.display = 'none';
  179. }
  180. log.info("The cargo was delivered");
  181. }
  182. }
  183. }
  184. /**
  185. * Fill settings tab
  186. */
  187. const tab = SettingsTab.add('MG', 'ГН');
  188. Object.keys(options.data).forEach(function(key){
  189. switch(options.data[key].type){
  190. case 'checkbox':
  191. const input = document.createElement('input');
  192. input.id = key;
  193. input.type = 'checkbox';
  194. input.checked = options.data[key].value;
  195. input.addEventListener('change', function(event){
  196. options.data[event.target.id].value = event.target.checked;
  197. options.data[event.target.id].save();
  198. });
  199. const label = document.createElement('label');
  200. label.htmlFor = input.id;
  201. label.textContent = options.data[key].name;
  202. tab.appendChild(input);
  203. tab.appendChild(label);
  204. tab.appendChild(document.createElement('br'));
  205. break;
  206. case 'list':
  207. tab.appendChild(document.createElement('hr'));
  208. const name = document.createElement('p');
  209. name.textContent = options.data[key].name;
  210. name.appendChild(document.createElement('br'));
  211. tab.appendChild(name);
  212. Object.keys(options.data[key].value).forEach(function(questType){
  213. const input = document.createElement('input');
  214. input.id = key + '_' + questType;
  215. input.dataset.quest = questType;
  216. input.type = options.data[key].value[questType].type;
  217. input.max = '50'; input.min = '0'; input.step = '1';
  218. input.value = options.data[key].value[questType].level;
  219. input.style.width = '45px';
  220. input.addEventListener('change', function(event){
  221. options.data[key].value[event.target.dataset.quest].level = event.target.value;
  222. options.data[key].save();
  223. });
  224. const label = document.createElement('label');
  225. label.htmlFor = input.id;
  226. label.textContent = options.data[key].value[questType].name;
  227. label.style.width = '65px';
  228. label.style.display = 'inline-block';
  229. tab.append(label,input,document.createElement('br'));
  230. });
  231. break;
  232. default:
  233. log.error('unknown option type: ' + options.data[key].type );
  234. break;
  235. }
  236. });