Add GrepoAutoRuralResources.js
This commit is contained in:
168
GrepoAutoRuralResources.js
Normal file
168
GrepoAutoRuralResources.js
Normal file
@@ -0,0 +1,168 @@
|
||||
// ==UserScript==
|
||||
// @name GrepoTweaks-AutoRuralResources (Captain-Free Version)
|
||||
// @namespace sentinelindicator
|
||||
// @version 2.2.0
|
||||
// @description Auto farm loot from rural villages using per-town AJAX requests, no Captain required
|
||||
// @author Dimitrios
|
||||
// @match http://*.grepolis.com/game/*
|
||||
// @match https://*.grepolis.com/game/*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
const uw = typeof unsafeWindow !== "undefined" ? unsafeWindow : window;
|
||||
|
||||
const timerInterval = 300000; // 5 minutes
|
||||
const delta_time = 10000;
|
||||
let loop, lastTime, timer;
|
||||
let startOnLogin = true;
|
||||
|
||||
const buttonHtml =
|
||||
'<div class="divider"></div>' +
|
||||
'<div class="activity" id="btbutton" style="filter: brightness(70%) sepia(100%) hue-rotate(-50deg) saturate(1000%) contrast(0.8);">' +
|
||||
'<p id="ptimer" style="z-index:6; top:-8px; position:relative; font-weight:bold;"></p>' +
|
||||
'</div>';
|
||||
|
||||
function getPolisList() {
|
||||
const islandList = [];
|
||||
const polisList = [];
|
||||
const towns = uw.MM.getCollections().Town[0].models;
|
||||
|
||||
for (let town of towns) {
|
||||
const { on_small_island, island_id, id } = town.attributes;
|
||||
if (on_small_island) continue;
|
||||
if (!islandList.includes(island_id)) {
|
||||
islandList.push(island_id);
|
||||
polisList.push(id);
|
||||
}
|
||||
}
|
||||
return polisList;
|
||||
}
|
||||
|
||||
function getLootableFarms(town_id) {
|
||||
const { models: farms } = uw.MM.getOnlyCollectionByName('FarmTown');
|
||||
const { models: relations } = uw.MM.getOnlyCollectionByName('FarmTownPlayerRelation');
|
||||
const town = uw.ITowns.towns[town_id];
|
||||
const x = town.getIslandCoordinateX();
|
||||
const y = town.getIslandCoordinateY();
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
const result = [];
|
||||
|
||||
for (let farm of farms) {
|
||||
if (farm.attributes.island_x !== x || farm.attributes.island_y !== y) continue;
|
||||
|
||||
for (let rel of relations) {
|
||||
if (
|
||||
rel.attributes.farm_town_id === farm.attributes.id &&
|
||||
rel.attributes.relation_status === 1 &&
|
||||
(!rel.attributes.lootable_at || now >= rel.attributes.lootable_at)
|
||||
) {
|
||||
result.push({ town_id, farm_town_id: rel.attributes.farm_town_id, relation_id: rel.id });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function claimSingle(town_id, farm_town_id, relation_id) {
|
||||
const data = {
|
||||
model_url: `FarmTownPlayerRelation/${relation_id}`,
|
||||
action_name: 'claim',
|
||||
arguments: { farm_town_id: farm_town_id, type: 'resources', option: 1 },
|
||||
town_id: town_id,
|
||||
};
|
||||
uw.gpAjax.ajaxPost('frontend_bridge', 'execute', data);
|
||||
}
|
||||
|
||||
async function claimIndividually(polisList) {
|
||||
let max = 60;
|
||||
for (let town_id of polisList) {
|
||||
const farms = getLootableFarms(town_id);
|
||||
for (let farm of farms) {
|
||||
claimSingle(farm.town_id, farm.farm_town_id, farm.relation_id);
|
||||
await new Promise(r => setTimeout(r, 500));
|
||||
if (!--max) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getNextCollectionTime() {
|
||||
const models = uw.MM.getCollections().FarmTownPlayerRelation[0].models;
|
||||
let lootTimes = {};
|
||||
|
||||
for (let m of models) {
|
||||
const time = m.attributes.lootable_at;
|
||||
lootTimes[time] = (lootTimes[time] || 0) + 1;
|
||||
}
|
||||
|
||||
let max = 0;
|
||||
let next = 0;
|
||||
for (let key in lootTimes) {
|
||||
if (lootTimes[key] > max) {
|
||||
max = lootTimes[key];
|
||||
next = key;
|
||||
}
|
||||
}
|
||||
|
||||
const seconds = next - Math.floor(Date.now() / 1000);
|
||||
return seconds > 0 ? seconds * 1000 : 0;
|
||||
}
|
||||
|
||||
async function mainLoop() {
|
||||
const next = getNextCollectionTime();
|
||||
if (timer + 2 * delta_time < next) {
|
||||
timer = next + Math.floor(Math.random() * delta_time);
|
||||
}
|
||||
|
||||
if (timer < 1) {
|
||||
const polisList = getPolisList();
|
||||
await claimIndividually(polisList);
|
||||
timer = timerInterval + Math.floor(Math.random() * delta_time);
|
||||
setTimeout(() => uw.WMap.removeFarmTownLootCooldownIconAndRefreshLootTimers(), 2000);
|
||||
}
|
||||
|
||||
const now = Date.now();
|
||||
timer -= now - lastTime;
|
||||
lastTime = now;
|
||||
|
||||
const bt = document.getElementById('ptimer');
|
||||
bt.innerHTML = timer > 0 ? parseInt(timer / 1000) : '0';
|
||||
}
|
||||
|
||||
function handleClick() {
|
||||
const isCaptainActive = uw.GameDataPremium.isAdvisorActivated('captain');
|
||||
|
||||
if (!loop) {
|
||||
timer = getNextCollectionTime() + Math.random() * delta_time;
|
||||
lastTime = Date.now();
|
||||
loop = setInterval(mainLoop, 1000);
|
||||
|
||||
uw.$('#btbutton').css(
|
||||
'filter',
|
||||
isCaptainActive
|
||||
? 'brightness(100%) sepia(100%) hue-rotate(90deg) saturate(1500%) contrast(0.8)'
|
||||
: 'brightness(294%) sepia(100%) hue-rotate(15deg) saturate(1000%) contrast(0.8)'
|
||||
);
|
||||
} else {
|
||||
clearInterval(loop);
|
||||
loop = null;
|
||||
uw.$('#btbutton').css(
|
||||
'filter',
|
||||
'brightness(70%) sepia(100%) hue-rotate(-50deg) saturate(1000%) contrast(0.8)'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
if (!document.getElementById('btbutton')) {
|
||||
uw.$('.tb_activities, .toolbar_activities').find('.middle').append(buttonHtml);
|
||||
}
|
||||
if (startOnLogin) handleClick();
|
||||
}, 4000);
|
||||
|
||||
uw.$(document).on('click', '#btbutton', handleClick);
|
||||
|
||||
console.log('[GrepoTweaks-AutoRuralResources] Captain-free script loaded 🚀');
|
||||
})();
|
||||
Reference in New Issue
Block a user