asd
This commit is contained in:
13
init-db.sql
13
init-db.sql
@@ -32,6 +32,17 @@ CREATE TABLE IF NOT EXISTS scoreboard_state (
|
|||||||
UNIQUE(team_id, service_name)
|
UNIQUE(team_id, service_name)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- Team scores table - track total and flag points over time
|
||||||
|
CREATE TABLE IF NOT EXISTS team_scores (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
team_id INTEGER NOT NULL,
|
||||||
|
team_name VARCHAR(255) NOT NULL,
|
||||||
|
total_score FLOAT DEFAULT 0,
|
||||||
|
flag_points FLOAT DEFAULT 0,
|
||||||
|
round INTEGER NOT NULL,
|
||||||
|
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
-- Attacks tracking table for scoreboard injector
|
-- Attacks tracking table for scoreboard injector
|
||||||
CREATE TABLE IF NOT EXISTS attacks (
|
CREATE TABLE IF NOT EXISTS attacks (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
@@ -84,6 +95,8 @@ ON CONFLICT (key) DO NOTHING;
|
|||||||
|
|
||||||
-- Create indexes for performance
|
-- Create indexes for performance
|
||||||
CREATE INDEX IF NOT EXISTS idx_scoreboard_state_team_service ON scoreboard_state(team_id, service_name);
|
CREATE INDEX IF NOT EXISTS idx_scoreboard_state_team_service ON scoreboard_state(team_id, service_name);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_team_scores_round ON team_scores(round);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_team_scores_team_id ON team_scores(team_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_attacks_timestamp ON attacks(timestamp);
|
CREATE INDEX IF NOT EXISTS idx_attacks_timestamp ON attacks(timestamp);
|
||||||
CREATE INDEX IF NOT EXISTS idx_attacks_our_attack ON attacks(is_our_attack);
|
CREATE INDEX IF NOT EXISTS idx_attacks_our_attack ON attacks(is_our_attack);
|
||||||
CREATE INDEX IF NOT EXISTS idx_attacks_attack_to_us ON attacks(is_attack_to_us);
|
CREATE INDEX IF NOT EXISTS idx_attacks_attack_to_us ON attacks(is_attack_to_us);
|
||||||
|
|||||||
@@ -189,8 +189,9 @@ async def socketio_listener():
|
|||||||
"""Listen to ForcAD scoreboard using Socket.IO"""
|
"""Listen to ForcAD scoreboard using Socket.IO"""
|
||||||
sio = socketio.AsyncClient(logger=False, engineio_logger=False)
|
sio = socketio.AsyncClient(logger=False, engineio_logger=False)
|
||||||
|
|
||||||
# Cache for task names
|
# Cache for task and team names
|
||||||
task_names = {}
|
task_names = {}
|
||||||
|
team_names = {}
|
||||||
|
|
||||||
@sio.event(namespace='/game_events')
|
@sio.event(namespace='/game_events')
|
||||||
async def update_scoreboard(data):
|
async def update_scoreboard(data):
|
||||||
@@ -200,11 +201,20 @@ async def socketio_listener():
|
|||||||
round_num = event_data.get('round', 0)
|
round_num = event_data.get('round', 0)
|
||||||
round_start = event_data.get('round_start', 0)
|
round_start = event_data.get('round_start', 0)
|
||||||
team_tasks = event_data.get('team_tasks', [])
|
team_tasks = event_data.get('team_tasks', [])
|
||||||
|
teams_data = event_data.get('teams', [])
|
||||||
|
|
||||||
print(f"📊 Round {round_num} - Processing {len(team_tasks)} team updates")
|
print(f"📊 Round {round_num} - Processing {len(team_tasks)} team updates")
|
||||||
|
|
||||||
conn = await db_pool.acquire()
|
conn = await db_pool.acquire()
|
||||||
try:
|
try:
|
||||||
|
# Store team scores
|
||||||
|
for team in teams_data:
|
||||||
|
team_id = team.get('id')
|
||||||
|
await conn.execute("""
|
||||||
|
INSERT INTO team_scores (team_id, team_name, total_score, flag_points, round, timestamp)
|
||||||
|
VALUES ($1, $2, $3, $4, $5, NOW())
|
||||||
|
""", team_id, team_names.get(team_id, f'Team {team_id}'),
|
||||||
|
team.get('score', 0), team.get('flag_points', 0), round_num)
|
||||||
for team_task in team_tasks:
|
for team_task in team_tasks:
|
||||||
team_id = team_task.get('team_id')
|
team_id = team_task.get('team_id')
|
||||||
task_id = team_task.get('task_id')
|
task_id = team_task.get('task_id')
|
||||||
@@ -294,6 +304,10 @@ async def socketio_listener():
|
|||||||
for task in tasks:
|
for task in tasks:
|
||||||
task_names[task.get('id')] = task.get('name')
|
task_names[task.get('id')] = task.get('name')
|
||||||
|
|
||||||
|
# Cache team names
|
||||||
|
for team in teams:
|
||||||
|
team_names[team.get('id')] = team.get('name')
|
||||||
|
|
||||||
team_names_str = ', '.join([f"{t.get('name')} (ID:{t.get('id')})" for t in teams])
|
team_names_str = ', '.join([f"{t.get('name')} (ID:{t.get('id')})" for t in teams])
|
||||||
task_names_str = ', '.join([t.get('name') for t in tasks])
|
task_names_str = ', '.join([t.get('name') for t in tasks])
|
||||||
print(f" Teams: {team_names_str}")
|
print(f" Teams: {team_names_str}")
|
||||||
@@ -390,25 +404,42 @@ async def get_stats():
|
|||||||
|
|
||||||
@app.get("/attacks", dependencies=[Depends(verify_token)])
|
@app.get("/attacks", dependencies=[Depends(verify_token)])
|
||||||
async def get_attacks(limit: int = 100, our_attacks: Optional[bool] = None, attacks_to_us: Optional[bool] = None):
|
async def get_attacks(limit: int = 100, our_attacks: Optional[bool] = None, attacks_to_us: Optional[bool] = None):
|
||||||
"""Get recent attacks"""
|
"""Get recent attacks with team names"""
|
||||||
conn = await get_db()
|
conn = await get_db()
|
||||||
try:
|
try:
|
||||||
query = "SELECT * FROM attacks WHERE 1=1"
|
query = """
|
||||||
|
SELECT
|
||||||
|
a.*,
|
||||||
|
ts_attacker.team_name as attacker_team_name,
|
||||||
|
ts_victim.team_name as victim_team_name
|
||||||
|
FROM attacks a
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT DISTINCT ON (team_id) team_id, team_name
|
||||||
|
FROM team_scores
|
||||||
|
ORDER BY team_id, timestamp DESC
|
||||||
|
) ts_attacker ON a.attacker_team_id = ts_attacker.team_id
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT DISTINCT ON (team_id) team_id, team_name
|
||||||
|
FROM team_scores
|
||||||
|
ORDER BY team_id, timestamp DESC
|
||||||
|
) ts_victim ON a.victim_team_id = ts_victim.team_id
|
||||||
|
WHERE 1=1
|
||||||
|
"""
|
||||||
params = []
|
params = []
|
||||||
param_count = 0
|
param_count = 0
|
||||||
|
|
||||||
if our_attacks is not None:
|
if our_attacks is not None:
|
||||||
param_count += 1
|
param_count += 1
|
||||||
query += f" AND is_our_attack = ${param_count}"
|
query += f" AND a.is_our_attack = ${param_count}"
|
||||||
params.append(our_attacks)
|
params.append(our_attacks)
|
||||||
|
|
||||||
if attacks_to_us is not None:
|
if attacks_to_us is not None:
|
||||||
param_count += 1
|
param_count += 1
|
||||||
query += f" AND is_attack_to_us = ${param_count}"
|
query += f" AND a.is_attack_to_us = ${param_count}"
|
||||||
params.append(attacks_to_us)
|
params.append(attacks_to_us)
|
||||||
|
|
||||||
param_count += 1
|
param_count += 1
|
||||||
query += f" ORDER BY timestamp DESC LIMIT ${param_count}"
|
query += f" ORDER BY a.timestamp DESC LIMIT ${param_count}"
|
||||||
params.append(limit)
|
params.append(limit)
|
||||||
|
|
||||||
rows = await conn.fetch(query, *params)
|
rows = await conn.fetch(query, *params)
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
<th>Attacker</th>
|
<th>Attacker</th>
|
||||||
<th>Victim</th>
|
<th>Victim</th>
|
||||||
<th>Service</th>
|
<th>Service</th>
|
||||||
<th>Points</th>
|
<th>Flags</th>
|
||||||
<th>Type</th>
|
<th>Type</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -126,13 +126,16 @@
|
|||||||
typeLabel = '<span class="badge bg-danger">Against Us</span>';
|
typeLabel = '<span class="badge bg-danger">Against Us</span>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const attackerName = attack.attacker_team_id ? (attack.attacker_team_name || `Team ${attack.attacker_team_id}`) : 'Unknown';
|
||||||
|
const victimName = attack.victim_team_id ? (attack.victim_team_name || `Team ${attack.victim_team_id}`) : 'Unknown';
|
||||||
|
|
||||||
html += `
|
html += `
|
||||||
<tr>
|
<tr>
|
||||||
<td>${new Date(attack.timestamp).toLocaleString()}</td>
|
<td>${new Date(attack.timestamp).toLocaleString()}</td>
|
||||||
<td>Team ${attack.attacker_team_id}</td>
|
<td>${attackerName}</td>
|
||||||
<td>Team ${attack.victim_team_id}</td>
|
<td>${victimName}</td>
|
||||||
<td>${attack.service_name}</td>
|
<td>${attack.service_name}</td>
|
||||||
<td>${attack.points ? attack.points.toFixed(2) : '-'}</td>
|
<td>${attack.points ? Math.round(attack.points) : '-'}</td>
|
||||||
<td>${typeLabel}</td>
|
<td>${typeLabel}</td>
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`;
|
||||||
|
|||||||
Reference in New Issue
Block a user