atttack planner postponed/removed
This commit is contained in:
2
app.py
2
app.py
@@ -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")
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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') {
|
||||||
|
|||||||
@@ -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:**
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 %}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user