// ==UserScript== // @name EvolveIdleSaveManager // @version 0.1 // @description Automatically synchronize EvolveIdle saves across devices // @author Daxtorim // @match https://pmotschmann.github.io/Evolve/ // @icon https://www.google.com/s2/favicons?sz=64&domain=github.io // @require https://code.jquery.com/jquery-3.7.0.min.js // @grant unsafeWindow // ==/UserScript== // ===================================================================== // Whatever just so you know where the last savegame came from const DEVICE_NAME = "unknown" // Time in milliseconds between automatic savegame uploads // set to 0 to disable const SAVE_INTERVAL = 0 // https://gist.github.com//XXXXXXXXXXXXXXXXXXXXXXXXXXXX // |------- this part --------| const GIST_ID = "XXX" // your *classic* github token with gist permissions // https://github.com/settings/tokens const AUTH_TOKEN = "ghp_XXX" // ===================================================================== $.ajaxSetup({ cache: false }); // We want the actual data function fetchAndProcessGist() { console.log("EvolveIdle: fetching savegame from gist") $.ajax({ url: 'https://api.github.com/gists/' + GIST_ID, type: 'GET', beforeSend: function(xhr) { xhr.setRequestHeader('Authorization', 'token ' + AUTH_TOKEN); }, success: function(data, txtStatus, jqXHR) { const savefile = data.files["savgame.json"].content const content = JSON.parse(savefile) const textArea = document.getElementById("importExport") textArea.value = content.savegame // importGame() would reload the page creating an infinite loop of page reloads here } }) } function pushSavegameToGist(data) { $.ajax({ url: 'https://api.github.com/gists/' + GIST_ID, type: 'PATCH', data: JSON.stringify(data), beforeSend: function(xhr) { xhr.setRequestHeader('Authorization', 'token ' + AUTH_TOKEN); }, success: function(data, txtStatus, jqXHR) { const e = document.getElementById("sync-gist-button") if (e) { e.classList.remove("has-text-error") e.classList.add("has-text-success") setTimeout(() => {e.classList.remove("has-text-success")}, 5000) } }, error: function(jqXHR, txtStatus, error) { const e = document.getElementById("sync-gist-button") if (e) { e.classList.add("has-text-error") } } }); } function syncEvolveSavegame() { let content = {} const date = new Date() content.lastUpdateTime = date.toISOString() content.lastUpdateDevice = DEVICE_NAME content.savegame = unsafeWindow.exportGame() const patch = { files: { 'savgame.json': { content: JSON.stringify(content) } } } pushSavegameToGist(patch) } function createHTMLSyncButton() { const settingsMenu = document.getElementById("settings") if (!settingsMenu) { setTimeout(createHTMLSyncButton, 1000) return } const syncButton = document.createElement("button") syncButton.innerText = "Push to gist" syncButton.id = "sync-gist-button" syncButton.className = "button" syncButton.onclick = syncEvolveSavegame const backupButton = settingsMenu.getElementsByClassName("importExport")[1].lastElementChild backupButton.before(syncButton) } (async function() { 'use strict'; fetchAndProcessGist() createHTMLSyncButton() if (SAVE_INTERVAL > 0) { setInterval(syncEvolveSavegame, SAVE_INTERVAL) } })();