diff --git a/web/routes/players.py b/web/routes/players.py index 5a7f444..a0f9d65 100644 --- a/web/routes/players.py +++ b/web/routes/players.py @@ -299,27 +299,20 @@ def api_batch_stats(): # Use safe conversion with default 0 if None # Force 0.0 if value is 0 or None to ensure JSON compatibility radar = { - 'AIM': float(f.get('score_aim') or 0.0), - 'DEFENSE': float(f.get('score_defense') or 0.0), - 'UTILITY': float(f.get('score_utility') or 0.0), - 'CLUTCH': float(f.get('score_clutch') or 0.0), - 'ECONOMY': float(f.get('score_economy') or 0.0), - 'PACE': float(f.get('score_pace') or 0.0), - 'PISTOL': float(f.get('score_pistol') or 0.0), - 'STABILITY': float(f.get('score_stability') or 0.0) + 'STA': float(f.get('score_sta') or 0.0), + 'BAT': float(f.get('score_bat') or 0.0), + 'HPS': float(f.get('score_hps') or 0.0), + 'PTL': float(f.get('score_ptl') or 0.0), + 'SIDE': float(f.get('score_tct') or 0.0), + 'UTIL': float(f.get('score_util') or 0.0) } # 2. Basic Stats for Table - rating_val = f.get('core_avg_rating2') - if rating_val is None: - rating_val = f.get('core_avg_rating') - if rating_val is None: - rating_val = f.get('basic_avg_rating') basic = { - 'rating': float(rating_val or 0), - 'kd': float(f.get('core_avg_kd') or f.get('basic_avg_kd') or 0), - 'adr': float(f.get('core_avg_adr') or f.get('basic_avg_adr') or 0), - 'kast': float(f.get('core_avg_kast') or f.get('basic_avg_kast') or 0), + 'rating': float(f.get('basic_avg_rating') or 0), + 'kd': float(f.get('basic_avg_kd') or 0), + 'adr': float(f.get('basic_avg_adr') or 0), + 'kast': float(f.get('basic_avg_kast') or 0), 'hs_rate': float(f.get('basic_headshot_rate') or 0), 'fk_rate': float(f.get('basic_first_kill_rate') or 0), 'matches': int(f.get('matches_played') or 0) diff --git a/web/routes/tactics.py b/web/routes/tactics.py index d6b1a5a..dcf5d5c 100644 --- a/web/routes/tactics.py +++ b/web/routes/tactics.py @@ -27,7 +27,6 @@ def api_analyze(): total_kd = 0 total_adr = 0 count = 0 - radar_vectors = [] for p in players: p_dict = dict(p) @@ -38,25 +37,10 @@ def api_analyze(): player_data.append(p_dict) if stats: - rating_val = stats.get('core_avg_rating2') - if rating_val is None: - rating_val = stats.get('core_avg_rating') - if rating_val is None: - rating_val = stats.get('basic_avg_rating') - total_rating += rating_val or 0 - total_kd += stats.get('core_avg_kd', stats.get('basic_avg_kd', 0)) or 0 - total_adr += stats.get('core_avg_adr', stats.get('basic_avg_adr', 0)) or 0 + total_rating += stats.get('basic_avg_rating', 0) or 0 + total_kd += stats.get('basic_avg_kd', 0) or 0 + total_adr += stats.get('basic_avg_adr', 0) or 0 count += 1 - radar_vectors.append([ - float(stats.get('score_aim') or 0), - float(stats.get('score_defense') or 0), - float(stats.get('score_utility') or 0), - float(stats.get('score_clutch') or 0), - float(stats.get('score_economy') or 0), - float(stats.get('score_pace') or 0), - float(stats.get('score_pistol') or 0), - float(stats.get('score_stability') or 0) - ]) # 2. Shared Matches shared_matches = StatsService.get_shared_matches(steam_ids) @@ -69,23 +53,6 @@ def api_analyze(): 'adr': total_adr / count if count else 0 } - chemistry = 0 - if len(radar_vectors) >= 2: - def cosine_sim(a, b): - dot = sum(x * y for x, y in zip(a, b)) - na = sum(x * x for x in a) ** 0.5 - nb = sum(y * y for y in b) ** 0.5 - if na == 0 or nb == 0: - return 0 - return dot / (na * nb) - - sims = [] - for i in range(len(radar_vectors)): - for j in range(i + 1, len(radar_vectors)): - sims.append(cosine_sim(radar_vectors[i], radar_vectors[j])) - if sims: - chemistry = sum(sims) / len(sims) * 100 - # 4. Map Stats Calculation map_stats = {} # {map_name: {'count': 0, 'wins': 0}} total_shared_matches = len(shared_matches) @@ -118,8 +85,7 @@ def api_analyze(): 'shared_matches': [dict(m) for m in shared_matches], 'avg_stats': avg_stats, 'map_stats': map_stats_list, - 'total_shared_matches': total_shared_matches, - 'chemistry': chemistry + 'total_shared_matches': total_shared_matches }) # API: Save Board diff --git a/web/services/feature_service.py b/web/services/feature_service.py index 22f403a..115cb30 100644 --- a/web/services/feature_service.py +++ b/web/services/feature_service.py @@ -78,12 +78,8 @@ class FeatureService: } for legacy_key, l3_key in alias_map.items(): - legacy_val = f.get(legacy_key) - l3_val = f.get(l3_key) - if legacy_val is None and l3_val is not None: - f[legacy_key] = l3_val - elif l3_val is None and legacy_val is not None: - f[l3_key] = legacy_val + if legacy_key not in f or f.get(legacy_key) is None: + f[legacy_key] = f.get(l3_key) if f.get("matches_played") is None: f["matches_played"] = f.get("total_matches", 0) or 0 diff --git a/web/services/stats_service.py b/web/services/stats_service.py index 4079178..23738a8 100644 --- a/web/services/stats_service.py +++ b/web/services/stats_service.py @@ -733,19 +733,16 @@ class StatsService: from web.services.feature_service import FeatureService import json + # 1. Get Active Roster IDs lineups = WebService.get_lineups() active_roster_ids = [] - target_steam_id = str(target_steam_id) if lineups: - for lineup in lineups: - try: - raw_ids = json.loads(lineup.get('player_ids_json') or '[]') - roster_ids = [str(uid) for uid in raw_ids] - if target_steam_id in roster_ids: - active_roster_ids = roster_ids - break - except Exception: - continue + try: + raw_ids = json.loads(lineups[0]['player_ids_json']) + active_roster_ids = [str(uid) for uid in raw_ids] + except: + pass + if not active_roster_ids: return None @@ -755,8 +752,11 @@ class StatsService: return None stats_map = {str(row["steam_id_64"]): FeatureService._normalize_features(dict(row)) for row in rows} + target_steam_id = str(target_steam_id) + + # If target not in map (e.g. no L3 data), try to add empty default if target_steam_id not in stats_map: - return None + stats_map[target_steam_id] = {} metrics = [ # TIER 1: CORE diff --git a/web/templates/players/list.html b/web/templates/players/list.html index a71e879..eb663ba 100644 --- a/web/templates/players/list.html +++ b/web/templates/players/list.html @@ -40,15 +40,15 @@