2.1 : New

This commit is contained in:
2026-01-28 01:20:26 +08:00
parent b3941cad3b
commit 4afb728bfa
12 changed files with 1084 additions and 16 deletions

View File

@@ -157,6 +157,7 @@ class PlayerEconomy:
main_weapon: str = ""
has_helmet: bool = False
has_defuser: bool = False
has_zeus: bool = False
round_performance_score: float = 0.0
@dataclass
@@ -865,6 +866,9 @@ class MatchParser:
if evt.get('trade_score_change'):
re.trade_killer_steam_id = list(evt['trade_score_change'].keys())[0]
if evt.get('assist_killer_score_change'):
re.assister_steam_id = list(evt['assist_killer_score_change'].keys())[0]
if evt.get('flash_assist_killer_score_change'):
re.flash_assist_steam_id = list(evt['flash_assist_killer_score_change'].keys())[0]
@@ -944,6 +948,7 @@ class MatchParser:
has_helmet = False
has_defuser = False
has_zeus = False
if isinstance(items, list):
for it in items:
if isinstance(it, dict):
@@ -952,6 +957,8 @@ class MatchParser:
has_helmet = True
elif name == 'item_defuser':
has_defuser = True
elif name and ('taser' in name or 'zeus' in name):
has_zeus = True
rd.economies.append(PlayerEconomy(
steam_id_64=str(sid),
@@ -961,6 +968,7 @@ class MatchParser:
main_weapon=main_weapon,
has_helmet=has_helmet,
has_defuser=has_defuser,
has_zeus=has_zeus,
round_performance_score=float(score)
))
@@ -1026,6 +1034,28 @@ class MatchParser:
victim_pos=(vpos.get('x', 0), vpos.get('y', 0), vpos.get('z', 0))
)
rd.events.append(re)
c4_events = r.get('c4_event', [])
for e in c4_events:
if not isinstance(e, dict):
continue
event_name = str(e.get('event_name') or '').lower()
if not event_name:
continue
if 'plant' in event_name:
etype = 'bomb_plant'
elif 'defus' in event_name:
etype = 'bomb_defuse'
else:
continue
sid = e.get('steamid_64')
re = RoundEvent(
event_id=f"{self.match_id}_{rd.round_num}_{etype}_{e.get('pasttime', 0)}_{sid}",
event_type=etype,
event_time=int(e.get('pasttime', 0) or 0),
attacker_steam_id=str(sid) if sid is not None else None,
)
rd.events.append(re)
self.match_data.rounds.append(rd)
@@ -1325,14 +1355,14 @@ def save_match(cursor, m: MatchData):
cursor.execute("""
INSERT OR REPLACE INTO fact_round_events
(event_id, match_id, round_num, event_type, event_time, attacker_steam_id, victim_steam_id,
(event_id, match_id, round_num, event_type, event_time, attacker_steam_id, victim_steam_id, assister_steam_id,
weapon, is_headshot, is_wallbang, is_blind, is_through_smoke, is_noscope,
trade_killer_steam_id, flash_assist_steam_id, score_change_attacker, score_change_victim,
attacker_pos_x, attacker_pos_y, attacker_pos_z, victim_pos_x, victim_pos_y, victim_pos_z)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", (
e.event_id, m.match_id, r.round_num, e.event_type, e.event_time, e.attacker_steam_id, e.victim_steam_id,
e.weapon, e.is_headshot, e.is_wallbang, e.is_blind, e.is_through_smoke, e.is_noscope,
e.assister_steam_id, e.weapon, e.is_headshot, e.is_wallbang, e.is_blind, e.is_through_smoke, e.is_noscope,
e.trade_killer_steam_id, e.flash_assist_steam_id, e.score_change_attacker, e.score_change_victim,
ax, ay, az, vx, vy, vz
))
@@ -1340,10 +1370,10 @@ def save_match(cursor, m: MatchData):
for pe in r.economies:
cursor.execute("""
INSERT OR REPLACE INTO fact_round_player_economy
(match_id, round_num, steam_id_64, side, start_money, equipment_value, main_weapon, has_helmet, has_defuser, round_performance_score)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
(match_id, round_num, steam_id_64, side, start_money, equipment_value, main_weapon, has_helmet, has_defuser, has_zeus, round_performance_score)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", (
m.match_id, r.round_num, pe.steam_id_64, pe.side, pe.start_money, pe.equipment_value, pe.main_weapon, pe.has_helmet, pe.has_defuser, pe.round_performance_score
m.match_id, r.round_num, pe.steam_id_64, pe.side, pe.start_money, pe.equipment_value, pe.main_weapon, pe.has_helmet, pe.has_defuser, pe.has_zeus, pe.round_performance_score
))
# 6. Calculate & Save Clutch Attempts

View File

@@ -18,6 +18,17 @@ logger = logging.getLogger(__name__)
L3_DB_PATH = Config.DB_L3_PATH
SCHEMA_PATH = os.path.join(Config.BASE_DIR, 'database', 'L3', 'schema.sql')
def _get_existing_columns(conn, table_name):
cur = conn.execute(f"PRAGMA table_info({table_name})")
return {row[1] for row in cur.fetchall()}
def _ensure_columns(conn, table_name, columns):
existing = _get_existing_columns(conn, table_name)
for col, col_type in columns.items():
if col in existing:
continue
conn.execute(f"ALTER TABLE {table_name} ADD COLUMN {col} {col_type}")
def init_db():
l3_dir = os.path.dirname(L3_DB_PATH)
if not os.path.exists(l3_dir):
@@ -26,6 +37,40 @@ def init_db():
conn = sqlite3.connect(L3_DB_PATH)
with open(SCHEMA_PATH, 'r', encoding='utf-8') as f:
conn.executescript(f.read())
_ensure_columns(
conn,
"dm_player_features",
{
"rd_phase_kill_early_share": "REAL",
"rd_phase_kill_mid_share": "REAL",
"rd_phase_kill_late_share": "REAL",
"rd_phase_death_early_share": "REAL",
"rd_phase_death_mid_share": "REAL",
"rd_phase_death_late_share": "REAL",
"rd_firstdeath_team_first_death_rounds": "INTEGER",
"rd_firstdeath_team_first_death_win_rate": "REAL",
"rd_invalid_death_rounds": "INTEGER",
"rd_invalid_death_rate": "REAL",
"rd_pressure_kpr_ratio": "REAL",
"rd_pressure_perf_ratio": "REAL",
"rd_pressure_rounds_down3": "INTEGER",
"rd_pressure_rounds_normal": "INTEGER",
"rd_matchpoint_kpr_ratio": "REAL",
"rd_matchpoint_perf_ratio": "REAL",
"rd_matchpoint_rounds": "INTEGER",
"rd_comeback_kill_share": "REAL",
"rd_comeback_rounds": "INTEGER",
"rd_trade_response_10s_rate": "REAL",
"rd_weapon_top_json": "TEXT",
"rd_roundtype_split_json": "TEXT",
"map_stability_coef": "REAL",
"basic_avg_knife_kill": "REAL",
"basic_avg_zeus_kill": "REAL",
"basic_zeus_pick_rate": "REAL",
},
)
conn.commit()
conn.close()
logger.info("L3 DB Initialized/Updated with Schema.")