210 lines
8.0 KiB
JavaScript
210 lines
8.0 KiB
JavaScript
// ==UserScript==
|
|
// @name Grepolis Data Sender (Deep Scan v6.5 — Toolbar Pause Button + Soft Refresh & Full Stats)
|
|
// @namespace http://tampermonkey.net/
|
|
// @version 6.5
|
|
// @description Sends town stats, extracts Premium Exchange title, and soft-refreshes tab every 30s via Marketplace building click. Includes pause/resume button in top toolbar.
|
|
// @author Dimitrios
|
|
// @match https://*.grepolis.com/game/*
|
|
// @grant unsafeWindow
|
|
// @updateURL https://git.haunter-pets.top/haunter/grepodata/raw/branch/main/Grepolis_Data_Sender.user.js
|
|
// @downloadURL https://git.haunter-pets.top/haunter/grepodata/raw/branch/main/Grepolis_Data_Sender.user.js
|
|
// ==/UserScript==
|
|
|
|
(function () {
|
|
'use strict';
|
|
|
|
console.log("💰 DeepScan v6.5 loaded — Soft refresh + Toolbar pause button + full stats");
|
|
|
|
const uw = typeof unsafeWindow !== "undefined" ? unsafeWindow : window;
|
|
let latestBasicPayload = null;
|
|
let paused = false;
|
|
|
|
// 🧠 Toolbar button HTML
|
|
const deepScanButtonHtml =
|
|
'<div class="divider"></div>' +
|
|
'<div class="activity" id="dsbutton" style="filter: brightness(70%) sepia(100%) hue-rotate(-50deg) saturate(1000%) contrast(0.8);">' +
|
|
'<p id="dslabel" style="z-index:6; top:-8px; position:relative; font-weight:bold;">DeepScan</p>' +
|
|
'</div>';
|
|
|
|
// 🧠 Toggle pause/resume
|
|
function toggleDeepScanButton() {
|
|
paused = !paused;
|
|
|
|
const label = document.getElementById('dslabel');
|
|
const btn = document.getElementById('dsbutton');
|
|
|
|
if (paused) {
|
|
label.textContent = 'Paused';
|
|
btn.style.filter = 'brightness(70%) sepia(100%) hue-rotate(-50deg) saturate(1000%) contrast(0.8)';
|
|
} else {
|
|
label.textContent = 'DeepScan';
|
|
btn.style.filter = 'brightness(294%) sepia(100%) hue-rotate(15deg) saturate(1000%) contrast(0.8)';
|
|
}
|
|
|
|
console.log(`🔘 DeepScan is now ${paused ? 'paused' : 'running'}`);
|
|
}
|
|
|
|
// 🧠 Inject button into toolbar
|
|
setTimeout(() => {
|
|
if (!document.getElementById('dsbutton')) {
|
|
uw.$('.tb_activities, .toolbar_activities').find('.middle').append(deepScanButtonHtml);
|
|
}
|
|
}, 4000);
|
|
|
|
uw.$(document).on('click', '#dsbutton', toggleDeepScanButton);
|
|
|
|
// 📌 Extract Premium Exchange title
|
|
function getGoldMarketTitle() {
|
|
const titleEl = document.querySelector(
|
|
".classic_window.market #premium_exchange .game_border_header .title.exchange_title"
|
|
);
|
|
const titleText = titleEl?.textContent.trim() || "";
|
|
console.log("📌 Gold Market Title:", titleText);
|
|
return titleText;
|
|
}
|
|
|
|
// 📊 Extract gold market data
|
|
function scrapeGoldMarketExchange() {
|
|
const exchange = {};
|
|
const resourceTypes = ["wood", "stone", "iron"];
|
|
const isSellTabActive =
|
|
document.querySelector("#premium_exchange .gp_page_caption.js-page-caption-1.active") &&
|
|
document.querySelector("#premium_exchange .gp_tab_page.js-page-1.active");
|
|
|
|
if (!isSellTabActive) {
|
|
console.warn("🚫 Sell tab not active — skipping gold extraction");
|
|
return null;
|
|
}
|
|
|
|
const blocks = document.querySelectorAll(
|
|
"#premium_exchange .gp_tab_page.js-page-1.active .resources_wrapper .resource"
|
|
);
|
|
|
|
blocks.forEach((block, i) => {
|
|
const type = resourceTypes[i] || `res_${i}`;
|
|
const currentEl = block.querySelector(".progressbar_bg .caption span.current");
|
|
const maxEl = block.querySelector(".progressbar_bg .caption span.max");
|
|
|
|
exchange[type] = {
|
|
current: currentEl?.textContent.trim() || "0",
|
|
max: maxEl?.textContent.trim() || "0"
|
|
};
|
|
});
|
|
|
|
console.log("📊 Gold Market Sell Tab data:", exchange);
|
|
return exchange;
|
|
}
|
|
|
|
// 📤 Send town + gold data
|
|
function sendBasicStats() {
|
|
if (paused) {
|
|
console.log("⏸️ DeepScan is paused — skipping data send");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const towns = uw.ITowns?.towns || {};
|
|
const player = uw.Game?.player_name || "unknown";
|
|
const player_id = uw.Game?.player_id || "unknown";
|
|
|
|
const stats = Object.values(towns).map(town => {
|
|
const res = town.resources();
|
|
const buildings = town.buildings()?.attributes ?? {};
|
|
const marketLevel = typeof town.getMarketplaceLevel === "function"
|
|
? town.getMarketplaceLevel()
|
|
: buildings.market || null;
|
|
|
|
return {
|
|
town_id: town.id,
|
|
town_name: town.name,
|
|
wood: res.wood,
|
|
stone: res.stone,
|
|
iron: res.iron,
|
|
population: res.population,
|
|
points: town.getPoints(),
|
|
buildings,
|
|
market: { level: marketLevel }
|
|
};
|
|
});
|
|
|
|
const goldMarket = scrapeGoldMarketExchange();
|
|
const goldTitle = getGoldMarketTitle();
|
|
|
|
latestBasicPayload = {
|
|
type: "basic",
|
|
timestamp: new Date().toISOString(),
|
|
player,
|
|
player_id,
|
|
towns: stats,
|
|
gold_market: goldMarket || {},
|
|
gold_market_title: goldTitle || ""
|
|
};
|
|
|
|
console.log("📤 Sending payload:", latestBasicPayload);
|
|
|
|
fetch("https://grepo.haunter-pets.top/api/grepolis-data", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify(latestBasicPayload)
|
|
})
|
|
.then(res => res.text())
|
|
.then(txt => console.log("✅ Data sent:", txt))
|
|
.catch(err => console.error("❌ Failed to send:", err));
|
|
} catch (e) {
|
|
console.error("💥 Error sending stats:", e);
|
|
}
|
|
}
|
|
|
|
// 🏛️ Soft refresh: click building and switch tab
|
|
function refreshGoldWindow() {
|
|
if (paused) {
|
|
console.log("⏸️ DeepScan is paused — skipping refresh");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const marketArea = document.querySelector("area#building_main_area_market");
|
|
if (marketArea) {
|
|
marketArea.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
|
console.log("🏛️ Clicked Marketplace area to trigger Premium Exchange");
|
|
|
|
// Wait 1.5s and switch to Sell tab
|
|
setTimeout(() => {
|
|
const newWin = Array.from(document.querySelectorAll(".classic_window.market"))
|
|
.find(win => win.querySelector("#premium_exchange"));
|
|
|
|
if (newWin) {
|
|
const sellTab = newWin.querySelector(".gp_page_caption.js-page-caption-1");
|
|
if (sellTab) {
|
|
sellTab.click();
|
|
console.log("🔁 Switched to Premium Exchange Sell tab");
|
|
} else {
|
|
console.warn("⚠️ Sell tab not found in window");
|
|
}
|
|
} else {
|
|
console.warn("❌ Premium Exchange window not found after click");
|
|
}
|
|
}, 1500);
|
|
} else {
|
|
console.warn("❌ Marketplace area not found — cannot trigger Premium Exchange");
|
|
}
|
|
} catch (err) {
|
|
console.error("💥 Error in refreshGoldWindow:", err);
|
|
}
|
|
}
|
|
|
|
// 🔁 Main loop
|
|
function runDataCycle() {
|
|
setInterval(() => {
|
|
console.log("🕒 Data cycle tick — soft refresh + send stats");
|
|
refreshGoldWindow();
|
|
setTimeout(sendBasicStats, 3000);
|
|
}, 30000);
|
|
}
|
|
|
|
window.addEventListener("load", () => {
|
|
console.log("🚀 DeepScan v6.5 booting up...");
|
|
runDataCycle();
|
|
});
|
|
})();
|