Fix host reconnection losing player state and first-answer bonus
- Persist firstCorrectPlayerId to backend during state sync - Restore full players array (not just host) on host reconnect - Add default values to WELCOME payload for new/unmatched players - Add migration for first_correct_player_id column in game_sessions
This commit is contained in:
parent
32696ad33d
commit
035ea57274
4 changed files with 22 additions and 3 deletions
|
|
@ -71,7 +71,8 @@ export const useGame = () => {
|
|||
const gameConfigRef = useRef<GameConfig>(DEFAULT_GAME_CONFIG);
|
||||
const gamePinRef = useRef<string | null>(null);
|
||||
const hostSecretRef = useRef<string | null>(null);
|
||||
const gameStateRef = useRef<GameState>('LANDING');
|
||||
const gameStateRef = useRef<GameState>("LANDING");
|
||||
const firstCorrectPlayerIdRef = useRef<string | null>(null);
|
||||
|
||||
useEffect(() => { timeLeftRef.current = timeLeft; }, [timeLeft]);
|
||||
useEffect(() => { playersRef.current = players; }, [players]);
|
||||
|
|
@ -81,6 +82,7 @@ export const useGame = () => {
|
|||
useEffect(() => { gamePinRef.current = gamePin; }, [gamePin]);
|
||||
useEffect(() => { hostSecretRef.current = hostSecret; }, [hostSecret]);
|
||||
useEffect(() => { gameStateRef.current = gameState; }, [gameState]);
|
||||
useEffect(() => { firstCorrectPlayerIdRef.current = firstCorrectPlayerId; }, [firstCorrectPlayerId]);
|
||||
|
||||
const generateGamePin = () => Math.floor(Math.random() * 900000) + 100000 + "";
|
||||
|
||||
|
|
@ -98,6 +100,7 @@ export const useGame = () => {
|
|||
body: JSON.stringify({
|
||||
gameState: gameStateRef.current,
|
||||
currentQuestionIndex: currentQuestionIndexRef.current,
|
||||
firstCorrectPlayerId: firstCorrectPlayerIdRef.current,
|
||||
players: playersRef.current,
|
||||
}),
|
||||
});
|
||||
|
|
@ -296,6 +299,7 @@ export const useGame = () => {
|
|||
setQuiz(hostData.quiz);
|
||||
setGameConfig(hostData.gameConfig);
|
||||
setCurrentQuestionIndex(hostData.currentQuestionIndex || 0);
|
||||
setFirstCorrectPlayerId(hostData.firstCorrectPlayerId || null);
|
||||
|
||||
const hostPlayer = (hostData.players || []).find((p: Player) => p.id === 'host');
|
||||
if (hostPlayer) {
|
||||
|
|
@ -303,7 +307,7 @@ export const useGame = () => {
|
|||
setCurrentPlayerName('Host');
|
||||
setCurrentPlayerScore(hostPlayer.score);
|
||||
setCurrentStreak(hostPlayer.streak);
|
||||
setPlayers([hostPlayer]);
|
||||
setPlayers(hostData.players || []);
|
||||
|
||||
if (hostPlayer.lastAnswerCorrect !== null) {
|
||||
setHasAnswered(true);
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ const runMigrations = () => {
|
|||
game_state TEXT NOT NULL DEFAULT 'LOBBY',
|
||||
current_question_index INTEGER NOT NULL DEFAULT 0,
|
||||
players_data TEXT NOT NULL DEFAULT '[]',
|
||||
first_correct_player_id TEXT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
|
@ -52,6 +53,13 @@ const runMigrations = () => {
|
|||
`);
|
||||
console.log("Migration: Created game_sessions table");
|
||||
}
|
||||
|
||||
const sessionTableInfo = db.prepare("PRAGMA table_info(game_sessions)").all() as { name: string }[];
|
||||
const hasFirstCorrect = sessionTableInfo.some(col => col.name === "first_correct_player_id");
|
||||
if (!hasFirstCorrect) {
|
||||
db.exec("ALTER TABLE game_sessions ADD COLUMN first_correct_player_id TEXT");
|
||||
console.log("Migration: Added first_correct_player_id to game_sessions");
|
||||
}
|
||||
};
|
||||
|
||||
runMigrations();
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ CREATE TABLE IF NOT EXISTS game_sessions (
|
|||
game_state TEXT NOT NULL DEFAULT 'LOBBY',
|
||||
current_question_index INTEGER NOT NULL DEFAULT 0,
|
||||
players_data TEXT NOT NULL DEFAULT '[]',
|
||||
first_correct_player_id TEXT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ interface GameSession {
|
|||
game_state: string;
|
||||
current_question_index: number;
|
||||
players_data: string;
|
||||
first_correct_player_id: string | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
|
@ -112,6 +113,7 @@ router.get('/:pin/host', (req: Request, res: Response) => {
|
|||
gameState: session.game_state,
|
||||
currentQuestionIndex: session.current_question_index,
|
||||
players: JSON.parse(session.players_data),
|
||||
firstCorrectPlayerId: session.first_correct_player_id,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Error getting host session:', err);
|
||||
|
|
@ -123,7 +125,7 @@ router.patch('/:pin', (req: Request, res: Response) => {
|
|||
try {
|
||||
const { pin } = req.params;
|
||||
const hostSecret = req.headers['x-host-secret'] as string;
|
||||
const { hostPeerId, gameState, currentQuestionIndex, players } = req.body;
|
||||
const { hostPeerId, gameState, currentQuestionIndex, players, firstCorrectPlayerId } = req.body;
|
||||
|
||||
if (!hostSecret) {
|
||||
res.status(401).json({ error: 'Host secret required' });
|
||||
|
|
@ -156,6 +158,10 @@ router.patch('/:pin', (req: Request, res: Response) => {
|
|||
updates.push('players_data = ?');
|
||||
values.push(JSON.stringify(players));
|
||||
}
|
||||
if (firstCorrectPlayerId !== undefined) {
|
||||
updates.push("first_correct_player_id = ?");
|
||||
values.push(firstCorrectPlayerId);
|
||||
}
|
||||
|
||||
if (updates.length === 0) {
|
||||
res.status(400).json({ error: 'No updates provided' });
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue