package handler import ( "ecs/proto" "ecs/proto/pb" "ecs/servers/game/data" "ecs/servers/game/logic" "github.com/oylshe1314/framework/client/rpc" "github.com/oylshe1314/framework/net" "github.com/oylshe1314/framework/server" "github.com/oylshe1314/framework/util" ) type userAuthContext struct { newId uint64 players []*logic.Player verifyAck *proto.MsgUserTokenVerifyAck } type MessageHandler struct { Handler } func NewMessageHandler(svr server.Server, httpRpcClient rpc.HttpRpcClient, tables *data.Tables, eventManager *logic.EventManager, serverManager *logic.ServerManager, playerManager *logic.PlayerManager) *MessageHandler { return &MessageHandler{ Handler: Handler{ server: svr, httpRpcClient: httpRpcClient, tables: tables, eventManager: eventManager, serverManager: serverManager, playerManager: playerManager}, } } func (this *MessageHandler) TipNotice(conn *net.Conn, err error) error { //return conn.Send(uint16(pb.ModId_ModuleCommon), uint16(pb.MsgId_ModCommonTipNotice), &proto.MsgTipNoticeAck{Message: this.tables.TipNotice.GetLang(err.Error(), int(proto.LanguageSimpleChinese))}) return conn.Send(uint16(pb.ModId_ModuleCommon), uint16(pb.MsgId_ModCommonTipNotice), &pb.TipNoticeAck{Message: err.Error()}) } func (this *MessageHandler) HandleConnect(conn *net.Conn) { conn.Beating(uint16(pb.ModId_ModuleCommon), uint16(pb.MsgId_ModCommonHeartbeat), 60) } func (this *MessageHandler) HandleDisconnect(conn *net.Conn) { var object = conn.Object() if object == nil { return } player, ok := object.(*logic.Player) if !ok { return } this.playerManager.Lost(player) this.eventManager.PlayerLogin(player, logic.LogTypePlayerLost, 0, conn.RemoteAddr()) } func (this *MessageHandler) Heartbeat(msg *net.Message) { var req = new(pb.HeartbeatReq) var err = msg.Read(req) if err != nil { this.Logger().Error(err) _ = this.TipNotice(msg.Conn, proto.ErrMessageError) return } var now = util.NowUnix() msg.Conn.Beat(now) var ack = &pb.HeartbeatAck{Index: req.Index, ServerTime: now} _ = msg.Reply(ack) } func (this *MessageHandler) UserAuth(msg *net.Message) { var req = new(pb.UserAuthReq) var err = msg.Read(req) if err != nil { this.Logger().Error(err) _ = this.TipNotice(msg.Conn, proto.ErrMessageError) return } if len(req.Token) == 0 { this.Logger().Error("User auth token is empty") _ = this.TipNotice(msg.Conn, proto.ErrInvalidToken) return } var verifyReq = &proto.MsgUserTokenVerifyReq{Token: req.GetToken(), ServerId: this.serverManager.Config().AreaConfig.Id} if this.Logger().IsDebugEnabled() { this.Logger().Debugf("[user:/verify/token] -> verifyReq: %s", util.ToJsonString(verifyReq)) } var verifyAck = new(proto.MsgUserTokenVerifyAck) reply, err := this.httpRpcClient.RandPost("user", "/verify/token", nil, verifyReq, verifyAck) if err != nil { this.Logger().Error(err) _ = this.TipNotice(msg.Conn, proto.ErrInternalError) return } if err = reply.Error(); err != nil { this.Logger().Error(reply.Message) _ = this.TipNotice(msg.Conn, err) return } if reply.Data == nil { this.Logger().Error("User auth token verify error, reply.Data == nil") _ = this.TipNotice(msg.Conn, proto.ErrInvalidToken) return } if this.Logger().IsDebugEnabled() { this.Logger().Debugf("[user:/verify/token] <- verifyAck: %s", util.ToJsonString(verifyAck)) } if !proto.CheckPlatform(verifyAck.Platform) { this.Logger().Error("User auth token verify ack platform error, platfrom: ", verifyAck.Platform) _ = this.TipNotice(msg.Conn, proto.ErrInternalError) return } if !proto.CheckChannel(verifyAck.Channel) { this.Logger().Error("User auth token verify ack channel error, channel: ", verifyAck.Channel) _ = this.TipNotice(msg.Conn, proto.ErrInternalError) return } players, err := this.playerManager.QueryPlayers(verifyAck.UserId) //query player from database if err != nil { this.Logger().Error(err) _ = this.TipNotice(msg.Conn, proto.ErrInternalError) return } var roleList []*pb.Role for i := range players { if players[i].BanningTime < 0 || players[i].BanningTime > util.NowUnix() { this.Logger().Error("Player role banned, roleId: %d, banTime: %d", players[i].RoleId, players[i].BanningTime) continue } var player = this.playerManager.GetPlayer(players[i].RoleId) //get player from memory if player != nil { this.playerManager.Kick(player, proto.ErrLoginOtherPlace.Error()) this.eventManager.PlayerLogin(player, logic.LogTypePlayerKickOut, 0, player.Temp.Address) player = nil } roleList = append(roleList, &pb.Role{Id: players[i].RoleId, Name: players[i].RoleName, Gender: players[i].RoleGender}) } msg.Conn.BindObject(&userAuthContext{players: players, verifyAck: verifyAck}) var ack = &pb.UserAuthAck{UserId: verifyAck.UserId, RoleList: roleList} _ = msg.Reply(ack) } func (this *MessageHandler) RoleCreate(msg *net.Message) { var object = msg.Conn.Object() if object == nil { _ = this.TipNotice(msg.Conn, proto.ErrUserNotLogin) return } authCtx, ok := object.(*userAuthContext) if !ok { _ = this.TipNotice(msg.Conn, proto.ErrBadRequest) return } if len(authCtx.players) >= this.serverManager.Config().MaxRoles { _ = this.TipNotice(msg.Conn, proto.ErrRolesAlreadyMax) return } var req = new(pb.RoleCreateReq) var err = msg.Read(req) if err != nil { this.Logger().Error(err) _ = this.TipNotice(msg.Conn, proto.ErrMessageError) return } if len(req.Name) == 0 { this.Logger().Error("Parameter error, req.Name can not be empty") _ = this.TipNotice(msg.Conn, proto.ErrParameterError) return } if req.Gender != 0 && req.Gender != 1 { this.Logger().Error("Parameter error, req.Gender: ", req.Gender) _ = this.TipNotice(msg.Conn, proto.ErrParameterError) return } roleId, err := this.playerManager.NewRoleId() if err != nil { this.Logger().Error(err) _ = this.TipNotice(msg.Conn, proto.ErrInternalError) return } var areaConfig = this.serverManager.Config().AreaConfig var player = this.playerManager.NewPlayer() player.RoleId = roleId player.Platform = authCtx.verifyAck.Platform player.Channel = authCtx.verifyAck.Channel player.UserId = authCtx.verifyAck.UserId player.ServerId = areaConfig.Id player.Username = authCtx.verifyAck.Username player.CreateTime = util.NowUnix() player.Language = 0 player.RoleName = req.Name player.RoleGender = req.Gender err = this.playerManager.SavePlayer(player) if err != nil { this.Logger().Error(err) _ = this.TipNotice(msg.Conn, proto.ErrInternalError) return } authCtx.newId = player.RoleId authCtx.players = append(authCtx.players, player) _ = msg.Reply(&pb.RoleCreateAck{Role: &pb.Role{Id: player.RoleId, Name: player.RoleName, Gender: player.RoleGender}}) this.eventManager.PlayerCreate(player, logic.LogTypePlayerRoleCreate) } func (this *MessageHandler) RoleLogin(msg *net.Message) { var object = msg.Conn.Object() if object == nil { _ = this.TipNotice(msg.Conn, proto.ErrUserNotLogin) return } authCtx, ok := object.(*userAuthContext) if !ok { _ = this.TipNotice(msg.Conn, proto.ErrBadRequest) return } if len(authCtx.players) == 0 { _ = this.TipNotice(msg.Conn, proto.ErrRoleNotCreated) return } var req = new(pb.RoleLoginReq) var err = msg.Read(req) if err != nil { this.Logger().Error(err) _ = this.TipNotice(msg.Conn, proto.ErrMessageError) return } if req.RoleId == 0 { this.Logger().Error("Parameter error, req.RoleId: ", req.RoleId) _ = this.TipNotice(msg.Conn, proto.ErrParameterError) return } var player *logic.Player for i := range authCtx.players { if authCtx.players[i].RoleId == req.RoleId { player = authCtx.players[i] if player.RoleId != authCtx.newId { player, err = this.playerManager.QueryPlayer(req.RoleId) if err != nil { this.Logger().Error(err) _ = this.TipNotice(msg.Conn, proto.ErrInternalError) return } } break } } if player == nil { this.Logger().Error("Parameter error, req.RoleId: ", req.RoleId) _ = this.TipNotice(msg.Conn, proto.ErrRoleNotFound) return } player.Temp.Address = msg.Conn.RemoteAddr() msg.Conn.BindObject(player) this.playerManager.Enter(player, msg.Conn) this.eventManager.PlayerLogin(player, logic.LogTypePlayerRoleLogin, 0, msg.Conn.RemoteAddr()) } func (this *MessageHandler) RoleLogout(msg *net.Message) { var object = msg.Conn.Object() if object == nil { return } msg.Conn.ClearObject() player, ok := object.(*logic.Player) if !ok { return } this.playerManager.Exit(player) this.eventManager.PlayerLogin(player, logic.LogTypePlayerRoleLogout, 0, msg.Conn.RemoteAddr()) } func (this *MessageHandler) Reconnect(msg *net.Message) { var req = new(pb.ReconnectReq) var err = msg.Read(req) if err != nil { this.Logger().Error(err) _ = this.TipNotice(msg.Conn, proto.ErrMessageError) _ = msg.Conn.Send(uint16(pb.ModId_ModuleLevel), uint16(pb.MsgId_ModLevelSceneEnter), &pb.SceneEnterAck{SceneId: 2}) return } var player = this.playerManager.GetPlayer(req.RoleId) if player == nil { _ = this.TipNotice(msg.Conn, proto.ErrUserNotLogin) _ = msg.Conn.Send(uint16(pb.ModId_ModuleLevel), uint16(pb.MsgId_ModLevelSceneEnter), &pb.SceneEnterAck{SceneId: 2}) return } player.Temp.Address = msg.Conn.RemoteAddr() msg.Conn.BindObject(player) this.playerManager.Reenter(player, msg.Conn) this.eventManager.PlayerLogin(player, logic.LogTypePlayerReconnect, 0, msg.Conn.RemoteAddr()) } func (this *MessageHandler) Message(msg *net.Message) { var object = msg.Conn.Object() if object == nil { _ = this.TipNotice(msg.Conn, proto.ErrUserNotLogin) return } player, ok := object.(*logic.Player) if !ok { _ = this.TipNotice(msg.Conn, proto.ErrRoleNotLogged) return } //player = this.playerManager.GetPlayer(player.UserId) //if player == nil { // _ = this.TipNotice(msg.Conn, proto.ErrRoleNotLogged) // return //} this.playerManager.Handle(player, msg) }