Skip to content

Commit 4b42ee8

Browse files
Merge branch 'dev' into refactor/61
2 parents 93353c5 + 1cb31a9 commit 4b42ee8

27 files changed

+295
-47
lines changed

backend/src/main/java/io/f1/backend/domain/admin/app/AdminDetailService.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.f1.backend.domain.admin.dao.AdminRepository;
44
import io.f1.backend.domain.admin.dto.AdminPrincipal;
55
import io.f1.backend.domain.admin.entity.Admin;
6+
import io.f1.backend.global.exception.errorcode.AdminErrorCode;
67

78
import lombok.RequiredArgsConstructor;
89

@@ -23,7 +24,9 @@ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundEx
2324
adminRepository
2425
.findByUsername(username)
2526
.orElseThrow(
26-
() -> new UsernameNotFoundException("E404007: 존재하지 않는 관리자입니다."));
27+
() ->
28+
new UsernameNotFoundException(
29+
AdminErrorCode.ADMIN_NOT_FOUND.getMessage()));
2730
// 프론트엔드로 내려가지 않는 예외
2831
return new AdminPrincipal(admin);
2932
}

backend/src/main/java/io/f1/backend/domain/admin/app/handler/AdminLoginFailureHandler.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.fasterxml.jackson.databind.ObjectMapper;
44

55
import io.f1.backend.domain.admin.dto.AdminLoginFailResponse;
6+
import io.f1.backend.global.exception.errorcode.AuthErrorCode;
67

78
import jakarta.servlet.http.HttpServletRequest;
89
import jakarta.servlet.http.HttpServletResponse;
@@ -31,7 +32,9 @@ public void onAuthenticationFailure(
3132
response.setContentType("application/json;charset=UTF-8");
3233

3334
AdminLoginFailResponse errorResponse =
34-
new AdminLoginFailResponse("E401005", "아이디 또는 비밀번호가 일치하지 않습니다.");
35+
new AdminLoginFailResponse(
36+
AuthErrorCode.LOGIN_FAILED.getCode(),
37+
AuthErrorCode.LOGIN_FAILED.getMessage());
3538

3639
response.getWriter().write(objectMapper.writeValueAsString(errorResponse));
3740
}

backend/src/main/java/io/f1/backend/domain/admin/app/handler/AdminLoginSuccessHandler.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import io.f1.backend.domain.admin.dao.AdminRepository;
77
import io.f1.backend.domain.admin.dto.AdminPrincipal;
88
import io.f1.backend.domain.admin.entity.Admin;
9+
import io.f1.backend.global.exception.CustomException;
10+
import io.f1.backend.global.exception.errorcode.AdminErrorCode;
911

