feat: Enhance session persistence by marking players offline in active games and improving rejoin room with server callbacks.
All checks were successful
Build and Deploy / build (push) Successful in 1m11s
All checks were successful
Build and Deploy / build (push) Successful in 1m11s
This commit is contained in:
@@ -17,5 +17,7 @@
|
||||
- [Resizable Draft Interface](./devlog/2025-12-16-200500_resizable_draft_ui.md): Completed. Implemented user-resizable pool panel and card sizes with persistence.
|
||||
- [Draft UI Zoom Zone](./devlog/2025-12-16-203000_zoom_zone.md): Completed. Implemented dedicated zoom zone for card preview.
|
||||
- [Host Disconnect Pause](./devlog/2025-12-16-213500_host_disconnect_pause.md): Completed. Specific logic to pause game when host leaves.
|
||||
- [Anti-Tampering System](./devlog/2025-12-16-215000_anti_tampering.md): Completed. Robust server-side validation using socket session binding and ownership checks.
|
||||
- [2025-12-16-215000_anti_tampering.md](./devlog/2025-12-16-215000_anti_tampering.md): Implemented server-side validation for game actions.
|
||||
- [2025-12-16-220000_session_persistence.md](./devlog/2025-12-16-220000_session_persistence.md): Plan for session persistence and safer room exit logic.
|
||||
- [2025-12-16-221000_lobby_improvements.md](./devlog/2025-12-16-221000_lobby_improvements.md): Plan for kick functionality and exit button relocation.
|
||||
- [Fix Draft UI Layout](./devlog/2025-12-16-215500_fix_draft_ui_layout.md): Completed. Fixed "Waiting for next pack" layout to be consistently full-screen.
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# implementation_plan - Draft Session Persistence and Restoration
|
||||
|
||||
This plan addresses the issue where users are unable to reliably rejoin a draft session as a player after reloading or exiting, often re-entering as a spectator. It ensures robust session synchronization to local storage and handles player "leave" actions safely during active games.
|
||||
|
||||
## User Objectives
|
||||
- **Session Restoring**: Automatically rejoin the correct session and player seat upon reloading the application.
|
||||
- **Prevent Accidental Data Loss**: Ensure "Exiting" a room during an active draft does not destroy the player's seat, allowing them to rejoin.
|
||||
- **Start New Draft**: Maintain the ability for a user to explicitly invalid/abandon an old session to start a new one (handled by creating a new room, which overwrites local storage).
|
||||
|
||||
## Proposed Changes
|
||||
|
||||
### 1. Server-Side: Safer `leaveRoom` Logic
|
||||
**File**: `src/server/managers/RoomManager.ts`
|
||||
- Modify `leaveRoom` method.
|
||||
- **Logic**:
|
||||
- If `room.status` is `'waiting'`, remove the player (current behavior).
|
||||
- If `room.status` is `'drafting'`, `'deck_building'`, or `'playing'`, **DO NOT** remove the player from `room.players`. Instead, mark them as `isOffline = true` (similar to a disconnect).
|
||||
- This ensures that if the user rejoins with the same `playerId`, they find their existing seat instead of being assigned a new "spectator" role.
|
||||
|
||||
### 2. Server-Side: Robust `rejoin_room` Handler
|
||||
**File**: `src/server/index.ts`
|
||||
- Update `socket.on('rejoin_room')`.
|
||||
- **Change**: Implement an acknowledgement `callback` pattern consistent with other socket events.
|
||||
- **Logic**:
|
||||
- Accept `{ roomId, playerId }`.
|
||||
- If successful, invoke `callback({ success: true, room, draftState })`.
|
||||
- Broadcast `room_update` to other players (to show user is back online).
|
||||
|
||||
### 3. Client-Side: Correct Rejoin Implementation
|
||||
**File**: `src/client/src/modules/lobby/LobbyManager.tsx`
|
||||
- **Fix**: In the `rejoin_room` emit call, explicitly include the `playerId`.
|
||||
- **Enhancement**: Utilize the callback from the server to confirm reconnection before setting state.
|
||||
- **Exit Handling**: The `handleExitRoom` function clears `localStorage`, which is correct for an explicit "Exit". However, thanks to the server-side change, if the user manually rejoins the same room code, they will reclaim their seat effectively.
|
||||
|
||||
## Verification Plan
|
||||
1. **Test Reload**: Start a draft, refresh the browser. Verify user auto-rejoins as Player.
|
||||
2. **Test Exit & Rejoin**: Start a draft, click "Exit Room". Re-enter the Room ID manually. Verify user rejoins as Player (not Spectator).
|
||||
3. **Test New Draft**: Create a room, start draft. Open new tab (or exit), create NEW room. Verify new room works and old session doesn't interfere.
|
||||
@@ -0,0 +1,46 @@
|
||||
# implementation_plan - Lobby Improvements and Kick Functionality
|
||||
|
||||
This plan addresses user feedback regarding the draft resumption experience, exit button placement, and host management controls.
|
||||
|
||||
## User Objectives
|
||||
1. **Resume Draft on Re-entry**: Ensure that manually joining a room (after exiting) correctly restores the draft view if a draft is in progress.
|
||||
2. **Exit Button Placement**: Move the "Exit Room" button to be near the player's name in the lobby sidebar.
|
||||
3. **Kick Player**: Allow the Host to kick players from the room.
|
||||
|
||||
## Proposed Changes
|
||||
|
||||
### 1. Server-Side: Kick Functionality
|
||||
**File**: `src/server/managers/RoomManager.ts`
|
||||
- **Method**: `kickPlayer(roomId, playerId)`
|
||||
- **Logic**:
|
||||
- Remove the player from `room.players`.
|
||||
- If the game is active (drafting/playing), this is a destructive action. We will assume for now it removes them completely (or marks offline? "Kick" usually implies removal).
|
||||
- *Decision*: If kicked, they are removed. If the game breaks, that's the host's responsibility.
|
||||
|
||||
**File**: `src/server/index.ts`
|
||||
- **Event**: `kick_player`
|
||||
- **Logic**:
|
||||
- Verify requester is Host.
|
||||
- Call `roomManager.kickPlayer`.
|
||||
- Broadcast `room_update`.
|
||||
- Emit `kicked` event to the target socket (to force them to client-side exit).
|
||||
|
||||
### 2. Client-Side: Re-entry Logic Fix
|
||||
**File**: `src/client/src/modules/lobby/GameRoom.tsx`
|
||||
- **Logic**: Ensure `GameRoom` correctly initializes or updates `draftState` when receiving new props.
|
||||
- Add a `useEffect` to update local `draftState` if `initialDraftState` prop changes (though `key` change on component might be better, we'll use `useEffect`).
|
||||
|
||||
### 3. Client-Side: UI Updates
|
||||
**File**: `src/client/src/modules/lobby/GameRoom.tsx`
|
||||
- **Sidebar**:
|
||||
- Update the player list rendering.
|
||||
- If `p.id === currentPlayerId`, show an **Exit/LogOut** button next to the name.
|
||||
- If `isMeHost` and `p.id !== me`, show a **Kick/Ban** button next to the name.
|
||||
- **Handlers**:
|
||||
- `handleKick(targetId)`: Warning confirmation -> Emit `kick_player`.
|
||||
- `handleExit()`: Trigger the existing `onExit`.
|
||||
|
||||
## Verification Plan
|
||||
1. **Test Kick**: Host kicks a player. Player should be removed from list and client should revert to lobby (via socket event).
|
||||
2. **Test Exit**: Click new Exit button in sidebar. Should leave room.
|
||||
3. **Test Re-join**: Join the room code again. Should immediately load the Draft View (not the Lobby View).
|
||||
Reference in New Issue
Block a user