您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Provides some general additions to Elethor
当前为
- // ==UserScript==
- // @name Elethor General Purpose
- // @description Provides some general additions to Elethor
- // @namespace https://www.elethor.com/
- // @version 1.4.1
- // @author Anders Morgan Larsen (Xortrox)
- // @match https://elethor.com/*
- // @match https://www.elethor.com/*
- // @run-at document-start
- // @grant none
- // ==/UserScript==
- (function() {
- const currentUserData = {};
- const moduleName = 'Elethor General Purpose';
- const version = '1.4.1'
- function initializeXHRHook() {
- let rawSend = XMLHttpRequest.prototype.send;
- XMLHttpRequest.prototype.send = function() {
- if (!this._hooked) {
- this._hooked = true;
- this.addEventListener('readystatechange', function() {
- if (this.readyState === XMLHttpRequest.DONE) {
- setupHook(this);
- }
- }, false);
- }
- rawSend.apply(this, arguments);
- }
- function setupHook(xhr) {
- if (window.elethorGeneralPurposeOnXHR) {
- const e = new Event('EGPXHR');
- e.xhr = xhr;
- window.elethorGeneralPurposeOnXHR.dispatchEvent(e);
- }
- }
- window.elethorGeneralPurposeOnXHR = new EventTarget();
- console.log(`[${moduleName} v${version}] XHR Hook initialized.`);
- }
- function initializeUserLoadListener() {
- elethorGeneralPurposeOnXHR.addEventListener('EGPXHR', function (e) {
- if (e && e.xhr
- && e.xhr.responseURL
- && e.xhr.responseURL.endsWith
- && e.xhr.responseURL.endsWith('/game/user')
- ) {
- try {
- const userData = JSON.parse(e.xhr.responseText);
- console.log(`[${moduleName} v${version}] User Data hook:`, userData);
- if (userData) {
- for (const key of Object.keys(userData)) {
- currentUserData[key] = userData[key];
- }
- console.log(`[${moduleName} v${version}] User Data loaded:`, currentUserData);
- }
- } catch (e) {
- console.log(`[${moduleName} v${version}] Error parsing userData:`, e);
- }
- }
- });
- console.log(`[${moduleName} v${version}] User Load Listener initialized.`);
- }
- function initializeToastKiller() {
- document.addEventListener('click', function(e) {
- if (e.target
- && e.target.className
- && e.target.className.includes
- && e.target.className.includes('toasted')
- ) {
- e.target.remove();
- }
- });
- console.log(`[${moduleName} v${version}] Toast Killer initialized.`);
- }
- function initializeInventoryStatsLoadListener() {
- elethorGeneralPurposeOnXHR.addEventListener('EGPXHR', function (e) {
- if (e && e.xhr
- && e.xhr.responseURL
- && e.xhr.responseURL.endsWith
- && e.xhr.responseURL.endsWith('/game/inventory/stats')
- ) {
- setTimeout(() => {
- updateEquipmentPercentageSummary();
- setTimeout(updateInventoryStatsPercentages, 1000);
- });
- }
- });
- console.log(`[${moduleName} v${version}] Inventory Stats Load Listener initialized.`);
- }
- function updateEquipmentPercentageSummary() {
- document.querySelector('.is-equipment>div>div').setAttribute('style', 'width: 50%')
- let percentagesTable = document.querySelector('#egpPercentagesSummary')
- if (!percentagesTable){
- percentagesTable = document.querySelector('.is-equipment>div>div:nth-child(2)').cloneNode(true);
- percentagesTable.setAttribute('style', 'width: 25%');
- percentagesTable.id='egpPercentagesSummary';
- document.querySelector('.is-equipment>div').appendChild(percentagesTable);
- for (const child of percentagesTable.children[0].children) {
- if (child && child.children && child.children[0]) {
- child.children[0].remove();
- }
- }
- document.querySelector('#egpPercentagesSummary>table>tr:nth-child(8)').setAttribute('style', 'height:43px');
- }
- }
- function getStatSummary(equipment) {
- const summary = {
- base: {},
- energizements: {}
- };
- if (equipment) {
- for (const key of Object.keys(equipment)) {
- const item = equipment[key];
- /**
- * Sums base attributes by name
- * */
- if (item && item.attributes) {
- for (const attributeName of Object.keys(item.attributes)) {
- const attributeValue = item.attributes[attributeName];
- if (!summary.base[attributeName]) {
- summary.base[attributeName] = 0;
- }
- summary.base[attributeName] += attributeValue;
- }
- }
- /**
- * Sums energizements by stat name
- * */
- if (item && item.upgrade && item.upgrade.energizements) {
- for (const energizement of item.upgrade.energizements) {
- if (!summary.energizements[energizement.stat]) {
- summary.energizements[energizement.stat] = 0;
- }
- summary.energizements[energizement.stat] += Number(energizement.boost);
- }
- }
- }
- }
- return summary;
- }
- function updateInventoryStatsPercentages() {
- let percentagesTable = document.querySelector('#egpPercentagesSummary')
- if (percentagesTable && currentUserData && currentUserData.equipment){
- const statSummary = getStatSummary(currentUserData.equipment);
- const baseKeys = Object.keys(statSummary.base);
- const energizementKeys = Object.keys(statSummary.energizements);
- let allKeys = baseKeys.concat(energizementKeys);
- const filterUniques = {};
- for (const key of allKeys){
- filterUniques[key] = true;
- }
- allKeys = Object.keys(filterUniques);
- allKeys.sort();
- allKeys.push('actions');
- const tableRows = percentagesTable.children[0].children;
- for(const row of tableRows) {
- if (row
- && row.children
- && row.children[0]
- && row.children[0].children[0]
- ) {
- const rowText = row.children[0].children[0];
- rowText.innerText = '';
- }
- }
- let rowIndex = 0;
- for (const key of allKeys) {
- if (key === 'puncture') {
- continue;
- }
- const row = tableRows[rowIndex];
- if (row
- && row.children
- && row.children[0]
- && row.children[0].children[0]
- ) {
- const rowText = row.children[0].children[0];
- const rowBase = statSummary.base[key] || 0;
- const rowEnergizement = (statSummary.energizements[key] || 0);
- const rowEnergizementPercentage = (statSummary.energizements[key] || 0) * 100;
- if (key.startsWith('+')) {
- rowText.innerText = `${key} per 10 levels: ${rowEnergizement}`;
- } else if (key === 'actions') {
- const actions = currentUserData.user.bonus_actions || 0;
- rowText.innerText = `Bonus Actions: ${actions}`;
- } else {
- rowText.innerText = `${key}: ${rowBase} (${rowEnergizementPercentage.toFixed(0)}%)`;
- }
- rowIndex++;
- }
- }
- }
- }
- (function run() {
- initializeToastKiller();
- initializeXHRHook();
- initializeUserLoadListener();
- initializeInventoryStatsLoadListener();
- console.log(`[${moduleName} v${version}] Loaded.`);
- })();
- (async function loadRerollDisableButtonModule() {
- async function waitForEcho() {
- return new Promise((resolve, reject) => {
- const interval = setInterval(() => {
- if (window.Echo) {
- clearInterval(interval);
- resolve();
- }
- }, 100);
- });
- }
- async function waitForUser() {
- return new Promise((resolve, reject) => {
- const interval = setInterval(() => {
- if (currentUserData.user && currentUserData.user.id !== undefined) {
- clearInterval(interval);
- resolve();
- }
- }, 100);
- });
- }
- await waitForEcho();
- await waitForUser();
- elethorGeneralPurposeOnXHR.addEventListener('EGPXHR', async function (e) {
- if (e && e.xhr && e.xhr.responseURL) {
- if(e.xhr.responseURL.includes('/game/energize')) {
- const itemID = e.xhr.responseURL.substr(e.xhr.responseURL.lastIndexOf('/')+1);
- window.lastEnergizeID = Number(itemID);
- }
- }
- });
- function initializeDisableEnergizementButtonOnReroll() {
- const privateRoom = `App.User.${currentUserData.user.id}`;
- console.log(`[${moduleName} v${version}] Binding to private room ${privateRoom}`);
- window.Echo.private(privateRoom).listen(".App\\Domain\\Inventory\\Events\\UpdateItem", (data) => {
- if (data && data.item.id === window.lastEnergizeID){
- //enableEnergizementButton();
- }
- });
- document.addEventListener('click', function(e) {
- try {
- if (!e
- || !e.target
- || !e.target.parentElement
- || !e.target.className
- || !e.target.parentElement.className
- || !e.target.innerText
- || !e.target.innerText.includes
- ) {
- return;
- }
- if ((e.target.innerText.includes('Reroll Energizements') || e.target.innerText.includes('Costs 1 Standard Energizing Shard'))
- && (e.target.className.includes('button') || e.target.parentElement.className.includes('button'))
- ) {
- // disableEnergizementButton();
- // setTimeout(enableEnergizementButton, 500);
- }
- } catch (e) {
- console.warn(`[${moduleName} v${version}] Error during document click:`, e);
- }
- });
- }
- initializeDisableEnergizementButtonOnReroll();
- function disableEnergizementButton() {
- const button = getEnergizementButton();
- if (!button) {
- return;
- }
- button.setAttribute('style', 'pointer-events: none');
- button.setAttribute('disabled', 'true');
- }
- function enableEnergizementButton() {
- const button = getEnergizementButton();
- if (!button) {
- return;
- }
- button.removeAttribute('style');
- button.removeAttribute('disabled');
- }
- function getEnergizementButton() {
- let button;
- document.querySelectorAll('.buttons>.button.is-multiline.is-info>span:first-child').forEach((e) => {
- if (e && e.innerText && e.innerText === 'Reroll Energizements') {
- button = e.parentElement;
- }
- });
- return button;
- }
- })();
- (function loadResourceNodeUpdater() {
- function updateExperienceRates() {
- document.querySelectorAll('.is-resource-node').forEach(visualizeResourceNodeExperienceRates);
- function visualizeResourceNodeExperienceRates(node) {
- const purity = getNodePurityPercentage(node);
- const density = getNodeDensityPercentage(node);
- const experience = getNodeExperience(node);
- const ore = 16;
- const experienceRate = getExperienceRate(density, experience);
- const oreRate = getOreRate(density, purity, ore);
- node.children[0].setAttribute('data-after', `${experienceRate} xp/h ${oreRate} ore/h`);
- }
- function getNodePurityPercentage(node) {
- const column = node.children[0].children[2];
- const label = column.getElementsByClassName('has-text-weight-bold')[0].parentElement;
- const percentage = Number(label.innerText.replace('%','').split(':')[1])
- return percentage;
- }
- function getNodeDensityPercentage(node) {
- const column = node.children[0].children[1];
- const label = column.getElementsByClassName('has-text-weight-bold')[0].parentElement;
- const percentage = Number(label.innerText.replace('%','').split(':')[1])
- return percentage;
- }
- function getNodeExperience(node) {
- const column = node.children[0].children[3];
- const label = column.getElementsByClassName('has-text-weight-bold')[0].parentElement;
- const value = Number(label.innerText.replace('%','').split(':')[1])
- return value;
- }
- function getExperienceRate(density, experience) {
- return Number((3600 / (60 / (density / 100)) * experience).toFixed(3));
- }
- function getOreRate(density, purity, ore) {
- return Number((3600 / (60 / (density / 100)) * (purity / 100) * ore).toFixed(3));
- }
- }
- updateExperienceRates();
- window.elethorResourceInterval = setInterval(updateExperienceRates, 500);
- initializeResourceNodeView();
- async function initializeResourceNodeView() {
- await waitForField(document, 'head');
- var css = '.columns.is-mobile.is-size-7-mobile::after { content: attr(data-after); padding: 12px;}',
- head = document.head || document.getElementsByTagName('head')[0],
- style = document.createElement('style');
- head.appendChild(style);
- style.type = 'text/css';
- if (style.styleSheet){
- // This is required for IE8 and below.
- style.styleSheet.cssText = css;
- } else {
- style.appendChild(document.createTextNode(css));
- }
- }
- async function waitForField(target, field) {
- return new Promise((resolve, reject) => {
- const interval = setInterval(() => {
- if (target[field] !== undefined) {
- clearInterval(interval);
- resolve();
- }
- }, 100);
- });
- }
- })();
- })();