- 03 Jul, 2026 24 commits
-
-
Mahmoud Aglan authored
- auth.php: eliminate double token verification (decode JWT payload directly) - auth.php: cascade delete related data on account deletion (blocks, daily_claims, challenges, achievements, group_members) - auth.php: add server-side username regex validation - register.js: add client-side username character validation - profile/view.js: show "Unrated" for players with 0 games at 1200 rating - i18n: add auth.invalid_username and profile.unrated keys Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Phase 1 (Chess Multiplayer Bulletproof): - net.js: check content-type before JSON parse, clear error on HTML responses - modal.js: stack-based resolve — stacked modals no longer hang - match-session.js: fix null dereference after destroy, remove listener on cleanup - match-session.js: only fire onConnectionRestored after actual disconnect - lobby.js: prevent duplicate startGame calls with gameStarted flag - lobby.js: add pollInFlight guard, clear timeouts on unmount - lobby.js: derive color from match data when undefined (friend invite fix) - scene.js: queue navigation during transition instead of dropping it - chess/game.js: pass timeControl to result scene for correct rematch Phase 5 (Core UX): - table.js: hide "My Games" button for non-chess games (no history scenes) - queue.js: add polling overlap guard - profile/view.js: show "Unrated" for new players instead of 1200 - i18n: add profile.unrated key (ar/en) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Created core/config.js with SUPABASE_URL, STOCKFISH_URL, DEFAULT_RATING - login.js, register.js, realtime.js now import from shared config - chess/game.js and bot-select.js use STOCKFISH_URL constant - multiplayer.js uses DEFAULT_RATING from config - ludo/game.js: named TURBO_SPEED constant - table.js: removed dead `disabled = false` code path Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Updated tokens.css with aligned color values and added missing tokens (bg-panel, bg-inset, bg-dark, gold-dark, purple-light, violet, green, green-light, amber, red-light, red-soft, text-dim, text-light, info). Updated theme.js applyColors map to support all new tokens via admin branding panel. Converted ~85% of all inline hex colors across 50+ JS files to use var(--token) references. Remaining ~160 are canvas colors (which can't use CSS vars) and unmapped game-specific colors. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
27 files converted to use the emoji(slot, fallback, size) function from core/theme.js, enabling full emoji customization via the admin branding panel. Covers core modules, all 4 game scenes, play flow, social, rewards, org, and tournaments. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Replace all 40+ remaining Arabic strings in tournament-detail.js. Add tournament format/prizes/registration/standings/rounds keys to both ar and en dictionaries. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Replace hardcoded Arabic in tournament-arena.js (7 strings), tournament-detail.js (10 strings), tournament-live.js (8 strings). Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
All UI text across 57 files now goes through the i18n system (core/i18n.js). Added ~120 new translation keys covering: auth, daily rewards, challenges, ranks, shop, groups, tournaments, puzzles, orgs, emotes, and backgammon doubling. Both ar and en dictionaries are complete and in sync. Data strings (country names, FIDE titles, variant names, puzzle themes) are intentionally left as-is — they use name/nameEn data pattern. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Phase 2.4: multiplayer.php now routes to correct table for all games (chess→matches, domino→domino_matches, backgammon→backgammon_matches, ludo→ludo_matches). Validates game_key against allowed list. Phase 4.3: handleServerState in backgammon only copies specific fields (state, dice, turn, gameOver) instead of Object.assign which clobbered local methods and properties. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Phase 1.13: add unmountGame export for chess — stops clock, destroys board, nulls gameState on scene exit. Phase 5.1: notification items now navigate to relevant section on click (friends, play, tournaments, achievements based on type). Phase 6.6: remove remaining stopDisconnectWatch calls from domino/ludo since disconnect detection is now fully handled by match-session.js. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Phase 7.1: add 30+ missing i18n keys for queue timeout, game states, achievements, and chat. Replace hardcoded Arabic in chess game scene with t() calls. Phase 7.3: replace hardcoded hex colors in chess HUD and draw dialog with CSS variables (--text-primary, --bg-surface, --success, --error). Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Phase 1.6: add pollInFlight guard to match-session.js so overlapping polls are skipped when server is slow. Phase 2.5: room code generation retries up to 5 times on collision. Phase 2.6: join_room uses service key, checks if room is full, prevents double-join, and auto-starts when player count is met. Phase 3.1: dealAndSyncToServer retries on failure with toast notification. Phase 3.3: drawFromBoneyard syncs once after all tiles drawn instead of firing N parallel requests. Phase 3.6: check-invites uses PostgREST cs filter on JSONB players array instead of scanning all waiting matches. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Phase 4: getPipCount now accepts variant param (fixes wrong pip count for thirtyone variant), backgammon quit button shows confirmation dialog in live mode. Phase 3: syncPassToServer no longer pre-increments moveCount before network success, winners array guards against empty state.players. Phase 2: ludo bot "thinking" indicator uses dedicated .pp-status span instead of clobbering the player name. Phase 6: chat.php unread/recent queries batched into single DB calls instead of N+1 per friendship. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Phase 5: queue 60s timeout with retry prompt, match history accepts game_key, spectate routes to correct game scene, shop shows "owned" indicator, profile shows dash instead of 1200 for unrated players. Phase 6: remove duplicate disconnectWatch calls (use match-session only), fix auth.php double token verification with requireAuthUser(), cascade delete related data on account deletion. Phase 1: fix opponentRating using actual rating in live mode instead of botElos lookup. Fix achievements recursive mount — update in-place instead of re-calling mountAchievements. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- friends.js: add unmountFriends() to clear refresh/invite timers - play/mod.js: register unmountLobby for game-lobby scene - social/mod.js: register unmountFriends for friends scene - net.js: add 10s request timeout via AbortController - net.js: add mutex for token refresh (prevents duplicate refresh calls) - notifications.js: don't auto-mark-read on mount; add explicit button - chat.js: pass lastTime as 'after' param for incremental fetch Fixes WTF #38, #63, #66, #69, #91, #175 Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- modal.js: dismiss existing modal before showing new one (prevents stacking) - scene.js: call unmount on current scene during replace() and switchWorld() - chat.js: remove || true from scroll condition (only auto-scroll on new msgs) - shop/browse.js: check gems affordability alongside coins - ludo/game.js: fix undefined isLoser — use isLastPlace - backgammon/rules.js: fix VARIANTS.standard crash — use VARIANTS.sheshbesh - backgammon/game.js: sanitize opponentName and avatar URL (XSS prevention) Fixes WTF #22, #25, #26, #59, #68, #71, #113 Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Phase 1 fixes: - lobby.js: guest waits 2.5s before entering game (gives host time to detect) - challenge.js: validate match_id exists before navigating to lobby - match-session.js: remove visibilitychange listener on destroy (memory leak fix) - match-session.js: only fire onConnectionRestored after actual disconnection - net.js: handle non-JSON server responses gracefully (nginx 502 pages etc) - result.js: pass actual timeControl to rematch instead of hardcoded rapid_10_0 - Remove dead chess/logic/live.js and ludo/logic/live.js (unused) Fixes WTF #15, #19, #23, #24, #35, #37, #54, #150 Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Reject invalid time_control values before DB write - Reject invalid game_key values before DB write - Also added missing DB indexes and reward_config rows via migration Fixes WTF #schema-2-3, Phase 0.7-0.9 Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Replace wildcard CORS (Access-Control-Allow-Origin: *) with domain whitelist across all 37 API files via shared includes/cors.php - friends.php: sanitize PostgREST filter inputs (strip special chars from search) - friends.php: validate UUID format for profile ID lookups - friends.php: verify user is invite target before accept/decline (domino, ludo, chess) - config/constants.php: read secrets from .env file or env vars (no more hardcoded keys) - Add .env to .gitignore Fixes WTF #5-6, #9-11 Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- handleGameMove: verify caller is a player in the match before allowing moves - handleResign: verify participant before allowing resignation - handleDraw: verify participant + use merge_game_state RPC (preserves heartbeat data) - handleComplete: verify participant + validate winners are actual match players (prevents coin exploit) - handleFindActiveMatch: restrict to own user only (prevents info disclosure) - Validate result enum values in handleComplete Fixes WTF #1-4, #46 Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Prioritized plan to go from 240 WTFs to all 4 games working in multiplayer. Phase 0 locks down security, phases 1-4 bring each game online, phases 5-7 polish UX/stability/theming. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
SSHed into Supabase DB and compared all table schemas, RLS policies, RPCs, enums, indexes, and reward_config rows against what the code expects. Found 21 mismatches including: service key bypassing RLS (making RLS useless), missing indexes, missing reward rows, handleDraw destroying game_state, and complete_match trusting client-provided winners array. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Full codebase scan covering security, bugs, race conditions, UX dead ends, theming violations, dead code, and user journey problems. Includes root cause analysis for broken friend invites and priority fix list. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 25 Jun, 2026 3 commits
-
-
Mahmoud Aglan authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Adds range slider sections for HUD, Tab Bar, Home Page, Quick Actions, Game Tiles, Game Menu Sheet, Menu Buttons, Menu Chips, and Bot Cards — covering all sizing, spacing, padding, margin, and font controls. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- All Arabic labels replaced with English descriptive labels - API save_theme now also writes local theme.json (prevents stale overrides) - Added Ludo Board Colors section (9 controls) - Added Backgammon Board Colors section (14 controls) - Page lang/dir switched from ar/rtl to en/ltr Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 23 Jun, 2026 5 commits
-
-
Mahmoud Aglan authored
Root cause: draw offers stored in game_state were lost when a concurrent move write did read→merge→write (non-atomic). Now uses PostgreSQL jsonb || operator via merge_game_state() RPC for atomic merges. Also adds: - mp_log table for server-side multiplayer event logging - Frontend sessionStorage logging (sessionStorage.mp_log) for debugging draw offers, moves, and poll events - Logging on match_created, move, resign, draw_accepted, game_state_merge Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Screenshots confirm: moves sync to opponent board, resign shows victory screen. Both directions verified via Puppeteer + API. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The `matches` table has no `last_activity` or `ended_at` columns. PostgREST rejects the entire PATCH when ANY column doesn't exist, causing every move update and resignation to silently fail. - Remove `last_activity` from handleGameMove (column doesn't exist) - Change `ended_at` to `completed_at` in handleResign, handleDraw, handleComplete (correct column name per DB schema) This was the root cause of zero sync in multiplayer chess. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Add dequeue handler to backgammon-match.php (was missing) - Add 90-second stale entry cleanup to ludo/domino/backgammon queues - Add atomic opponent claiming (conditional update) to prevent race conditions - Fix client queue.js to route dequeue to correct game endpoint - Register unmountQueue for proper cleanup when exiting search screen - Remove json_encode on jsonb fields in backgammon (prevent double-encoding) Fixes: self-matching, ghost queue entries, and race condition where two players simultaneously claim the same opponent. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The root cause: PHP's json_encode() was used on jsonb fields before passing to SupabaseClient->insert/update, which json_encodes the entire payload. This double-encoded game_state into a JSON string scalar. When the match_heartbeat RPC did `jsonb_string || jsonb_object`, PostgreSQL created an array instead of merging, corrupting game_state. The polling logic then couldn't find move_count or last_move in the array, so moves never synced between players. Fix: pass PHP arrays directly for all jsonb columns (game_state, moves, positions, scores, winners, hands, boneyard). The Supabase client handles encoding once at the HTTP layer. Also: when reading game_state back from the DB, handle the case where PostgREST returns it as a decoded array/object (not a string) since jsonb columns are deserialized automatically. Affected: chess, ludo, domino — all multiplayer match creation and move/state updates. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 22 Jun, 2026 1 commit
-
-
Mahmoud Aglan authored
Use Math.min() scaling (same approach as chess pieces) instead of forcing sprites into a square bounding box which stretched non-square pawn images uploaded via admin branding. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 21 Jun, 2026 4 commits
-
-
Mahmoud Aglan authored
The notifications API selected a column 'metadata' that doesn't exist in the table (actual column is 'data'). This caused PostgREST to return an error, which the error handler caught and returned empty. Users never saw their notifications. Also added body_ar to the select and frontend display. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Ludo: - Add endingGame guard to prevent double endGame calls - Parse server winners from live polling (fixes empty leaderboard when opponent wins remotely) - Fix win/loss detection: last place = loss (was broken for 2-player) Chess: - Add 5s failsafe timer: result screen shows even if network hangs - Deduplicate navigation logic with navigated flag - Prevent double-navigation if both .then and failsafe fire Backgammon: - Add scene.exitGameMode() to both result navigation paths (was missing, could leave UI in game-mode state) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Without this, the render loop, polling, heartbeat, and turn timers would continue running after navigating away from the game scene. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Chess: - "التحليل التفصيلي" button in review now navigates to chess-analysis (interactive move-by-move board with eval bar) instead of scene.pop() Ludo: - Complete leaderboard showing all players ranked 1st-4th - Each player shown with their name, color dot, and medal/rank - Current player highlighted with gold border - Proper rewards display (coins + XP + rating change) - Pass playerNames and playerColors from game to result scene Backgammon: - Add rewards display (coins + XP) to result screen - Emit coins:earned and xp:earned events for HUD sync Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 20 Jun, 2026 3 commits
-
-
Mahmoud Aglan authored
showOpponentPopup existed but was never called. Now tapping an opponent's panel in live mode opens their profile with add-friend option. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- endGame and handleExit pass mode/numPlayers/seats/humanCount/difficulty to the result scene - Result "play again" restarts with same settings (not always 4p bot) - Live mode "play again" goes to queue (finds new match, not old one) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- afterMove: use boardSlot for firework/flash colors (not player index) - afterMove: in local-multi, ANY human capturing triggers celebration (not just player 0) - botLoop: capture detection checks all human players in local-multi (not just myPlayerIndex=0) - animateDice: shake dice-area for all human players in local-multi (previously only shook for player 0, panel for others) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-