101 lines
4.1 KiB
Python
101 lines
4.1 KiB
Python
"""
|
|
Spatial Processor - Handles classic spatial (xyz) data
|
|
|
|
Responsibilities:
|
|
- Extract attacker/victim position data from classic round_list
|
|
- Update fact_round_events with spatial coordinates
|
|
- Prepare data for future heatmap/tactical board analysis
|
|
"""
|
|
|
|
import sqlite3
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class SpatialProcessor:
|
|
@staticmethod
|
|
def process(match_data, conn: sqlite3.Connection) -> bool:
|
|
"""
|
|
Process spatial data from classic round_list
|
|
|
|
Args:
|
|
match_data: MatchData object with round_list parsed
|
|
conn: L2 database connection
|
|
|
|
Returns:
|
|
bool: True if successful
|
|
"""
|
|
try:
|
|
if not hasattr(match_data, 'data_round_list') or not match_data.data_round_list:
|
|
return True
|
|
|
|
round_list = match_data.data_round_list.get('round_list', [])
|
|
|
|
if not round_list:
|
|
return True
|
|
|
|
cursor = conn.cursor()
|
|
update_count = 0
|
|
|
|
for idx, rd in enumerate(round_list, start=1):
|
|
round_num = idx
|
|
|
|
# Process kill events with spatial data
|
|
all_kill = rd.get('all_kill', [])
|
|
for kill in all_kill:
|
|
attacker = kill.get('attacker', {})
|
|
victim = kill.get('victim', {})
|
|
|
|
attacker_steam_id = str(attacker.get('steamid_64', ''))
|
|
victim_steam_id = str(victim.get('steamid_64', ''))
|
|
event_time = kill.get('pasttime', 0)
|
|
|
|
# Extract positions
|
|
attacker_pos = attacker.get('pos', {})
|
|
victim_pos = victim.get('pos', {})
|
|
|
|
attacker_pos_x = attacker_pos.get('x', 0) if isinstance(attacker_pos, dict) else 0
|
|
attacker_pos_y = attacker_pos.get('y', 0) if isinstance(attacker_pos, dict) else 0
|
|
attacker_pos_z = attacker_pos.get('z', 0) if isinstance(attacker_pos, dict) else 0
|
|
|
|
victim_pos_x = victim_pos.get('x', 0) if isinstance(victim_pos, dict) else 0
|
|
victim_pos_y = victim_pos.get('y', 0) if isinstance(victim_pos, dict) else 0
|
|
victim_pos_z = victim_pos.get('z', 0) if isinstance(victim_pos, dict) else 0
|
|
|
|
# Update existing event with spatial data
|
|
# We match by match_id, round_num, attacker, victim, and event_time
|
|
cursor.execute('''
|
|
UPDATE fact_round_events
|
|
SET attacker_pos_x = ?,
|
|
attacker_pos_y = ?,
|
|
attacker_pos_z = ?,
|
|
victim_pos_x = ?,
|
|
victim_pos_y = ?,
|
|
victim_pos_z = ?
|
|
WHERE match_id = ?
|
|
AND round_num = ?
|
|
AND attacker_steam_id = ?
|
|
AND victim_steam_id = ?
|
|
AND event_time = ?
|
|
AND event_type = 'kill'
|
|
AND data_source_type = 'classic'
|
|
''', (
|
|
attacker_pos_x, attacker_pos_y, attacker_pos_z,
|
|
victim_pos_x, victim_pos_y, victim_pos_z,
|
|
match_data.match_id, round_num, attacker_steam_id,
|
|
victim_steam_id, event_time
|
|
))
|
|
|
|
if cursor.rowcount > 0:
|
|
update_count += 1
|
|
|
|
logger.debug(f"Updated {update_count} events with spatial data for match {match_data.match_id}")
|
|
return True
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error processing spatial data for match {match_data.match_id}: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|