fel kesz game backend
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user