diff --git a/Grepolis_Data_Sender.user.js b/Grepolis_Data_Sender.user.js index 3627d12..46f3bb8 100644 --- a/Grepolis_Data_Sender.user.js +++ b/Grepolis_Data_Sender.user.js @@ -1,8 +1,8 @@ // ==UserScript== -// @name Grepolis Data Sender (Deep Scan v4.8 — Fixed Town ID) +// @name Grepolis Data Sender (Deep Scan v5.2 — Gold Sell Tab & Town Snapshot) // @namespace http://tampermonkey.net/ -// @version 4.9 -// @description Sends town stats and merges marketplace offers into correct town (robust ID detection) +// @version 5.2 +// @description Sends town stats always, and Premium Exchange gold market from "Sell resources for gold" tab only // @author Dimitrios // @match https://*.grepolis.com/game/* // @grant unsafeWindow @@ -13,12 +13,44 @@ (function () { 'use strict'; - console.log("🧠 DeepScan v4.9 initialized..."); + console.log("💰 DeepScan v5.2 loaded — Town stats always, Premium gold tab if active"); const uw = typeof unsafeWindow !== "undefined" ? unsafeWindow : window; let latestBasicPayload = null; - // 🔄 Send town snapshot and cache + // 💱 Extract data ONLY from "Sell resources for gold" tab + 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 all town stats — always function sendBasicStats() { try { const towns = uw.ITowns?.towns || {}; @@ -45,12 +77,15 @@ }; }); + const goldMarket = scrapeGoldMarketExchange(); // may return null + latestBasicPayload = { type: "basic", timestamp: new Date().toISOString(), player, player_id, - towns: stats + towns: stats, + gold_market: goldMarket || {} // always include field }; fetch("https://grepo.haunter-pets.top/api/grepolis-data", { @@ -59,121 +94,23 @@ body: JSON.stringify(latestBasicPayload) }) .then(res => res.text()) - .then(txt => console.log("✅ Basic stats sent:", txt)) - .catch(err => console.error("❌ Failed to send basic stats:", err)); + .then(txt => console.log("✅ Data sent:", txt)) + .catch(err => console.error("❌ Failed to send:", err)); } catch (e) { - console.error("💥 Error collecting basic stats:", e); + console.error("💥 Error sending data:", e); } } - // 📄 Parse marketplace trade offers - function parseMarketOffers() { - const rows = document.querySelectorAll(".js-tutorial-market-offers-table tbody tr"); - const offers = []; - - rows.forEach(row => { - const cells = row.querySelectorAll("td"); - if (cells.length < 10) return; - - const extractType = (td) => { - const icon = td.querySelector("span"); - if (!icon) return ""; - if (icon.classList.contains("market_wood_icon")) return "wood"; - if (icon.classList.contains("market_stone_icon")) return "stone"; - if (icon.classList.contains("market_iron_icon")) return "iron"; - return ""; - }; - - offers.push({ - offer_id: row.dataset.offerId || null, - give_type: extractType(cells[0]), - give_amount: cells[1]?.textContent.trim() || "", - get_amount: cells[4]?.textContent.trim() || "", - get_type: extractType(cells[5]), - duration: cells[7]?.textContent.trim() || "", - player: cells[8]?.querySelector(".gp_player_link")?.textContent.trim() || "unknown" - }); - }); - - return offers; - } - - // 🧬 Merge trades into correct town object - function sendMergedMarketStats() { - try { - const offers = parseMarketOffers(); - if (offers.length === 0) { - console.warn("⚠️ No marketplace offers detected"); - return; - } - - const townId = - uw.Game?.townId || - uw.ITowns?.getCurrentTown()?.id || - uw.current_town_id || - "unknown"; - - console.log("🏙️ Active Town ID:", townId); - console.log("📋 Available Town IDs:", latestBasicPayload?.towns?.map(t => t.town_id)); - - if (!latestBasicPayload || !latestBasicPayload.towns) { - console.warn("🚫 Basic stats not yet initialized"); - return; - } - - const town = latestBasicPayload.towns.find(t => String(t.town_id) === String(townId)); - if (!town) { - console.warn(`🧭 No matching town found for ID ${townId}`); - return; - } - - town.market.offers = offers; - latestBasicPayload.timestamp = new Date().toISOString(); - - 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("✅ Merged trades sent:", txt)) - .catch(err => console.error("❌ Failed to send merged data:", err)); - } catch (err) { - console.error("💥 Error during marketplace merge:", err); - } - } - - // 👁️ Watch for marketplace panel opening - function monitorMarketplace() { - const observer = new MutationObserver(() => { - const panel = document.querySelector('.marketplace.all_offers'); - if (panel && panel.offsetParent !== null) { - console.log("👁️ Marketplace opened — merging trades"); - observer.disconnect(); - sendMergedMarketStats(); - setInterval(sendMergedMarketStats, 30000); - } - }); - - observer.observe(document.body, { childList: true, subtree: true }); - } - - // 🕓 Start script after town data is ready - function waitForTowns() { - const towns = uw.ITowns?.towns; - if (towns && Object.keys(towns).length > 0) { - console.log("🧭 Towns ready — starting DeepScan"); + // ⏱️ Timer: always sends town info; adds gold data only if Sell tab active + function runDataSendInterval() { + setInterval(() => { + console.log("🕒 Snapshot triggered — scanning town and gold sell tab..."); sendBasicStats(); - setInterval(sendBasicStats, 30000); - monitorMarketplace(); - } else { - console.log("⏳ Waiting for town data..."); - setTimeout(waitForTowns, 1000); - } + }, 30000); } window.addEventListener("load", () => { - console.log("🚀 Game page loaded — DeepScan v4.8 booting..."); - waitForTowns(); + console.log("🚀 Grepolis page ready — DeepScan v5.2 booting..."); + runDataSendInterval(); }); })();