feat: 重构游戏房间架构
This commit is contained in:
@@ -22,7 +22,7 @@ public record UserInfoResponse(
|
||||
*/
|
||||
public static UserInfoResponse from(UserEntity user) {
|
||||
return new UserInfoResponse(
|
||||
user.getId(),
|
||||
user.getAccount().getId(),
|
||||
user.getNickName(),
|
||||
user.getAvatar(),
|
||||
user.getSignature(),
|
||||
|
||||
@@ -34,8 +34,16 @@ public class GameRecordEntity extends UUIDBaseEntity {
|
||||
@Column(name = "winner_id", length = 64)
|
||||
private String winnerId;
|
||||
|
||||
/** 结果类型:win(一方获胜)、draw(平局)、resign(认输) */
|
||||
@Column(name = "result_type", nullable = false, length = 16)
|
||||
/**
|
||||
* 结果类型
|
||||
* <ul>
|
||||
* <li>{@code pending} — 对局进行中,尚未产生结果(游戏开始时设置)</li>
|
||||
* <li>{@code win} — 一方获胜</li>
|
||||
* <li>{@code draw} — 平局</li>
|
||||
* <li>{@code resign} — 一方认输</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Column(name = "result_type", length = 16)
|
||||
private String resultType;
|
||||
|
||||
/** 对局开始时间 */
|
||||
|
||||
@@ -18,6 +18,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
@@ -95,6 +96,7 @@ public class RoomManager {
|
||||
* @param creatorId 房主 accountId
|
||||
* @return 创建结果
|
||||
*/
|
||||
@Transactional
|
||||
public CreateRoomResponse createRoom(CreateRoomRequest request, String creatorId) {
|
||||
// 校验游戏存在且启用
|
||||
GameConfigEntity gameConfig = gameConfigRepository.findByGameId(request.gameId())
|
||||
@@ -172,6 +174,7 @@ public class RoomManager {
|
||||
* @param userId 用户 accountId
|
||||
* @return 房间信息
|
||||
*/
|
||||
@Transactional
|
||||
public RoomItemResponse joinRoom(JoinRoomRequest request, String userId) {
|
||||
GameRoomEntity room = gameRoomRepository.findById(request.roomId())
|
||||
.orElseThrow(() -> new BusinessException(ErrorCode.ROOM_NOT_FOUND));
|
||||
@@ -236,6 +239,7 @@ public class RoomManager {
|
||||
* @param roomId 房间 ID
|
||||
* @param userId 用户 accountId
|
||||
*/
|
||||
@Transactional
|
||||
public void leaveRoom(String roomId, String userId) {
|
||||
GameRoomEntity room = gameRoomRepository.findById(roomId)
|
||||
.orElseThrow(() -> new BusinessException(ErrorCode.ROOM_NOT_FOUND));
|
||||
@@ -286,6 +290,7 @@ public class RoomManager {
|
||||
* @param roomId 房间 ID
|
||||
* @param ownerId 房主 accountId
|
||||
*/
|
||||
@Transactional
|
||||
public void disbandRoom(String roomId, String ownerId) {
|
||||
GameRoomEntity room = gameRoomRepository.findById(roomId)
|
||||
.orElseThrow(() -> new BusinessException(ErrorCode.ROOM_NOT_FOUND));
|
||||
@@ -324,6 +329,7 @@ public class RoomManager {
|
||||
* @param ownerId 房主 accountId
|
||||
* @param targetUserId 目标用户 accountId
|
||||
*/
|
||||
@Transactional
|
||||
public void kickPlayer(String roomId, String ownerId, String targetUserId) {
|
||||
GameRoomEntity room = gameRoomRepository.findById(roomId)
|
||||
.orElseThrow(() -> new BusinessException(ErrorCode.ROOM_NOT_FOUND));
|
||||
@@ -366,6 +372,7 @@ public class RoomManager {
|
||||
* @param userId 用户 accountId
|
||||
* @return 新的准备状态
|
||||
*/
|
||||
@Transactional
|
||||
public boolean toggleReady(String roomId, String userId) {
|
||||
GameRoomEntity room = gameRoomRepository.findById(roomId)
|
||||
.orElseThrow(() -> new BusinessException(ErrorCode.ROOM_NOT_FOUND));
|
||||
@@ -400,6 +407,7 @@ public class RoomManager {
|
||||
* @param roomId 房间 ID
|
||||
* @param userId 操作者 accountId(必须是房主)
|
||||
*/
|
||||
@Transactional
|
||||
public void startGame(String roomId, String userId) {
|
||||
GameRoomEntity room = gameRoomRepository.findById(roomId)
|
||||
.orElseThrow(() -> new BusinessException(ErrorCode.ROOM_NOT_FOUND));
|
||||
@@ -430,9 +438,10 @@ public class RoomManager {
|
||||
room.setStatus("playing");
|
||||
gameRoomRepository.save(room);
|
||||
|
||||
// 创建游戏记录
|
||||
// 创建游戏记录(resultType 初始为 pending,游戏结束时由 onGameOver 更新)
|
||||
GameRecordEntity record = new GameRecordEntity()
|
||||
.setRoomId(roomId)
|
||||
.setResultType("pending")
|
||||
.setStartedAt(LocalDateTime.now());
|
||||
gameRecordRepository.save(record);
|
||||
|
||||
@@ -637,6 +646,7 @@ public class RoomManager {
|
||||
* @param winnerId 胜者 accountId(null 表示平局)
|
||||
* @param resultType 结果类型(win/draw/resign)
|
||||
*/
|
||||
@Transactional
|
||||
public void onGameOver(String roomId, String winnerId, String resultType) {
|
||||
GameRoomEntity room = gameRoomRepository.findById(roomId).orElse(null);
|
||||
if (room == null) return;
|
||||
|
||||
@@ -133,12 +133,12 @@ public class RoomWebSocketHandler extends TextWebSocketHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理重连(在注册会话之前,避免广播到尚未完成握手的当前 session)
|
||||
roomManager.handleReconnect(roomId, userId);
|
||||
|
||||
// 注册会话
|
||||
sessionManager.addSession(roomId, userId, session);
|
||||
|
||||
// 处理重连
|
||||
roomManager.handleReconnect(roomId, userId);
|
||||
|
||||
log.info("[WS] 连接建立, roomId={}, userId={}, sessionId={}", roomId, userId, session.getId());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user