Skip to content

Commit

Permalink
[BE] 현재 단계를 음성 처리 서버, 클라이언트가 알 수 있어야한다. (#135)
Browse files Browse the repository at this point in the history
* feat: 게임 시작 후 클라이언트 연결 해제시 데이터 처리

* feat: 게임 random 선택

* chore: 문제별 시간 수정
  • Loading branch information
student079 authored Nov 21, 2024
1 parent edcd879 commit f5c334d
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 25 deletions.
9 changes: 4 additions & 5 deletions be/gameServer/src/modules/games/dto/turn-data.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,17 @@ export class TurnDataDto {
gameMode: GameMode;

@ApiProperty({
example: 10,
example: 7,
type: Number,
description: '해당 단계 게임 모드를 수행할 때의 제한시간',
description: '해당 단계 게임 모드를 수행할 때의 제한시간 (sec)',
})
timeLimit: number;

@ApiProperty({
example:
'도토리가 문을 도로록, 드르륵, 두루룩 열었는가? 드로록, 두루륵, 두르룩 열었는가.',
type: String,
description: '게임모드가 PRONUNCIATION일 때 가사',
required: false,
description: '가사',
})
lyrics?: string;
lyrics: string;
}
73 changes: 56 additions & 17 deletions be/gameServer/src/modules/games/games-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,82 @@ import { GameMode, TurnDataDto } from './dto/turn-data.dto';
import { RoomDataDto } from './../rooms/dto/room-data.dto';
import { GameDataDto } from './dto/game-data.dto';

const SAMPLE_DATA = [
{
timeLimit: 5,
lyrics: '간장공장 공장장은 강 공장장이고 된장공장 공장장은 공 공장장이다.',
},
{
timeLimit: 6,
lyrics:
'내가 그린 기린 그림은 긴 기린 그림이고 네가 그린 기린 그림은 안 긴 기린 그림이다.',
},
{
timeLimit: 6,
lyrics:
'저기 계신 콩국수 국수 장수는 새 콩국수 국수 장수이고, 여기 계신 콩국수 국수 장수는 헌 콩국수 국수 장수다.',
},
{
timeLimit: 3,
lyrics: '서울특별시 특허허가과 허가과장 허과장.',
},
{
timeLimit: 4,
lyrics: '중앙청 창살은 쌍창살이고 시청의 창살은 외창살이다.',
},
];

export function createTurnData(
roomData: RoomDataDto,
gameData: GameDataDto,
): TurnDataDto {
const gameModes = [GameMode.PRONUNCIATION, GameMode.CLEOPATRA];
const gameMode = gameModes[Math.floor(Math.random() * gameModes.length)];

let timeLimit: number;
if (gameMode === GameMode.CLEOPATRA) {
timeLimit = 10;
} else {
// 데이터에 따라 바뀜
timeLimit = 15;
}

let lyrics: string | undefined;
if (gameMode === GameMode.PRONUNCIATION) {
// 데이터에 따라 바뀜
lyrics = '테스트테스트테스트테스트테스트테스트테스트테스트테스트테스트';
return {
roomId: roomData.roomId,
playerNickname: gameData.currentPlayer,
gameMode,
timeLimit: 7,
lyrics: '안녕! 클레오파트라! 세상에서 제일가는 포테이토 칩!',
};
}
const randomSentence =
SAMPLE_DATA[Math.floor(Math.random() * SAMPLE_DATA.length)];

return {
roomId: roomData.roomId,
playerNickname: gameData.currentPlayer,
gameMode: gameMode,
timeLimit: timeLimit,
lyrics: lyrics,
gameMode,
timeLimit: randomSentence.timeLimit,
lyrics: randomSentence.lyrics,
};
}

export function selectCurrentPlayer(alivePlayers: string[]): string {
const randomIndex = Math.floor(Math.random() * alivePlayers.length);
return alivePlayers[randomIndex];
export function selectCurrentPlayer(
alivePlayers: string[],
previousPlayers: string[],
): string {
let candidates = alivePlayers;
if (previousPlayers[0] === previousPlayers[1]) {
candidates = alivePlayers.filter((player) => player !== previousPlayers[0]);
}
const randomIndex = Math.floor(Math.random() * candidates.length);
return candidates[randomIndex];
}

export function checkPlayersReady(roomData: RoomDataDto): boolean {
return roomData.players
.filter((player) => player.playerNickname !== roomData.hostNickname)
.every((player) => player.isReady);
}

export function removePlayerFromGame(
gameData: GameDataDto,
playerNickname: string,
): void {
gameData.alivePlayers = gameData.alivePlayers.filter(
(player: string) => player !== playerNickname,
);
}
39 changes: 37 additions & 2 deletions be/gameServer/src/modules/games/games.gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
createTurnData,
selectCurrentPlayer,
checkPlayersReady,
removePlayerFromGame,
} from './games-utils';

const VOICE_SERVERS = 'voice-servers';
Expand Down Expand Up @@ -87,7 +88,7 @@ export class GamesGateway implements OnGatewayDisconnect {
gameId: roomId,
alivePlayers,
currentTurn: 1,
currentPlayer: selectCurrentPlayer(alivePlayers),
currentPlayer: selectCurrentPlayer(alivePlayers, []),
previousPitch: 0,
previousPlayers: [],
};
Expand All @@ -96,7 +97,9 @@ export class GamesGateway implements OnGatewayDisconnect {
const turnData: TurnDataDto = createTurnData(roomData, gameData);

this.server.to(VOICE_SERVERS).emit('turnChanged', turnData);
this.logger.log('Turn data sent to voice servers:', turnData);
this.server.to(roomId).emit('turnChanged', turnData);
this.logger.log('Turn data sent to clients in room:', roomId);

this.logger.log(`Game started successfully in room: ${roomId}`);
} catch (error) {
Expand All @@ -110,6 +113,38 @@ export class GamesGateway implements OnGatewayDisconnect {
}
}

// // 음성 처리 결과 수신
// socket.on("voiceResult", (result) => {
// console.log("Voice result received:", result);
// io.to(result.roomId).emit("voiceProcessingResult", result);
// });

@SubscribeMessage('disconnect')
async handleDisconnect() {}
async handleDisconnect(@ConnectedSocket() client: Socket) {
try {
const { roomId, playerNickname } = client.data;
const gameDataString = await this.redisService.get<string>(
`game:${roomId}`,
);

if (!gameDataString) {
this.logger.log(`Game not found: ${roomId}`);
return;
}

const gameData: GameDataDto = JSON.parse(gameDataString);

removePlayerFromGame(gameData, playerNickname);

if (gameData.alivePlayers.length <= 0) {
this.logger.log(`${roomId} deleting game`);
await this.redisService.delete(`game:${roomId}`);
} else {
await this.redisService.set(`game:${roomId}`, JSON.stringify(gameData));
}
this.logger.log(`${playerNickname} leave game`);
} catch (error) {
this.logger.error('Error handling disconnect: ', error.message);
}
}
}
4 changes: 3 additions & 1 deletion be/gameServer/src/modules/rooms/rooms.gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,9 @@ export class RoomsGateway implements OnGatewayDisconnect {
);

this.logger.log(`host ${playerNickname} leave room`);
this.logger.log(`host changed to ${roomData.players[0]}`);
this.logger.log(
`host changed to ${roomData.players[0].playerNickname}`,
);
this.server.to(roomId).emit('updateUsers', roomData.players);
} else {
this.logger.log(`${roomId} deleting room`);
Expand Down

0 comments on commit f5c334d

Please sign in to comment.