Skip to content

Commit 9598683

Browse files
authored
✨ feat : 게임 방 입장(+유효성 검증) 구현
* ✨ 게임 방 입장(+유효성 검증) 구현 * ♻️ 누락 import 추가 * ♻️ 클라이언트 send시 로그 추가 * chore: Java 스타일 수정 * ♻️ PR 리뷰 반영 * chore: Java 스타일 수정 * 🔥 refactor: validationResponse삭제 no content로 응답 변경으로 인한 응답 dto 삭제 * ♻️ PR 리뷰 반영-2 * ♻️ PR 리뷰 반영-2 * ✨ 유효성 체크 요청시 validation 어노테이션 추가 * chore: Java 스타일 수정 --------- Co-authored-by: github-actions <>
1 parent e1bc7b6 commit 9598683

21 files changed

+293
-2
lines changed

backend/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,11 @@ out/
4242
### .idea ###
4343
.idea
4444

45+
### websocket test ###
46+
src/main/resources/static/ws-test.html
47+
src/main/resources/static/ws-test.js
48+
49+
50+
4551
### images/thumbnail ###
4652
images/thumbnail/**

backend/src/main/java/io/f1/backend/domain/game/api/RoomController.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io.f1.backend.domain.game.app.RoomService;
44
import io.f1.backend.domain.game.dto.request.RoomCreateRequest;
5+
import io.f1.backend.domain.game.dto.request.RoomValidationRequest;
56
import io.f1.backend.domain.game.dto.response.RoomCreateResponse;
67
import io.f1.backend.domain.game.dto.response.RoomListResponse;
78

@@ -38,6 +39,12 @@ public RoomCreateResponse saveRoom(@RequestBody @Valid RoomCreateRequest request
3839
return roomService.saveRoom(request, loginUser);
3940
}
4041

42+
@PostMapping("/validation")
43+
@ResponseStatus(HttpStatus.NO_CONTENT)
44+
public void validateRoom(@RequestBody @Valid RoomValidationRequest request) {
45+
roomService.validateRoom(request);
46+
}
47+
4148
@GetMapping
4249
public RoomListResponse getAllRooms() {
4350
return roomService.getAllRooms();

backend/src/main/java/io/f1/backend/domain/game/app/RoomService.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,21 @@
22

33
import static io.f1.backend.domain.game.mapper.RoomMapper.*;
44

5+
import io.f1.backend.domain.game.dto.RoomInitialData;
56
import io.f1.backend.domain.game.dto.request.RoomCreateRequest;
7+
import io.f1.backend.domain.game.dto.request.RoomValidationRequest;
8+
import io.f1.backend.domain.game.dto.response.GameSettingResponse;
9+
import io.f1.backend.domain.game.dto.response.PlayerListResponse;
10+
import io.f1.backend.domain.game.dto.response.QuizResponse;
611
import io.f1.backend.domain.game.dto.response.RoomCreateResponse;
712
import io.f1.backend.domain.game.dto.response.RoomListResponse;
813
import io.f1.backend.domain.game.dto.response.RoomResponse;
14+
import io.f1.backend.domain.game.dto.response.RoomSettingResponse;
915
import io.f1.backend.domain.game.model.GameSetting;
1016
import io.f1.backend.domain.game.model.Player;
1117
import io.f1.backend.domain.game.model.Room;
1218
import io.f1.backend.domain.game.model.RoomSetting;
19+
import io.f1.backend.domain.game.model.RoomState;
1320
import io.f1.backend.domain.game.store.RoomRepository;
1421
import io.f1.backend.domain.quiz.entity.Quiz;
1522
import io.f1.backend.domain.user.entity.User;
@@ -44,6 +51,58 @@ public RoomCreateResponse saveRoom(RoomCreateRequest request, Map<String, Object
4451
return new RoomCreateResponse(newId);
4552
}
4653

54+
public void validateRoom(RoomValidationRequest request) {
55+
56+
Room room =
57+
roomRepository
58+
.findRoom(request.roomId())
59+
.orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다."));
60+
61+
if (room.getState().equals(RoomState.PLAYING)) {
62+
throw new IllegalArgumentException("403 게임이 진행중입니다.");
63+
}
64+
65+
int maxUserCnt = room.getRoomSetting().maxUserCount();
66+
int currentCnt = room.getPlayerSessionMap().size();
67+
if (maxUserCnt == currentCnt) {
68+
throw new IllegalArgumentException("403 정원이 모두 찼습니다.");
69+
}
70+
71+
if (room.getRoomSetting().locked()
72+
&& !room.getRoomSetting().password().equals(request.password())) {
73+
throw new IllegalArgumentException("401 비밀번호가 일치하지 않습니다.");
74+
}
75+
}
76+
77+
public RoomInitialData enterRoom(Long roomId, String sessionId) {
78+
79+
Room room =
80+
roomRepository
81+
.findRoom(roomId)
82+
.orElseThrow(() -> new IllegalArgumentException("404 존재하지 않는 방입니다."));
83+
84+
// todo security
85+
Player player = new Player(1L, "빵야빵야");
86+
87+
Map<String, Player> playerSessionMap = room.getPlayerSessionMap();
88+
89+
playerSessionMap.put(sessionId, player);
90+
91+
String destination = "/sub/room/" + roomId;
92+
93+
RoomSettingResponse roomSettingResponse = toRoomSettingResponse(room);
94+
// todo quiz 생성 api 완성 후 수정
95+
QuizResponse quiz =
96+
new QuizResponse(room.getGameSetting().getQuizId(), "title", "설명", "url", 10);
97+
GameSettingResponse gameSettingResponse =
98+
toGameSettingResponse(room.getGameSetting(), quiz);
99+
100+
PlayerListResponse playerListResponse = toPlayerListResponse(room);
101+
102+
return new RoomInitialData(
103+
destination, roomSettingResponse, gameSettingResponse, playerListResponse);
104+
}
105+
47106
// todo quizService에서 퀴즈 조회 메서드로 변경
48107
public RoomListResponse getAllRooms() {
49108
List<Room> rooms = roomRepository.findAll();
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.f1.backend.domain.game.dto;
2+
3+
public enum MessageType {
4+
ROOM_SETTING,
5+
GAME_SETTING,
6+
PLAYER_LIST,
7+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package io.f1.backend.domain.game.dto;
2+
3+
import io.f1.backend.domain.game.dto.response.GameSettingResponse;
4+
import io.f1.backend.domain.game.dto.response.PlayerListResponse;
5+
import io.f1.backend.domain.game.dto.response.RoomSettingResponse;
6+
7+
public record RoomInitialData(
8+
String destination,
9+
RoomSettingResponse roomSettingResponse,
10+
GameSettingResponse gameSettingResponse,
11+
PlayerListResponse playerListResponse) {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.f1.backend.domain.game.dto;
2+
3+
public interface WebSocketDto<T> {
4+
MessageType getType();
5+
6+
T getMessage();
7+
}

backend/src/main/java/io/f1/backend/domain/game/dto/request/RoomCreateRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ public record RoomCreateRequest(
1212
@Max(value = 8, message = "방 인원 수는 최대 8명 입니다.")
1313
Integer maxUserCount,
1414
@NotNull String password,
15-
@NotNull boolean locked) {}
15+
@NotNull Boolean locked) {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.f1.backend.domain.game.dto.request;
2+
3+
import jakarta.validation.constraints.NotNull;
4+
5+
public record RoomValidationRequest(
6+
@NotNull(message = "roomId 값은 필수입니다. ") Long roomId,
7+
@NotNull(message = "비밀번호는 null 값이 아니여야합니다. ") String password) {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.f1.backend.domain.game.dto.response;
2+
3+
import io.f1.backend.domain.game.dto.MessageType;
4+
import io.f1.backend.domain.game.dto.WebSocketDto;
5+
6+
import lombok.AllArgsConstructor;
7+
import lombok.Getter;
8+
9+
@Getter
10+
@AllArgsConstructor
11+
public class DefaultWebSocketResponse<T> implements WebSocketDto<T> {
12+
private final MessageType type;
13+
private final T message;
14+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package io.f1.backend.domain.game.dto.response;
2+
3+
public record GameSettingResponse(int round, int timeLimit, QuizResponse quiz) {}

0 commit comments

Comments
 (0)