Skip to content

Commit

Permalink
UserScript: add user-script
Browse files Browse the repository at this point in the history
The userscript aims at loading any version of the automation.
To avoid any breaking changes, it was split into 2 files:
  - Automation-UserScript.js that will be used by the end-user
    and should never change
  - ComponentLoader.js that will be in charge of loading any
    needed js files and run the automation once loaded
  • Loading branch information
Farigh committed Jun 3, 2022
1 parent be7c964 commit aac4429
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 0 deletions.
37 changes: 37 additions & 0 deletions Automation-UserScript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// ==UserScript==
// @name Pokeclicker Automation
// @namespace https://github.com/Farigh/pokeclicker-automation/
// @version 0.1
// @description Automation for pokeclicker.com
// @author GARCIN David
// @match https://www.pokeclicker.com
// @icon https://www.google.com/s2/favicons?sz=64&domain=pokeclicker.com
// @grant none
// ==/UserScript==

// By default, the script is set to take the latest version available
// It could be preferable to set this to a label or a commit instead,
// if you want to fix a set version of the script
var releaseLabel = "master";

var pokeclickerAutomationReleaseUrl = "https://raw.githubusercontent.com/Farigh/pokeclicker-automation/" + releaseLabel + "/";

// Github only serves plain-text so we can't load it as a script object directly
let xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function()
{
if ((xmlhttp.readyState == 4) && (xmlhttp.status == 200))
{
// Store the content into a script div
var script = document.createElement('script');
script.innerHTML = xmlhttp.responseText;
script.id = "pokeclicker-automation-component-loader";
document.head.appendChild(script);

AutomationComponentLoader.loadFromUrl(pokeclickerAutomationReleaseUrl);
}
}

// Download the content
xmlhttp.open("GET", pokeclickerAutomationReleaseUrl + "src/ComponentLoader.js", true);
xmlhttp.send();
112 changes: 112 additions & 0 deletions src/ComponentLoader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/**
* @class The automation loader abstraction class.
*
* This class contains a loadFromUrl function that is used by the userscript to load the module.
* This is possible because pokeclicker is in the same origin as GitHub.
* pokeclicker.com is probably only an alias on a github.io pages.
*/
class AutomationComponentLoader
{
static __baseUrl = null;
static __loadingTable = {};

/**
* @brief Loads the Automation classes from the given @p baseUrl
*
* @param baseUrl: The base URL to download the lib component files from
*
* @warning This function should never change its prototype, otherwise it would break the API
*/
static loadFromUrl(baseUrl)
{
this.__baseUrl = baseUrl;

this.__loadScript("src/lib/Click.js");
this.__loadScript("src/lib/Dungeon.js");
this.__loadScript("src/lib/Farm.js");
this.__loadScript("src/lib/Gym.js");
this.__loadScript("src/lib/Hatchery.js");
this.__loadScript("src/lib/Items.js");
this.__loadScript("src/lib/Menu.js");
this.__loadScript("src/lib/Quest.js");
this.__loadScript("src/lib/Trivia.js");
this.__loadScript("src/lib/Underground.js");
this.__loadScript("src/lib/Utils.js");

this.__setupAutomationRunner();
}

/**
* @brief Download the given @p fileRelativePath js file, and loads it into the page as a script component
*
* @param fileRelativePath: The file path relative to the @p __baseUrl
*/
static __loadScript(fileRelativePath)
{
let scriptName = this.__extractNameFromFile(fileRelativePath);
this.__loadingTable[scriptName] = false;

// Github only serves plain-text so we can't load it as a script object directly
let request = new XMLHttpRequest();
request.onreadystatechange = function()
{
if ((request.readyState == 4) && (request.status == 200))
{
// Store the content into a script div
var script = document.createElement('script');
script.innerHTML = request.responseText;
script.id = "pokeclicker-automation-" + scriptName;
document.head.appendChild(script);

this.__loadingTable[scriptName] = true;
}
}.bind(this);

// Download the content
request.open("GET", this.__baseUrl + fileRelativePath, true);
request.send();
}

/**
* @brief Extracts the script name from the given @p filePath
*
* @param filePath: The path to extract the script name from
*/
static __extractNameFromFile(filePath)
{
return filePath.match(/^(.*\/)?([^/]+)\.js$/)[2].toLowerCase();
}

/**
* @brief Sets a loading watcher.
* Once all scripts are properly loaded, the main class is loaded.
* Once done, it runs the automation.
*/
static __setupAutomationRunner()
{
let isMainLoading = false;

let watcher = setInterval(function ()
{
let isLoadingCompleted = Object.keys(this.__loadingTable).every(key => this.__loadingTable[key]);

if (!isLoadingCompleted)
{
return;
}

// Load the main class last (dependency requirement)
if (!isMainLoading)
{
this.__loadScript("src/Automation.js");
isMainLoading = true;
return;
}

clearInterval(watcher);

// Start the automation
Automation.start();
}.bind(this), 200); // Check every 200ms
}
}

0 comments on commit aac4429

Please sign in to comment.