Skip to content

Commit

Permalink
PR#64, PR#65
Browse files Browse the repository at this point in the history
  • Loading branch information
Berygna committed Jun 22, 2024
1 parent 391ad83 commit a045f98
Show file tree
Hide file tree
Showing 11 changed files with 345 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
package gooroommoon.algofi_core.algorithmproblem;

import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Algorithmproblem {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long AlgorithmproblemId;
private String title;

@JsonProperty("level")
private String level;
private String content;
private int recommend_time;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.Optional;

public interface AlgorithmproblemRepository extends JpaRepository<Algorithmproblem, Long> {

/**
*랜덤으로 문제 가져오는 쿼리
*/
@Query("select a from Algorithmproblem a where a.level like :level order by rand() limit 1")
Algorithmproblem getRandomAlgorithmproblem(@Param("level")String level);
Optional<Algorithmproblem> getRandomAlgorithmproblem(@Param("level")String level);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gooroommoon.algofi_core.algorithmproblem;

import gooroommoon.algofi_core.algorithmproblem.dto.AlgorithmproblemResponse;
import gooroommoon.algofi_core.algorithmproblem.exception.AlgorithmproblemNotFoundException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
Expand All @@ -16,7 +17,8 @@ public class AlgorithmproblemService {
* 랜덤으로 가져오는 서비스 작성 -> repository에서 해결
*/
public AlgorithmproblemResponse getRandom(String level) {
Algorithmproblem randomAlgorithmproblem = algorithmproblemRepository.getRandomAlgorithmproblem(level);
Algorithmproblem randomAlgorithmproblem = algorithmproblemRepository.getRandomAlgorithmproblem(level)
.orElseThrow(() -> new AlgorithmproblemNotFoundException("문제를 찾을 수 없습니다."));

return fromAlgorithmproblem(randomAlgorithmproblem);
}
Expand All @@ -26,7 +28,6 @@ private AlgorithmproblemResponse fromAlgorithmproblem(Algorithmproblem Algorithm
.title(Algorithmproblem.getTitle())
.content(Algorithmproblem.getContent())
.level(Algorithmproblem.getLevel())
.recommend_time(Algorithmproblem.getRecommend_time())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,4 @@ public class AlgorithmproblemResponse {
private String title;
private String level;
private String content;
private int recommend_time;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package gooroommoon.algofi_core.Algorithmproblem.exception;
package gooroommoon.algofi_core.algorithmproblem.exception;

public class AlgorithmproblemNotFoundException extends RuntimeException{
public AlgorithmproblemNotFoundException(String message) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBro
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
messages
.nullDestMatcher().permitAll()
.simpSubscribeDestMatchers("/user/queue/game/session").permitAll()
.simpSubscribeDestMatchers("/user/queue/game/session",
"/user/queue/game/sessions",
"/user/queue/game/join",
"/user/queue/game/start",
"/user/queue/game/result",
"/user/queue/game/over").authenticated()
.simpSubscribeDestMatchers("/topic/room/*").permitAll()
.simpDestMatchers("/app/**").authenticated()
.anyMessage().denyAll();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,37 @@
package gooroommoon.algofi_core.game.session;


import gooroommoon.algofi_core.algorithmproblem.Algorithmproblem;
import gooroommoon.algofi_core.algorithmproblem.AlgorithmproblemService;
import gooroommoon.algofi_core.algorithmproblem.dto.AlgorithmproblemResponse;
import gooroommoon.algofi_core.algorithmproblem.exception.AlgorithmproblemNotFoundException;
import gooroommoon.algofi_core.auth.member.MemberService;
import gooroommoon.algofi_core.chat.dto.MessageDTO;
import gooroommoon.algofi_core.chat.entity.Chatroom;
import gooroommoon.algofi_core.chat.entity.Message;
import gooroommoon.algofi_core.chat.entity.MessageType;
import gooroommoon.algofi_core.chat.repository.ChatroomRepository;
import gooroommoon.algofi_core.chat.service.ChatService;
import gooroommoon.algofi_core.game.session.dto.*;
import gooroommoon.algofi_core.game.session.exception.*;
import gooroommoon.algofi_core.gameresult.GameresultService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.user.SimpUserRegistry;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.socket.messaging.SessionDisconnectEvent;

import java.util.Map;
import java.util.Set;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.*;

@Service
@RequiredArgsConstructor
@Slf4j
public class GameSessionService {

//유저가 채팅방에 새로 들어올 때 입장 메시지 보내는 메서드 호출하기
Expand Down Expand Up @@ -62,6 +68,7 @@ public GameSessionsResponse getSessionsResponse() {
.host(memberService.getMemberNickName(session.getHostId()))
.hostId(session.getHostId())
.title(session.getTitle())
.players(session.getPlayers())
.maxPlayer(session.getMaxPlayer())
.problemLevel(session.getProblemLevel())
.timerTime(session.getTimerTime())
Expand All @@ -72,15 +79,15 @@ public GameSessionsResponse getSessionsResponse() {
}

public void sendSessions(String loginId) {
messagingTemplate.convertAndSendToUser(loginId, "/queue/game/session", getSessionsResponse());
messagingTemplate.convertAndSendToUser(loginId, "/queue/game/sessions", getSessionsResponse());
}

public void sendSessions() {
GameSessionsResponse response = getSessionsResponse();
userRegistry.getUsers().forEach(user -> {
String playerId = user.getPrincipal().getName();
if(!gameSessions.containsKey(playerId)) {
messagingTemplate.convertAndSendToUser(playerId, "/queue/game/session", response);
messagingTemplate.convertAndSendToUser(playerId, "/queue/game/sessions", response);
}
});
}
Expand All @@ -93,7 +100,8 @@ public void createSession(String hostId, GameSessionUpdateRequest request) {
chatRoomRepository.save(chatroom);
chatService.enterRoom(session.getChatroomId(), hostId);

sendUpdateToPlayers(session);
sendUpdateToPlayers(session, "join");
sendSessions();
}

public void addPlayer(String hostId, String playerId) {
Expand All @@ -103,15 +111,16 @@ public void addPlayer(String hostId, String playerId) {
gameSessions.put(playerId, session);
chatService.enterRoom(session.getChatroomId(), playerId);

sendUpdateToPlayers(session);
sendUpdateToPlayers(session, "join");
sendSessions();
}

public void updateSetting(String hostId, GameSessionUpdateRequest request) {
GameSession session = getSession(hostId);
if(session.getHostId().equals(hostId)) {
session.updateSettings(request.getTitle(), request.getProblemLevel(), request.getTimerTime());

sendUpdateToPlayers(session);
sendUpdateToPlayers(session, "session");
} else {
throw new NotAHostException("방장만 게임 설정을 변경할 수 있습니다.");
}
Expand All @@ -121,7 +130,7 @@ public void playerReady(String playerId) {
GameSession session = getSession(playerId);
session.addReadyPlayer(playerId);

sendUpdateToPlayers(session);
sendUpdateToPlayers(session, "session");
}

public void startGame(String hostId) {
Expand All @@ -132,11 +141,39 @@ public void startGame(String hostId) {
if(!session.getHostId().equals(hostId)) {
throw new NotAHostException("방장만 게임을 시작할 수 있습니다.");
}
String problemLevel = session.getProblemLevel();
//TODO 문제 가져와서 넣기
//랜덤 알고리즘문제
algorithmproblemService.getRandom(session.getProblemLevel());
try {
int attempts = 0;
int maxAttempts = 5; // 최대 재시도 횟수 설정
boolean success = false;

while (attempts < maxAttempts && !success) {
try {
AlgorithmproblemResponse randomProblem = algorithmproblemService.getRandom(problemLevel);
log.info("randomProblem.title = {}", randomProblem.getTitle());
log.info("randomProblem.level = {}", randomProblem.getLevel());
success = true; // 성공적으로 문제를 찾음
} catch (AlgorithmproblemNotFoundException e) {
attempts++;
log.warn("문제를 찾을 수 없습니다. 재시도 중... ({}/{})", attempts, maxAttempts);
}
}

if (!success) {
log.error("문제를 찾을 수 없습니다. 재시도 횟수 초과");
// 클라이언트에게 실패 응답을 보냄 (선택사항)
throw new AlgorithmproblemNotFoundException("문제를 찾을 수 없습니다. 재시도 횟수 초과");
}
} catch (Exception e) {
log.error("예상치 못한 오류 발생", e);
// 클라이언트에게 오류 응답을 보냄 (선택사항)
}

session.start();
//TODO 알고리즘 문제 가져와서 메시지 발행

GameSessionService gameSessionService = this;
ScheduledFuture<?> timeOverTask = executorService.schedule(() ->
gameSessionService.closeGame(session,null, session.getTimerTime())
Expand All @@ -160,6 +197,7 @@ public void submitCode(String playerId, GameCodeRequest request) {
.toEntity(SubmitResultResponse.class)
.subscribe(response -> {
String message = response.getBody().getMessage();
messagingTemplate.convertAndSendToUser(playerId, "/queue/game/result", message);
if(message.equals("맞았습니다.")) {
closeGame(session, playerId, (int)(System.currentTimeMillis() - session.getStartTime()));
} else {
Expand All @@ -173,17 +211,17 @@ public void closeGame(GameSession session, String winnerId, int runningTime) {
GameSessionOverResponse winnerResponse = new GameSessionOverResponse(GameOverType.WIN, runningTime);
GameSessionOverResponse loserResponse = new GameSessionOverResponse(GameOverType.LOSE, runningTime);
messagingTemplate.convertAndSendToUser(
winnerId, "/queue/game/session", winnerResponse
winnerId, "/queue/game/over", winnerResponse
);
session.getPlayersStream().forEach(id -> {
if(!id.equals(winnerId))
messagingTemplate.convertAndSendToUser(id, "/queue/game/session", loserResponse);
messagingTemplate.convertAndSendToUser(id, "/queue/game/over", loserResponse);
});
session.getTimeOverTask().cancel(true);
} else {
GameSessionOverResponse timeOverResponse = new GameSessionOverResponse(GameOverType.TIME_OVER, runningTime);
session.getPlayersStream().forEach(id ->
messagingTemplate.convertAndSendToUser(id, "/queue/game/session", timeOverResponse));
messagingTemplate.convertAndSendToUser(id, "/queue/game/over", timeOverResponse));
}
}
//게임이 종료된 후 클라이언트의 요청을 받아 코드를 저장
Expand All @@ -207,11 +245,20 @@ public void savePlayerCode(String playerId, GameCodeRequest request) {

private void saveResult(GameSession session) {
//TODO 게임 결과 저장
//TODO hostCode, guestCode,
String chatroomId = session.getChatroomId();
Set<String> players = session.getPlayers();
String hostCode = "hostCode";
String guestCode = "guestCode";
Algorithmproblem algorithmproblem = new Algorithmproblem();
gameresultService.save(chatroomId,players,hostCode,guestCode,algorithmproblem,runningTime);
removeSession(session);
//TODO 게임 세션 삭제
}

public void removeSession(GameSession session) {
session.getPlayersStream().forEach(gameSessions::remove);
sendSessions();
}

private void checkPlayerInGame(String playerId) {
Expand All @@ -220,10 +267,10 @@ private void checkPlayerInGame(String playerId) {
}
}

private void sendUpdateToPlayers(GameSession session) {
private void sendUpdateToPlayers(GameSession session, String destination) {
session.getPlayersStream().forEach(id ->
messagingTemplate.convertAndSendToUser(
id, "/queue/game/session", toResponse(session)
id, "/queue/game/" + destination, toResponse(session)
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.*;

import java.util.List;
import java.util.Set;

@Getter
@AllArgsConstructor
Expand All @@ -23,6 +24,7 @@ public static class Session {
private String host;
private String hostId;
private String title;
private Set<String> players;
private int maxPlayer;
private String problemLevel;
private int timerTime;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.security.Principal;
import java.util.List;

@Slf4j
Expand All @@ -24,8 +24,8 @@ public class GameresultController {
*/
//TODO uri 정해야함
@GetMapping("/api/game/member/{GameresultId}")
public ResponseEntity findGameresult(@PathVariable Long GameresultId, Principal principal) {
GameresultResponse gameresult = gameresultService.findGameresult(principal.getName(), GameresultId);
public ResponseEntity findGameresult(@PathVariable Long GameresultId, Authentication auth) {
GameresultResponse gameresult = gameresultService.findGameresult(auth.getName(), GameresultId);

//TODO 상태코드랑, 메세지같이 보내야함
return ResponseEntity.ok().body(gameresult);
Expand All @@ -36,8 +36,8 @@ public ResponseEntity findGameresult(@PathVariable Long GameresultId, Principal
*/
//TODO uri 정해야함
@GetMapping("/api/game/member/gameresults")
public ResponseEntity<List<GameresultsResponse>> findAllGameresults(Principal principal) {
List<GameresultsResponse> gameresultList = gameresultService.findGameresultList(principal.getName());
public ResponseEntity<List<GameresultsResponse>> findAllGameresults(Authentication auth) {
List<GameresultsResponse> gameresultList = gameresultService.findGameresultList(auth.getName());

return ResponseEntity.ok().body(gameresultList);
}
Expand Down
Loading

0 comments on commit a045f98

Please sign in to comment.