1012
import jakarta.servlet.http.HttpServletRequest;
1113
import jakarta.servlet.http.HttpServletResponse;
@@ -36,7 +38,7 @@ public void onAuthenticationSuccess(
3638
Admin admin =
3739
adminRepository
3840
.findByUsername(principal.getUsername())
39-
.orElseThrow(() -> new RuntimeException("E404007: 존재하지 않는 관리자입니다."));
41+
.orElseThrow(() -> new CustomException(AdminErrorCode.ADMIN_NOT_FOUND));
4042

4143
admin.updateLastLogin(LocalDateTime.now());
4244
adminRepository.save(admin);

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

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,20 @@
44
import static io.f1.backend.domain.game.mapper.RoomMapper.toGameSetting;
55
import static io.f1.backend.domain.game.mapper.RoomMapper.toGameSettingResponse;
66
import static io.f1.backend.domain.game.mapper.RoomMapper.toPlayerListResponse;
7+
import static io.f1.backend.domain.game.mapper.RoomMapper.toQuestionResultResponse;
8+
import static io.f1.backend.domain.game.mapper.RoomMapper.toRankUpdateResponse;
79
import static io.f1.backend.domain.game.mapper.RoomMapper.toRoomResponse;
810
import static io.f1.backend.domain.game.mapper.RoomMapper.toRoomSetting;
911
import static io.f1.backend.domain.game.mapper.RoomMapper.toRoomSettingResponse;
1012
import static io.f1.backend.global.util.SecurityUtils.getCurrentUserId;
1113
import static io.f1.backend.global.util.SecurityUtils.getCurrentUserNickname;
1214

15+
import io.f1.backend.domain.game.dto.ChatMessage;
16+
import io.f1.backend.domain.game.dto.PlayerReadyData;
1317
import io.f1.backend.domain.game.dto.RoomEventType;
1418
import io.f1.backend.domain.game.dto.RoomExitData;
1519
import io.f1.backend.domain.game.dto.RoomInitialData;
20+
import io.f1.backend.domain.game.dto.RoundResult;
1621
import io.f1.backend.domain.game.dto.request.RoomCreateRequest;
1722
import io.f1.backend.domain.game.dto.request.RoomValidationRequest;
1823
import io.f1.backend.domain.game.dto.response.GameSettingResponse;
@@ -29,6 +34,7 @@
2934
import io.f1.backend.domain.game.model.RoomSetting;
3035
import io.f1.backend.domain.game.model.RoomState;
3136
import io.f1.backend.domain.game.store.RoomRepository;
37+
import io.f1.backend.domain.question.entity.Question;
3238
import io.f1.backend.domain.quiz.app.QuizService;
3339
import io.f1.backend.domain.quiz.entity.Quiz;
3440
import io.f1.backend.global.exception.CustomException;
@@ -140,7 +146,8 @@ public RoomInitialData initializeRoomSocket(Long roomId, String sessionId) {
140146

141147
PlayerListResponse playerListResponse = toPlayerListResponse(room);
142148

143-
SystemNoticeResponse systemNoticeResponse = ofPlayerEvent(player, RoomEventType.ENTER);
149+
SystemNoticeResponse systemNoticeResponse =
150+
ofPlayerEvent(player.getNickname(), RoomEventType.ENTER);
144151

145152
return new RoomInitialData(
146153
getDestination(roomId),
@@ -175,14 +182,30 @@ public RoomExitData exitRoom(Long roomId, String sessionId) {
175182
removePlayer(room, sessionId, removePlayer);
176183

177184
SystemNoticeResponse systemNoticeResponse =
178-
ofPlayerEvent(removePlayer, RoomEventType.EXIT);
185+
ofPlayerEvent(removePlayer.nickname, RoomEventType.EXIT);
179186

180187
PlayerListResponse playerListResponse = toPlayerListResponse(room);
181188

182189
return new RoomExitData(destination, playerListResponse, systemNoticeResponse, false);
183190
}
184191
}
185192

193+
public PlayerReadyData handlePlayerReady(Long roomId, String sessionId) {
194+
Player player =
195+
roomRepository
196+
.findPlayerInRoomBySessionId(roomId, sessionId)
197+
.orElseThrow(() -> new CustomException(RoomErrorCode.PLAYER_NOT_FOUND));
198+
199+
player.toggleReady();
200+
201+
String destination = getDestination(roomId);
202+
203+
Room room = findRoom(roomId);
204+
PlayerListResponse playerListResponse = toPlayerListResponse(room);
205+
206+
return new PlayerReadyData(destination, playerListResponse);
207+
}
208+
186209
public RoomListResponse getAllRooms() {
187210
List<Room> rooms = roomRepository.findAll();
188211
List<RoomResponse> roomResponses =
@@ -198,6 +221,36 @@ public RoomListResponse getAllRooms() {
198221
return new RoomListResponse(roomResponses);
199222
}
200223

224+
// todo 동시성적용
225+
public RoundResult chat(Long roomId, String sessionId, ChatMessage chatMessage) {
226+
Room room = findRoom(roomId);
227+
228+
String destination = getDestination(roomId);
229+
230+
if (!room.isPlaying()) {
231+
return buildResultOnlyChat(destination, chatMessage);
232+
}
233+
234+
Question currentQuestion = room.getCurrentQuestion();
235+
236+
String answer = currentQuestion.getAnswer();
237+
238+
if (!answer.equals(chatMessage.message())) {
239+
return buildResultOnlyChat(destination, chatMessage);
240+
}
241+
242+
room.increasePlayerCorrectCount(sessionId);
243+
244+
return RoundResult.builder()
245+
.destination(destination)
246+
.questionResult(
247+
toQuestionResultResponse(currentQuestion.getId(), chatMessage, answer))
248+
.rankUpdate(toRankUpdateResponse(room))
249+
.systemNotice(ofPlayerEvent(chatMessage.nickname(), RoomEventType.ENTER))
250+
.chat(chatMessage)
251+
.build();
252+
}
253+
201254
private Player getRemovePlayer(Room room, String sessionId) {
202255
Player removePlayer = room.getPlayerSessionMap().get(sessionId);
203256
if (removePlayer == null) {
@@ -255,4 +308,8 @@ private void removePlayer(Room room, String sessionId, Player removePlayer) {
255308
room.removeUserId(removePlayer.getId());
256309
room.removeSessionId(sessionId);
257310
}
311+
312+
private RoundResult buildResultOnlyChat(String destination, ChatMessage chatMessage) {
313+
return RoundResult.builder().destination(destination).chat(chatMessage).build();
314+
}
258315
}
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;
2+
3+
import java.time.Instant;
4+
5+
public record ChatMessage(String nickname, String message, Instant timestamp) {}

backend/src/main/java/io/f1/backend/domain/game/dto/MessageType.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@ public enum MessageType {
66
PLAYER_LIST,
77
SYSTEM_NOTICE,
88
GAME_START,
9+
CHAT,
10+
QUESTION_RESULT,
11+
RANK_UPDATE,
912
}
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;
2+
3+
import io.f1.backend.domain.game.dto.response.PlayerListResponse;
4+
5+
public record PlayerReadyData(String destination, PlayerListResponse response) {}
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;
2+
3+
public record Rank(String nickname, int correctCount) {}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package io.f1.backend.domain.game.dto;
2+
3+
import io.f1.backend.domain.game.dto.response.QuestionResultResponse;
4+
import io.f1.backend.domain.game.dto.response.RankUpdateResponse;
5+
import io.f1.backend.domain.game.dto.response.SystemNoticeResponse;
6+
7+
import lombok.Builder;
8+
import lombok.Getter;
9+
10+
@Getter
11+
public class RoundResult {
12+
String destination;
13+
QuestionResultResponse questionResult;
14+
RankUpdateResponse rankUpdate;
15+
SystemNoticeResponse systemNotice;
16+
ChatMessage chat;
17+
18+
@Builder
19+
public RoundResult(
20+
String destination,
21+
QuestionResultResponse questionResult,
22+
RankUpdateResponse rankUpdate,
23+
SystemNoticeResponse systemNotice,
24+
ChatMessage chat) {
25+
this.destination = destination;
26+
this.questionResult = questionResult;
27+
this.rankUpdate = rankUpdate;
28+
this.systemNotice = systemNotice;
29+
this.chat = chat;
30+
}
31+
32+
public boolean hasChat() {
33+
return chat != null;
34+
}
35+
36+
public boolean hasOnlyChat() {
37+
return chat != null && questionResult == null && rankUpdate == null && systemNotice == null;
38+
}
39+
}
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 QuestionResultResponse(Long questionId, String correctUser, String answer) {}

0 commit comments

Comments
 (0)