atttack planner postponed/removed

This commit is contained in:
2026-05-04 23:19:09 +03:00
parent e9cc81b582
commit 138841b027
12 changed files with 4 additions and 95 deletions

2
app.py
View File

@@ -6,7 +6,6 @@ from routes.api import api
from routes.dashboard import dashboard from routes.dashboard import dashboard
from routes.auth import auth from routes.auth import auth
from routes.tracker import tracker from routes.tracker import tracker
from routes.attack_planner import attack_planner
import logging import logging
logging.basicConfig( logging.basicConfig(
@@ -72,7 +71,6 @@ app.register_blueprint(api)
app.register_blueprint(dashboard) app.register_blueprint(dashboard)
app.register_blueprint(auth) app.register_blueprint(auth)
app.register_blueprint(tracker) app.register_blueprint(tracker)
app.register_blueprint(attack_planner)
if __name__ == '__main__': if __name__ == '__main__':
print("✅ Grepolis Remote — DB initialised") print("✅ Grepolis Remote — DB initialised")

View File

@@ -193,7 +193,7 @@ function gatherState() {
}; };
}); });
// ---- World speed & unit speed table (for attack planner calculations) ----- // ---- World speed & unit speed table -----
let world_speed = 1; let world_speed = 1;
let unit_speeds = {}; let unit_speeds = {};
try { try {

View File

@@ -235,9 +235,6 @@ function boot() {
if (typeof window._grcInitTracker === 'function') { if (typeof window._grcInitTracker === 'function') {
window._grcInitTracker(); // live tracker event-driven window._grcInitTracker(); // live tracker event-driven
} }
if (typeof window._grcInitAttackPlanner === 'function') {
window._grcInitAttackPlanner(); // attack planner countdown engine
}
} }
if (document.readyState === 'complete') { if (document.readyState === 'complete') {

View File

@@ -84,7 +84,7 @@ Command delivery relies on HTTP polling. If an attack plan requires a launch in
**Benefits:** **Benefits:**
- **Zero Polling Latency:** Commands arrive in ~100ms instead of 8-18 seconds. - **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. - **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. - **Instant UI Updates:** The dashboard can update in real-time as members come online or troop counts change.
## 3. Server-Sent Events (SSE) Lag/Refresh Bug Fix ## 3. Server-Sent Events (SSE) Lag/Refresh Bug Fix
**Issue:** **Issue:**

View File

@@ -100,7 +100,7 @@ def receive_state():
)) ))
conn.commit() conn.commit()
# Store world speed + unit data for attack planner calculations # Store world speed + unit data
world_speed = data.get('world_speed') world_speed = data.get('world_speed')
unit_speeds = data.get('unit_speeds') unit_speeds = data.get('unit_speeds')
if world_id and world_speed is not None and unit_speeds: if world_id and world_speed is not None and unit_speeds:

View File

