package handler import ( "encoding/json" "fmt" "github.com/rabbitmq/amqp091-go" "samba/pkg/log" "samba/proto" . "samba/server/game/baseroom" . "samba/server/game/player" . "samba/server/truco/room" . "samba/server/truco/service" "samba/util/config" "samba/util/model" "samba/util/util" "strconv" ) func NewPlayer(uid int64) (*Player, error) { p := &Player{UserInfo: &model.UserInfo{UID: uid}} return p, p.Load() } func MakePlayerToProto(user *Player, clubId int) *proto.Player { protoPlayer := &proto.Player{ UserId: user.UID, ClubId: clubId, Mnick: user.MNick, HeadUrl: user.HeadURL, IconId: user.IconId, AvatarFrame: user.AvatarFrame, Sex: user.Sex, TakeCoin: user.TakeCoin, Poker: nil, Seat: -1, IsRed: 0, State: 1, ClubTakeCoin: user.TakeClubCoin, } if clubId == 0 { coins, _ := model.NewUserResourceOp().Get(user.UID, model.ResCoins) protoPlayer.Coin = coins } else { coins, _ := model.NewUserClubInfoOp().Get(user.UID, clubId, model.ResClubUserScore) protoPlayer.ClubCoin = coins } return protoPlayer } func onEnterRoom(_ *amqp091.Delivery, msg map[string]interface{}) { msgId, _, uid, data := ParseMsg(msg) req, err := util.MapToStructT[proto.ReqEnterRoom](data) if err != nil { log.Error(err.Error()) return } rm := RoomMgr.Find(req.RoomId) if rm != nil { rm.OnMessage(msgId, msg) } else { SendMsgToGate(uid, proto.RspEnterRoomId, &proto.RspEnterRoom{Code: proto.NotExistRoom, RoomId: req.RoomId}) } } func onLeaveRoom(_ *amqp091.Delivery, msg map[string]interface{}) { msgId, _, uid, data := ParseMsg(msg) req, err := util.MapToStructT[proto.ReqLeaveRoom](data) if err != nil { log.Error(err.Error()) return } rm := RoomMgr.Find(req.RoomId) if rm != nil { rm.OnMessage(msgId, msg) } else { SendMsgToGate(uid, proto.RspLeaveRoomId, &proto.RspLeaveRoom{Code: proto.Ok, RoomId: req.RoomId}) } } func checkSetPokers(req *proto.ReqSetPokers) (*TrucoRoom, proto.ErrorCode) { if config.Config.Application.Gm < 1 { return nil, proto.NotOpenGm } rm := RoomMgr.Find(req.RoomId) if rm == nil { return nil, proto.NotExistRoom } return rm.(*TrucoRoom), proto.Ok } // gm配牌指令 func onSetPokers(d *amqp091.Delivery, msg map[string]interface{}) { req, err := util.MapToStructT[proto.ReqSetPokers](msg["p"]) if err != nil { log.Error(err.Error()) return } response := make(map[string]interface{}) response["r"] = "0" room, code := checkSetPokers(req) if code == proto.Ok { room.SetGmPokers(req.UserId, req.Pokers, req.GhostPoker) } response["p"] = proto.RspSetPokers{Code: code} if data, err := json.Marshal(response); err == nil { _ = TrucoService.PublishRpc(d, data) } } // 玩家在房间内掉线,主动申请重连 func onReconnect(_ *amqp091.Delivery, msg map[string]interface{}) { _, _, uid, data := ParseMsg(msg) req, err := util.MapToStructT[proto.ReqReconnect](data) if err != nil { log.Error(err.Error()) return } if req.RoomId >= config.Cmd.MaxRoomId || req.RoomId < config.Cmd.MinRoomId { log.Debug(fmt.Sprintf("玩家申请重连:%v room:%v conf.maxid:%v conf.minid:%v", uid, req.RoomId, config.Cmd.MaxRoomId, config.Cmd.MinRoomId)) return } log.Debug(fmt.Sprintf("玩家申请重连:%v", uid)) if ir := RoomMgr.Find(req.RoomId); ir != nil { if rm, ok := ir.(*TrucoRoom); ok { msg["uid"] = uid seat := rm.GetSeat(uid) if seat == nil { log.Error(rm.Log("player:%d seat is nil", uid)) return } log.Debug(rm.SeatLog(seat, "seat:%v 重连", seat.No())) rm.OnMessage(proto.ReqReconnectId, msg) return } } log.Debug(fmt.Sprintf("玩家申请重连:%v 房间不存在", uid)) SendMsgToGate(uid, proto.RspReconnectId, &proto.RspReconnect{Code: proto.NotExistRoom}) } // 玩家下线,未开始游戏则踢出去,已开始游戏则设置假退出 func onUserOffline(d *amqp091.Delivery, msg map[string]interface{}) { _, _, _, data := ParseMsg(msg) req, err := util.MapToStructT[proto.UserOnline](data) if err != nil { log.Error(err.Error()) return } uid, _ := strconv.ParseInt(req.Uid, 10, 64) log.Debug(fmt.Sprintf("玩家下线:%v", uid)) onCancelMatchRoom(d, util.MakeMessage(proto.ReqCancelMatchRoomId, &proto.ReqCancelMatchRoom{RoomType: 0}, uid, 0)) irs := RoomMgr.FindPlayerRooms(uid) for _, ir := range irs { if rm, ok := ir.(*TrucoRoom); ok { rm.SetFakeLeave(uid, true) } } } // 更新配置 func onUpdateConfig(_ *amqp091.Delivery, _ map[string]interface{}) { log.Debug("更新配置") model.InitStub() } // 有同类服务启动,本服务没有玩家使用时,自动关闭 func onUpdateService(_ *amqp091.Delivery, msg map[string]interface{}) { _, _, _, data := ParseMsg(msg) req, err := util.MapToStructT[proto.NtfNewService](data) if err != nil { log.Error(err.Error()) return } if req.Type == TrucoService.Type() && req.IsClub == (config.Cmd.IsClub > 0) { if req.RouterKey != QueueName() { log.Info(fmt.Sprintf("新服务:%v上线,本服务等待玩家离开后关闭 req:%+v", req.RouterKey, req)) TrucoService.AutoWaitStop = true RoomMgr.DelEmptyRoom() } } } // gm解散指定房间 func onDisbandRoom(_ *amqp091.Delivery, msg map[string]interface{}) { _, _, uid, data := ParseMsg(msg) req, err := util.MapToStructT[proto.ReqDisbandRoom](data) if err != nil { log.Error(err.Error()) return } if rm := RoomMgr.Find(req.RoomId); rm != nil { rm.OnMessage(proto.ReqDisbandRoomId, msg) } else { SendMsgToGate(uid, proto.RspUserDisbandRoomId, &proto.RspUserDisbandRoom{Code: proto.NotExistRoom}) } } // 管理员解散指定房间 func onUserDisbandRoom(_ *amqp091.Delivery, msg map[string]interface{}) { _, _, uid, data := ParseMsg(msg) req, err := util.MapToStructT[proto.ReqUserDisbandRoom](data) if err != nil { log.Error(err.Error()) return } if rm := RoomMgr.Find(req.RoomId); rm != nil { rm.OnMessage(proto.ReqUserDisbandRoomId, msg) } else { SendMsgToGate(uid, proto.RspUserDisbandRoomId, &proto.RspUserDisbandRoom{Code: proto.NotExistRoom}) } }