Skip to content

Commit 4c599cf

Browse files
committed
✨ 게임 방 입장(+유효성 검증) 구현
1 parent 2d3c46d commit 4c599cf

24 files changed

+430
-8
lines changed

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,8 +2,10 @@
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

8+
import io.f1.backend.domain.game.dto.response.RoomValidationResponse;
79
import jakarta.validation.Valid;
810

911
import lombok.RequiredArgsConstructor;
@@ -35,4 +37,9 @@ public RoomCreateResponse saveRoom(@RequestBody @Valid RoomCreateRequest request
3537

3638
return roomService.saveRoom(request, loginUser);
3739
}
40+
41+
@PostMapping("/validation")
42+
public RoomValidationResponse validateRoom(@RequestBody RoomValidationRequest request) {
43+
return roomService.validateRoom(request);
44+
}
3845
}

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

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,38 @@
11
package io.f1.backend.domain.game.app;
22

3+
import static io.f1.backend.domain.game.mapper.RoomMapper.toGameSettingResponse;
4+
import static io.f1.backend.domain.game.mapper.RoomMapper.toPlayerListResponse;
35
import static io.f1.backend.domain.game.mapper.RoomMapper.toRoomSetting;
6+
import static io.f1.backend.domain.game.mapper.RoomMapper.toRoomSettingResponse;
47

8+
import io.f1.backend.domain.game.dto.RoomInitialData;
59
import io.f1.backend.domain.game.dto.request.RoomCreateRequest;
10+
import io.f1.backend.domain.game.dto.request.RoomValidationRequest;
11+
import io.f1.backend.domain.game.dto.response.GameSettingResponse;
12+
import io.f1.backend.domain.game.dto.response.PlayerListResponse;
13+
import io.f1.backend.domain.game.dto.response.QuizResponse;
614
import io.f1.backend.domain.game.dto.response.RoomCreateResponse;
15+
import io.f1.backend.domain.game.dto.response.RoomSettingResponse;
16+
import io.f1.backend.domain.game.dto.response.RoomValidationResponse;
717
import io.f1.backend.domain.game.model.GameSetting;
818
import io.f1.backend.domain.game.model.Player;
919
import io.f1.backend.domain.game.model.Room;
1020
import io.f1.backend.domain.game.model.RoomSetting;
21+
import io.f1.backend.domain.game.model.RoomState;
1122
import io.f1.backend.domain.game.store.RoomRepository;
12-
13-
import lombok.RequiredArgsConstructor;
14-
15-
import org.springframework.stereotype.Service;
16-
1723
import java.util.Map;
1824
import java.util.concurrent.atomic.AtomicLong;
25+
import lombok.RequiredArgsConstructor;
26+
import lombok.extern.slf4j.Slf4j;
27+
import org.springframework.stereotype.Service;
1928

29+
@Slf4j
2030
@Service
2131
@RequiredArgsConstructor
2232
public class RoomService {
2333

2434
private final RoomRepository roomRepository;
35+
2536
private final AtomicLong roomIdGenerator = new AtomicLong(0);
2637

2738
public RoomCreateResponse saveRoom(RoomCreateRequest request, Map<String, Object> loginUser) {
@@ -38,4 +49,53 @@ public RoomCreateResponse saveRoom(RoomCreateRequest request, Map<String, Object
3849

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

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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package io.f1.backend.domain.game.dto.request;
2+
3+
public record RoomValidationRequest(Long roomId, String password) {
4+
5+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
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+
import lombok.AllArgsConstructor;
6+
import lombok.Getter;
7+
8+
@Getter
9+
@AllArgsConstructor
10+
public class DefaultWebSocketResponse<T> implements WebSocketDto<T> {
11+
private final MessageType type;
12+
private final T message;
13+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package io.f1.backend.domain.game.dto.response;
2+
3+
public record GameSettingResponse(int round, int timeLimit, QuizResponse quiz) {
4+
5+
}
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.response;
2+
3+
import java.util.List;
4+
5+
public record PlayerListResponse(String host, List<PlayerResponse> players) {
6+
7+
}

0 commit comments

Comments
 (0)