diff --git a/engine/user_profile_integration.py b/engine/user_profile_integration.py index 61061d4..f8aa348 100644 --- a/engine/user_profile_integration.py +++ b/engine/user_profile_integration.py @@ -8,6 +8,7 @@ import json import uuid import platform import hashlib +import os from datetime import datetime from engine.score_api_client import ScoreAPIClient @@ -27,6 +28,7 @@ class UserProfileIntegration: print(f"✓ Connected to score server at {api_url}") else: print(f"✗ Score server not available at {api_url} - running offline") + def generate_device_id(self): """Generate a unique device ID based on system information""" @@ -47,23 +49,45 @@ class UserProfileIntegration: def load_active_profile(self): """Load the currently active profile""" + print(f"[DEBUG] Attempting to load profile from: {self.profiles_file}") + print(f"[DEBUG] File exists: {os.path.exists(self.profiles_file)}") + try: with open(self.profiles_file, 'r') as f: - data = json.load(f) + raw_content = f.read() + print(f"[DEBUG] File content length: {len(raw_content)} bytes") + print(f"[DEBUG] File content (first 500 chars): {raw_content[:500]}") + + data = json.loads(raw_content) + print(f"[DEBUG] Parsed JSON keys: {list(data.keys())}") + print(f"[DEBUG] Active profile key value: {data.get('active_profile')}") + print(f"[DEBUG] Available profiles: {list(data.get('profiles', {}).keys())}") + active_name = data.get('active_profile') - if active_name and active_name in data['profiles']: - self.current_profile = data['profiles'][active_name] - print(f"Loaded profile: {self.current_profile['name']}") - - # Sync with API if available - if self.api_enabled: - self.sync_profile_with_api() - - return True - except (FileNotFoundError, json.JSONDecodeError) as e: - print(f"Could not load profile: {e}") + if active_name: + print(f"[DEBUG] Looking for profile: '{active_name}'") + if active_name in data['profiles']: + self.current_profile = data['profiles'][active_name] + print(f"✓ Loaded profile: {self.current_profile['name']}") + + # Sync with API if available + if self.api_enabled: + self.sync_profile_with_api() + + return True + else: + print(f"[DEBUG] Profile '{active_name}' not found in profiles dict") + else: + print(f"[DEBUG] No active_profile specified in JSON") + except FileNotFoundError as e: + print(f"✗ Profile file not found: {e}") + except json.JSONDecodeError as e: + print(f"✗ Failed to parse profile JSON: {e}") + except Exception as e: + print(f"✗ Unexpected error loading profile: {e}") self.current_profile = None + print(f"[DEBUG] Profile loading failed, current_profile set to None") return False def get_profile_name(self): @@ -117,13 +141,19 @@ class UserProfileIntegration: def update_game_stats(self, score, completed=True): """Update the current profile's game statistics""" + print(f"[DEBUG UPDATE_STATS] update_game_stats called with score={score}, completed={completed}") + print(f"[DEBUG UPDATE_STATS] self.current_profile is None: {self.current_profile is None}") + if not self.current_profile: - print("No profile loaded - stats not saved") + print("[DEBUG UPDATE_STATS] No profile loaded - stats not saved") return False + print(f"[DEBUG UPDATE_STATS] Profile name: {self.current_profile.get('name', 'UNKNOWN')}") + # Submit score to API first if available if self.api_enabled: profile_name = self.current_profile['name'] + print(f"[DEBUG UPDATE_STATS] API enabled, submitting score for {profile_name}") result = self.api_client.submit_score( self.device_id, profile_name, @@ -140,23 +170,30 @@ class UserProfileIntegration: print(f"✗ Failed to submit score to server: {result.get('message')}") try: - # Update local profile + print(f"[DEBUG UPDATE_STATS] Attempting to read {self.profiles_file}") with open(self.profiles_file, 'r') as f: data = json.load(f) + print(f"[DEBUG UPDATE_STATS] Read profiles file successfully") + print(f"[DEBUG UPDATE_STATS] Profiles keys in file: {list(data.get('profiles', {}).keys())}") + profile_name = self.current_profile['name'] + print(f"[DEBUG UPDATE_STATS] Looking for profile '{profile_name}' in file") + if profile_name in data['profiles']: profile = data['profiles'][profile_name] + print(f"[DEBUG UPDATE_STATS] Found profile in file") # Update statistics if completed: - profile['games_played'] += 1 - print(f"Game completed for {profile_name}! Total games: {profile['games_played']}") + profile['games_played'] = profile.get('games_played', 0) + 1 + print(f"[DEBUG UPDATE_STATS] Game completed! Total games now: {profile['games_played']}") - profile['total_score'] += score - if score > profile['best_score']: + profile['total_score'] = profile.get('total_score', 0) + score + old_best = profile.get('best_score', 0) + if score > old_best: profile['best_score'] = score - print(f"New best score for {profile_name}: {score}!") + print(f"[DEBUG UPDATE_STATS] New best score for {profile_name}: {score}!") profile['last_played'] = datetime.now().isoformat() @@ -164,14 +201,41 @@ class UserProfileIntegration: self.current_profile = profile # Save back to file + print(f"[DEBUG UPDATE_STATS] Writing updated profile back to {self.profiles_file}") with open(self.profiles_file, 'w') as f: json.dump(data, f, indent=2) - print(f"Local profile stats updated: Score +{score}, Total: {profile['total_score']}") + print(f"[DEBUG UPDATE_STATS] Successfully saved! Score +{score}, New total: {profile['total_score']}, Best: {profile.get('best_score', 0)}") + + # Call JavaScript function to sync profile back to localStorage (Pyodide only) + try: + # noinspection PyUnresolvedReference + from js import window + window.syncProfileUpdateToLocalStorage( + profile_name, + profile['best_score'], + profile['games_played'], + profile['total_score'] + ) + print(f"[DEBUG UPDATE_STATS] JS sync call completed successfully") + except ImportError: + print(f"[DEBUG UPDATE_STATS] Note: 'js' module not available (running in non-Pyodide environment)") + except Exception as js_err: + print(f"[DEBUG UPDATE_STATS] Warning: Failed to call JS sync function: {js_err}") + return True + else: + print(f"[DEBUG UPDATE_STATS] Profile '{profile_name}' NOT FOUND in profiles file!") + print(f"[DEBUG UPDATE_STATS] Available profiles: {list(data.get('profiles', {}).keys())}") + except FileNotFoundError as e: + print(f"[DEBUG UPDATE_STATS] ERROR: Profile file not found: {e}") + except json.JSONDecodeError as e: + print(f"[DEBUG UPDATE_STATS] ERROR: Invalid JSON in profile file: {e}") except Exception as e: - print(f"Error updating profile stats: {e}") + print(f"[DEBUG UPDATE_STATS] ERROR: Unexpected error updating profile stats: {e}") + import traceback + traceback.print_exc() return False diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..ad34fd9 Binary files /dev/null and b/favicon.ico differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..b3bc49a --- /dev/null +++ b/index.html @@ -0,0 +1,966 @@ + + +
+ + +Eliminate the rats before they multiply! A strategic maze game with bombs, mines, and gas.
+Browser Edition powered by Python + Pygame via Pyodide
+ +Move your cursor around the maze and use your arsenal to eliminate rats before they overrun the level:
+