From bb7d7392a89f66fad894de0eeb276a4e711cdcba Mon Sep 17 00:00:00 2001 From: haunter Date: Mon, 20 Apr 2026 12:24:51 +0300 Subject: [PATCH] enchance data --- GrepolisRemoteControl.user.js | 44 +++++++++++++++++++++++++++++++---- db.py | 18 ++++++++++++++ routes/api.py | 32 ++++++++++++++++++------- routes/dashboard.py | 35 ++++++++++++++++++---------- templates/dashboard.html | 30 ++++++++++++++++++++---- 5 files changed, 129 insertions(+), 30 deletions(-) diff --git a/GrepolisRemoteControl.user.js b/GrepolisRemoteControl.user.js index a257a22..4dcacec 100644 --- a/GrepolisRemoteControl.user.js +++ b/GrepolisRemoteControl.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name Grepolis Remote Control // @namespace http://tampermonkey.net/ -// @version 1.2 +// @version 1.3 // @description Polls grepo.haunter-pets.top for remote commands and executes them in-game // @author Dimitrios // @match https://*.grepolis.com/game/* @@ -67,9 +67,13 @@ // Push town state to relay // ---------------------------------------------------------------- function gatherState() { - const towns = uw.ITowns?.towns || {}; - const player = uw.Game?.player_name || ''; - const world = uw.Game?.world_id || ''; + const towns = uw.ITowns?.towns || {}; + const player = uw.Game?.player_name || ''; + const player_id = uw.Game?.player_id ?? null; + const alliance_id = uw.Game?.alliance_id ?? null; + const total_points = uw.Game?.player_points ?? 0; + const world = uw.Game?.world_id || ''; + const townList = Object.values(towns).map(town => { const res = town.resources(); @@ -135,9 +139,35 @@ log(`storage capacity lookup failed: ${e}`); } + // ---- Coordinates & sea zone ----------------------------------------- + let x = null, y = null, sea = null; + try { + x = town.getIslandCoordinateX?.() ?? null; + y = town.getIslandCoordinateY?.() ?? null; + if (typeof x === 'number' && typeof y === 'number') { + sea = Math.floor(x / 100) * 10 + Math.floor(y / 100); + } + } catch (e) {} + + // ---- Researches ----------------------------------------------------- + let researches = {}; + try { + const r = town.researches?.(); + if (r) researches = r.attributes ?? (typeof r === 'object' ? r : {}); + } catch (e) {} + + // ---- Extra town flags ----------------------------------------------- + let has_premium = false; + let bonuses = {}; + let wonder_points = 0; + try { has_premium = town.hasPremium?.() || false; } catch (e) {} + try { bonuses = town.getBonus?.() || {}; } catch (e) {} + try { wonder_points = town.wonder_points || 0; } catch (e) {} + return { town_id: town.id, town_name: town.name, + x, y, sea, wood: res.wood, stone: res.stone, iron: res.iron, @@ -149,10 +179,14 @@ units: unitsObj, buildingOrder: buildQueue, buildData: buildDataMap, + researches, + has_premium, + bonuses, + wonder_points, }; }); - return { player, world_id: world, towns: townList }; + return { player, player_id, alliance_id, total_points, world_id: world, towns: townList }; } function pushState() { diff --git a/db.py b/db.py index b82f1c9..d037bc8 100644 --- a/db.py +++ b/db.py @@ -35,11 +35,29 @@ def init_db(): town_id TEXT PRIMARY KEY, town_name TEXT, player TEXT, + player_id TEXT, + alliance_id TEXT, world_id TEXT, + x REAL, + y REAL, + sea INTEGER, data TEXT NOT NULL, -- full JSON snapshot updated_at TEXT NOT NULL DEFAULT (datetime('now')) ) ''') + # Migration: add new columns if upgrading an existing database + for _col in [ + 'ALTER TABLE town_state ADD COLUMN player_id TEXT', + 'ALTER TABLE town_state ADD COLUMN alliance_id TEXT', + 'ALTER TABLE town_state ADD COLUMN x REAL', + 'ALTER TABLE town_state ADD COLUMN y REAL', + 'ALTER TABLE town_state ADD COLUMN sea INTEGER', + ]: + try: + c.execute(_col) + except Exception: + pass # column already exists + conn.commit() conn.close() diff --git a/routes/api.py b/routes/api.py index 4006f46..b11e65d 100644 --- a/routes/api.py +++ b/routes/api.py @@ -17,26 +17,40 @@ def receive_state(): return jsonify({'error': 'no data'}), 400 towns = data.get('towns', []) - player = data.get('player', '') - world_id = data.get('world_id', '') + player = data.get('player', '') + player_id = data.get('player_id', '') + alliance_id = str(data.get('alliance_id', '') or '') + world_id = data.get('world_id', '') conn = get_db() c = conn.cursor() for town in towns: + x = town.get('x') + y = town.get('y') + sea = town.get('sea') c.execute(''' - INSERT INTO town_state (town_id, town_name, player, world_id, data, updated_at) - VALUES (?, ?, ?, ?, ?, ?) + INSERT INTO town_state + (town_id, town_name, player, player_id, alliance_id, world_id, x, y, sea, data, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(town_id) DO UPDATE SET - town_name = excluded.town_name, - player = excluded.player, - world_id = excluded.world_id, - data = excluded.data, - updated_at = excluded.updated_at + town_name = excluded.town_name, + player = excluded.player, + player_id = excluded.player_id, + alliance_id = excluded.alliance_id, + world_id = excluded.world_id, + x = excluded.x, + y = excluded.y, + sea = excluded.sea, + data = excluded.data, + updated_at = excluded.updated_at ''', ( str(town['town_id']), town.get('town_name', ''), player, + player_id, + alliance_id, world_id, + x, y, sea, json.dumps(town), datetime.utcnow().isoformat() )) diff --git a/routes/dashboard.py b/routes/dashboard.py index 30d1be3..93f9f7f 100644 --- a/routes/dashboard.py +++ b/routes/dashboard.py @@ -23,7 +23,8 @@ def index(): def get_towns(): conn = get_db() rows = conn.execute(''' - SELECT town_id, town_name, player, world_id, data, updated_at + SELECT town_id, town_name, player, player_id, alliance_id, + world_id, x, y, sea, data, updated_at FROM town_state ORDER BY town_name ASC ''').fetchall() @@ -33,11 +34,16 @@ def get_towns(): for row in rows: d = json.loads(row['data']) towns.append({ - 'town_id': row['town_id'], - 'town_name': row['town_name'], - 'player': row['player'], - 'world_id': row['world_id'], - 'updated_at': row['updated_at'], + 'town_id': row['town_id'], + 'town_name': row['town_name'], + 'player': row['player'], + 'player_id': row['player_id'], + 'alliance_id': row['alliance_id'], + 'world_id': row['world_id'], + 'x': row['x'], + 'y': row['y'], + 'sea': row['sea'], + 'updated_at': row['updated_at'], 'resources': { 'wood': d.get('wood', 0), 'stone': d.get('stone', 0), @@ -45,12 +51,17 @@ def get_towns(): 'storage': d.get('storage', 0), 'population': d.get('population', 0), }, - 'buildings': d.get('buildings', {}), - 'units': d.get('units', {}), - 'points': d.get('points', 0), - 'god': d.get('god', None), - 'build_queue': d.get('buildingOrder', []), - 'build_data': d.get('buildData', {}), + 'buildings': d.get('buildings', {}), + 'units': d.get('units', {}), + 'points': d.get('points', 0), + 'god': d.get('god', None), + 'build_queue': d.get('buildingOrder', []), + 'build_data': d.get('buildData', {}), + 'researches': d.get('researches', {}), + 'has_premium': d.get('has_premium', False), + 'bonuses': d.get('bonuses', {}), + 'wonder_points': d.get('wonder_points', 0), + 'total_points': d.get('total_points', 0), }) return jsonify(towns) diff --git a/templates/dashboard.html b/templates/dashboard.html index 7a74c07..619edbd 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -253,6 +253,11 @@ Στρατος
+ +
+ Ερευνες +
+
@@ -474,8 +479,8 @@ function renderTowns() { return `
-
${t.town_name}
-
${t.points} pts · ${t.god || 'No god'} · ${ageMin}m ago
+
${t.town_name}${t.has_premium ? ' ' : ''}
+
${t.sea != null ? `🌊 Θ${t.sea} · ` : ''}${t.points} pts · ${t.god || 'No god'} · ${ageMin}m ago
${fmt(t.resources.wood)}
${fmt(t.resources.stone)}
@@ -532,12 +537,29 @@ function renderTownDetails() { `; const godName = t.god ? t.god.charAt(0).toUpperCase() + t.god.slice(1) : 'Κανένας'; + const seaStr = t.sea != null ? `Θ${t.sea}` : '—'; + const coordStr = (t.x != null && t.y != null) ? ` (${Math.round(t.x)}:${Math.round(t.y)})` : ''; document.getElementById('td-general').innerHTML = ` -
Πόντοι: ${t.points}
+
Πόντοι: ${t.points}${t.wonder_points ? ` / Θαύμα: ${t.wonder_points}` : ''}
Θεός: ${godName}
-
Παίκτης: ${t.player}
+
Θάλασσα: ${seaStr}${coordStr}
+
Παίκτης: ${t.player}${t.has_premium ? ' ' : ''}
+ ${t.alliance_id ? `
Συμμαχία: ${t.alliance_id}
` : ''} `; + // ---- Researches ---- + const researchObj = t.researches || {}; + const researchEntries = Object.entries(researchObj).filter(([, v]) => v === true || v === 1 || Number(v) > 0); + let resHtml = ''; + if (researchEntries.length) { + resHtml = researchEntries.map(([k]) => + `
✓ ${k.replace(/_/g, ' ')}
` + ).join(''); + } else { + resHtml = '
Καμία έρευνα
'; + } + document.getElementById('td-researches').innerHTML = resHtml; + const unitsObj = t.units || {}; let unitsHtml = ''; for(const [unitKey, count] of Object.entries(unitsObj)) {