// ==UserScript== // @name Grepolis Data Sender (Deep Scan v6.8 β€” Toolbar Pause Button + Window Reopen & Full Stats) // @namespace http://tampermonkey.net/ // @version 6.8 // @description Sends town stats, extracts Premium Exchange title, and refreshes tab every 30s by closing and reopening Marketplace. 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.8 loaded β€” Toolbar pause button + window reopen + full stats"); const uw = typeof unsafeWindow !== "undefined" ? unsafeWindow : window; let latestBasicPayload = null; let paused = false; // 🧠 Toolbar button HTML const deepScanButtonHtml = '
' + '
' + '

DeepScan

' + '
'; // 🧠 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); } } // ❎ Close all Marketplace windows function forceCloseMarketplaceWindows() { const marketWindows = document.querySelectorAll(".classic_window.market"); marketWindows.forEach(win => { const closeBtn = win.querySelector(".buttons_container .btn_wnd.close"); if (closeBtn) { closeBtn.click(); console.log("❎ Clicked close button for Marketplace window:", win.id); } else { console.warn("⚠️ Close button not found in window:", win.id); } }); } // πŸ›οΈ Refresh Premium Exchange tab by closing and reopening function refreshGoldWindow() { if (paused) { console.log("⏸️ DeepScan is paused β€” skipping refresh"); return; } try { forceCloseMarketplaceWindows(); setTimeout(() => { const marketArea = document.querySelector("area#building_main_area_market"); if (marketArea) { marketArea.dispatchEvent(new MouseEvent("click", { bubbles: true })); console.log("πŸ›οΈ Clicked Marketplace area to reopen Premium Exchange"); 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 reopened window"); } } else { console.warn("❌ Premium Exchange window not found after reopening"); } }, 1500); } else { console.warn("❌ Marketplace area not found β€” cannot reopen Premium Exchange"); } }, 5000); } catch (err) { console.error("πŸ’₯ Error in refreshGoldWindow:", err); } } // πŸ” Main loop function runDataCycle() { setInterval(() => { console.log("πŸ•’ Data cycle tick β€” close/reopen + send stats"); refreshGoldWindow(); setTimeout(sendBasicStats, 7000); // after reopen + tab switch }, 30000); } window.addEventListener("load", () => { console.log("πŸš€ DeepScan v6.8 booting up..."); runDataCycle(); }); })();