fel kesz game backend

This commit is contained in:
2025-09-15 19:00:35 +02:00
parent 7963f28021
commit 3af8de2797
267 changed files with 15655 additions and 347 deletions
@@ -54,6 +54,31 @@ interface DeleteMessageData {
messageId: string;
}
// Game-related WebSocket interfaces (prepared for future implementation)
interface JoinGameRoomData {
gameCode: string;
}
interface LeaveGameRoomData {
gameCode: string;
}
interface GameStateUpdateData {
gameId: string;
gameCode: string;
players: string[];
state: string;
currentTurn?: string;
}
interface GameActionData {
gameId: string;
gameCode: string;
playerId: string;
action: 'pick_card' | 'play_card' | 'end_turn' | 'leave_game';
data?: any;
}
export class WebSocketService {
private io: SocketIOServer;
private jwtService: JWTService;
@@ -236,6 +261,12 @@ export class WebSocketService {
socket.on('chat:delete', (data: DeleteChatData) => this.handleDeleteChat(socket, data));
socket.on('chat:archive:delete', (data: DeleteChatArchiveData) => this.handleDeleteChatArchive(socket, data));
socket.on('message:delete', (data: DeleteMessageData) => this.handleDeleteMessage(socket, data));
// Game event handlers (prepared for future implementation)
socket.on('game:join', (data: JoinGameRoomData) => this.handleJoinGameRoom(socket, data));
socket.on('game:leave', (data: LeaveGameRoomData) => this.handleLeaveGameRoom(socket, data));
socket.on('game:action', (data: GameActionData) => this.handleGameAction(socket, data));
socket.on('disconnect', () => this.handleDisconnection(socket));
}
@@ -1172,4 +1203,211 @@ export class WebSocketService {
}
}
}
// Game-related WebSocket handlers (prepared for future implementation)
/**
* Handle player joining a game room for real-time updates
* @param socket The authenticated socket
* @param data Game room data containing game code
*/
private async handleJoinGameRoom(socket: AuthenticatedSocket, data: JoinGameRoomData) {
try {
const userId = socket.userId!;
const gameRoom = `game_${data.gameCode}`;
logAuth('Player joining game room', userId, {
gameCode: data.gameCode,
gameRoom,
socketId: socket.id
});
// Join the WebSocket room for this game
await socket.join(gameRoom);
// Emit confirmation to the player
socket.emit('game:joined', {
gameCode: data.gameCode,
room: gameRoom,
message: 'Successfully joined game room'
});
// Notify other players in the game room
socket.to(gameRoom).emit('game:player_joined', {
playerId: userId,
gameCode: data.gameCode,
timestamp: new Date().toISOString()
});
logAuth('Player joined game room successfully', userId, {
gameCode: data.gameCode,
gameRoom
});
} catch (error) {
logError('Error joining game room', error as Error);
socket.emit('game:error', {
message: 'Failed to join game room',
gameCode: data.gameCode
});
}
}
/**
* Handle player leaving a game room
* @param socket The authenticated socket
* @param data Game room data containing game code
*/
private async handleLeaveGameRoom(socket: AuthenticatedSocket, data: LeaveGameRoomData) {
try {
const userId = socket.userId!;
const gameRoom = `game_${data.gameCode}`;
logAuth('Player leaving game room', userId, {
gameCode: data.gameCode,
gameRoom,
socketId: socket.id
});
// Leave the WebSocket room
await socket.leave(gameRoom);
// Notify other players in the game room
socket.to(gameRoom).emit('game:player_left', {
playerId: userId,
gameCode: data.gameCode,
timestamp: new Date().toISOString()
});
// Confirm to the leaving player
socket.emit('game:left', {
gameCode: data.gameCode,
message: 'Successfully left game room'
});
logAuth('Player left game room successfully', userId, {
gameCode: data.gameCode,
gameRoom
});
} catch (error) {
logError('Error leaving game room', error as Error);
socket.emit('game:error', {
message: 'Failed to leave game room',
gameCode: data.gameCode
});
}
}
/**
* Handle game actions (cards, turns, etc.) - prepared for future implementation
* @param socket The authenticated socket
* @param data Game action data
*/
private async handleGameAction(socket: AuthenticatedSocket, data: GameActionData) {
try {
const userId = socket.userId!;
const gameRoom = `game_${data.gameCode}`;
logAuth('Game action received', userId, {
gameId: data.gameId,
gameCode: data.gameCode,
action: data.action,
socketId: socket.id
});
// Validate that the player is authorized to perform this action
if (data.playerId !== userId) {
socket.emit('game:error', {
message: 'Unauthorized action',
gameCode: data.gameCode
});
return;
}
// TODO: Implement specific game logic here
// This will be implemented when the game flow is discussed
// For now, just broadcast the action to other players
socket.to(gameRoom).emit('game:action_performed', {
playerId: userId,
gameCode: data.gameCode,
action: data.action,
data: data.data,
timestamp: new Date().toISOString()
});
// Confirm action to the acting player
socket.emit('game:action_confirmed', {
gameCode: data.gameCode,
action: data.action,
message: 'Action processed successfully'
});
logAuth('Game action processed', userId, {
gameId: data.gameId,
gameCode: data.gameCode,
action: data.action
});
} catch (error) {
logError('Error processing game action', error as Error);
socket.emit('game:error', {
message: 'Failed to process game action',
gameCode: data.gameCode,
action: data.action
});
}
}
/**
* Broadcast game state updates to all players in a game
* @param gameCode The game code
* @param gameState The updated game state
*/
public broadcastGameStateUpdate(gameCode: string, gameState: GameStateUpdateData): void {
try {
const gameRoom = `game_${gameCode}`;
this.io.to(gameRoom).emit('game:state_updated', {
...gameState,
timestamp: new Date().toISOString()
});
logRequest('Game state broadcasted', undefined, undefined, {
gameCode,
gameRoom,
playerCount: gameState.players.length
});
} catch (error) {
logError('Error broadcasting game state', error as Error);
}
}
/**
* Notify players when a game starts
* @param gameCode The game code
* @param players Array of player IDs
*/
public notifyGameStart(gameCode: string, players: string[]): void {
try {
const gameRoom = `game_${gameCode}`;
this.io.to(gameRoom).emit('game:started', {
gameCode,
players,
message: 'Game has started!',
timestamp: new Date().toISOString()
});
logRequest('Game start notification sent', undefined, undefined, {
gameCode,
playerCount: players.length
});
} catch (error) {
logError('Error notifying game start', error as Error);
}
}
}