package room // 包名声明:房间消息处理,与房间同包 import ( "context" // 标准库:handler 入参上下文 "git.lzcwy.cn/zhengchiliu/zt-online-game-backend/internal/dto" "git.lzcwy.cn/zhengchiliu/zt-online-game-backend/internal/game" "git.lzcwy.cn/zhengchiliu/zt-online-game-backend/internal/wsgateway" ) // RegisterHandlers 向 Hub 注册房间相关消息的处理函数。 func RegisterHandlers(hub *wsgateway.Hub, m *Manager) { hub.RegisterHandler(wsgateway.TypeRoomJoin, func(ctx context.Context, c *wsgateway.Connection, env *wsgateway.Envelope) { var req dto.WSRoomJoinRequest // 解析上行体 if err := wsgateway.BindPayload(env, &req); err != nil { // 参数错误 c.SendError(env.Seq, 0, "参数错误: "+err.Error()) // 回错误 return } r, ok := m.Get(req.RoomID) // 查房间 if !ok { // 房间不存在 c.SendError(env.Seq, 0, "房间不存在") return } if err := r.Join(c.UserID()); err != nil { // 入座 c.SendError(env.Seq, 0, err.Error()) // 回错误(如房间已满) return } m.bind(c.UserID(), r.ID()) // 绑定用户与房间 }) hub.RegisterHandler(wsgateway.TypeRoomReady, func(ctx context.Context, c *wsgateway.Connection, env *wsgateway.Envelope) { var req dto.WSRoomReadyRequest // 解析上行体 if err := wsgateway.BindPayload(env, &req); err != nil { // 参数错误 c.SendError(env.Seq, 0, "参数错误: "+err.Error()) return } r, ok := m.RoomOf(c.UserID()) // 取用户所在房间 if !ok { // 不在任何房间 c.SendError(env.Seq, 0, "不在房间内") return } if err := r.Ready(c.UserID(), req.Ready); err != nil { // 设置准备 c.SendError(env.Seq, 0, err.Error()) } }) hub.RegisterHandler(wsgateway.TypeRoomAction, func(ctx context.Context, c *wsgateway.Connection, env *wsgateway.Envelope) { var req dto.WSRoomActionRequest // 解析上行体 if err := wsgateway.BindPayload(env, &req); err != nil { // 参数错误 c.SendError(env.Seq, 0, "参数错误: "+err.Error()) return } r, ok := m.RoomOf(c.UserID()) // 取用户所在房间 if !ok { // 不在任何房间 c.SendError(env.Seq, 0, "不在房间内") return } action := game.Action{Name: req.Action, Payload: req.Payload} // 封装为玩法动作 if err := r.Submit(c.UserID(), action); err != nil { // 提交给玩法 c.SendError(env.Seq, 0, err.Error()) // 回错误(如不是你的回合) } }) hub.RegisterHandler(wsgateway.TypeRoomLeave, func(ctx context.Context, c *wsgateway.Connection, env *wsgateway.Envelope) { r, ok := m.RoomOf(c.UserID()) // 取用户所在房间 if !ok { // 不在任何房间 c.SendError(env.Seq, 0, "不在房间内") return } if err := r.Leave(c.UserID()); err != nil { // 离座 c.SendError(env.Seq, 0, err.Error()) return } m.unbind(c.UserID()) // 解绑 }) hub.RegisterHandler(wsgateway.TypeRoomReconnect, func(ctx context.Context, c *wsgateway.Connection, env *wsgateway.Envelope) { var req dto.WSRoomReconnectRequest // 解析上行体 if err := wsgateway.BindPayload(env, &req); err != nil { // 参数错误 c.SendError(env.Seq, 0, "参数错误: "+err.Error()) return } r, ok := m.Get(req.RoomID) // 按 ID 取房间 if !ok { // 房间已不存在(可能已关闭) c.SendError(env.Seq, 0, "房间不存在") return } if err := r.Reconnect(c.UserID()); err != nil { // 恢复在线并下发快照 c.SendError(env.Seq, 0, err.Error()) return } m.bind(c.UserID(), r.ID()) // 重新绑定 }) }