live scan fix
This commit is contained in:
111
future_ideas.md
Normal file
111
future_ideas.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# Future Ideas & Optimizations
|
||||
|
||||
This document tracks potential architectural improvements and features inspired by other Grepolis alliance coordination scripts (like GrepoData and Noct).
|
||||
|
||||
## 1. Timestamp-Based Polling Optimization (`since` parameter)
|
||||
**Inspired by:** `noct-api.grepo-soft.workers.dev`
|
||||
|
||||
**Current State:**
|
||||
The Tampermonkey client polls the server every 8-18 seconds and receives the full state/command payload every time, even if nothing has changed.
|
||||
|
||||
**Proposed Implementation:**
|
||||
- Add a `since` timestamp parameter to the client's poll requests.
|
||||
- The server checks if any commands or state updates have occurred *after* the `since` timestamp.
|
||||
- **If no new data:** The server returns an empty `HTTP 204 No Content` response.
|
||||
- **If new data:** The server returns `HTTP 200 OK` with only the data that changed.
|
||||
|
||||
**Benefits:**
|
||||
- Drastically reduces server bandwidth and CPU load.
|
||||
- Minimizes the size of network requests on the client side, making the script stealthier and less resource-intensive in the browser.
|
||||
|
||||
**Concrete Code Example (How Noct does it):**
|
||||
```javascript
|
||||
// 1. Client-side polling logic
|
||||
let lastFetchTime = Date.now();
|
||||
|
||||
async function pollCommands() {
|
||||
const url = `https://noct-api.grepo-soft.workers.dev/api/alliance/commands` +
|
||||
`?alliance=p0PmzsZMo4xZ2o29uvqggy5d` +
|
||||
`&world=gr118` +
|
||||
`&clientId=848938473` +
|
||||
`&since=${lastFetchTime}`; // Ask only for things after this timestamp
|
||||
|
||||
const response = await fetch(url);
|
||||
|
||||
// 2. Server returns HTTP 204 (No Content) if nothing new happened
|
||||
if (response.status === 204) {
|
||||
return; // Empty payload, exit early
|
||||
}
|
||||
|
||||
// 3. Server returns HTTP 200 (OK) only if there are NEW commands
|
||||
if (response.status === 200) {
|
||||
const data = await response.json();
|
||||
|
||||
// Process new commands...
|
||||
executeCommands(data.commands);
|
||||
|
||||
// Update the timestamp so the next poll only asks for things after this moment
|
||||
lastFetchTime = Date.now();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```python
|
||||
# Backend (Python/Flask Equivalent)
|
||||
@app.route('/api/alliance/commands')
|
||||
def get_commands():
|
||||
# Get the timestamp from the URL query
|
||||
since_ts = int(request.args.get('since', 0))
|
||||
|
||||
# Query DB for commands created AFTER the 'since' timestamp
|
||||
new_commands = db.execute(
|
||||
"SELECT * FROM commands WHERE created_at_ts > ?", (since_ts,)
|
||||
).fetchall()
|
||||
|
||||
if not new_commands:
|
||||
# Return empty body with 204 No Content
|
||||
return '', 204
|
||||
|
||||
return jsonify({"commands": new_commands}), 200
|
||||
```
|
||||
|
||||
## 2. WebSocket Architecture for Real-Time Synchronization
|
||||
**Inspired by:** `grepodata.com` (ReactPHP WebSocket server)
|
||||
|
||||
**Current State:**
|
||||
Command delivery relies on HTTP polling. If an attack plan requires a launch in 30 seconds, but the client is on an 18-second polling interval, there is a high risk of missing the execution window or executing late.
|
||||
|
||||
**Proposed Implementation:**
|
||||
- Integrate `Flask-SocketIO` (or a standalone async WebSocket server) into the backend.
|
||||
- The client script establishes a persistent `wss://` connection upon loading the game.
|
||||
- The client authenticates using its `clan_key` and subscribes to its alliance "topic/room".
|
||||
- When an admin arms an attack plan or a player updates their town state, the server instantly *pushes* the payload to all connected alliance members.
|
||||
|
||||
**Benefits:**
|
||||
- **Zero Polling Latency:** Commands arrive in ~100ms instead of 8-18 seconds.
|
||||
- **Perfect Attack Timing:** Ensures clients receive armed plans immediately, maximizing the margin for precise execution.
|
||||
- **Instant UI Updates:** The dashboard and attack planner can update in real-time as members come online or troop counts change.
|
||||
|
||||
## 3. Server-Sent Events (SSE) Lag/Refresh Bug Fix
|
||||
**Issue:**
|
||||
When refreshing or hitting the "back" button on the Live Tracker (`tracker.html`), the page occasionally hangs, lags heavily, or completely fails to load.
|
||||
|
||||
**Root Cause:**
|
||||
The Live Tracker uses SSE (`EventSource`) to receive real-time movement updates. Modern browsers strictly limit simultaneous HTTP/1.1 connections to the same server (usually 6 maximum). When the user navigates away or refreshes, the browser drops the frontend page, but the Python/Flask backend (`tracker.py`) does not immediately detect the broken pipe and keeps the socket open, waiting to send data.
|
||||
If the user hits refresh multiple times, these "ghost" connections stack up. Upon reaching 6 ghost connections, the browser refuses to load any further requests until the old connections naturally time out (which can take 30+ seconds).
|
||||
|
||||
**Proposed Fix:**
|
||||
1. **Client-side (`tracker.html`)**: Ensure the browser explicitly tells the server the connection is closing exactly as the page unloads.
|
||||
```javascript
|
||||
window.addEventListener('beforeunload', () => {
|
||||
if (typeof es !== 'undefined' && es !== null) {
|
||||
es.close();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
2. **Server-side (`tracker.py`)**: Ensure the generator handles client disconnects gracefully and immediately cleans up the subscriber queue without waiting for a timeout.
|
||||
```python
|
||||
# Make sure the generator yields spaces/heartbeats actively so the OS
|
||||
# throws an IOError/GeneratorExit the moment the client drops.
|
||||
```
|
||||
Reference in New Issue
Block a user