This commit is contained in:
ilyastar9999
2025-12-03 13:46:00 +03:00
parent bf764601d2
commit 07b338e823
2 changed files with 72 additions and 42 deletions

View File

@@ -21,6 +21,17 @@ CREATE TABLE IF NOT EXISTS service_logs (
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
); );
-- Scoreboard state table - current flags count for each team+service
CREATE TABLE IF NOT EXISTS scoreboard_state (
id SERIAL PRIMARY KEY,
team_id INTEGER NOT NULL,
service_name VARCHAR(255) NOT NULL,
stolen_flags INTEGER DEFAULT 0,
lost_flags INTEGER DEFAULT 0,
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(team_id, service_name)
);
-- 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,
@@ -72,6 +83,7 @@ INSERT INTO settings (key, value) VALUES
ON CONFLICT (key) DO NOTHING; 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_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);

View File

@@ -194,7 +194,7 @@ async def socketio_listener():
@sio.event(namespace='/game_events') @sio.event(namespace='/game_events')
async def update_scoreboard(data): async def update_scoreboard(data):
"""Handle scoreboard update events""" """Handle scoreboard update - compare with previous state to detect NEW attacks"""
try: try:
event_data = data.get('data', {}) event_data = data.get('data', {})
round_num = event_data.get('round', 0) round_num = event_data.get('round', 0)
@@ -203,58 +203,76 @@ async def socketio_listener():
print(f"📊 Round {round_num} - Processing {len(team_tasks)} team updates") print(f"📊 Round {round_num} - Processing {len(team_tasks)} team updates")
# Get task names from previous init_scoreboard or fetch them
conn = await db_pool.acquire() conn = await db_pool.acquire()
try: try:
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')
stolen = team_task.get('stolen', 0) current_stolen = team_task.get('stolen', 0)
lost = team_task.get('lost', 0) current_lost = team_task.get('lost', 0)
score = team_task.get('score', 0)
status = team_task.get('status', 0)
# Only process if there are stolen or lost flags
if stolen > 0 or lost > 0:
# Determine service name
service_name = task_names.get(task_id, f"task_{task_id}") service_name = task_names.get(task_id, f"task_{task_id}")
# Create attack records based on stolen/lost changes # Get previous state from database
prev_state = await conn.fetchrow(
"SELECT stolen_flags, lost_flags FROM scoreboard_state WHERE team_id = $1 AND service_name = $2",
team_id, service_name
)
prev_stolen = prev_state['stolen_flags'] if prev_state else 0
prev_lost = prev_state['lost_flags'] if prev_state else 0
# Calculate NEW flags (difference from previous state)
new_stolen = current_stolen - prev_stolen
new_lost = current_lost - prev_lost
# Update current state in database
await conn.execute("""
INSERT INTO scoreboard_state (team_id, service_name, stolen_flags, lost_flags, last_updated)
VALUES ($1, $2, $3, $4, NOW())
ON CONFLICT (team_id, service_name)
DO UPDATE SET stolen_flags = $3, lost_flags = $4, last_updated = NOW()
""", team_id, service_name, current_stolen, current_lost)
# Create attack record only for NEW stolen flags
if new_stolen > 0:
timestamp = datetime.utcnow() timestamp = datetime.utcnow()
attack_id = f"r{round_num}_stolen_team{team_id}_{service_name}_{int(timestamp.timestamp())}"
# If flags were stolen BY this team
if stolen > 0:
is_our_attack = team_id == OUR_TEAM_ID is_our_attack = team_id == OUR_TEAM_ID
# Generate attack record for each stolen flag (simplified)
attack_id = f"r{round_num}_stolen_team{team_id}_task{task_id}_{int(timestamp.timestamp())}"
# For stolen flags, we are the attacker await conn.execute("""
INSERT INTO attacks (attack_id, attacker_team_id, service_name, timestamp, points, is_our_attack, is_attack_to_us)
VALUES ($1, $2, $3, $4, $5, $6, $7)
ON CONFLICT (attack_id) DO NOTHING
""", attack_id, team_id, service_name, timestamp, float(new_stolen), is_our_attack, False)
if is_our_attack: if is_our_attack:
# We stole from someone (we don't know exact victim from this event) print(f" ✅ We stole {new_stolen} NEW flags from {service_name} (total: {current_stolen})")
await conn.execute(""" else:
INSERT INTO attacks (attack_id, attacker_team_id, victim_team_id, service_name, flag, timestamp, points, is_our_attack, is_attack_to_us) print(f" 📌 Team {team_id} stole {new_stolen} NEW flags from {service_name} (total: {current_stolen})")
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
ON CONFLICT (attack_id) DO NOTHING # Create attack record only for NEW lost flags
""", attack_id, team_id, 0, service_name, f"ROUND_{round_num}", timestamp, stolen, True, False) if new_lost > 0:
print(f" ✅ Our team stole {stolen} flags from {service_name}") timestamp = datetime.utcnow()
attack_id = f"r{round_num}_lost_team{team_id}_{service_name}_{int(timestamp.timestamp())}"
# If flags were lost BY this team
if lost > 0:
is_attack_to_us = team_id == OUR_TEAM_ID is_attack_to_us = team_id == OUR_TEAM_ID
attack_id = f"r{round_num}_lost_team{team_id}_task{task_id}_{int(timestamp.timestamp())}"
# For lost flags, we are the victim
if is_attack_to_us:
# Someone stole from us
await conn.execute(""" await conn.execute("""
INSERT INTO attacks (attack_id, attacker_team_id, victim_team_id, service_name, flag, timestamp, points, is_our_attack, is_attack_to_us) INSERT INTO attacks (attack_id, victim_team_id, service_name, timestamp, points, is_our_attack, is_attack_to_us)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) VALUES ($1, $2, $3, $4, $5, $6, $7)
ON CONFLICT (attack_id) DO NOTHING ON CONFLICT (attack_id) DO NOTHING
""", attack_id, 0, team_id, service_name, f"ROUND_{round_num}", timestamp, lost, False, True) """, attack_id, team_id, service_name, timestamp, float(new_lost), False, is_attack_to_us)
print(f" ⚠️ We lost {lost} flags on {service_name}")
# Check for alerts if is_attack_to_us:
print(f" ⚠️ We LOST {new_lost} NEW flags on {service_name} (total lost: {current_lost})")
# Check for alerts on high-value attacks
if new_lost >= ALERT_THRESHOLD_POINTS:
await check_and_create_alerts(conn, 0, service_name) await check_and_create_alerts(conn, 0, service_name)
else:
print(f" 📌 Team {team_id} lost {new_lost} NEW flags on {service_name} (total: {current_lost})")
finally: finally:
await db_pool.release(conn) await db_pool.release(conn)