diff --git a/db.py b/db.py index 838df1b..71a2f50 100644 --- a/db.py +++ b/db.py @@ -182,6 +182,7 @@ def init_db(): 'ALTER TABLE commands ADD COLUMN position INTEGER', 'ALTER TABLE farm_settings ADD COLUMN bandit_camp_enabled INTEGER NOT NULL DEFAULT 0', "ALTER TABLE clan_members ADD COLUMN features TEXT NOT NULL DEFAULT 'farm,admin'", + 'ALTER TABLE clan_members ADD COLUMN world_id TEXT', 'ALTER TABLE users ADD COLUMN clan_id INTEGER REFERENCES clans(id)', ]: try: @@ -224,6 +225,7 @@ def init_db(): clan_id INTEGER NOT NULL REFERENCES clans(id), player_id TEXT NOT NULL, player_name TEXT, + world_id TEXT, features TEXT NOT NULL DEFAULT 'farm,admin', joined_at TEXT NOT NULL DEFAULT (datetime('now')), UNIQUE(clan_id, player_id) diff --git a/routes/api.py b/routes/api.py index e5263da..aeec8f6 100644 --- a/routes/api.py +++ b/routes/api.py @@ -29,17 +29,17 @@ def _get_clan_from_request(): # ------------------------------------------------------------------ # Helper — auto-register a player_id under a clan on first push. # ------------------------------------------------------------------ -def _auto_register_member(clan_id, player_id, player_name): +def _auto_register_member(clan_id, player_id, player_name, world_id=''): conn = get_db() conn.execute(''' - INSERT OR IGNORE INTO clan_members (clan_id, player_id, player_name) - VALUES (?, ?, ?) - ''', (clan_id, str(player_id), player_name or '')) - # Update name in case it changed + INSERT OR IGNORE INTO clan_members (clan_id, player_id, player_name, world_id) + VALUES (?, ?, ?, ?) + ''', (clan_id, str(player_id), player_name or '', world_id or '')) + # Update name and world on every push (they can change) conn.execute(''' - UPDATE clan_members SET player_name = ? + UPDATE clan_members SET player_name = ?, world_id = ? WHERE clan_id = ? AND player_id = ? - ''', (player_name or '', clan_id, str(player_id))) + ''', (player_name or '', world_id or '', clan_id, str(player_id))) conn.commit() conn.close() @@ -63,7 +63,7 @@ def receive_state(): # Auto-register this player to the clan that matches the key (if any) clan = _get_clan_from_request() if clan: - _auto_register_member(clan['id'], player_id, player) + _auto_register_member(clan['id'], player_id, player, world_id) conn = get_db() c = conn.cursor() diff --git a/routes/auth.py b/routes/auth.py index 4062359..b574ff4 100644 --- a/routes/auth.py +++ b/routes/auth.py @@ -126,7 +126,7 @@ def options(): members = [] if clan: rows = conn.execute( - '''SELECT cm.id, cm.player_id, cm.player_name, cm.joined_at, cm.features, + '''SELECT cm.id, cm.player_id, cm.player_name, cm.world_id, cm.joined_at, cm.features, ts.updated_at FROM clan_members cm LEFT JOIN town_state ts ON ts.player_id = cm.player_id @@ -147,14 +147,15 @@ def options(): except Exception: pass members.append({ - 'id': row['id'], - 'player_id': row['player_id'], - 'player_name': row['player_name'] or 'Άγνωστος', - 'joined_at': row['joined_at'][:10] if row['joined_at'] else '', - 'is_online': is_online, - 'feat_farm': 'farm' in (row['features'] or 'farm,admin'), - 'feat_admin': 'admin' in (row['features'] or 'farm,admin'), - 'feat_atk_planner': 'attack_planner' in (row['features'] or ''), + 'id': row['id'], + 'player_id': row['player_id'], + 'player_name': row['player_name'] or 'Άγνωστος', + 'world_id': row['world_id'] or '–', + 'joined_at': row['joined_at'][:10] if row['joined_at'] else '', + 'is_online': is_online, + 'feat_farm': 'farm' 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 ''), }) diff --git a/routes/dashboard.py b/routes/dashboard.py index 566f0c4..fa4ba2a 100644 --- a/routes/dashboard.py +++ b/routes/dashboard.py @@ -100,7 +100,19 @@ def player_tracker(player_id, world_id): @dashboard.route('/player///attack-planner') @login_required def player_attack_planner(player_id, world_id): - return render_template('attack_planner.html', player_id=player_id, world_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) # ------------------------------------------------------------------ diff --git a/templates/attack_planner.html b/templates/attack_planner.html index eff2800..0bc3ec8 100644 --- a/templates/attack_planner.html +++ b/templates/attack_planner.html @@ -21,10 +21,11 @@ .card-title{font-size:1rem;font-weight:700;color:var(--gold);margin-bottom:1rem;padding-bottom:.75rem;border-bottom:1px solid var(--border)} label{display:block;font-size:.8rem;color:var(--muted);margin-bottom:.3rem;margin-top:.75rem} label:first-of-type{margin-top:0} - input[type=text],input[type=number],input[type=datetime-local]{ + input[type=text],input[type=number],input[type=datetime-local],select{ width:100%;padding:9px 12px;background:#0f0f1a;border:1px solid var(--border); border-radius:8px;color:var(--text);font-size:.875rem;font-family:inherit;transition:border-color .2s} - input:focus{outline:none;border-color:var(--gold)} + input:focus,select:focus{outline:none;border-color:var(--gold)} + select option{background:#181824} .btn{padding:9px 18px;border:none;border-radius:8px;font-family:inherit;font-weight:600; font-size:.85rem;cursor:pointer;transition:all .2s} .btn-gold{background:var(--gold);color:#0f0f1a}.btn-gold:hover{background:#e0b85a} @@ -56,9 +57,8 @@ padding:10px 14px;border-radius:8px;font-size:.83rem;margin-top:.75rem} .warn-box{background:rgba(240,192,64,.08);border:1px solid rgba(240,192,64,.25);color:var(--yellow); padding:10px 14px;border-radius:8px;font-size:.83rem;margin-top:.5rem} - #msg{display:none;margin-top:.75rem} - .countdown{font-family:monospace;font-weight:700;color:var(--yellow)} - .section-sep{height:1px;background:var(--border);margin:1.5rem 0} + .town-meta{font-size:.75rem;color:var(--muted);margin-top:4px} + .section-sep{height:1px;background:var(--border);margin:1rem 0} .plan-row{cursor:pointer}.plan-row:hover td{background:rgba(200,164,74,.05)} .detail-panel{display:none} .detail-panel.open{display:block} @@ -68,25 +68,32 @@ .unit-input input{padding:6px 8px;font-size:.82rem} .feasible-ok{color:var(--green);font-size:.78rem} .feasible-err{color:var(--red);font-size:.78rem} + #msg{display:none;margin-top:.75rem} + + +
- +
-
📋 Ενεργά Πλάνα
+
📋 Πλάνα Επίθεσης — {{ world_id }}
Φόρτωση...
-
Λεπτομέρειες Πλάνου
@@ -95,27 +102,29 @@
-
-
➕ Νέο Πλάνο Επίθεσης
+
➕ Νέο Πλάνο
+ + + - - + + - - + + -
- ⏱ Η ώρα άφιξης πρέπει να είναι τουλάχιστον 2 λεπτά στο μέλλον. Όλες οι ώρες αποθηκεύονται σε UTC. +
+ ⏱ Η ώρα άφιξης πρέπει να είναι τουλάχιστον 2 λεπτά στο μέλλον.
@@ -124,30 +133,21 @@
- +