@@ -156,8 +156,6 @@ def options():
'is_online': is_online, 'is_online': is_online,
'feat_farm': 'farm' in (row['features'] or 'farm,admin'), 'feat_farm': 'farm' in (row['features'] or 'farm,admin'),
'feat_admin': 'admin' in (row['features'] or 'farm,admin'), 'feat_admin': 'admin' in (row['features'] or 'farm,admin'),
'feat_atk_planner': 'attack_planner' in (row['features'] or ''),
'feat_atk_planner_admin': 'attack_planner_admin' in (row['features'] or ''),
}) })
conn.close() conn.close()
@@ -238,10 +236,8 @@ def remove_member(player_id, world_id):
def update_member_features(player_id, world_id): def update_member_features(player_id, world_id):
farm = 'farm' if request.form.get('farm') else None farm = 'farm' if request.form.get('farm') else None
admin = 'admin' if request.form.get('admin') else None admin = 'admin' if request.form.get('admin') else None
atk_planner = 'attack_planner' if request.form.get('attack_planner') else None
atk_planner_admin = 'attack_planner_admin' if request.form.get('attack_planner_admin') else None
features = ','.join(f for f in [farm, admin, atk_planner, atk_planner_admin] if f) or '' features = ','.join(f for f in [farm, admin] if f) or ''
conn = get_db() conn = get_db()
clan = conn.execute( clan = conn.execute(

View File

@@ -97,24 +97,6 @@ def player_farm(player_id, world_id):
def player_tracker(player_id, world_id): def player_tracker(player_id, world_id):
return render_template('tracker.html', player_id=player_id, world_id=world_id) return render_template('tracker.html', player_id=player_id, world_id=world_id)
@dashboard.route('/player/<player_id>/<world_id>/attack-planner')
@login_required
def player_attack_planner(player_id, world_id):
clan_key = ''
if current_user.clan_id:
conn = get_db()
clan = conn.execute(
'SELECT clan_key FROM clans WHERE id = ?', (current_user.clan_id,)
).fetchone()
conn.close()
if clan:
clan_key = clan['clan_key']
return render_template('attack_planner.html',
player_id=player_id,
world_id=world_id,
clan_key=clan_key)
# ------------------------------------------------------------------ # ------------------------------------------------------------------
# GET /dashboard/farm-settings — returns current farm config # GET /dashboard/farm-settings — returns current farm config
# POST /dashboard/farm-settings — updates farm config # POST /dashboard/farm-settings — updates farm config
@@ -291,50 +273,6 @@ def get_towns():
return jsonify(towns) return jsonify(towns)
# ------------------------------------------------------------------
# GET /dashboard/clan-towns?world_id=...
# Returns all towns for ALL clan members in a given world.
# Used by attack planner to let admin pick any player's town.
# ------------------------------------------------------------------
@dashboard.route('/dashboard/clan-towns', methods=['GET'])
@login_required
def get_clan_towns():
world_id = request.args.get('world_id', '').strip()
clan_id = current_user.clan_id
if not clan_id or not world_id:
return jsonify([])
conn = get_db()
rows = conn.execute('''
SELECT ts.town_id, ts.town_name, ts.player, ts.player_id,
ts.x, ts.y, ts.sea, ts.world_id, ts.updated_at, ts.data
FROM town_state ts
INNER JOIN clan_members cm
ON cm.player_id = ts.player_id
AND cm.world_id = ts.world_id
AND cm.clan_id = ?
WHERE ts.world_id = ?
ORDER BY ts.player ASC, ts.town_name ASC
''', (clan_id, world_id)).fetchall()
conn.close()
towns = []
for r in rows:
d = json.loads(r['data']) if r['data'] else {}
towns.append({
'town_id': r['town_id'],
'town_name': r['town_name'],
'player': r['player'],
'player_id': r['player_id'],
'world_id': r['world_id'],
'x': r['x'],
'y': r['y'],
'sea': r['sea'],
'units': d.get('units', {}),
})
return jsonify(towns)
# ------------------------------------------------------------------ # ------------------------------------------------------------------
# POST /dashboard/blueprints # POST /dashboard/blueprints
# Toggle a blueprint for a specific town # Toggle a blueprint for a specific town

View File

@@ -100,12 +100,6 @@
.hub-card.tracker::before { background: radial-gradient(circle at top left, rgba(111,207,207,0.08), transparent 70%); } .hub-card.tracker::before { background: radial-gradient(circle at top left, rgba(111,207,207,0.08), transparent 70%); }
.hub-card.tracker:hover { border-color: #6fcfcf; box-shadow: 0 12px 40px rgba(111,207,207,0.15); } .hub-card.tracker:hover { border-color: #6fcfcf; box-shadow: 0 12px 40px rgba(111,207,207,0.15); }
/* Attack Planner — red/orange */
.hub-card.attack { border-color: #301a1a; }
.hub-card.attack::before { background: radial-gradient(circle at top left, rgba(224,85,85,0.08), transparent 70%); }
.hub-card.attack:hover { border-color: #e05555; box-shadow: 0 12px 40px rgba(224,85,85,0.15); }
.hub-card.attack .card-title { color: #e05555; }
.card-icon { .card-icon {
font-size: 2.8rem; font-size: 2.8rem;
margin-bottom: 1rem; margin-bottom: 1rem;
@@ -179,12 +173,6 @@
<div class="card-desc">Παρακολούθηση κινήσεων στρατού σε πραγματικό χρόνο. Εισερχόμενες επιθέσεις και ενισχύσεις.</div> <div class="card-desc">Παρακολούθηση κινήσεων στρατού σε πραγματικό χρόνο. Εισερχόμενες επιθέσεις και ενισχύσεις.</div>
</a> </a>
<a href="/player/{{ player_id }}/{{ world_id }}/attack-planner" class="hub-card attack">
<span class="card-icon">⚔️</span>
<div class="card-title">Attack Planner</div>
<div class="card-desc">Συντονισμένες επιθέσεις σε ακριβή χρόνο. Υπολογισμός χρόνου αποστολής, επιστροφής και πλοίων.</div>
</a>
</div> </div>
<a href="/" class="back-link">← Επιστροφή στην επιλογή παίκτη</a> <a href="/" class="back-link">← Επιστροφή στην επιλογή παίκτη</a>

View File

@@ -295,20 +295,12 @@
<label class="toggle-label"> <label class="toggle-label">
<input type="checkbox" name="admin" onchange="this.form.submit()" {{ 'checked' if m.feat_admin }}> 🏛 Admin <input type="checkbox" name="admin" onchange="this.form.submit()" {{ 'checked' if m.feat_admin }}> 🏛 Admin
</label> </label>
<label class="toggle-label">
<input type="checkbox" name="attack_planner" onchange="this.form.submit()" {{ 'checked' if m.feat_atk_planner }}> ⚔️ Planner
</label>
<label class="toggle-label">
<input type="checkbox" name="attack_planner_admin" onchange="this.form.submit()" {{ 'checked' if m.feat_atk_planner_admin }}> 🎯 Planner Admin
</label>
</div> </div>
</form> </form>
{% else %} {% else %}
<div class="toggle-group" style="opacity: 0.8;"> <div class="toggle-group" style="opacity: 0.8;">
<span class="toggle-label" style="cursor:default; border-color: {{ '#3fb950' if m.feat_farm else '#30363d' }}; color: {{ '#3fb950' if m.feat_farm else '#8b949e' }};">🌾 Farm</span> <span class="toggle-label" style="cursor:default; border-color: {{ '#3fb950' if m.feat_farm else '#30363d' }}; color: {{ '#3fb950' if m.feat_farm else '#8b949e' }};">🌾 Farm</span>
<span class="toggle-label" style="cursor:default; border-color: {{ '#3fb950' if m.feat_admin else '#30363d' }}; color: {{ '#3fb950' if m.feat_admin else '#8b949e' }};">🏛 Admin</span> <span class="toggle-label" style="cursor:default; border-color: {{ '#3fb950' if m.feat_admin else '#30363d' }}; color: {{ '#3fb950' if m.feat_admin else '#8b949e' }};">🏛 Admin</span>
<span class="toggle-label" style="cursor:default; border-color: {{ '#3fb950' if m.feat_atk_planner else '#30363d' }}; color: {{ '#3fb950' if m.feat_atk_planner else '#8b949e' }};">⚔️ Planner</span>
<span class="toggle-label" style="cursor:default; border-color: {{ '#3fb950' if m.feat_atk_planner_admin else '#30363d' }}; color: {{ '#3fb950' if m.feat_atk_planner_admin else '#8b949e' }};">🎯 Planner Admin</span>
</div> </div>
{% endif %} {% endif %}