Advertisement
Guest User

salienidle

a guest
Jun 22nd, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.69 KB | None | 0 0
  1. // ==UserScript==
  2. // @name saliengame_idler
  3. // @namespace http://tampermonkey.net/
  4. // @version 1
  5. // @description Beat all the saliens levels
  6. // @author https://github.com/ensingm2/saliengame_idler
  7. // @match https://steamcommunity.com/saliengame
  8. // @match https://steamcommunity.com/saliengame/
  9. // @match https://steamcommunity.com/saliengame/play
  10. // @match https://steamcommunity.com/saliengame/play/
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14.  
  15. // This is the zone you want to attack (Optional, otherwise picks one for you).
  16. var target_zone = -1;
  17.  
  18. // Variables. Don't change these unless you know what you're doing.
  19. var max_scores = [600, 1200, 2400] // Max scores for each difficulty (easy, medium, hard)
  20. var round_length = 110; // Round Length (In Seconds)
  21. var update_length = 1; // How long to wait between updates (In Seconds)
  22. var loop_rounds = true;
  23. var language = "english"; // Used when POSTing scores
  24. var access_token = "";
  25. var current_game_id = undefined;
  26. var current_timeout = undefined;
  27. var max_retry = 3; // Max number of retries to report your score
  28. var current_retry = 0;
  29. var auto_first_join = true; // Automatically join the best zone at first
  30. var current_planet_id = undefined;
  31.  
  32. class BotGUI {
  33. constructor(state) {
  34. console.log('GUI Has been created');
  35.  
  36. this.state = state;
  37.  
  38. this.createStatusWindow();
  39. }
  40.  
  41. createStatusWindow() {
  42. if(document.getElementById('salienbot_gui')) {
  43. return false;
  44. }
  45.  
  46. var $statusWindow = $J([
  47. '<div id="salienbot_gui" style="background: #191919; z-index: 1; border: 3px solid #83d674; padding: 20px; margin: 15px; width: 300px; transform: translate(0, 0);">',
  48. '<h1><a href="https://github.com/ensingm2/saliengame_idler/">Salien Game Idler</a></h1>',
  49. '<p style="margin-top: -.8em; font-size: .75em"><span id="salienbot_status"></span></p>', // Running or stopped
  50. '<p>Task: <span id="salienbot_task">Initializing</span></p>', // Current task
  51. `<p>Target Zone: <span id="salienbot_zone">None</span></p>`,
  52. '<p>Level: <span id="salienbot_level">' + this.state.level + '</span> &nbsp;&nbsp;&nbsp;&nbsp; EXP: <span id="salienbot_exp">' + this.state.exp + '</span></p>',
  53. '<p>Est. TimeToLVL: <span id="salienbot_esttimlvl"></span></p>',
  54. '</div>'
  55. ].join(''))
  56.  
  57. $J('#salien_game_placeholder').append( $statusWindow )
  58. }
  59.  
  60. updateStatus(running) {
  61. const statusTxt = running ? '<span style="color: green;">✓ Running</span>' : '<span style="color: red;">✗ Stopped</span>';
  62.  
  63. $J('#salienbot_status').html(statusTxt);
  64. }
  65.  
  66. updateTask(status, log_to_console) {
  67. if(log_to_console)
  68. console.log(status);
  69. document.getElementById('salienbot_task').innerText = status;
  70. }
  71.  
  72. updateExp(exp) {
  73. document.getElementById('salienbot_exp').innerText = exp;
  74. }
  75.  
  76. updateLevel(level) {
  77. document.getElementById('salienbot_zone').innerText = level;
  78. }
  79.  
  80. updateEstimatedTime(secondsLeft) {
  81. let date = new Date(null);
  82. date.setSeconds(secondsLeft);
  83. var result = date.toISOString().substr(11, 8);
  84.  
  85. var timeTxt = result.replace(/(\d{2}):(\d{2}):(\d{2})/gm, '$1h $2m $3s');
  86.  
  87. document.getElementById('salienbot_esttimlvl').innerText = timeTxt;
  88. }
  89.  
  90. updateZone(zone, progress) {
  91. var printString = zone;
  92. if(progress !== undefined)
  93. printString += " (" + (progress * 100).toFixed(2) + "% Complete)"
  94.  
  95. document.getElementById('salienbot_zone').innerText = printString;
  96. }
  97. };
  98.  
  99. var gui = new BotGUI({
  100. level: gPlayerInfo.level,
  101. exp: gPlayerInfo.score
  102. });
  103.  
  104. function calculateTimeToNextLevel() {
  105. const missingExp = gPlayerInfo.next_level_score - gPlayerInfo.score;
  106. const nextScoreAmount = max_scores[INJECT_get_difficulty(target_zone)];
  107. const roundTime = round_length + update_length;
  108.  
  109. const secondsLeft = missingExp / nextScoreAmount * roundTime;
  110.  
  111. return secondsLeft;
  112. }
  113.  
  114. // Grab the user's access token
  115. var INJECT_get_access_token = function() {
  116. $J.ajax({
  117. type: "GET",
  118. url: "https://steamcommunity.com/saliengame/gettoken",
  119. success: function(data) {
  120. if(data.token != undefined) {
  121. console.log("Got access token: " + data.token);
  122. access_token = data.token;
  123. }
  124. else {
  125. console.log("Failed to retrieve access token.")
  126. access_token = undefined;
  127. }
  128. }
  129. });
  130. }
  131.  
  132. // Make the call to start a round, and kick-off the idle process
  133. var INJECT_start_round = function(zone, access_token) {
  134. // Leave the game if we're already in one.
  135. if(current_game_id !== undefined) {
  136. gui.updateTask("Previous game detected. Ending it.", true);
  137. INJECT_leave_round();
  138. }
  139.  
  140. // Update the estimate
  141. gui.updateEstimatedTime(calculateTimeToNextLevel())
  142.  
  143. // Send the POST to join the game.
  144. $J.ajax({
  145. type: "POST",
  146. url: "https://community.steam-api.com/ITerritoryControlMinigameService/JoinZone/v0001/",
  147. data: { access_token: access_token, zone_position: zone },
  148. success: function(data) {
  149. console.log("Round successfully started in zone #" + zone);
  150. console.log(data);
  151.  
  152. // Update the GUI
  153. window.gui.updateZone(zone, data.response.zone_info.capture_progress);
  154.  
  155. if (data.response.zone_info !== undefined) {
  156. current_game_id = data.response.zone_info.gameid;
  157. INJECT_wait_for_end(round_length);
  158. } else {
  159. SwitchNextZone();
  160. }
  161. },
  162. error: function (xhr, ajaxOptions, thrownError) {
  163. alert("Error starting round: " + xhr.status + ": " + thrownError);
  164. }
  165. });
  166. }
  167.  
  168. // Update time remaining, and wait for the round to complete.
  169. var INJECT_wait_for_end = function(time_remaining) {
  170. gui.updateTask("Waiting " + time_remaining + "s for round to end", false);
  171.  
  172. // Wait
  173. var wait_time;
  174. var callback;
  175. if(time_remaining <= update_length) {
  176. wait_time = time_remaining*1000;
  177. callback = function() { INJECT_end_round(); };
  178. }
  179. else {
  180. var wait_time = update_length*1000;
  181. callback = function() { INJECT_wait_for_end(time_remaining); };
  182. }
  183.  
  184. // Decrement timer
  185. time_remaining -= update_length;
  186.  
  187. // Set the timeout
  188. current_timeout = setTimeout(callback, wait_time);
  189. }
  190.  
  191. // Send the call to end a round, and restart if needed.
  192. var INJECT_end_round = function() {
  193. // Grab the max score we're allowed to send
  194. var score = max_scores[INJECT_get_difficulty(target_zone)];
  195.  
  196. // Post our "Yay we beat the level" call
  197. $J.ajax({
  198. type: "POST",
  199. url: "https://community.steam-api.com/ITerritoryControlMinigameService/ReportScore/v0001/",
  200. data: { access_token: access_token, score: score, language: language },
  201. success: function(data) {
  202. if( $J.isEmptyObject(data.response) ) {
  203. if (current_retry < max_retry) {
  204. gui.updateTask("Empty Response. Waiting 5s and trying again.", true);
  205. current_timeout = setTimeout(function() { INJECT_end_round(); }, 5000);
  206. current_retry++;
  207. } else {
  208. current_retry = 0;
  209. SwitchNextZone();
  210. }
  211. }
  212. else {
  213. console.log("Successfully finished the round and got expected data back:");
  214. console.log("Level: ", data.response.new_level, "\nEXP: ", data.response.new_score);
  215. console.log(data);
  216.  
  217. gui.updateLevel(data.response.new_level);
  218. gui.updateExp(data.response.new_score);
  219. // When we get a new EXP we also want to recalculate the time for next level.
  220. gui.updateEstimatedTime(calculateTimeToNextLevel())
  221.  
  222. // Update the player info in the UI
  223. INJECT_update_player_info();
  224.  
  225. // Update the GUI
  226. window.gui.updateZone("None");
  227.  
  228. // Restart the round if we have that variable set
  229. if(loop_rounds) {
  230. UpdateNotificationCounts();
  231. current_game_id = undefined;
  232. INJECT_start_round(target_zone, access_token)
  233. }
  234. }
  235. }
  236. });
  237. }
  238.  
  239. // Leave an existing game
  240. var INJECT_leave_round = function() {
  241. if(current_game_id === undefined)
  242. return;
  243.  
  244. console.log("Leaving game: " + current_game_id);
  245.  
  246. // Cancel timeouts
  247. clearTimeout(current_timeout);
  248.  
  249. // POST to the endpoint
  250. $J.ajax({
  251. async: false,
  252. type: "POST",
  253. url: "https://community.steam-api.com/IMiniGameService/LeaveGame/v0001/",
  254. data: { access_token: access_token, gameid: current_game_id },
  255. success: function(data) {}
  256. });
  257.  
  258. // Clear the current game ID var
  259. current_game_id = undefined;
  260. gui.updateStatus(0);
  261. }
  262.  
  263. // returns 0 for easy, 1 for medium, 2 for hard
  264. var INJECT_get_difficulty = function(zone_id) {
  265. return window.gGame.m_State.m_PlanetData.zones[zone_id].difficulty - 1;
  266. }
  267.  
  268. // Updates the player info
  269. // Currently unused. This was meant to hopefully update the UI.
  270. var INJECT_update_player_info = function() {
  271. gServer.GetPlayerInfo(
  272. function( results ) {
  273. gPlayerInfo = results.response;
  274. },
  275. function(){}
  276. );
  277. }
  278.  
  279. // Update the zones of the grid (map) on the current planet
  280. var INJECT_update_grid = function() {
  281. if(current_planet_id === undefined)
  282. return;
  283.  
  284. gui.updateTask('Updating grid', true);
  285.  
  286. // GET to the endpoint
  287. $J.ajax({
  288. async: false,
  289. type: "GET",
  290. url: "https://community.steam-api.com/ITerritoryControlMinigameService/GetPlanet/v0001/",
  291. data: { id: current_planet_id },
  292. success: function(data) {
  293. window.gGame.m_State.m_PlanetData = data.response.planets[0];
  294. window.gGame.m_State.m_PlanetData.zones.forEach( function ( zone ) {
  295. window.gGame.m_State.m_Grid.m_Tiles[zone.zone_position].Info.progress = zone.capture_progress;
  296. window.gGame.m_State.m_Grid.m_Tiles[zone.zone_position].Info.captured = zone.captured;
  297. });
  298. console.log("Successfully updated map data on planet: " + current_planet_id);
  299. }
  300. });
  301. }
  302.  
  303. // Get the best zone available
  304. function GetBestZone() {
  305. var bestZoneIdx;
  306. var highestDifficulty = -1;
  307.  
  308. gui.updateStatus('Getting best zone');
  309.  
  310. for (var idx = 0; idx < window.gGame.m_State.m_Grid.m_Tiles.length; idx++) {
  311. var zone = window.gGame.m_State.m_Grid.m_Tiles[idx].Info;
  312. if (!zone.captured) {
  313. if (zone.boss) {
  314. console.log("Zone " + idx + " with boss. Switching to it.");
  315. return idx;
  316. }
  317.  
  318. if(zone.difficulty > highestDifficulty) {
  319. highestDifficulty = zone.difficulty;
  320. maxProgress = zone.progress;
  321. bestZoneIdx = idx;
  322. } else if(zone.difficulty < highestDifficulty) continue;
  323.  
  324. if(zone.progress < maxProgress) {
  325. maxProgress = zone.progress;
  326. bestZoneIdx = idx;
  327. }
  328. }
  329. }
  330.  
  331. if(bestZoneIdx !== undefined) {
  332. 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}`);
  333. }
  334.  
  335. return bestZoneIdx;
  336. }
  337.  
  338. // Switch to the next zone when one is completed
  339. function SwitchNextZone() {
  340. INJECT_leave_round();
  341. INJECT_update_grid();
  342. var next_zone = GetBestZone();
  343. if (next_zone !== undefined) {
  344. console.log("Zone #" + target_zone + " has ended. Trying #" + next_zone);
  345. target_zone = next_zone;
  346. INJECT_start_round(next_zone, access_token);
  347. } else {
  348. console.log("There's no more zone, the planet must be completed. You'll need to choose another planet!");
  349. target_zone = -1;
  350. }
  351. }
  352.  
  353. // Auto-grab the access token
  354. INJECT_get_access_token();
  355.  
  356. // Auto join best zone at first
  357. if (auto_first_join == true) {
  358. var delayingStart = setTimeout(firstJoin, 3000);
  359. function firstJoin() {
  360. clearTimeout(delayingStart);
  361. current_planet_id = window.gGame.m_State.m_PlanetData.id;
  362. if(target_zone === -1)
  363. target_zone = GetBestZone();
  364. INJECT_start_round(target_zone, access_token);
  365. }
  366. }
  367.  
  368. // Disable the game animations to minimize browser CPU usage
  369. requestAnimationFrame = function(){}
  370.  
  371. // Overwrite join function so clicking on a grid square will run our code instead
  372. gServer.JoinZone = function (zone_id, callback, error_callback) {
  373. current_planet_id = window.gGame.m_State.m_PlanetData.id;
  374. target_zone = zone_id;
  375. INJECT_start_round(zone_id, access_token);
  376. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement