Advertisement
Guest User

обновленная скрипта

a guest
Jun 24th, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.51 KB | None | 0 0
  1. // This is the zone you want to attack (Optional, otherwise picks one for you).
  2. var target_zone = -1;
  3.  
  4. // Variables. Don't change these unless you know what you're doing.
  5. var real_round_length = 120; // Round Length of a real game (In Seconds, for calculating score)
  6. var resend_frequency = 110; // Frequency at which we can say we finished a round (May be different than real length)
  7. var update_length = 1; // How long to wait between updates (In Seconds)
  8. var loop_rounds = true;
  9. var language = "english"; // Used when POSTing scores
  10. var access_token = "";
  11. var current_game_id = undefined;
  12. var current_timeout = undefined;
  13. var max_retry = 5; // Max number of retries to send requests
  14. var auto_first_join = true; // Automatically join the best zone at first
  15. var current_planet_id = undefined;
  16. var current_game_start = undefined; // Timestamp for when the current game started
  17.  
  18. class BotGUI {
  19. constructor(state) {
  20. console.log('GUI Has been created');
  21.  
  22. this.state = state;
  23.  
  24. this.createStatusWindow();
  25. }
  26.  
  27. createStatusWindow() {
  28. if(document.getElementById('salienbot_gui')) {
  29. return false;
  30. }
  31.  
  32. var $statusWindow = $J([
  33. '<div id="salienbot_gui" style="background: #191919; z-index: 1; border: 3px solid #83d674; padding: 20px; margin: 15px; width: 300px; transform: translate(0, 0);">',
  34. '<h1><a href="https://github.com/ensingm2/saliengame_idler/">Salien Game Idler</a></h1>',
  35. '<p style="margin-top: -.8em; font-size: .75em"><span id="salienbot_status"></span></p>', // Running or stopped
  36. '<p><b>Task:</b> <span id="salienbot_task">Initializing</span></p>', // Current task
  37. `<p><b>Target Zone:</b> <span id="salienbot_zone">None</span></p>`,
  38. `<p style="display: none;" id="salienbot_zone_difficulty_div"><b>Zone Difficulty:</b> <span id="salienbot_zone_difficulty"></span></p>`,
  39. '<p><b>Level:</b> <span id="salienbot_level">' + this.state.level + '</span> &nbsp;&nbsp;&nbsp;&nbsp; <b>EXP:</b> <span id="salienbot_exp">' + this.state.exp + '</span></p>',
  40. '<p><b>Lvl Up In:</b> <span id="salienbot_esttimlvl"></span></p>',
  41. '<p><input id="disableAnimsBtn" type="button" onclick="INJECT_disable_animations()" value="Disable Animations"/></p>',
  42. '</div>'
  43. ].join(''))
  44.  
  45. $J('#salien_game_placeholder').append( $statusWindow )
  46. }
  47.  
  48. updateStatus(running) {
  49. const statusTxt = running ? '<span style="color: green;">✓ Running</span>' : '<span style="color: red;">✗ Stopped</span>';
  50.  
  51. $J('#salienbot_status').html(statusTxt);
  52. }
  53.  
  54. updateTask(status, log_to_console) {
  55. if(log_to_console || log_to_console === undefined)
  56. console.log(status);
  57. document.getElementById('salienbot_task').innerText = status;
  58. }
  59.  
  60. updateExp(exp) {
  61. document.getElementById('salienbot_exp').innerText = exp;
  62. }
  63.  
  64. updateLevel(level) {
  65. document.getElementById('salienbot_level').innerText = level;
  66. }
  67.  
  68. updateEstimatedTime(secondsLeft) {
  69. let date = new Date(null);
  70. date.setSeconds(secondsLeft);
  71. var result = date.toISOString().substr(11, 8);
  72.  
  73. var timeTxt = result.replace(/(\d{2}):(\d{2}):(\d{2})/gm, '$1h $2m $3s');
  74.  
  75. document.getElementById('salienbot_esttimlvl').innerText = timeTxt;
  76. }
  77.  
  78. updateZone(zone, progress, difficulty) {
  79. var printString = zone;
  80. if(progress !== undefined)
  81. printString += " (" + (progress * 100).toFixed(2) + "% Complete)"
  82. if(progress === undefined) {
  83. $J("#salienbot_zone_difficulty_div").hide();
  84. difficulty = "";
  85. }
  86. else
  87. $J("#salienbot_zone_difficulty_div").show();
  88.  
  89. document.getElementById('salienbot_zone').innerText = printString;
  90. document.getElementById('salienbot_zone_difficulty').innerText = difficulty;
  91. }
  92. };
  93.  
  94. var gui = new BotGUI({
  95. level: gPlayerInfo.level,
  96. exp: gPlayerInfo.score
  97. });
  98.  
  99. function calculateTimeToNextLevel() {
  100. const missingExp = gPlayerInfo.next_level_score - gPlayerInfo.score;
  101. const nextScoreAmount = get_max_score(target_zone);
  102. const roundTime = resend_frequency + update_length;
  103.  
  104. const secondsLeft = missingExp / nextScoreAmount * roundTime;
  105.  
  106. return secondsLeft;
  107. }
  108.  
  109. // Grab the user's access token
  110. var INJECT_get_access_token = function() {
  111. $J.ajax({
  112. async: false,
  113. type: "GET",
  114. url: "https://steamcommunity.com/saliengame/gettoken",
  115. success: function(data) {
  116. if(data.token != undefined) {
  117. console.log("Got access token: " + data.token);
  118. access_token = data.token;
  119. }
  120. else {
  121. console.log("Failed to retrieve access token.")
  122. access_token = undefined;
  123. }
  124. }
  125. });
  126. }
  127.  
  128. // Make the call to start a round, and kick-off the idle process
  129. var INJECT_start_round = function(zone, access_token, attempt_no) {
  130. if(attempt_no === undefined)
  131. attempt_no = 0;
  132.  
  133. // Leave the game if we're already in one.
  134. if(current_game_id !== undefined) {
  135. gui.updateTask("Previous game detected. Ending it.", true);
  136. INJECT_leave_round();
  137. }
  138.  
  139. // Send the POST to join the game.
  140. $J.ajax({
  141. type: "POST",
  142. url: "https://community.steam-api.com/ITerritoryControlMinigameService/JoinZone/v0001/",
  143. data: { access_token: access_token, zone_position: zone },
  144. success: function(data) {
  145. if( $J.isEmptyObject(data.response) ) {
  146. if(attempt_no < max_retry) {
  147. console.log("Error getting zone response:",data);
  148. gui.updateTask("Waiting 5s and re-sending join attempt(Attempt #" + attempt_no + ").");
  149. setTimeout(function() { INJECT_start_round(zone, access_token, attempt_no+1); }, 5000);
  150. }
  151. else {
  152. gui.updateTask("Something went wrong attempting to start a round. Please refresh");
  153. gui.updateStatus(false);
  154. return;
  155. }
  156. }
  157. else {
  158. console.log("Round successfully started in zone #" + zone);
  159. console.log(data);
  160.  
  161. // Set target
  162. target_zone = zone;
  163.  
  164. // Update the GUI
  165. gui.updateStatus(true);
  166. gui.updateZone(zone, data.response.zone_info.capture_progress, data.response.zone_info.difficulty);
  167. gui.updateEstimatedTime(calculateTimeToNextLevel())
  168.  
  169. current_game_id = data.response.zone_info.gameid;
  170. current_game_start = new Date().getTime();
  171. INJECT_wait_for_end(resend_frequency);
  172. }
  173. },
  174. error: function (xhr, ajaxOptions, thrownError) {
  175. alert("Error starting round: " + xhr.status + ": " + thrownError);
  176. }
  177. });
  178. }
  179.  
  180. // Update time remaining, and wait for the round to complete.
  181. var INJECT_wait_for_end = function() {
  182. var now = new Date().getTime();
  183. var time_passed_ms = now - current_game_start;
  184. var time_remaining_ms = (resend_frequency*1000) - time_passed_ms;
  185. var time_remaining = Math.round(time_remaining_ms/1000);
  186. gui.updateTask("Waiting " + time_remaining + "s for round to end", false);
  187.  
  188. // Wait
  189. var wait_time = update_length*1000;;
  190. var callback;
  191.  
  192. // use absolute timestamps to calculate if the game is over, since setTimeout timings are not always reliable
  193. if(time_remaining_ms <= 0) {
  194. callback = function() { INJECT_end_round(); };
  195. }
  196. else {
  197. callback = function() { INJECT_wait_for_end(); };
  198. }
  199.  
  200. // Set the timeout
  201. current_timeout = setTimeout(callback, wait_time);
  202. }
  203.  
  204. // Send the call to end a round, and restart if needed.
  205. var INJECT_end_round = function(attempt_no) {
  206. if(attempt_no === undefined)
  207. attempt_no = 0;
  208.  
  209. // Grab the max score we're allowed to send
  210. var score = get_max_score();
  211.  
  212. // Update gui
  213. gui.updateTask("Ending Round");
  214.  
  215. // Post our "Yay we beat the level" call
  216. $J.ajax({
  217. type: "POST",
  218. url: "https://community.steam-api.com/ITerritoryControlMinigameService/ReportScore/v0001/",
  219. data: { access_token: access_token, score: score, language: language },
  220. success: function(data) {
  221. if( $J.isEmptyObject(data.response) ) {
  222. if(attempt_no < max_retry) {
  223. console.log("Error getting zone response:",data);
  224. gui.updateTask("Waiting 5s and re-sending score(Attempt #" + attempt_no + ").");
  225. setTimeout(function() { INJECT_end_round(attempt_no+1); }, 5000);
  226. }
  227. else {
  228. gui.updateTask("Something went wrong attempting to send results. Please refresh");
  229. gui.updateStatus(false);
  230. return;
  231. }
  232. }
  233. else {
  234. console.log("Successfully finished the round and got expected data back:");
  235. console.log("Level: ", data.response.new_level, "\nEXP: ", data.response.new_score);
  236. console.log(data);
  237.  
  238. gui.updateLevel(data.response.new_level);
  239. gui.updateExp(data.response.new_score);
  240. // When we get a new EXP we also want to recalculate the time for next level.
  241. gui.updateEstimatedTime(calculateTimeToNextLevel())
  242.  
  243. // Update the player info in the UI
  244. INJECT_update_player_info();
  245.  
  246. // Update the GUI
  247. window.gui.updateZone("None");
  248.  
  249. // Restart the round if we have that variable set
  250. if(loop_rounds) {
  251. UpdateNotificationCounts();
  252. current_game_id = undefined;
  253. INJECT_start_round(target_zone, access_token)
  254. }
  255. }
  256. }
  257. });
  258. }
  259.  
  260. // Leave an existing game
  261. var INJECT_leave_round = function() {
  262. if(current_game_id === undefined)
  263. return;
  264.  
  265. console.log("Leaving game: " + current_game_id);
  266.  
  267. // Cancel timeouts
  268. clearTimeout(current_timeout);
  269.  
  270. // POST to the endpoint
  271. $J.ajax({
  272. async: false,
  273. type: "POST",
  274. url: "https://community.steam-api.com/IMiniGameService/LeaveGame/v0001/",
  275. data: { access_token: access_token, gameid: current_game_id },
  276. success: function(data) {}
  277. });
  278.  
  279. // Clear the current game ID var
  280. current_game_id = undefined;
  281.  
  282. // Update the GUI
  283. gui.updateTask("Left Zone #" + target_zone);
  284. gui.updateStatus(false);
  285.  
  286. target_zone = -1;
  287. }
  288.  
  289. // returns 0 for easy, 1 for medium, 2 for hard
  290. var INJECT_get_difficulty = function(zone_id) {
  291. return window.gGame.m_State.m_PlanetData.zones[zone_id].difficulty;
  292. }
  293.  
  294. // Updates the player info
  295. // Currently unused. This was meant to hopefully update the UI.
  296. var INJECT_update_player_info = function() {
  297. gServer.GetPlayerInfo(
  298. function( results ) {
  299. gPlayerInfo = results.response;
  300. },
  301. function(){}
  302. &nbsp;);
  303. }
  304.  
  305. // Update the zones of the grid (map) on the current planet
  306. var INJECT_update_grid = function() {
  307. if(current_planet_id === undefined)
  308. return;
  309.  
  310. gui.updateTask('Updating grid', true);
  311.  
  312. // GET to the endpoint
  313. $J.ajax({
  314. async: false,
  315. type: "GET",
  316. url: "https://community.steam-api.com/ITerritoryControlMinigameService/GetPlanet/v0001/",
  317. data: { id: current_planet_id },
  318. success: function(data) {
  319. window.gGame.m_State.m_PlanetData = data.response.planets[0];
  320. window.gGame.m_State.m_PlanetData.zones.forEach( function ( zone ) {
  321. window.gGame.m_State.m_Grid.m_Tiles[zone.zone_position].Info.progress = zone.capture_progress;
  322. window.gGame.m_State.m_Grid.m_Tiles[zone.zone_position].Info.captured = zone.captured;
  323. });
  324. console.log("Successfully updated map data on planet: " + current_planet_id);
  325. }
  326. });
  327. }
  328.  
  329. // Defaults to max score of current zone & full round duration if no params are given
  330. function get_max_score(zone, round_duration) {
  331. // defaults
  332. if(zone === undefined)
  333. zone = target_zone;
  334. if(round_duration === undefined)
  335. round_duration = real_round_length;
  336.  
  337. var difficulty = INJECT_get_difficulty(zone);
  338. var score = 5 * round_duration * Math.pow(2, (difficulty-1));
  339.  
  340. return score;
  341. }
  342.  
  343. // Get the best zone available
  344. function GetBestZone() {
  345. var bestZoneIdx;
  346. var highestDifficulty = -1;
  347.  
  348. gui.updateTask('Getting best zone');
  349.  
  350. for (var idx = 0; idx < window.gGame.m_State.m_Grid.m_Tiles.length; idx++) {
  351. var zone = window.gGame.m_State.m_Grid.m_Tiles[idx].Info;
  352. if (!zone.captured) {
  353. if (zone.boss) {
  354. console.log("Zone " + idx + " with boss. Switching to it.");
  355. return idx;
  356. }
  357.  
  358. if(zone.difficulty > highestDifficulty) {
  359. highestDifficulty = zone.difficulty;
  360. maxProgress = zone.progress;
  361. bestZoneIdx = idx;
  362. } else if(zone.difficulty < highestDifficulty) continue;
  363.  
  364. if(zone.progress < maxProgress) {
  365. maxProgress = zone.progress;
  366. bestZoneIdx = idx;
  367. }
  368. }
  369. }
  370.  
  371. if(bestZoneIdx !== undefined) {
  372. console.log(`${window.gGame.m_State.m_PlanetData.state.name} - Zone ${bestZoneIdx} Progress: ${window.gGame.m_State.m_Grid.m_Tiles[bestZoneIdx].Info.progress} Difficulty: ${window.gGame.m_State.m_Grid.m_Tiles[bestZoneIdx].Info.difficulty}`);
  373. }
  374.  
  375. return bestZoneIdx;
  376. }
  377.  
  378. // Switch to the next zone when one is completed
  379. function SwitchNextZone(attempt_no) {
  380. if(attempt_no === undefined)
  381. attempt_no = 0;
  382.  
  383. INJECT_leave_round();
  384. INJECT_update_grid();
  385. var next_zone = GetBestZone();
  386. if (next_zone !== undefined) {
  387. console.log("Found Best Zone: " + next_zone);
  388. INJECT_start_round(next_zone, access_token, attempt_no);
  389. } else {
  390. console.log("There's no more zone, the planet must be completed. You'll need to choose another planet!");
  391. target_zone = -1;
  392. }
  393. }
  394.  
  395. // Leave the planet
  396. var INJECT_leave_planet = function() {
  397. function wait_for_state_load() {
  398. if(gGame.m_IsStateLoading || gGame.m_State instanceof CBattleSelectionState)
  399. setTimeout(function() { wait_for_state_load(); }, 50);
  400. else
  401. INJECT_init();
  402. }
  403.  
  404. // Leave our current round if we haven't.
  405. INJECT_leave_round();
  406.  
  407. // (Modified) Default Code
  408. gAudioManager.PlaySound( 'ui_select_backwards' );
  409. gServer.LeaveGameInstance(
  410. gGame.m_State.m_PlanetData.id,
  411. function() {
  412. gGame.ChangeState( new CPlanetSelectionState() );
  413. // Wait for the new state to load, then hook in
  414. wait_for_state_load();
  415. }
  416. &nbsp;);
  417. }
  418.  
  419. var INJECT_join_planet = function(planet_id, success_callback, error_callback) {
  420. function wait_for_state_load() {
  421. if(gGame.m_IsStateLoading || gGame.m_State instanceof CPlanetSelectionState)
  422. setTimeout(function() { wait_for_state_load(); }, 50);
  423. else
  424. INJECT_init();
  425. }
  426.  
  427. // Modified Default code
  428. var rgParams = {
  429. id: planet_id,
  430. access_token: access_token
  431. };
  432.  
  433. $J.ajax({
  434. url: window.gServer.m_WebAPI.BuildURL( 'ITerritoryControlMinigameService', 'JoinPlanet', true ),
  435. method: 'POST',
  436. data: rgParams
  437. }).success( function( results, textStatus, request ) {
  438. if ( request.getResponseHeader( 'x-eresult' ) == 1 ) {
  439. success_callback( results );
  440. // Wait for the new state to load, then hook in
  441. wait_for_state_load();
  442. }
  443. else {
  444. console.log(results, textStatus, request);
  445. error_callback();
  446. }
  447. }).fail( error_callback );
  448. }
  449. var INJECT_init_battle_selection = function() {
  450. gui.updateStatus(true);
  451. gui.updateTask("Initializing Battle Selection Menu.");
  452. // Auto join best zone at first
  453. if (auto_first_join == true) {
  454. firstJoin();
  455. function firstJoin() {
  456. // Wait for state & access_token
  457. if(access_token === undefined || gGame === undefined || gGame.m_IsStateLoading || gGame.m_State instanceof CPlanetSelectionState) {
  458. setTimeout(function() { firstJoin(); }, 100);
  459. console.log("waiting");
  460. return;
  461. }
  462.  
  463. current_planet_id = window.gGame.m_State.m_PlanetData.id;
  464.  
  465. var first_zone;
  466. if(target_zone === -1)
  467. first_zone = GetBestZone();
  468. else
  469. first_zone = target_zone
  470.  
  471. if(access_token === undefined)
  472. INJECT_get_access_token();
  473.  
  474. INJECT_start_round(first_zone, access_token);
  475. }
  476. }
  477.  
  478. // Overwrite join function so clicking on a grid square will run our code instead
  479. gServer.JoinZone = function (zone_id, callback, error_callback) {
  480. current_planet_id = window.gGame.m_State.m_PlanetData.id;
  481. INJECT_start_round(zone_id, access_token);
  482. }
  483.  
  484. // Hook the Grid click function
  485. var grid_click_default = gGame.m_State.m_Grid.click;
  486. gGame.m_State.m_Grid.click = function(tileX, tileY) {
  487. // Get the selected zone ID
  488. var zoneIdx = _GetTileIdx( tileX, tileY );
  489.  
  490. // Return if it's the current zone (Don't want clicking on same zone to leave/rejoin)
  491. if(target_zone === zoneIdx)
  492. return;
  493.  
  494. // Return if it's a completed zone
  495. if(window.gGame.m_State.m_Grid.m_Tiles[zoneIdx].Info.captured) {
  496. console.log("Manually selected zone already captured. Returning.");
  497. return;
  498. }
  499.  
  500. // Update the GUI
  501. gui.updateTask("Attempting manual switch to Zone #" + zoneIdx);
  502.  
  503. // Leave existing round
  504. INJECT_leave_round();
  505.  
  506. // Join new round
  507. INJECT_start_round(zoneIdx, access_token);
  508. }
  509.  
  510. // Hook the Leave Planet Button
  511. gGame.m_State.m_LeaveButton.click = function(btn) {
  512. INJECT_leave_planet();
  513. };
  514. }
  515.  
  516. var INJECT_init_planet_selection = function() {
  517. gui.updateStatus(true);
  518. gui.updateTask("Initializing Planet Selection Menu.");
  519.  
  520. // Hook the Join Planet Function
  521. gServer.JoinPlanet = function(planet_id, success_callback, error_callback) {
  522. INJECT_join_planet(planet_id, success_callback, error_callback);
  523. }
  524.  
  525. // Update GUI
  526. gui.updateStatus(false);
  527. gui.updateTask("At Planet Selection");
  528. gui.updateZone("None");
  529. };
  530.  
  531. var INJECT_init = function() {
  532. if (gGame.m_State instanceof CBattleSelectionState)
  533. INJECT_init_battle_selection();
  534. else if (gGame.m_State instanceof CPlanetSelectionState)
  535. INJECT_init_planet_selection();
  536. };
  537.  
  538. var INJECT_disable_animations = function() {
  539. var confirmed = confirm("Disabling animations will vastly reduce resources used, but you will no longer be able to manually swap zones until you refresh. Continue?");
  540.  
  541. if(confirmed) {
  542. requestAnimationFrame = function(){};
  543. $J("#disableAnimsBtn").prop("disabled",true).prop("value", "Animations Disabled.");
  544. }
  545. };
  546.  
  547. // ============= CODE THAT AUTORUNS ON LOAD =============
  548. // Auto-grab the access token
  549. INJECT_get_access_token();
  550.  
  551. // Run the global initializer, which will call the function for whichever screen you're in
  552. INJECT_init();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement