diff --git a/backend/src/main/java/io/f1/backend/domain/game/app/GameService.java b/backend/src/main/java/io/f1/backend/domain/game/app/GameService.java index 4c2d2010..2ecae340 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/app/GameService.java +++ b/backend/src/main/java/io/f1/backend/domain/game/app/GameService.java @@ -1,10 +1,13 @@ package io.f1.backend.domain.game.app; +import static io.f1.backend.domain.game.mapper.RoomMapper.toGameSettingResponse; +import static io.f1.backend.domain.game.mapper.RoomMapper.toPlayerListResponse; import static io.f1.backend.domain.game.mapper.RoomMapper.toQuestionStartResponse; -import static io.f1.backend.domain.game.websocket.WebSocketUtils.getDestination; import static io.f1.backend.domain.quiz.mapper.QuizMapper.toGameStartResponse; import io.f1.backend.domain.game.dto.MessageType; +import io.f1.backend.domain.game.dto.request.GameSettingChanger; +import io.f1.backend.domain.game.dto.response.PlayerListResponse; import io.f1.backend.domain.game.event.RoomUpdatedEvent; import io.f1.backend.domain.game.model.Player; import io.f1.backend.domain.game.model.Room; @@ -20,14 +23,15 @@ import io.f1.backend.global.exception.errorcode.RoomErrorCode; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import java.util.List; -import java.util.Map; import java.util.Objects; +@Slf4j @Service @RequiredArgsConstructor public class GameService { @@ -70,11 +74,39 @@ public void gameStart(Long roomId, UserPrincipal principal) { toQuestionStartResponse(room, START_DELAY)); } - private boolean validateReadyStatus(Room room) { + public void handlePlayerReady(Long roomId, String sessionId) { - Map playerSessionMap = room.getPlayerSessionMap(); + Room room = findRoom(roomId); - return playerSessionMap.values().stream().allMatch(Player::isReady); + Player player = room.getPlayerBySessionId(sessionId); + + toggleReadyIfPossible(room, player); + + String destination = getDestination(roomId); + + PlayerListResponse playerListResponse = toPlayerListResponse(room); + log.info(playerListResponse.toString()); + messageSender.send(destination, MessageType.PLAYER_LIST, playerListResponse); + } + + public void changeGameSetting( + Long roomId, UserPrincipal principal, GameSettingChanger request) { + Room room = findRoom(roomId); + validateHostAndState(room, principal); + + if (!request.change(room, quizService)) { + return; + } + request.afterChange(room, messageSender); + + broadcastGameSetting(room); + + RoomUpdatedEvent roomUpdatedEvent = + new RoomUpdatedEvent( + room, + quizService.getQuizWithQuestionsById(room.getGameSetting().getQuizId())); + + eventPublisher.publishEvent(roomUpdatedEvent); } private void validateRoomStart(Room room, UserPrincipal principal) { @@ -82,7 +114,7 @@ private void validateRoomStart(Room room, UserPrincipal principal) { throw new CustomException(RoomErrorCode.NOT_ROOM_OWNER); } - if (!validateReadyStatus(room)) { + if (!room.validateReadyStatus()) { throw new CustomException(GameErrorCode.PLAYER_NOT_READY); } @@ -97,4 +129,41 @@ private List prepareQuestions(Room room, Quiz quiz) { Integer round = room.getGameSetting().getRound(); return quizService.getRandomQuestionsWithoutAnswer(quizId, round); } + + private Room findRoom(Long roomId) { + return roomRepository + .findRoom(roomId) + .orElseThrow(() -> new CustomException(RoomErrorCode.ROOM_NOT_FOUND)); + } + + private String getDestination(Long roomId) { + return "/sub/room/" + roomId; + } + + private void validateHostAndState(Room room, UserPrincipal principal) { + if (!room.isHost(principal.getUserId())) { + throw new CustomException(RoomErrorCode.NOT_ROOM_OWNER); + } + if (room.isPlaying()) { + throw new CustomException(RoomErrorCode.GAME_ALREADY_PLAYING); + } + } + + private void toggleReadyIfPossible(Room room, Player player) { + if (room.isPlaying()) { + throw new CustomException(RoomErrorCode.GAME_ALREADY_PLAYING); + } + if (!room.isHost(player.getId())) { + player.toggleReady(); + } + } + + private void broadcastGameSetting(Room room) { + String destination = getDestination(room.getId()); + Quiz quiz = quizService.getQuizWithQuestionsById(room.getGameSetting().getQuizId()); + messageSender.send( + destination, + MessageType.GAME_SETTING, + toGameSettingResponse(room.getGameSetting(), quiz)); + } } diff --git a/backend/src/main/java/io/f1/backend/domain/game/app/RoomService.java b/backend/src/main/java/io/f1/backend/domain/game/app/RoomService.java index eb5ae614..2ca33fa8 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/app/RoomService.java +++ b/backend/src/main/java/io/f1/backend/domain/game/app/RoomService.java @@ -190,21 +190,6 @@ public void exitRoom(Long roomId, String sessionId, UserPrincipal principal) { } } - public void handlePlayerReady(Long roomId, String sessionId) { - Player player = - roomRepository - .findPlayerInRoomBySessionId(roomId, sessionId) - .orElseThrow(() -> new CustomException(RoomErrorCode.PLAYER_NOT_FOUND)); - - player.toggleReady(); - - Room room = findRoom(roomId); - - String destination = getDestination(roomId); - - messageSender.send(destination, MessageType.PLAYER_LIST, toPlayerListResponse(room)); - } - public RoomListResponse getAllRooms() { List rooms = roomRepository.findAll(); List roomResponses = @@ -327,7 +312,7 @@ public void exitIfNotPlaying(Long roomId, String sessionId, UserPrincipal princi private Player getRemovePlayer(Room room, String sessionId, UserPrincipal principal) { Player removePlayer = room.getPlayerSessionMap().get(sessionId); if (removePlayer == null) { - room.removeUserId(principal.getUserId()); + room.removeValidatedUserId(principal.getUserId()); throw new CustomException(RoomErrorCode.SOCKET_SESSION_NOT_FOUND); } return removePlayer; @@ -374,7 +359,6 @@ private void changeHost(Room room, String hostSessionId) { } private void removePlayer(Room room, String sessionId, Player removePlayer) { - room.removeUserId(removePlayer.getId()); room.removeSessionId(sessionId); room.removeValidatedUserId(removePlayer.getId()); } diff --git a/backend/src/main/java/io/f1/backend/domain/game/dto/request/GameSettingChanger.java b/backend/src/main/java/io/f1/backend/domain/game/dto/request/GameSettingChanger.java new file mode 100644 index 00000000..fa3a4981 --- /dev/null +++ b/backend/src/main/java/io/f1/backend/domain/game/dto/request/GameSettingChanger.java @@ -0,0 +1,12 @@ +package io.f1.backend.domain.game.dto.request; + +import io.f1.backend.domain.game.model.Room; +import io.f1.backend.domain.game.websocket.MessageSender; +import io.f1.backend.domain.quiz.app.QuizService; + +public interface GameSettingChanger { + + boolean change(Room room, QuizService quizService); + + void afterChange(Room room, MessageSender messageSender); +} diff --git a/backend/src/main/java/io/f1/backend/domain/game/dto/request/QuizChangeRequest.java b/backend/src/main/java/io/f1/backend/domain/game/dto/request/QuizChangeRequest.java new file mode 100644 index 00000000..3ec2f497 --- /dev/null +++ b/backend/src/main/java/io/f1/backend/domain/game/dto/request/QuizChangeRequest.java @@ -0,0 +1,41 @@ +package io.f1.backend.domain.game.dto.request; + +import static io.f1.backend.domain.game.mapper.RoomMapper.toPlayerListResponse; +import static io.f1.backend.domain.game.websocket.WebSocketUtils.getDestination; + +import io.f1.backend.domain.game.dto.MessageType; +import io.f1.backend.domain.game.dto.response.PlayerListResponse; +import io.f1.backend.domain.game.model.Room; +import io.f1.backend.domain.game.websocket.MessageSender; +import io.f1.backend.domain.quiz.app.QuizService; +import io.f1.backend.domain.quiz.entity.Quiz; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public record QuizChangeRequest(long quizId) implements GameSettingChanger { + + @Override + public boolean change(Room room, QuizService quizService) { + if (room.getQuizId() == quizId) { + return false; // 동일하면 무시 + } + Quiz quiz = quizService.getQuizWithQuestionsById(quizId); + int questionSize = quiz.getQuestions().size(); + room.changeQuiz(quiz); + // 퀴즈의 문제 갯수로 변경 + room.changeRound(questionSize, questionSize); + return true; + } + + @Override + public void afterChange(Room room, MessageSender messageSender) { + room.resetAllPlayerReadyStates(); + + String destination = getDestination(room.getId()); + PlayerListResponse response = toPlayerListResponse(room); + + log.info(response.toString()); + messageSender.send(destination, MessageType.PLAYER_LIST, response); + } +} diff --git a/backend/src/main/java/io/f1/backend/domain/game/dto/request/RoundChangeRequest.java b/backend/src/main/java/io/f1/backend/domain/game/dto/request/RoundChangeRequest.java new file mode 100644 index 00000000..a3ad914e --- /dev/null +++ b/backend/src/main/java/io/f1/backend/domain/game/dto/request/RoundChangeRequest.java @@ -0,0 +1,27 @@ +package io.f1.backend.domain.game.dto.request; + +import io.f1.backend.domain.game.model.Room; +import io.f1.backend.domain.game.websocket.MessageSender; +import io.f1.backend.domain.quiz.app.QuizService; +import io.f1.backend.domain.quiz.entity.Quiz; + +public record RoundChangeRequest(int round) implements GameSettingChanger { + + @Override + public boolean change(Room room, QuizService quizService) { + if (room.getRound() == round) { + return false; // 동일하면 무시 + } + + Quiz quiz = quizService.findQuizById(room.getQuizId()); + int questionSize = quiz.getQuestions().size(); + + room.changeRound(round, questionSize); + return true; + } + + @Override + public void afterChange(Room room, MessageSender messageSender) { + // 고유한 후처리 동작 없음 + } +} diff --git a/backend/src/main/java/io/f1/backend/domain/game/dto/request/TimeLimit.java b/backend/src/main/java/io/f1/backend/domain/game/dto/request/TimeLimit.java new file mode 100644 index 00000000..b483e4ac --- /dev/null +++ b/backend/src/main/java/io/f1/backend/domain/game/dto/request/TimeLimit.java @@ -0,0 +1,29 @@ +package io.f1.backend.domain.game.dto.request; + +import io.f1.backend.global.exception.CustomException; +import io.f1.backend.global.exception.errorcode.GameErrorCode; + +import lombok.Getter; + +import java.util.Arrays; + +@Getter +public enum TimeLimit { + FIFTEEN(15), + THIRTY(30), + FORTY_FIVE(45), + SIXTY(60); + + private final int value; + + TimeLimit(int value) { + this.value = value; + } + + public static TimeLimit from(int value) { + return Arrays.stream(values()) + .filter(t -> t.value == value) + .findFirst() + .orElseThrow(() -> new CustomException(GameErrorCode.GAME_SETTING_CONFLICT)); + } +} diff --git a/backend/src/main/java/io/f1/backend/domain/game/dto/request/TimeLimitChangeRequest.java b/backend/src/main/java/io/f1/backend/domain/game/dto/request/TimeLimitChangeRequest.java new file mode 100644 index 00000000..aa088c7d --- /dev/null +++ b/backend/src/main/java/io/f1/backend/domain/game/dto/request/TimeLimitChangeRequest.java @@ -0,0 +1,22 @@ +package io.f1.backend.domain.game.dto.request; + +import io.f1.backend.domain.game.model.Room; +import io.f1.backend.domain.game.websocket.MessageSender; +import io.f1.backend.domain.quiz.app.QuizService; + +public record TimeLimitChangeRequest(int timeLimit) implements GameSettingChanger { + + @Override + public boolean change(Room room, QuizService quizService) { + if (room.getTimeLimit() == timeLimit) { + return false; // 동일하면 무시 + } + room.changeTimeLimit(TimeLimit.from(timeLimit)); + return true; + } + + @Override + public void afterChange(Room room, MessageSender messageSender) { + // 고유한 후처리 동작 없음 + } +} diff --git a/backend/src/main/java/io/f1/backend/domain/game/mapper/RoomMapper.java b/backend/src/main/java/io/f1/backend/domain/game/mapper/RoomMapper.java index a05a097f..206282d5 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/mapper/RoomMapper.java +++ b/backend/src/main/java/io/f1/backend/domain/game/mapper/RoomMapper.java @@ -56,7 +56,7 @@ public static GameSettingResponse toGameSettingResponse(GameSetting gameSetting, public static PlayerListResponse toPlayerListResponse(Room room) { List playerResponseList = room.getPlayerSessionMap().values().stream() - .map(player -> new PlayerResponse(player.getNickname(), false)) + .map(player -> new PlayerResponse(player.getNickname(), player.isReady())) .toList(); return new PlayerListResponse(room.getHost().getNickname(), playerResponseList); diff --git a/backend/src/main/java/io/f1/backend/domain/game/model/GameSetting.java b/backend/src/main/java/io/f1/backend/domain/game/model/GameSetting.java index bf17a522..9c38bd68 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/model/GameSetting.java +++ b/backend/src/main/java/io/f1/backend/domain/game/model/GameSetting.java @@ -1,19 +1,34 @@ package io.f1.backend.domain.game.model; +import io.f1.backend.domain.game.dto.request.TimeLimit; +import io.f1.backend.domain.quiz.entity.Quiz; +import io.f1.backend.global.exception.CustomException; +import io.f1.backend.global.exception.errorcode.GameErrorCode; + import lombok.AllArgsConstructor; import lombok.Getter; -import java.util.Objects; - @Getter @AllArgsConstructor public class GameSetting { private Long quizId; - private Integer round; // 게임 변경 시 해당 게임의 총 문제 수로 설정 + private Integer round; private int timeLimit; - public boolean validateQuizId(Long quizId) { - return Objects.equals(this.quizId, quizId); + public void changeQuiz(Quiz quiz) { + quizId = quiz.getId(); + round = quiz.getQuestions().size(); // 라운드를 바꾼 퀴즈의 문제 수로 동기화 + } + + public void changeTimeLimit(TimeLimit timeLimit) { + this.timeLimit = timeLimit.getValue(); + } + + public void changeRound(int round, int questionsCount) { + if (round > questionsCount) { + throw new CustomException(GameErrorCode.ROUND_EXCEEDS_QUESTION_COUNT); + } + this.round = round; } } diff --git a/backend/src/main/java/io/f1/backend/domain/game/model/Player.java b/backend/src/main/java/io/f1/backend/domain/game/model/Player.java index 9d20b212..fe92c1a3 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/model/Player.java +++ b/backend/src/main/java/io/f1/backend/domain/game/model/Player.java @@ -24,6 +24,10 @@ public void toggleReady() { this.isReady = !this.isReady; } + public void setReadyFalse() { + this.isReady = false; + } + public void increaseCorrectCount() { correctCount++; } diff --git a/backend/src/main/java/io/f1/backend/domain/game/model/Room.java b/backend/src/main/java/io/f1/backend/domain/game/model/Room.java index fd581102..7580594c 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/model/Room.java +++ b/backend/src/main/java/io/f1/backend/domain/game/model/Room.java @@ -1,6 +1,8 @@ package io.f1.backend.domain.game.model; +import io.f1.backend.domain.game.dto.request.TimeLimit; import io.f1.backend.domain.question.entity.Question; +import io.f1.backend.domain.quiz.entity.Quiz; import io.f1.backend.global.exception.CustomException; import io.f1.backend.global.exception.errorcode.RoomErrorCode; @@ -11,6 +13,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; @@ -99,10 +102,6 @@ public void removeValidatedUserId(Long userId) { validatedUserIds.remove(userId); } - public void removeUserId(Long userId) { - validatedUserIds.remove(userId); - } - public void increasePlayerCorrectCount(String sessionId) { this.playerSessionMap.get(sessionId).increaseCorrectCount(); } @@ -141,4 +140,48 @@ public boolean isLastPlayer(String sessionId) { .count(); return connectedCount == 1 && playerSessionMap.containsKey(sessionId); } + + public boolean validateReadyStatus() { + + return playerSessionMap.values().stream().allMatch(Player::isReady); + } + + public Player getPlayerBySessionId(String sessionId) { + Player player = playerSessionMap.get(sessionId); + if (player == null) { + throw new CustomException(RoomErrorCode.PLAYER_NOT_FOUND); + } + return player; + } + + public void resetAllPlayerReadyStates() { + for (Player player : playerSessionMap.values()) { + if (Objects.equals(player.getId(), getHost().getId())) continue; + player.setReadyFalse(); + } + } + + public void changeQuiz(Quiz quiz) { + gameSetting.changeQuiz(quiz); + } + + public void changeTimeLimit(TimeLimit timeLimit) { + gameSetting.changeTimeLimit(timeLimit); + } + + public void changeRound(int round, int questionCount) { + gameSetting.changeRound(round, questionCount); + } + + public Long getQuizId() { + return gameSetting.getQuizId(); + } + + public int getTimeLimit() { + return gameSetting.getTimeLimit(); + } + + public int getRound() { + return gameSetting.getRound(); + } } diff --git a/backend/src/main/java/io/f1/backend/domain/game/sse/listener/RoomDeletedEventListener.java b/backend/src/main/java/io/f1/backend/domain/game/sse/listener/RoomDeletedEventListener.java index eee8d11e..8b8962de 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/sse/listener/RoomDeletedEventListener.java +++ b/backend/src/main/java/io/f1/backend/domain/game/sse/listener/RoomDeletedEventListener.java @@ -11,7 +11,9 @@ import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +@Component @RequiredArgsConstructor public class RoomDeletedEventListener { diff --git a/backend/src/main/java/io/f1/backend/domain/game/sse/listener/RoomUpdatedEventListener.java b/backend/src/main/java/io/f1/backend/domain/game/sse/listener/RoomUpdatedEventListener.java index 5f957de2..17c81a59 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/sse/listener/RoomUpdatedEventListener.java +++ b/backend/src/main/java/io/f1/backend/domain/game/sse/listener/RoomUpdatedEventListener.java @@ -1,16 +1,19 @@ package io.f1.backend.domain.game.sse.listener; +import static io.f1.backend.domain.game.sse.mapper.SseMapper.*; + import io.f1.backend.domain.game.event.RoomUpdatedEvent; import io.f1.backend.domain.game.sse.app.SseService; import io.f1.backend.domain.game.sse.dto.LobbySseEvent; import io.f1.backend.domain.game.sse.dto.RoomUpdatedPayload; -import io.f1.backend.domain.game.sse.mapper.SseMapper; import lombok.RequiredArgsConstructor; import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +@Component @RequiredArgsConstructor public class RoomUpdatedEventListener { @@ -19,7 +22,7 @@ public class RoomUpdatedEventListener { @Async @EventListener public void roomUpdate(RoomUpdatedEvent event) { - LobbySseEvent sseEvent = SseMapper.fromRoomUpdated(event); + LobbySseEvent sseEvent = fromRoomUpdated(event); sseService.notifyLobbyUpdate(sseEvent); } } diff --git a/backend/src/main/java/io/f1/backend/domain/game/store/RoomRepository.java b/backend/src/main/java/io/f1/backend/domain/game/store/RoomRepository.java index f2852c5d..32e777e3 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/store/RoomRepository.java +++ b/backend/src/main/java/io/f1/backend/domain/game/store/RoomRepository.java @@ -1,6 +1,5 @@ package io.f1.backend.domain.game.store; -import io.f1.backend.domain.game.model.Player; import io.f1.backend.domain.game.model.Room; import java.util.List; @@ -15,6 +14,4 @@ public interface RoomRepository { List findAll(); void removeRoom(Long roomId); - - Optional findPlayerInRoomBySessionId(Long roomId, String sessionId); } diff --git a/backend/src/main/java/io/f1/backend/domain/game/store/RoomRepositoryImpl.java b/backend/src/main/java/io/f1/backend/domain/game/store/RoomRepositoryImpl.java index 7efd4d9e..cffbba47 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/store/RoomRepositoryImpl.java +++ b/backend/src/main/java/io/f1/backend/domain/game/store/RoomRepositoryImpl.java @@ -1,6 +1,5 @@ package io.f1.backend.domain.game.store; -import io.f1.backend.domain.game.model.Player; import io.f1.backend.domain.game.model.Room; import org.springframework.stereotype.Repository; @@ -36,11 +35,6 @@ public void removeRoom(Long roomId) { roomMap.remove(roomId); } - @Override - public Optional findPlayerInRoomBySessionId(Long roomId, String sessionId) { - return findRoom(roomId).map(room -> room.getPlayerSessionMap().get(sessionId)); - } - // 테스트 전용 메소드 public Room getRoomForTest(Long roomId) { return roomMap.get(roomId); diff --git a/backend/src/main/java/io/f1/backend/domain/game/websocket/controller/GameSocketController.java b/backend/src/main/java/io/f1/backend/domain/game/websocket/controller/GameSocketController.java index 90a2bb3a..06ee39d0 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/websocket/controller/GameSocketController.java +++ b/backend/src/main/java/io/f1/backend/domain/game/websocket/controller/GameSocketController.java @@ -7,6 +7,9 @@ import io.f1.backend.domain.game.app.RoomService; import io.f1.backend.domain.game.dto.ChatMessage; import io.f1.backend.domain.game.dto.request.DefaultWebSocketRequest; +import io.f1.backend.domain.game.dto.request.QuizChangeRequest; +import io.f1.backend.domain.game.dto.request.RoundChangeRequest; +import io.f1.backend.domain.game.dto.request.TimeLimitChangeRequest; import io.f1.backend.domain.game.websocket.service.SessionService; import io.f1.backend.domain.user.dto.UserPrincipal; @@ -82,6 +85,30 @@ public void chat( @MessageMapping("/room/ready/{roomId}") public void playerReady(@DestinationVariable Long roomId, Message message) { - roomService.handlePlayerReady(roomId, getSessionId(message)); + gameService.handlePlayerReady(roomId, getSessionId(message)); + } + + @MessageMapping("/room/quiz/{roomId}") + public void quizChange( + @DestinationVariable Long roomId, + Message> message) { + UserPrincipal principal = getSessionUser(message); + gameService.changeGameSetting(roomId, principal, message.getPayload().getMessage()); + } + + @MessageMapping("/room/time-limit/{roomId}") + public void timeLimitChange( + @DestinationVariable Long roomId, + Message> message) { + UserPrincipal principal = getSessionUser(message); + gameService.changeGameSetting(roomId, principal, message.getPayload().getMessage()); + } + + @MessageMapping("/room/round/{roomId}") + public void roundChange( + @DestinationVariable Long roomId, + Message> message) { + UserPrincipal principal = getSessionUser(message); + gameService.changeGameSetting(roomId, principal, message.getPayload().getMessage()); } } diff --git a/backend/src/main/java/io/f1/backend/global/exception/errorcode/GameErrorCode.java b/backend/src/main/java/io/f1/backend/global/exception/errorcode/GameErrorCode.java index 923252d3..5daf88f0 100644 --- a/backend/src/main/java/io/f1/backend/global/exception/errorcode/GameErrorCode.java +++ b/backend/src/main/java/io/f1/backend/global/exception/errorcode/GameErrorCode.java @@ -9,7 +9,9 @@ @RequiredArgsConstructor public enum GameErrorCode implements ErrorCode { GAME_SETTING_CONFLICT("E409002", HttpStatus.CONFLICT, "게임 설정이 맞지 않습니다."), - PLAYER_NOT_READY("E403004", HttpStatus.FORBIDDEN, "게임 시작을 위한 준비 상태가 아닙니다."); + PLAYER_NOT_READY("E403004", HttpStatus.FORBIDDEN, "게임 시작을 위한 준비 상태가 아닙니다."), + ROUND_EXCEEDS_QUESTION_COUNT( + "E400016", HttpStatus.BAD_REQUEST, "라운드 수는 선택한 퀴즈의 문제 수보다 많을 수 없습니다."); private final String code; diff --git a/backend/src/main/java/io/f1/backend/global/exception/errorcode/RoomErrorCode.java b/backend/src/main/java/io/f1/backend/global/exception/errorcode/RoomErrorCode.java index 0041e450..4eb1ff6e 100644 --- a/backend/src/main/java/io/f1/backend/global/exception/errorcode/RoomErrorCode.java +++ b/backend/src/main/java/io/f1/backend/global/exception/errorcode/RoomErrorCode.java @@ -15,7 +15,7 @@ public enum RoomErrorCode implements ErrorCode { PLAYER_NOT_FOUND("E404007", HttpStatus.NOT_FOUND, "존재하지 않는 플레이어입니다."), SOCKET_SESSION_NOT_FOUND("E404006", HttpStatus.NOT_FOUND, "존재하지 않는 소켓 세션입니다."), GAME_ALREADY_PLAYING("E400015", HttpStatus.BAD_REQUEST, "이미 게임이 진행 중 입니다."), - NOT_ROOM_OWNER("E403005", HttpStatus.FORBIDDEN, "방장만 게임 시작이 가능합니다."), + NOT_ROOM_OWNER("E403005", HttpStatus.FORBIDDEN, "방장의 권한입니다."), ROOM_ENTER_REQUIRED("E400014", HttpStatus.NOT_FOUND, "방 입장 후에 소켓 연결이 시도되어야합니다."); private final String code;