package com.webgame.webgamebackend.service.engine; import com.webgame.webgamebackend.ws.dto.WsMessage; import lombok.Getter; import java.util.List; import java.util.function.Consumer; /** * 房间上下文 * * 游戏引擎初始化时由 RoomManager 传入,包含引擎所需的房间信息和回调接口。 * 引擎不应持有对 RoomManager 的直接引用,所有与房间层的交互通过此上下文完成。 */ @Getter public class RoomContext { /** 房间 ID */ private final String roomId; /** 游戏 ID */ private final String gameId; /** 参与对局的玩家列表(按座位号排序,不可变) */ private final List players; /** 玩法模式 */ private final String mode; /** 底注金额 */ private final int stakes; /** 广播消息到房间内所有 WebSocket 会话(不暴露到 getter) */ private final Consumer broadcaster; /** 私有消息发送器(不暴露到 getter) */ private final PrivateMessageSender privateSender; /** 游戏结束回调(不暴露到 getter) */ private final GameOverCallback onGameOver; public RoomContext(String roomId, String gameId, List players, String mode, int stakes, Consumer broadcaster, PrivateMessageSender privateSender, GameOverCallback onGameOver) { this.roomId = roomId; this.gameId = gameId; this.players = List.copyOf(players); // 防御性拷贝 this.mode = mode; this.stakes = stakes; this.broadcaster = broadcaster; this.privateSender = privateSender; this.onGameOver = onGameOver; } /** * 广播消息到房间内所有人 */ public void broadcast(WsMessage message) { broadcaster.accept(message); } /** * 向指定用户发送私有消息(如重连时的状态同步) */ public void sendToUser(String userId, WsMessage message) { privateSender.send(userId, message); } /** * 游戏结束,通知房间层 * * @param winnerId 胜者 accountId,null 表示平局 * @param resultType 结果类型(win / draw / resign) */ public void gameOver(String winnerId, String resultType) { onGameOver.onGameOver(winnerId, resultType); } /** * 房间内玩家简要信息 */ public record PlayerInfo(String userId, int seatNumber) {} /** * 游戏结束回调接口 */ @FunctionalInterface public interface GameOverCallback { /** * 游戏结束通知 * * @param winnerId 胜者 accountId,null 表示平局 * @param resultType 结果类型 */ void onGameOver(String winnerId, String resultType); } /** * 私有消息发送接口 */ @FunctionalInterface public interface PrivateMessageSender { /** * 向指定用户的所有 WebSocket 会话发送消息 * * @param userId 目标用户 accountId * @param message 消息 */ void send(String userId, WsMessage message); } }