From d8e82fe4d4fbb1fed22a7a775675720003446f8e Mon Sep 17 00:00:00 2001 From: sehee Date: Mon, 14 Jul 2025 19:54:48 +0900 Subject: [PATCH 01/11] =?UTF-8?q?:sparkles:=20=EB=B0=A9=20=ED=87=B4?= =?UTF-8?q?=EC=9E=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/domain/game/app/RoomService.java | 111 ++++++++++++------ .../backend/domain/game/dto/MessageType.java | 1 + .../backend/domain/game/dto/RoomExitData.java | 10 ++ .../dto/response/SystemNoticeResponse.java | 7 ++ .../io/f1/backend/domain/game/model/Room.java | 4 + .../domain/game/store/RoomRepository.java | 2 + .../domain/game/store/RoomRepositoryImpl.java | 5 + .../game/websocket/GameSocketController.java | 28 ++++- 8 files changed, 132 insertions(+), 36 deletions(-) create mode 100644 backend/src/main/java/io/f1/backend/domain/game/dto/RoomExitData.java create mode 100644 backend/src/main/java/io/f1/backend/domain/game/dto/response/SystemNoticeResponse.java 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 a9d6f324..8aaea589 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 @@ -1,7 +1,12 @@ package io.f1.backend.domain.game.app; -import static io.f1.backend.domain.game.mapper.RoomMapper.*; +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.toRoomResponse; +import static io.f1.backend.domain.game.mapper.RoomMapper.toRoomSetting; +import static io.f1.backend.domain.game.mapper.RoomMapper.toRoomSettingResponse; +import io.f1.backend.domain.game.dto.RoomExitData; import io.f1.backend.domain.game.dto.RoomInitialData; import io.f1.backend.domain.game.dto.request.RoomCreateRequest; import io.f1.backend.domain.game.dto.request.RoomValidationRequest; @@ -12,6 +17,7 @@ import io.f1.backend.domain.game.dto.response.RoomListResponse; import io.f1.backend.domain.game.dto.response.RoomResponse; import io.f1.backend.domain.game.dto.response.RoomSettingResponse; +import io.f1.backend.domain.game.dto.response.SystemNoticeResponse; import io.f1.backend.domain.game.model.GameSetting; import io.f1.backend.domain.game.model.Player; import io.f1.backend.domain.game.model.Room; @@ -20,14 +26,13 @@ import io.f1.backend.domain.game.store.RoomRepository; import io.f1.backend.domain.quiz.entity.Quiz; import io.f1.backend.domain.user.entity.User; - -import lombok.RequiredArgsConstructor; - -import org.springframework.stereotype.Service; - +import java.time.LocalDateTime; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor @@ -54,9 +59,9 @@ public RoomCreateResponse saveRoom(RoomCreateRequest request, Map new IllegalArgumentException("404 존재하지 않는 방입니다.")); + roomRepository + .findRoom(request.roomId()) + .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.")); if (room.getState().equals(RoomState.PLAYING)) { throw new IllegalArgumentException("403 게임이 진행중입니다."); @@ -69,7 +74,7 @@ public void validateRoom(RoomValidationRequest request) { } if (room.getRoomSetting().locked() - && !room.getRoomSetting().password().equals(request.password())) { + && !room.getRoomSetting().password().equals(request.password())) { throw new IllegalArgumentException("401 비밀번호가 일치하지 않습니다."); } } @@ -77,9 +82,9 @@ public void validateRoom(RoomValidationRequest request) { public RoomInitialData enterRoom(Long roomId, String sessionId) { Room room = - roomRepository - .findRoom(roomId) - .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.")); + roomRepository + .findRoom(roomId) + .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.")); // todo security Player player = new Player(1L, "빵야빵야"); @@ -88,41 +93,79 @@ public RoomInitialData enterRoom(Long roomId, String sessionId) { playerSessionMap.put(sessionId, player); - String destination = "/sub/room/" + roomId; - RoomSettingResponse roomSettingResponse = toRoomSettingResponse(room); + // todo quiz 생성 api 완성 후 수정 QuizResponse quiz = - new QuizResponse(room.getGameSetting().getQuizId(), "title", "설명", "url", 10); + new QuizResponse(room.getGameSetting().getQuizId(), "title", "설명", "url", 10); GameSettingResponse gameSettingResponse = - toGameSettingResponse(room.getGameSetting(), quiz); + toGameSettingResponse(room.getGameSetting(), quiz); PlayerListResponse playerListResponse = toPlayerListResponse(room); return new RoomInitialData( - destination, roomSettingResponse, gameSettingResponse, playerListResponse); + getDestination(roomId), roomSettingResponse, gameSettingResponse, playerListResponse); + } + + public RoomExitData exitRoom(Long roomId, String sessionId) { + Room room = + roomRepository + .findRoom(roomId) + .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.")); + + Map playerSessionMap = room.getPlayerSessionMap(); + + String destination = getDestination(roomId); + + if (playerSessionMap.size() == 1 && playerSessionMap.get(sessionId) != null) { + roomRepository.removeRoom(roomId); + return new RoomExitData(destination,null, null, true); + } + + Player removedPlayer = playerSessionMap.remove(sessionId); + if (removedPlayer == null) { + throw new IllegalArgumentException("퇴장 처리 불가 - 404 해당 세션 플레이어는 존재하지않습니다."); + } + + if (room.getHost().getId().equals(removedPlayer.getId())) { + Optional nextHostSessionId = playerSessionMap.keySet().stream().findFirst(); + Player nextHost = playerSessionMap.get(nextHostSessionId.orElseThrow( + () -> new IllegalArgumentException("방장 교체 불가 - 404 해당 세션 플레이어는 존재하지않습니다."))); + room.updateHost(nextHost); + } + + SystemNoticeResponse systemNoticeResponse = new SystemNoticeResponse( + removedPlayer.getNickname() + "님이 퇴장하셨습니다.", LocalDateTime.now()); + + PlayerListResponse playerListResponse = toPlayerListResponse(room); + + return new RoomExitData(destination,playerListResponse, systemNoticeResponse, false); } // todo quizService에서 퀴즈 조회 메서드로 변경 public RoomListResponse getAllRooms() { List rooms = roomRepository.findAll(); List roomResponses = - rooms.stream() - .map( - room -> { - User user = new User(); // 임시 유저 객체 - user.setNickname("임시 유저 닉네임"); - - Quiz quiz = new Quiz(); // 임시 퀴즈 객체 - quiz.setTitle("임시 퀴즈 제목"); - quiz.setDescription("임시 퀴즈 설명"); - quiz.setThumbnailUrl("임시 이미지"); - quiz.setQuestions(List.of()); - quiz.setCreator(user); - - return toRoomResponse(room, quiz); - }) - .toList(); + rooms.stream() + .map( + room -> { + User user = new User(); // 임시 유저 객체 + user.setNickname("임시 유저 닉네임"); + + Quiz quiz = new Quiz(); // 임시 퀴즈 객체 + quiz.setTitle("임시 퀴즈 제목"); + quiz.setDescription("임시 퀴즈 설명"); + quiz.setThumbnailUrl("임시 이미지"); + quiz.setQuestions(List.of()); + quiz.setCreator(user); + + return toRoomResponse(room, quiz); + }) + .toList(); return new RoomListResponse(roomResponses); } + + private static String getDestination(Long roomId) { + return "/sub/room/" + roomId; + } } diff --git a/backend/src/main/java/io/f1/backend/domain/game/dto/MessageType.java b/backend/src/main/java/io/f1/backend/domain/game/dto/MessageType.java index bb748aac..f6d40420 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/dto/MessageType.java +++ b/backend/src/main/java/io/f1/backend/domain/game/dto/MessageType.java @@ -4,4 +4,5 @@ public enum MessageType { ROOM_SETTING, GAME_SETTING, PLAYER_LIST, + SYSTEM_NOTICE, } diff --git a/backend/src/main/java/io/f1/backend/domain/game/dto/RoomExitData.java b/backend/src/main/java/io/f1/backend/domain/game/dto/RoomExitData.java new file mode 100644 index 00000000..b32651b3 --- /dev/null +++ b/backend/src/main/java/io/f1/backend/domain/game/dto/RoomExitData.java @@ -0,0 +1,10 @@ +package io.f1.backend.domain.game.dto; + +import io.f1.backend.domain.game.dto.response.PlayerListResponse; +import io.f1.backend.domain.game.dto.response.SystemNoticeResponse; + +public record RoomExitData(String destination, PlayerListResponse playerListResponses, + SystemNoticeResponse systemNoticeResponse, + boolean removedRoom) { + +} diff --git a/backend/src/main/java/io/f1/backend/domain/game/dto/response/SystemNoticeResponse.java b/backend/src/main/java/io/f1/backend/domain/game/dto/response/SystemNoticeResponse.java new file mode 100644 index 00000000..1cc4803c --- /dev/null +++ b/backend/src/main/java/io/f1/backend/domain/game/dto/response/SystemNoticeResponse.java @@ -0,0 +1,7 @@ +package io.f1.backend.domain.game.dto.response; + +import java.time.LocalDateTime; + +public record SystemNoticeResponse(String noticeMessage, LocalDateTime timestamp) { + +} 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 ba0c56b5..151b3256 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 @@ -35,4 +35,8 @@ public Room(Long id, RoomSetting roomSetting, GameSetting gameSetting, Player ho this.gameSetting = gameSetting; this.host = host; } + + public void updateHost(Player nextHost){ + this.host = nextHost; + } } 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 83f1b415..6e87760d 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 @@ -11,4 +11,6 @@ public interface RoomRepository { Optional findRoom(Long roomId); List findAll(); + + void removeRoom(Long roomId); } 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 4daa0a27..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 @@ -30,6 +30,11 @@ public List findAll() { return new ArrayList<>(roomMap.values()); } + @Override + public void removeRoom(Long roomId) { + roomMap.remove(roomId); + } + // 테스트 전용 메소드 public Room getRoomForTest(Long roomId) { return roomMap.get(roomId); diff --git a/backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java b/backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java index a93f382c..a098c7f9 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java +++ b/backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java @@ -2,6 +2,7 @@ import io.f1.backend.domain.game.app.RoomService; import io.f1.backend.domain.game.dto.MessageType; +import io.f1.backend.domain.game.dto.RoomExitData; import io.f1.backend.domain.game.dto.RoomInitialData; import lombok.RequiredArgsConstructor; @@ -22,8 +23,7 @@ public class GameSocketController { @MessageMapping("/room/enter/{roomId}") public void roomEnter(@DestinationVariable Long roomId, Message message) { - StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message); - String websocketSessionId = accessor.getSessionId(); + String websocketSessionId = getSessionId(message); RoomInitialData roomInitialData = roomService.enterRoom(roomId, websocketSessionId); String destination = roomInitialData.destination(); @@ -35,4 +35,28 @@ public void roomEnter(@DestinationVariable Long roomId, Message message) { messageSender.send( destination, MessageType.PLAYER_LIST, roomInitialData.playerListResponse()); } + + @MessageMapping("/room/exit/{roomId}") + public void exitRoom(@DestinationVariable Long roomId, Message message) { + + String websocketSessionId = getSessionId(message); + + RoomExitData roomExitData = roomService.exitRoom(roomId, websocketSessionId); + + String destination = roomExitData.destination(); + + if (!roomExitData.removedRoom()) { + messageSender.send( + destination, MessageType.PLAYER_LIST, roomExitData.playerListResponses() + ); + messageSender.send( + destination , MessageType.SYSTEM_NOTICE, roomExitData.systemNoticeResponse() + ); + } + } + + private static String getSessionId(Message message) { + StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message); + return accessor.getSessionId(); + } } From 97d5ce4f73a11ea716e217b0a0861f07d52347e7 Mon Sep 17 00:00:00 2001 From: sehee Date: Mon, 14 Jul 2025 20:16:05 +0900 Subject: [PATCH 02/11] =?UTF-8?q?:sparkles:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B8=B0=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/game/api/RoomController.java | 7 +- .../backend/domain/game/app/RoomService.java | 64 ++++++++++--------- 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java b/backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java index ffc33605..048d071e 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java +++ b/backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java @@ -31,12 +31,7 @@ public class RoomController { @PostMapping @ResponseStatus(HttpStatus.CREATED) public RoomCreateResponse saveRoom(@RequestBody @Valid RoomCreateRequest request) { - - Map loginUser = new HashMap<>(); - loginUser.put("id", 1L); - loginUser.put("nickname", "빵야빵야"); - - return roomService.saveRoom(request, loginUser); + return roomService.saveRoom(request); } @PostMapping("/validation") 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 c12e3f7c..766fff41 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 @@ -1,6 +1,12 @@ package io.f1.backend.domain.game.app; -import static io.f1.backend.domain.game.mapper.RoomMapper.*; +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.toRoomResponse; +import static io.f1.backend.domain.game.mapper.RoomMapper.toRoomSetting; +import static io.f1.backend.domain.game.mapper.RoomMapper.toRoomSettingResponse; +import static io.f1.backend.global.util.SecurityUtils.getCurrentUserId; +import static io.f1.backend.global.util.SecurityUtils.getCurrentUserNickname; import io.f1.backend.domain.game.dto.RoomExitData; import io.f1.backend.domain.game.dto.RoomInitialData; @@ -23,19 +29,13 @@ import io.f1.backend.domain.game.store.RoomRepository; import io.f1.backend.domain.quiz.app.QuizService; import io.f1.backend.domain.quiz.entity.Quiz; -import io.f1.backend.domain.user.entity.User; import java.time.LocalDateTime; - -import lombok.RequiredArgsConstructor; - -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.stereotype.Service; - import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; import lombok.RequiredArgsConstructor; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; @Service @@ -47,12 +47,12 @@ public class RoomService { private final AtomicLong roomIdGenerator = new AtomicLong(0); private final ApplicationEventPublisher eventPublisher; - public RoomCreateResponse saveRoom(RoomCreateRequest request, Map loginUser) { + public RoomCreateResponse saveRoom(RoomCreateRequest request) { // todo 제일 작은 index quizId 가져와서 gameSetting(round 설정) GameSetting gameSetting = new GameSetting(1L, 10, 60); - // todo security에서 가져오는걸로 변경 - Player host = new Player((Long) loginUser.get("id"), loginUser.get("nickname").toString()); + + Player host = createPlayer(); RoomSetting roomSetting = toRoomSetting(request); Long newId = roomIdGenerator.incrementAndGet(); @@ -69,12 +69,13 @@ public RoomCreateResponse saveRoom(RoomCreateRequest request, Map new IllegalArgumentException("404 존재하지 않는 방입니다.")); + .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.-1")); if (room.getState().equals(RoomState.PLAYING)) { throw new IllegalArgumentException("403 게임이 진행중입니다."); @@ -87,7 +88,7 @@ public void validateRoom(RoomValidationRequest request) { } if (room.getRoomSetting().locked() - && !room.getRoomSetting().password().equals(request.password())) { + && !room.getRoomSetting().password().equals(request.password())) { throw new IllegalArgumentException("401 비밀번호가 일치하지 않습니다."); } } @@ -95,12 +96,11 @@ public void validateRoom(RoomValidationRequest request) { public RoomInitialData enterRoom(Long roomId, String sessionId) { Room room = - roomRepository - .findRoom(roomId) - .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.")); + roomRepository + .findRoom(roomId) + .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.")); - // todo security - Player player = new Player(1L, "빵야빵야"); + Player player = createPlayer(); Map playerSessionMap = room.getPlayerSessionMap(); @@ -132,7 +132,7 @@ public RoomExitData exitRoom(Long roomId, String sessionId) { if (playerSessionMap.size() == 1 && playerSessionMap.get(sessionId) != null) { roomRepository.removeRoom(roomId); - return new RoomExitData(destination,null, null, true); + return new RoomExitData(destination, null, null, true); } Player removedPlayer = playerSessionMap.remove(sessionId); @@ -152,25 +152,29 @@ public RoomExitData exitRoom(Long roomId, String sessionId) { PlayerListResponse playerListResponse = toPlayerListResponse(room); - return new RoomExitData(destination,playerListResponse, systemNoticeResponse, false); + return new RoomExitData(destination, playerListResponse, systemNoticeResponse, false); } public RoomListResponse getAllRooms() { List rooms = roomRepository.findAll(); List roomResponses = - rooms.stream() - .map( - room -> { - Long quizId = room.getGameSetting().getQuizId(); - Quiz quiz = quizService.getQuizById(quizId); - - return toRoomResponse(room, quiz); - }) - .toList(); + rooms.stream() + .map( + room -> { + Long quizId = room.getGameSetting().getQuizId(); + Quiz quiz = quizService.getQuizById(quizId); + + return toRoomResponse(room, quiz); + }) + .toList(); return new RoomListResponse(roomResponses); } private static String getDestination(Long roomId) { - return "/sub/room/" + roomId; + return "/sub/room/" + roomId; + } + + private static Player createPlayer() { + return new Player(getCurrentUserId(), getCurrentUserNickname()); } } From 938f2051a9fc6c5c0bbb2b326987a609e2d8176e Mon Sep 17 00:00:00 2001 From: sehee Date: Mon, 14 Jul 2025 20:57:29 +0900 Subject: [PATCH 03/11] =?UTF-8?q?:sparkles:=20quiz=20api=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/domain/game/app/RoomService.java | 17 +++++++------ .../domain/game/mapper/RoomMapper.java | 14 +++++++++-- .../backend/domain/quiz/app/QuizService.java | 25 ++++++++++--------- .../domain/quiz/dao/QuizRepository.java | 8 ++++-- 4 files changed, 40 insertions(+), 24 deletions(-) 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 766fff41..6fb0a779 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 @@ -1,5 +1,6 @@ package io.f1.backend.domain.game.app; +import static io.f1.backend.domain.game.mapper.RoomMapper.toGameSetting; 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.toRoomResponse; @@ -49,10 +50,13 @@ public class RoomService { public RoomCreateResponse saveRoom(RoomCreateRequest request) { - // todo 제일 작은 index quizId 가져와서 gameSetting(round 설정) - GameSetting gameSetting = new GameSetting(1L, 10, 60); + Long minQuizId = quizService.getQuizMinId(); + Quiz quiz = quizService.getQuizById(minQuizId); + + GameSetting gameSetting = toGameSetting(quiz); Player host = createPlayer(); + RoomSetting roomSetting = toRoomSetting(request); Long newId = roomIdGenerator.incrementAndGet(); @@ -61,9 +65,6 @@ public RoomCreateResponse saveRoom(RoomCreateRequest request) { roomRepository.saveRoom(room); - Long quizId = room.getGameSetting().getQuizId(); - Quiz quiz = quizService.getQuizById(quizId); - eventPublisher.publishEvent(new RoomCreatedEvent(room, quiz)); return new RoomCreateResponse(newId); @@ -108,9 +109,9 @@ public RoomInitialData enterRoom(Long roomId, String sessionId) { RoomSettingResponse roomSettingResponse = toRoomSettingResponse(room); - // todo quiz 생성 api 완성 후 수정 - QuizResponse quiz = - new QuizResponse(room.getGameSetting().getQuizId(), "title", "설명", "url", 10); + Long quizId = room.getGameSetting().getQuizId(); + Quiz quiz = quizService.getQuizById(quizId); + GameSettingResponse gameSettingResponse = toGameSettingResponse(room.getGameSetting(), quiz); 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 9044c41d..8e99ec17 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 @@ -16,11 +16,17 @@ public class RoomMapper { + private static final int DEFAULT_TIME_LIMIT = 60; + public static RoomSetting toRoomSetting(RoomCreateRequest request) { return new RoomSetting( request.roomName(), request.maxUserCount(), request.locked(), request.password()); } + public static GameSetting toGameSetting(Quiz quiz) { + return new GameSetting(quiz.getId(), quiz.getQuestions().size(), DEFAULT_TIME_LIMIT); + } + public static RoomSettingResponse toRoomSettingResponse(Room room) { return new RoomSettingResponse( room.getRoomSetting().roomName(), @@ -29,8 +35,8 @@ public static RoomSettingResponse toRoomSettingResponse(Room room) { } public static GameSettingResponse toGameSettingResponse( - GameSetting gameSetting, QuizResponse quiz) { - return new GameSettingResponse(gameSetting.getRound(), gameSetting.getTimeLimit(), quiz); + GameSetting gameSetting, Quiz quiz) { + return new GameSettingResponse(gameSetting.getRound(), gameSetting.getTimeLimit(), toQuizResponse(quiz)); } public static PlayerListResponse toPlayerListResponse(Room room) { @@ -56,4 +62,8 @@ public static RoomResponse toRoomResponse(Room room, Quiz quiz) { quiz.getQuestions().size(), quiz.getThumbnailUrl()); } + + public static QuizResponse toQuizResponse(Quiz quiz) { + return new QuizResponse(quiz.getId(), quiz.getTitle(), quiz.getDescription(), quiz.getThumbnailUrl(), quiz.getQuestions().size()); + } } diff --git a/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java b/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java index dde9f6f3..1526ef3c 100644 --- a/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java +++ b/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java @@ -11,19 +11,16 @@ import io.f1.backend.domain.quiz.entity.Quiz; import io.f1.backend.domain.user.dao.UserRepository; import io.f1.backend.domain.user.entity.User; - -import lombok.RequiredArgsConstructor; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; @Service @RequiredArgsConstructor @@ -42,7 +39,7 @@ public class QuizService { @Transactional public QuizCreateResponse saveQuiz(MultipartFile thumbnailFile, QuizCreateRequest request) - throws IOException { + throws IOException { String thumbnailPath = defaultThumbnailPath; if (thumbnailFile != null && !thumbnailFile.isEmpty()) { @@ -94,7 +91,11 @@ private String getExtension(String filename) { public Quiz getQuizById(Long quizId) { return quizRepository - .findById(quizId) - .orElseThrow(() -> new RuntimeException("E404002: 존재하지 않는 퀴즈입니다.")); + .findById(quizId) + .orElseThrow(() -> new RuntimeException("E404002: 존재하지 않는 퀴즈입니다.")); + } + + public Long getQuizMinId() { + return quizRepository.getQuizMinId(); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/io/f1/backend/domain/quiz/dao/QuizRepository.java b/backend/src/main/java/io/f1/backend/domain/quiz/dao/QuizRepository.java index a88c98e7..1ae8713b 100644 --- a/backend/src/main/java/io/f1/backend/domain/quiz/dao/QuizRepository.java +++ b/backend/src/main/java/io/f1/backend/domain/quiz/dao/QuizRepository.java @@ -1,7 +1,11 @@ package io.f1.backend.domain.quiz.dao; import io.f1.backend.domain.quiz.entity.Quiz; - import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +public interface QuizRepository extends JpaRepository { -public interface QuizRepository extends JpaRepository {} + @Query("SELECT MIN(q.id) FROM Quiz q") + Long getQuizMinId(); +} From 140d082918ad333ee8d726260e0996ffc6212d13 Mon Sep 17 00:00:00 2001 From: sehee Date: Mon, 14 Jul 2025 22:39:44 +0900 Subject: [PATCH 04/11] =?UTF-8?q?:recycle:=20LocaldateTime=20->=20Instant,?= =?UTF-8?q?=20lazy=20=EC=98=88=EC=99=B8=20fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/f1/backend/domain/game/app/RoomService.java | 5 ++--- .../domain/game/dto/response/SystemNoticeResponse.java | 4 ++-- .../java/io/f1/backend/domain/quiz/app/QuizService.java | 6 +++++- 3 files changed, 9 insertions(+), 6 deletions(-) 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 6fb0a779..2094d932 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 @@ -15,7 +15,6 @@ import io.f1.backend.domain.game.dto.request.RoomValidationRequest; import io.f1.backend.domain.game.dto.response.GameSettingResponse; import io.f1.backend.domain.game.dto.response.PlayerListResponse; -import io.f1.backend.domain.game.dto.response.QuizResponse; import io.f1.backend.domain.game.dto.response.RoomCreateResponse; import io.f1.backend.domain.game.dto.response.RoomListResponse; import io.f1.backend.domain.game.dto.response.RoomResponse; @@ -30,7 +29,7 @@ import io.f1.backend.domain.game.store.RoomRepository; import io.f1.backend.domain.quiz.app.QuizService; import io.f1.backend.domain.quiz.entity.Quiz; -import java.time.LocalDateTime; +import java.time.Instant; import java.util.List; import java.util.Map; import java.util.Optional; @@ -149,7 +148,7 @@ public RoomExitData exitRoom(Long roomId, String sessionId) { } SystemNoticeResponse systemNoticeResponse = new SystemNoticeResponse( - removedPlayer.getNickname() + "님이 퇴장하셨습니다.", LocalDateTime.now()); + removedPlayer.getNickname() + "님이 퇴장하셨습니다.", Instant.now()); PlayerListResponse playerListResponse = toPlayerListResponse(room); diff --git a/backend/src/main/java/io/f1/backend/domain/game/dto/response/SystemNoticeResponse.java b/backend/src/main/java/io/f1/backend/domain/game/dto/response/SystemNoticeResponse.java index 1cc4803c..7b86f160 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/dto/response/SystemNoticeResponse.java +++ b/backend/src/main/java/io/f1/backend/domain/game/dto/response/SystemNoticeResponse.java @@ -1,7 +1,7 @@ package io.f1.backend.domain.game.dto.response; -import java.time.LocalDateTime; +import java.time.Instant; -public record SystemNoticeResponse(String noticeMessage, LocalDateTime timestamp) { +public record SystemNoticeResponse(String noticeMessage, Instant timestamp) { } diff --git a/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java b/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java index 1526ef3c..956594bd 100644 --- a/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java +++ b/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java @@ -89,12 +89,16 @@ private String getExtension(String filename) { return filename.substring(filename.lastIndexOf(".") + 1); } + @Transactional(readOnly = true) public Quiz getQuizById(Long quizId) { - return quizRepository + Quiz quiz = quizRepository .findById(quizId) .orElseThrow(() -> new RuntimeException("E404002: 존재하지 않는 퀴즈입니다.")); + quiz.getQuestions().size(); + return quiz; } + @Transactional(readOnly = true) public Long getQuizMinId() { return quizRepository.getQuizMinId(); } From f220c5295096b5647c89c916d1d70abbbe75fdb0 Mon Sep 17 00:00:00 2001 From: github-actions <> Date: Mon, 14 Jul 2025 13:40:08 +0000 Subject: [PATCH 05/11] =?UTF-8?q?chore:=20Java=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/game/api/RoomController.java | 3 - .../backend/domain/game/app/RoomService.java | 68 +++++++++++-------- .../backend/domain/game/dto/RoomExitData.java | 10 +-- .../dto/response/SystemNoticeResponse.java | 4 +- .../domain/game/mapper/RoomMapper.java | 13 ++-- .../io/f1/backend/domain/game/model/Room.java | 2 +- .../game/websocket/GameSocketController.java | 6 +- .../backend/domain/quiz/app/QuizService.java | 24 ++++--- .../domain/quiz/dao/QuizRepository.java | 1 + 9 files changed, 72 insertions(+), 59 deletions(-) diff --git a/backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java b/backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java index 048d071e..79a245de 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java +++ b/backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java @@ -18,9 +18,6 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import java.util.HashMap; -import java.util.Map; - @RestController @RequestMapping("/rooms") @RequiredArgsConstructor 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 2094d932..cddc14f0 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 @@ -29,14 +29,17 @@ import io.f1.backend.domain.game.store.RoomRepository; import io.f1.backend.domain.quiz.app.QuizService; import io.f1.backend.domain.quiz.entity.Quiz; + +import lombok.RequiredArgsConstructor; + +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; + import java.time.Instant; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; -import lombok.RequiredArgsConstructor; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor @@ -69,13 +72,12 @@ public RoomCreateResponse saveRoom(RoomCreateRequest request) { return new RoomCreateResponse(newId); } - public void validateRoom(RoomValidationRequest request) { Room room = - roomRepository - .findRoom(request.roomId()) - .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.-1")); + roomRepository + .findRoom(request.roomId()) + .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.-1")); if (room.getState().equals(RoomState.PLAYING)) { throw new IllegalArgumentException("403 게임이 진행중입니다."); @@ -88,7 +90,7 @@ public void validateRoom(RoomValidationRequest request) { } if (room.getRoomSetting().locked() - && !room.getRoomSetting().password().equals(request.password())) { + && !room.getRoomSetting().password().equals(request.password())) { throw new IllegalArgumentException("401 비밀번호가 일치하지 않습니다."); } } @@ -96,9 +98,9 @@ public void validateRoom(RoomValidationRequest request) { public RoomInitialData enterRoom(Long roomId, String sessionId) { Room room = - roomRepository - .findRoom(roomId) - .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.")); + roomRepository + .findRoom(roomId) + .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.")); Player player = createPlayer(); @@ -112,19 +114,22 @@ public RoomInitialData enterRoom(Long roomId, String sessionId) { Quiz quiz = quizService.getQuizById(quizId); GameSettingResponse gameSettingResponse = - toGameSettingResponse(room.getGameSetting(), quiz); + toGameSettingResponse(room.getGameSetting(), quiz); PlayerListResponse playerListResponse = toPlayerListResponse(room); return new RoomInitialData( - getDestination(roomId), roomSettingResponse, gameSettingResponse, playerListResponse); + getDestination(roomId), + roomSettingResponse, + gameSettingResponse, + playerListResponse); } public RoomExitData exitRoom(Long roomId, String sessionId) { Room room = - roomRepository - .findRoom(roomId) - .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.")); + roomRepository + .findRoom(roomId) + .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.")); Map playerSessionMap = room.getPlayerSessionMap(); @@ -142,13 +147,18 @@ public RoomExitData exitRoom(Long roomId, String sessionId) { if (room.getHost().getId().equals(removedPlayer.getId())) { Optional nextHostSessionId = playerSessionMap.keySet().stream().findFirst(); - Player nextHost = playerSessionMap.get(nextHostSessionId.orElseThrow( - () -> new IllegalArgumentException("방장 교체 불가 - 404 해당 세션 플레이어는 존재하지않습니다."))); + Player nextHost = + playerSessionMap.get( + nextHostSessionId.orElseThrow( + () -> + new IllegalArgumentException( + "방장 교체 불가 - 404 해당 세션 플레이어는 존재하지않습니다."))); room.updateHost(nextHost); } - SystemNoticeResponse systemNoticeResponse = new SystemNoticeResponse( - removedPlayer.getNickname() + "님이 퇴장하셨습니다.", Instant.now()); + SystemNoticeResponse systemNoticeResponse = + new SystemNoticeResponse( + removedPlayer.getNickname() + "님이 퇴장하셨습니다.", Instant.now()); PlayerListResponse playerListResponse = toPlayerListResponse(room); @@ -158,15 +168,15 @@ public RoomExitData exitRoom(Long roomId, String sessionId) { public RoomListResponse getAllRooms() { List rooms = roomRepository.findAll(); List roomResponses = - rooms.stream() - .map( - room -> { - Long quizId = room.getGameSetting().getQuizId(); - Quiz quiz = quizService.getQuizById(quizId); - - return toRoomResponse(room, quiz); - }) - .toList(); + rooms.stream() + .map( + room -> { + Long quizId = room.getGameSetting().getQuizId(); + Quiz quiz = quizService.getQuizById(quizId); + + return toRoomResponse(room, quiz); + }) + .toList(); return new RoomListResponse(roomResponses); } diff --git a/backend/src/main/java/io/f1/backend/domain/game/dto/RoomExitData.java b/backend/src/main/java/io/f1/backend/domain/game/dto/RoomExitData.java index b32651b3..a42686ba 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/dto/RoomExitData.java +++ b/backend/src/main/java/io/f1/backend/domain/game/dto/RoomExitData.java @@ -3,8 +3,8 @@ import io.f1.backend.domain.game.dto.response.PlayerListResponse; import io.f1.backend.domain.game.dto.response.SystemNoticeResponse; -public record RoomExitData(String destination, PlayerListResponse playerListResponses, - SystemNoticeResponse systemNoticeResponse, - boolean removedRoom) { - -} +public record RoomExitData( + String destination, + PlayerListResponse playerListResponses, + SystemNoticeResponse systemNoticeResponse, + boolean removedRoom) {} diff --git a/backend/src/main/java/io/f1/backend/domain/game/dto/response/SystemNoticeResponse.java b/backend/src/main/java/io/f1/backend/domain/game/dto/response/SystemNoticeResponse.java index 7b86f160..911fbf50 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/dto/response/SystemNoticeResponse.java +++ b/backend/src/main/java/io/f1/backend/domain/game/dto/response/SystemNoticeResponse.java @@ -2,6 +2,4 @@ import java.time.Instant; -public record SystemNoticeResponse(String noticeMessage, Instant timestamp) { - -} +public record SystemNoticeResponse(String noticeMessage, Instant timestamp) {} 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 8e99ec17..2beb432f 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 @@ -34,9 +34,9 @@ public static RoomSettingResponse toRoomSettingResponse(Room room) { room.getPlayerSessionMap().size()); } - public static GameSettingResponse toGameSettingResponse( - GameSetting gameSetting, Quiz quiz) { - return new GameSettingResponse(gameSetting.getRound(), gameSetting.getTimeLimit(), toQuizResponse(quiz)); + public static GameSettingResponse toGameSettingResponse(GameSetting gameSetting, Quiz quiz) { + return new GameSettingResponse( + gameSetting.getRound(), gameSetting.getTimeLimit(), toQuizResponse(quiz)); } public static PlayerListResponse toPlayerListResponse(Room room) { @@ -64,6 +64,11 @@ public static RoomResponse toRoomResponse(Room room, Quiz quiz) { } public static QuizResponse toQuizResponse(Quiz quiz) { - return new QuizResponse(quiz.getId(), quiz.getTitle(), quiz.getDescription(), quiz.getThumbnailUrl(), quiz.getQuestions().size()); + return new QuizResponse( + quiz.getId(), + quiz.getTitle(), + quiz.getDescription(), + quiz.getThumbnailUrl(), + quiz.getQuestions().size()); } } 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 151b3256..00b7e71b 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 @@ -36,7 +36,7 @@ public Room(Long id, RoomSetting roomSetting, GameSetting gameSetting, Player ho this.host = host; } - public void updateHost(Player nextHost){ + public void updateHost(Player nextHost) { this.host = nextHost; } } diff --git a/backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java b/backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java index a098c7f9..05889207 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java +++ b/backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java @@ -47,11 +47,9 @@ public void exitRoom(@DestinationVariable Long roomId, Message message) { if (!roomExitData.removedRoom()) { messageSender.send( - destination, MessageType.PLAYER_LIST, roomExitData.playerListResponses() - ); + destination, MessageType.PLAYER_LIST, roomExitData.playerListResponses()); messageSender.send( - destination , MessageType.SYSTEM_NOTICE, roomExitData.systemNoticeResponse() - ); + destination, MessageType.SYSTEM_NOTICE, roomExitData.systemNoticeResponse()); } } diff --git a/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java b/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java index 956594bd..f5a86404 100644 --- a/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java +++ b/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java @@ -11,17 +11,20 @@ import io.f1.backend.domain.quiz.entity.Quiz; import io.f1.backend.domain.user.dao.UserRepository; import io.f1.backend.domain.user.entity.User; -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; -import java.util.UUID; + import lombok.RequiredArgsConstructor; + import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.UUID; + @Service @RequiredArgsConstructor public class QuizService { @@ -39,7 +42,7 @@ public class QuizService { @Transactional public QuizCreateResponse saveQuiz(MultipartFile thumbnailFile, QuizCreateRequest request) - throws IOException { + throws IOException { String thumbnailPath = defaultThumbnailPath; if (thumbnailFile != null && !thumbnailFile.isEmpty()) { @@ -91,9 +94,10 @@ private String getExtension(String filename) { @Transactional(readOnly = true) public Quiz getQuizById(Long quizId) { - Quiz quiz = quizRepository - .findById(quizId) - .orElseThrow(() -> new RuntimeException("E404002: 존재하지 않는 퀴즈입니다.")); + Quiz quiz = + quizRepository + .findById(quizId) + .orElseThrow(() -> new RuntimeException("E404002: 존재하지 않는 퀴즈입니다.")); quiz.getQuestions().size(); return quiz; } @@ -102,4 +106,4 @@ public Quiz getQuizById(Long quizId) { public Long getQuizMinId() { return quizRepository.getQuizMinId(); } -} \ No newline at end of file +} diff --git a/backend/src/main/java/io/f1/backend/domain/quiz/dao/QuizRepository.java b/backend/src/main/java/io/f1/backend/domain/quiz/dao/QuizRepository.java index 1ae8713b..3d4354be 100644 --- a/backend/src/main/java/io/f1/backend/domain/quiz/dao/QuizRepository.java +++ b/backend/src/main/java/io/f1/backend/domain/quiz/dao/QuizRepository.java @@ -1,6 +1,7 @@ package io.f1.backend.domain.quiz.dao; import io.f1.backend.domain.quiz.entity.Quiz; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; From 2f85c233e7215a32fc4136d0384d9b5b67e49694 Mon Sep 17 00:00:00 2001 From: sehee Date: Tue, 15 Jul 2025 10:22:39 +0900 Subject: [PATCH 06/11] =?UTF-8?q?:recycle:=20=EB=AF=B8=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=20import=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/f1/backend/domain/game/api/RoomController.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java b/backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java index 048d071e..c53beb0d 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java +++ b/backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java @@ -5,11 +5,8 @@ import io.f1.backend.domain.game.dto.request.RoomValidationRequest; import io.f1.backend.domain.game.dto.response.RoomCreateResponse; import io.f1.backend.domain.game.dto.response.RoomListResponse; - import jakarta.validation.Valid; - import lombok.RequiredArgsConstructor; - import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -18,9 +15,6 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import java.util.HashMap; -import java.util.Map; - @RestController @RequestMapping("/rooms") @RequiredArgsConstructor From 8a774254d9be123532189586ee9919a53478f683 Mon Sep 17 00:00:00 2001 From: sehee Date: Tue, 15 Jul 2025 11:16:26 +0900 Subject: [PATCH 07/11] =?UTF-8?q?:recycle:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EB=82=B4=EC=9A=A9=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/domain/game/app/RoomService.java | 12 +++++----- .../domain/game/dto/RoomEventType.java | 8 +++++++ .../backend/domain/game/dto/RoomExitData.java | 22 ++++++++++++++++--- .../domain/game/dto/RoomInitialData.java | 4 +++- .../domain/game/mapper/RoomMapper.java | 15 +++++++++++++ .../game/websocket/GameSocketController.java | 11 ++++++---- .../backend/domain/quiz/app/QuizService.java | 18 +++++---------- 7 files changed, 64 insertions(+), 26 deletions(-) create mode 100644 backend/src/main/java/io/f1/backend/domain/game/dto/RoomEventType.java 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 2094d932..e5a5e6ff 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 @@ -1,5 +1,6 @@ package io.f1.backend.domain.game.app; +import static io.f1.backend.domain.game.mapper.RoomMapper.ofPlayerEvent; import static io.f1.backend.domain.game.mapper.RoomMapper.toGameSetting; import static io.f1.backend.domain.game.mapper.RoomMapper.toGameSettingResponse; import static io.f1.backend.domain.game.mapper.RoomMapper.toPlayerListResponse; @@ -9,6 +10,7 @@ import static io.f1.backend.global.util.SecurityUtils.getCurrentUserId; import static io.f1.backend.global.util.SecurityUtils.getCurrentUserNickname; +import io.f1.backend.domain.game.dto.RoomEventType; import io.f1.backend.domain.game.dto.RoomExitData; import io.f1.backend.domain.game.dto.RoomInitialData; import io.f1.backend.domain.game.dto.request.RoomCreateRequest; @@ -29,7 +31,6 @@ import io.f1.backend.domain.game.store.RoomRepository; import io.f1.backend.domain.quiz.app.QuizService; import io.f1.backend.domain.quiz.entity.Quiz; -import java.time.Instant; import java.util.List; import java.util.Map; import java.util.Optional; @@ -116,8 +117,10 @@ public RoomInitialData enterRoom(Long roomId, String sessionId) { PlayerListResponse playerListResponse = toPlayerListResponse(room); + SystemNoticeResponse systemNoticeResponse = ofPlayerEvent(player, RoomEventType.ENTER); + return new RoomInitialData( - getDestination(roomId), roomSettingResponse, gameSettingResponse, playerListResponse); + getDestination(roomId), roomSettingResponse, gameSettingResponse, playerListResponse,systemNoticeResponse); } public RoomExitData exitRoom(Long roomId, String sessionId) { @@ -132,7 +135,7 @@ public RoomExitData exitRoom(Long roomId, String sessionId) { if (playerSessionMap.size() == 1 && playerSessionMap.get(sessionId) != null) { roomRepository.removeRoom(roomId); - return new RoomExitData(destination, null, null, true); + return RoomExitData.builder().destination(destination).build(); } Player removedPlayer = playerSessionMap.remove(sessionId); @@ -147,8 +150,7 @@ public RoomExitData exitRoom(Long roomId, String sessionId) { room.updateHost(nextHost); } - SystemNoticeResponse systemNoticeResponse = new SystemNoticeResponse( - removedPlayer.getNickname() + "님이 퇴장하셨습니다.", Instant.now()); + SystemNoticeResponse systemNoticeResponse = ofPlayerEvent(removedPlayer, RoomEventType.EXIT); PlayerListResponse playerListResponse = toPlayerListResponse(room); diff --git a/backend/src/main/java/io/f1/backend/domain/game/dto/RoomEventType.java b/backend/src/main/java/io/f1/backend/domain/game/dto/RoomEventType.java new file mode 100644 index 00000000..c6346c83 --- /dev/null +++ b/backend/src/main/java/io/f1/backend/domain/game/dto/RoomEventType.java @@ -0,0 +1,8 @@ +package io.f1.backend.domain.game.dto; + +public enum RoomEventType { + ENTER, + EXIT, + START, + END, +} diff --git a/backend/src/main/java/io/f1/backend/domain/game/dto/RoomExitData.java b/backend/src/main/java/io/f1/backend/domain/game/dto/RoomExitData.java index b32651b3..6aab5dfc 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/dto/RoomExitData.java +++ b/backend/src/main/java/io/f1/backend/domain/game/dto/RoomExitData.java @@ -2,9 +2,25 @@ import io.f1.backend.domain.game.dto.response.PlayerListResponse; import io.f1.backend.domain.game.dto.response.SystemNoticeResponse; +import lombok.Builder; +import lombok.Getter; -public record RoomExitData(String destination, PlayerListResponse playerListResponses, - SystemNoticeResponse systemNoticeResponse, - boolean removedRoom) { + +@Getter +public class RoomExitData { + + private final String destination; + private final PlayerListResponse playerListResponses; + private final SystemNoticeResponse systemNoticeResponse; + private final boolean removedRoom; + + @Builder + public RoomExitData(String destination, PlayerListResponse playerListResponses, + SystemNoticeResponse systemNoticeResponse, boolean removedRoom) { + this.destination = destination; + this.playerListResponses = playerListResponses; + this.systemNoticeResponse = systemNoticeResponse; + this.removedRoom = removedRoom; + } } diff --git a/backend/src/main/java/io/f1/backend/domain/game/dto/RoomInitialData.java b/backend/src/main/java/io/f1/backend/domain/game/dto/RoomInitialData.java index ecc16eca..c925b690 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/dto/RoomInitialData.java +++ b/backend/src/main/java/io/f1/backend/domain/game/dto/RoomInitialData.java @@ -3,9 +3,11 @@ import io.f1.backend.domain.game.dto.response.GameSettingResponse; import io.f1.backend.domain.game.dto.response.PlayerListResponse; import io.f1.backend.domain.game.dto.response.RoomSettingResponse; +import io.f1.backend.domain.game.dto.response.SystemNoticeResponse; public record RoomInitialData( String destination, RoomSettingResponse roomSettingResponse, GameSettingResponse gameSettingResponse, - PlayerListResponse playerListResponse) {} + PlayerListResponse playerListResponse, + SystemNoticeResponse systemNoticeResponse) {} 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 8e99ec17..50b66452 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 @@ -1,5 +1,6 @@ package io.f1.backend.domain.game.mapper; +import io.f1.backend.domain.game.dto.RoomEventType; import io.f1.backend.domain.game.dto.request.RoomCreateRequest; import io.f1.backend.domain.game.dto.response.GameSettingResponse; import io.f1.backend.domain.game.dto.response.PlayerListResponse; @@ -7,11 +8,14 @@ import io.f1.backend.domain.game.dto.response.QuizResponse; import io.f1.backend.domain.game.dto.response.RoomResponse; import io.f1.backend.domain.game.dto.response.RoomSettingResponse; +import io.f1.backend.domain.game.dto.response.SystemNoticeResponse; import io.f1.backend.domain.game.model.GameSetting; +import io.f1.backend.domain.game.model.Player; import io.f1.backend.domain.game.model.Room; import io.f1.backend.domain.game.model.RoomSetting; import io.f1.backend.domain.quiz.entity.Quiz; +import java.time.Instant; import java.util.List; public class RoomMapper { @@ -66,4 +70,15 @@ public static RoomResponse toRoomResponse(Room room, Quiz quiz) { public static QuizResponse toQuizResponse(Quiz quiz) { return new QuizResponse(quiz.getId(), quiz.getTitle(), quiz.getDescription(), quiz.getThumbnailUrl(), quiz.getQuestions().size()); } + + public static SystemNoticeResponse ofPlayerEvent(Player player, RoomEventType roomEventType ){ + String message = ""; + if(roomEventType == RoomEventType.ENTER){ + message = " 님이 입장하셨습니다"; + }else if (roomEventType == RoomEventType.EXIT) { + message = " 님이 퇴장하셨습니다"; + } + return new SystemNoticeResponse(player.getNickname() + message, Instant.now()); + + } } diff --git a/backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java b/backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java index a098c7f9..4dedf5e7 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java +++ b/backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java @@ -34,6 +34,9 @@ public void roomEnter(@DestinationVariable Long roomId, Message message) { destination, MessageType.GAME_SETTING, roomInitialData.gameSettingResponse()); messageSender.send( destination, MessageType.PLAYER_LIST, roomInitialData.playerListResponse()); + messageSender.send( + destination, MessageType.SYSTEM_NOTICE, roomInitialData.systemNoticeResponse()); + } @MessageMapping("/room/exit/{roomId}") @@ -43,14 +46,14 @@ public void exitRoom(@DestinationVariable Long roomId, Message message) { RoomExitData roomExitData = roomService.exitRoom(roomId, websocketSessionId); - String destination = roomExitData.destination(); + String destination = roomExitData.getDestination(); - if (!roomExitData.removedRoom()) { + if (!roomExitData.isRemovedRoom()) { messageSender.send( - destination, MessageType.PLAYER_LIST, roomExitData.playerListResponses() + destination, MessageType.PLAYER_LIST, roomExitData.getPlayerListResponses() ); messageSender.send( - destination , MessageType.SYSTEM_NOTICE, roomExitData.systemNoticeResponse() + destination , MessageType.SYSTEM_NOTICE, roomExitData.getSystemNoticeResponse() ); } } diff --git a/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java b/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java index 1c8a91c8..9942cfe0 100644 --- a/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java +++ b/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java @@ -1,9 +1,9 @@ package io.f1.backend.domain.quiz.app; +import static io.f1.backend.domain.quiz.mapper.QuizMapper.pageQuizToPageQuizListResponse; import static io.f1.backend.domain.quiz.mapper.QuizMapper.quizCreateRequestToQuiz; import static io.f1.backend.domain.quiz.mapper.QuizMapper.quizToQuizCreateResponse; import static io.f1.backend.domain.quiz.mapper.QuizMapper.toQuizListPageResponse; - import static java.nio.file.Files.deleteIfExists; import io.f1.backend.domain.question.app.QuestionService; @@ -17,18 +17,6 @@ import io.f1.backend.domain.quiz.entity.Quiz; import io.f1.backend.domain.user.dao.UserRepository; import io.f1.backend.domain.user.entity.User; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; @@ -36,7 +24,11 @@ import java.util.NoSuchElementException; import java.util.UUID; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; From d3314704628352f454fc214eb2010930cdaf472b Mon Sep 17 00:00:00 2001 From: sehee Date: Tue, 15 Jul 2025 11:19:24 +0900 Subject: [PATCH 08/11] =?UTF-8?q?:recycle:=20import=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/io/f1/backend/domain/quiz/app/QuizService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java b/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java index 35196ee4..9942cfe0 100644 --- a/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java +++ b/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java @@ -1,5 +1,6 @@ package io.f1.backend.domain.quiz.app; +import static io.f1.backend.domain.quiz.mapper.QuizMapper.pageQuizToPageQuizListResponse; import static io.f1.backend.domain.quiz.mapper.QuizMapper.quizCreateRequestToQuiz; import static io.f1.backend.domain.quiz.mapper.QuizMapper.quizToQuizCreateResponse; import static io.f1.backend.domain.quiz.mapper.QuizMapper.toQuizListPageResponse; From 5a9db09c5774d1356074f3fd0852a180c316548a Mon Sep 17 00:00:00 2001 From: github-actions <> Date: Tue, 15 Jul 2025 02:19:38 +0000 Subject: [PATCH 09/11] =?UTF-8?q?chore:=20Java=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/game/api/RoomController.java | 3 + .../backend/domain/game/app/RoomService.java | 67 +++++++++++-------- .../backend/domain/game/dto/RoomExitData.java | 10 +-- .../domain/game/mapper/RoomMapper.java | 7 +- .../game/websocket/GameSocketController.java | 9 +-- .../backend/domain/quiz/app/QuizService.java | 23 ++++--- 6 files changed, 68 insertions(+), 51 deletions(-) diff --git a/backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java b/backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java index c53beb0d..79a245de 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java +++ b/backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java @@ -5,8 +5,11 @@ import io.f1.backend.domain.game.dto.request.RoomValidationRequest; import io.f1.backend.domain.game.dto.response.RoomCreateResponse; import io.f1.backend.domain.game.dto.response.RoomListResponse; + import jakarta.validation.Valid; + import lombok.RequiredArgsConstructor; + import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; 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 e5a5e6ff..43df3f68 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 @@ -31,13 +31,16 @@ import io.f1.backend.domain.game.store.RoomRepository; import io.f1.backend.domain.quiz.app.QuizService; import io.f1.backend.domain.quiz.entity.Quiz; + +import lombok.RequiredArgsConstructor; + +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; + import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; -import lombok.RequiredArgsConstructor; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor @@ -70,13 +73,12 @@ public RoomCreateResponse saveRoom(RoomCreateRequest request) { return new RoomCreateResponse(newId); } - public void validateRoom(RoomValidationRequest request) { Room room = - roomRepository - .findRoom(request.roomId()) - .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.-1")); + roomRepository + .findRoom(request.roomId()) + .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.-1")); if (room.getState().equals(RoomState.PLAYING)) { throw new IllegalArgumentException("403 게임이 진행중입니다."); @@ -89,7 +91,7 @@ public void validateRoom(RoomValidationRequest request) { } if (room.getRoomSetting().locked() - && !room.getRoomSetting().password().equals(request.password())) { + && !room.getRoomSetting().password().equals(request.password())) { throw new IllegalArgumentException("401 비밀번호가 일치하지 않습니다."); } } @@ -97,9 +99,9 @@ public void validateRoom(RoomValidationRequest request) { public RoomInitialData enterRoom(Long roomId, String sessionId) { Room room = - roomRepository - .findRoom(roomId) - .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.")); + roomRepository + .findRoom(roomId) + .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.")); Player player = createPlayer(); @@ -113,21 +115,25 @@ public RoomInitialData enterRoom(Long roomId, String sessionId) { Quiz quiz = quizService.getQuizById(quizId); GameSettingResponse gameSettingResponse = - toGameSettingResponse(room.getGameSetting(), quiz); + toGameSettingResponse(room.getGameSetting(), quiz); PlayerListResponse playerListResponse = toPlayerListResponse(room); SystemNoticeResponse systemNoticeResponse = ofPlayerEvent(player, RoomEventType.ENTER); return new RoomInitialData( - getDestination(roomId), roomSettingResponse, gameSettingResponse, playerListResponse,systemNoticeResponse); + getDestination(roomId), + roomSettingResponse, + gameSettingResponse, + playerListResponse, + systemNoticeResponse); } public RoomExitData exitRoom(Long roomId, String sessionId) { Room room = - roomRepository - .findRoom(roomId) - .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.")); + roomRepository + .findRoom(roomId) + .orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다.")); Map playerSessionMap = room.getPlayerSessionMap(); @@ -145,12 +151,17 @@ public RoomExitData exitRoom(Long roomId, String sessionId) { if (room.getHost().getId().equals(removedPlayer.getId())) { Optional nextHostSessionId = playerSessionMap.keySet().stream().findFirst(); - Player nextHost = playerSessionMap.get(nextHostSessionId.orElseThrow( - () -> new IllegalArgumentException("방장 교체 불가 - 404 해당 세션 플레이어는 존재하지않습니다."))); + Player nextHost = + playerSessionMap.get( + nextHostSessionId.orElseThrow( + () -> + new IllegalArgumentException( + "방장 교체 불가 - 404 해당 세션 플레이어는 존재하지않습니다."))); room.updateHost(nextHost); } - SystemNoticeResponse systemNoticeResponse = ofPlayerEvent(removedPlayer, RoomEventType.EXIT); + SystemNoticeResponse systemNoticeResponse = + ofPlayerEvent(removedPlayer, RoomEventType.EXIT); PlayerListResponse playerListResponse = toPlayerListResponse(room); @@ -160,15 +171,15 @@ public RoomExitData exitRoom(Long roomId, String sessionId) { public RoomListResponse getAllRooms() { List rooms = roomRepository.findAll(); List roomResponses = - rooms.stream() - .map( - room -> { - Long quizId = room.getGameSetting().getQuizId(); - Quiz quiz = quizService.getQuizById(quizId); - - return toRoomResponse(room, quiz); - }) - .toList(); + rooms.stream() + .map( + room -> { + Long quizId = room.getGameSetting().getQuizId(); + Quiz quiz = quizService.getQuizById(quizId); + + return toRoomResponse(room, quiz); + }) + .toList(); return new RoomListResponse(roomResponses); } diff --git a/backend/src/main/java/io/f1/backend/domain/game/dto/RoomExitData.java b/backend/src/main/java/io/f1/backend/domain/game/dto/RoomExitData.java index 6aab5dfc..1fc51f2e 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/dto/RoomExitData.java +++ b/backend/src/main/java/io/f1/backend/domain/game/dto/RoomExitData.java @@ -2,10 +2,10 @@ import io.f1.backend.domain.game.dto.response.PlayerListResponse; import io.f1.backend.domain.game.dto.response.SystemNoticeResponse; + import lombok.Builder; import lombok.Getter; - @Getter public class RoomExitData { @@ -15,12 +15,14 @@ public class RoomExitData { private final boolean removedRoom; @Builder - public RoomExitData(String destination, PlayerListResponse playerListResponses, - SystemNoticeResponse systemNoticeResponse, boolean removedRoom) { + public RoomExitData( + String destination, + PlayerListResponse playerListResponses, + SystemNoticeResponse systemNoticeResponse, + boolean removedRoom) { this.destination = destination; this.playerListResponses = playerListResponses; this.systemNoticeResponse = systemNoticeResponse; this.removedRoom = removedRoom; } - } 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 81b9c93e..cd3d109f 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 @@ -76,14 +76,13 @@ public static QuizResponse toQuizResponse(Quiz quiz) { quiz.getQuestions().size()); } - public static SystemNoticeResponse ofPlayerEvent(Player player, RoomEventType roomEventType ){ + public static SystemNoticeResponse ofPlayerEvent(Player player, RoomEventType roomEventType) { String message = ""; - if(roomEventType == RoomEventType.ENTER){ + if (roomEventType == RoomEventType.ENTER) { message = " 님이 입장하셨습니다"; - }else if (roomEventType == RoomEventType.EXIT) { + } else if (roomEventType == RoomEventType.EXIT) { message = " 님이 퇴장하셨습니다"; } return new SystemNoticeResponse(player.getNickname() + message, Instant.now()); - } } diff --git a/backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java b/backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java index 4dedf5e7..9bf2f17f 100644 --- a/backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java +++ b/backend/src/main/java/io/f1/backend/domain/game/websocket/GameSocketController.java @@ -35,8 +35,7 @@ public void roomEnter(@DestinationVariable Long roomId, Message message) { messageSender.send( destination, MessageType.PLAYER_LIST, roomInitialData.playerListResponse()); messageSender.send( - destination, MessageType.SYSTEM_NOTICE, roomInitialData.systemNoticeResponse()); - + destination, MessageType.SYSTEM_NOTICE, roomInitialData.systemNoticeResponse()); } @MessageMapping("/room/exit/{roomId}") @@ -50,11 +49,9 @@ public void exitRoom(@DestinationVariable Long roomId, Message message) { if (!roomExitData.isRemovedRoom()) { messageSender.send( - destination, MessageType.PLAYER_LIST, roomExitData.getPlayerListResponses() - ); + destination, MessageType.PLAYER_LIST, roomExitData.getPlayerListResponses()); messageSender.send( - destination , MessageType.SYSTEM_NOTICE, roomExitData.getSystemNoticeResponse() - ); + destination, MessageType.SYSTEM_NOTICE, roomExitData.getSystemNoticeResponse()); } } diff --git a/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java b/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java index 9942cfe0..22caf65e 100644 --- a/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java +++ b/backend/src/main/java/io/f1/backend/domain/quiz/app/QuizService.java @@ -4,6 +4,7 @@ import static io.f1.backend.domain.quiz.mapper.QuizMapper.quizCreateRequestToQuiz; import static io.f1.backend.domain.quiz.mapper.QuizMapper.quizToQuizCreateResponse; import static io.f1.backend.domain.quiz.mapper.QuizMapper.toQuizListPageResponse; + import static java.nio.file.Files.deleteIfExists; import io.f1.backend.domain.question.app.QuestionService; @@ -17,14 +18,10 @@ import io.f1.backend.domain.quiz.entity.Quiz; import io.f1.backend.domain.user.dao.UserRepository; import io.f1.backend.domain.user.entity.User; -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.UUID; + import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; + import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; @@ -33,6 +30,13 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.UUID; + @Slf4j @Service @RequiredArgsConstructor @@ -190,9 +194,10 @@ public QuizListPageResponse getQuizzes(String title, String creator, Pageable pa @Transactional(readOnly = true) public Quiz getQuizById(Long quizId) { - Quiz quiz = quizRepository - .findById(quizId) - .orElseThrow(() -> new RuntimeException("E404002: 존재하지 않는 퀴즈입니다.")); + Quiz quiz = + quizRepository + .findById(quizId) + .orElseThrow(() -> new RuntimeException("E404002: 존재하지 않는 퀴즈입니다.")); quiz.getQuestions().size(); return quiz; } From 0a0c98e8e99fd234e264a3ad5b8afd6be79a12cc Mon Sep 17 00:00:00 2001 From: sehee Date: Tue, 15 Jul 2025 11:27:59 +0900 Subject: [PATCH 10/11] =?UTF-8?q?:recycle:=20=EB=B3=80=EC=88=98=EB=AA=85?= =?UTF-8?q?=20=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/f1/backend/domain/game/app/RoomService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 e5a5e6ff..cbae69fa 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 @@ -50,8 +50,8 @@ public class RoomService { public RoomCreateResponse saveRoom(RoomCreateRequest request) { - Long minQuizId = quizService.getQuizMinId(); - Quiz quiz = quizService.getQuizById(minQuizId); + Long quizMinId = quizService.getQuizMinId(); + Quiz quiz = quizService.getQuizById(quizMinId); GameSetting gameSetting = toGameSetting(quiz); From 01996ac8c9a72d1fc5aa255b9e293a77c629924f Mon Sep 17 00:00:00 2001 From: sehee Date: Tue, 15 Jul 2025 11:40:05 +0900 Subject: [PATCH 11/11] =?UTF-8?q?:recycle:=20=EB=B9=8C=EB=8D=94=ED=8C=A8?= =?UTF-8?q?=ED=84=B4=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20=ED=95=98?= =?UTF-8?q?=EB=A9=B4=EC=84=9C=20=EB=88=84=EB=9D=BD=EB=90=9C=20=EA=B0=92=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/f1/backend/domain/game/app/RoomService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1913cb7a..723c8355 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 @@ -141,7 +141,7 @@ public RoomExitData exitRoom(Long roomId, String sessionId) { if (playerSessionMap.size() == 1 && playerSessionMap.get(sessionId) != null) { roomRepository.removeRoom(roomId); - return RoomExitData.builder().destination(destination).build(); + return RoomExitData.builder().destination(destination).removedRoom(true).build(); } Player removedPlayer = playerSessionMap.remove(sessionId);