gold market update and remove the classic market
This commit is contained in:
@@ -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();
|
||||
});
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user