package msg import ( "rocommon" "rocommon/service" "rocommon/util" "roserver/baseserver/model" model2 "roserver/game/model" "roserver/serverproto" ) func init() { //登陆操作并获取角色数据 serverproto.Handle_GAME_CSLoginReq = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) { msg := ev.Msg().(*serverproto.CSLoginReq) util.InfoF("receive CSLoginReq msg=%v cliId=%v", msg, cliId) if msg.OpenId == "" { ack := &serverproto.SCLoginAck{ Error: int32(serverproto.ErrorCode_ERROR_FAIL), } model.ServiceReplay(ev, ack) return } if msg.GameVersion > 0 && msg.GameVersion != int32(serverproto.GameVersion_GameVersion_Main) { ack := &serverproto.SCLoginAck{ Error: int32(serverproto.ErrorCode_ERROR_GAME_VERSION), } model.ServiceReplay(ev, ack) return } //当前区服务器总在线 if model2.RoleMag.IsGameOnlineNumLimit() { ack := &serverproto.SCLoginAck{ Error: int32(serverproto.ErrorCode_ERROR_ROLE_SERVER_LIMIT), } model.ServiceReplay(ev, ack) return } openId := model.ConvertPlatform(msg.OpenId, msg.Platform) //添加一个角色 role, cidSame, bHas := model2.RoleMag.AddRole(cliId, openId, msg.SelectZone) if cidSame && role.GetOpenId() == openId { //重新登陆处理(同一个连接不允许多次发送CSLoginReq请求) if role.GetState() != model2.ROLE_STATE_DB_ADD_ROLE_SUCCESS { ack := &serverproto.SCLoginAck{ Error: int32(serverproto.ErrorCode_ERROR_RELOGIN), } model.ServiceReplay(ev, ack) return } } if !cidSame && role.GetOpenId() == openId && bHas { kickNtf := &serverproto.SSUserKickNtf{ Error: int32(serverproto.ErrorCode_ERROR_RELOGIN), ClientId: role.CliID().SessID, } role.ReplayGate(kickNtf, false) } role.SetSubPlatform(msg.SubPlatform) role.SetPlatform(msg.Platform) role.SetClientIP(msg.Ip) role.SetSelectZone(msg.SelectZone) //客户端登陆时选择的服务器zone //利用缓存数据 if bHas { role.SetSelectZone(msg.SelectZone) //客户端登陆时选择的服务器zone if role.GetState() == model2.ROLE_STATE_ONLINE { //把之前在线的玩家踢下线 role.KickWithSave(int32(serverproto.ErrorCode_ERROR_RELOGIN)) model2.RoleMag.RemoveRoleObj(role) role.SetCliID(cliId) model2.RoleMag.AddRoleObj(role) //role.LoginAck(serverproto.ErrorCode_ERROR_OK) role.SwitchState(int32(model2.ROLE_STATE_ONLINE), true) //不需要通知消息 } else if role.GetState() == model2.ROLE_STATE_OFFLINE { //移除新建的角色信息,复用离线池中的数据 model2.RoleMag.RemoveRoleFromChannel(role.CliID().SessID) role.SetCliID(cliId) //丛离线池中移除 model2.RoleMag.RemoveOfflineRole(role.GetUUid()) model2.RoleMag.AddRoleObj(role) //role.LoginAck(serverproto.ErrorCode_ERROR_OK) role.SwitchState(int32(model2.ROLE_STATE_ONLINE), true) //不需要通知消息 } else { role.SwitchState(model2.ROLE_STATE_ZOMBIE, nil) //还没创建角色成功时,有可能发起再次登录请求操作 if role.GetUUid() > 0 { model2.RoleMag.RemoveRoleObj(role) model2.RoleMag.AddRoleObj(role) } role.SetCliID(cliId) role.SetOpenId(openId) //拉取角色列表信息 role.SwitchState(model2.ROLE_STATE_PULLING_LIST, nil) } } else { role.SetSelectZone(msg.SelectZone) //客户端登陆时选择的服务器zone role.SetOpenId(openId) //拉取角色列表信息 role.SwitchState(model2.ROLE_STATE_PULLING_LIST, nil) } }) //客户端断线重连 serverproto.Handle_GAME_CSReconnectReq = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) { msg := ev.Msg().(*serverproto.CSReconnectReq) util.InfoF("CSReconnectReq msg=%v", msg) ackMsg := &serverproto.SCReconnectAck{ Error: int32(serverproto.ErrorCode_ERROR_ROLE_INVALID), } openId := model.ConvertPlatform(msg.OpenId, msg.Platform) reconnectUid, _ := model.Str2NumU64(msg.Uid) if reconnectUid <= 0 { reconnectRole := model2.RoleMag.GetRoleByOpenId(openId) if reconnectRole != nil { reconnectUid = reconnectRole.GetUUid() } if reconnectUid <= 0 { model.ServiceReplay(ev, ackMsg) util.InfoF("uid=%v openid=%v CSReconnectReqErr uid error", reconnectUid, openId) return } } //重新绑定session相关信息 onlineRole := model2.RoleMag.GetRoleFromUUid(reconnectUid) offlineRole := model2.RoleMag.GetRoleFromOffline(reconnectUid) //存在离线数据 if offlineRole != nil { if offlineRole.GetOpenId() != openId { model.ServiceReplay(ev, ackMsg) util.InfoF("uid=%v openid=%v CSReconnectReqErr openId error reLogin", reconnectUid, openId) return } offlineRole.SetReLogin(true) offlineRole.SetCliID(cliId) //移除新建的角色信息,复用离线池中的数据 model2.RoleMag.RemoveRoleFromChannel(cliId.SessID) //丛离线池中移除 model2.RoleMag.RemoveOfflineRole(reconnectUid) model2.RoleMag.AddRoleObj(offlineRole) } else if onlineRole != nil { //存在已经登陆的玩家 if onlineRole.GetState() == model2.ROLE_STATE_ONLINE { util.InfoF("uid=%v open=%v reLogin", onlineRole.GetUUid(), onlineRole.GetOpenId()) //把之前在线的玩家踢下线 onlineRole.KickWithSave(int32(serverproto.ErrorCode_ERROR_RELOGIN)) model2.RoleMag.RemoveRoleObj(onlineRole) onlineRole.SetReLogin(true) onlineRole.SetCliID(cliId) model2.RoleMag.AddRoleObj(onlineRole) //重新登陆前作一次保存操作 onlineRole.Save() } else if onlineRole.GetState() == model2.ROLE_STATE_OFFLINE { //更新队列[RoleManager) Update]比较慢,状态已经是offline但是还没有放到offline列表中 model2.RoleMag.RemoveRoleObj(onlineRole) onlineRole.SetReLogin(true) onlineRole.SetCliID(cliId) model2.RoleMag.AddRoleObj(onlineRole) } else { //在线但是没有登陆完成,发送重连消息太快,还没放到离线列表中 util.InfoF("uid=%v openid=%v CSReconnectReqErr has not login finish yet reLogin state=%v", onlineRole.GetUUid(), openId, onlineRole.GetState()) model.ServiceReplay(ev, ackMsg) return } } role := model2.RoleMag.GetRole(cliId) if role == nil { ackMsg.Error = int32(serverproto.ErrorCode_ERROR_FAIL) model.ServiceReplay(ev, ackMsg) //kickNtf := &serverproto.SSUserKickNtf{ // Error: int32(serverproto.ErrorCode_ERROR_FAIL), // ClientId: cliId.SessID, //} //model.ServiceReplay(ev, kickNtf) //超过时限的登录操作,或者之前非正常的登录操作导致role数据不存在(服务器意外重启导致的重连) util.InfoF("CSReconnectReqErr invalid reLogin cliid=%v uid=%v openid=%v", cliId, msg.Uid, msg.OpenId) return } //这边必须要做判断 ackMsg.Error = int32(serverproto.ErrorCode_ERROR_OK) model.ServiceReplay(ev, ackMsg) role.SwitchState(int32(model2.ROLE_STATE_ONLINE), false) //不需要通知消息 }) //获取角色数据并返回 serverproto.Handle_GAME_SSAccountGetRoleListAck = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) { msg := ev.Msg().(*serverproto.SSAccountGetRoleListAck) util.DebugF("receive SSAccountGetRoleListAck msg=%v cliId=%v", msg, cliId) if len(msg.Roles) > 0 { //在线离线处理 //和管道绑定的角色 channelRole := model2.RoleMag.GetRoleFromChannel(cliId.SessID) if channelRole == nil { util.ErrorF("receive SSAccountGetRoleListAckErr msg=%v cliId=%v", msg, cliId) return } //当前在线的角色 onlineRole := model2.RoleMag.GetRoleFromUUid(msg.Roles[0].Uid) offlineRole := model2.RoleMag.GetRoleFromOffline(msg.Roles[0].Uid) //离线数据还存在 if offlineRole != nil { util.InfoF("relogin offlinerole... msguid=%v oflineuid=%v", msg.Roles[0].Uid, offlineRole.GetUUid()) offlineRole.SetReLogin(true) offlineRole.SetCliID(channelRole.CliID()) //移除新建的角色信息,复用离线池中的数据 model2.RoleMag.RemoveRoleFromChannel(cliId.SessID) //丛离线池中移除 model2.RoleMag.RemoveOfflineRole(msg.Roles[0].Uid) model2.RoleMag.AddRoleObj(offlineRole) } else if onlineRole != nil { //这边不能判断State,有可能切换成offline但是还在online列表中(update时间修改长了) //存在已经登陆的玩家 util.InfoF("relogin uuid=%v", onlineRole.GetUUid()) //把之前在线的玩家踢下线 onlineRole.SwitchState(model2.ROLE_STATE_OFFLINE, nil) model2.RoleMag.RemoveRoleObj(onlineRole) onlineRole.SetReLogin(true) onlineRole.SetCliID(channelRole.CliID()) model2.RoleMag.AddRoleObj(onlineRole) //重新登陆前作一次保存操作 onlineRole.Save() //if onlineRole.GetState() == model2.ROLE_STATE_ONLINE { // util.InfoF("relogin uuid=%v", onlineRole.GetUUid()) // //把之前在线的玩家踢下线 // onlineRole.SwitchState(model2.ROLE_STATE_OFFLINE, nil) // model2.RoleMag.RemoveRoleObj(onlineRole) // // onlineRole.SetReLogin(true) // onlineRole.SetCliID(channelRole.CliID()) // model2.RoleMag.AddRoleObj(onlineRole) // //重新登陆前作一次保存操作 // onlineRole.Save() //} else { // //在线但是没有登陆完成 // //todo... //} } } //这边可能获取到空数据 role := model2.RoleMag.GetRole(cliId) if role == nil { util.ErrorF("receive SSAccountGetRoleListAckErr openid=%v msg=%v", role.GetOpenId(), msg) return } //这边必须要做判断 roleInfo := role.(*model2.Role) if len(roleInfo.UuidList) <= 0 && len(msg.Roles) > 0 { for _, dbRole := range msg.Roles { roleInfo.UuidList = append(roleInfo.UuidList, dbRole.Uid) roleInfo.UuidRoleList[dbRole.Uid] = dbRole } } //查看服务器是否已经关闭创建角色 if len(roleInfo.UuidList) <= 0 { if msg.IsCloseRegister { roleInfo.LoginAck(serverproto.ErrorCode_ERROR_ROLE_CAN_NOT_REGISTER) roleInfo.SwitchState(model2.ROLE_STATE_ZOMBIE, nil) return } } role.SwitchState(model2.ROLE_STATE_PULLED_LIST, nil) }) serverproto.Handle_GAME_CSCreateRoleReq = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) { // 如果做成多角色系统以后由客户端发起创建角色请求[CSCreateRoleReq] //todo...安全性检查,频繁发该协议 msg := ev.Msg().(*serverproto.CSCreateRoleReq) util.InfoF("CSCreateRoleReq msg=%v cliId=%v", msg, cliId) role := model2.RoleMag.GetRole(cliId) if role == nil { ackMsg := serverproto.SCCreateRoleAck{ Error: int32(serverproto.ErrorCode_ERROR_FAIL), } model.ServiceReplay(ev, ackMsg) util.ErrorF("uid=%v err role cliId not find openId=%v", msg.OpenId) return } if role.GetState() != model2.ROLE_STATE_PULLED_LIST && role.GetState() != model2.ROLE_STATE_CREATE_FAILURE { util.ErrorF("uid=%v err role stat=%v openId=%v", role.GetUUid(), role.GetState(), msg.OpenId) return } //合法性检查 _, ok := serverproto.JobCfgLoader[msg.JobId] if !ok { ackMsg := &serverproto.SCCreateRoleAck{ Error: int32(serverproto.ErrorCode_ERROR_FAIL), } role.ReplayGate(ackMsg, true) util.ErrorF("CSCreateRoleReq JobCfgLoader not found openid=%v jobId=%v activeCode=%v", msg.OpenId, msg.JobId, msg.ActiveCode) return } //判断是否是激活码模式 sConfig := service.GetServiceConfig() if sConfig.Node.AuthMode == model2.AUTHMODE_ACTIVE { //1,判断激活码是否存在 //2,后续发给服务器判断激活码是否已经被使用 retErr := model.CheckActiveCode(msg.ActiveCode) if retErr != serverproto.ErrorCode_ERROR_OK { ackMsg := &serverproto.SCCreateRoleAck{ Error: int32(retErr), } role.ReplayGate(ackMsg, true) util.ErrorF("CSCreateRoleReq activeCode err=%v activeCode=%v openId=%v", retErr, msg.ActiveCode, msg.OpenId) return } } //创建角色 role.SetCreateData(msg) role.SwitchState(model2.ROLE_STATE_CREATE, nil) }) serverproto.Handle_GAME_SSAddRoleBaseAck = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) { msg := ev.Msg().(*serverproto.SSAddRoleBaseAck) util.InfoF("SSAddRoleBaseAck msg=%v", msg) role := model2.RoleMag.GetRole(cliId) if role == nil { return } if msg.Err == int32(serverproto.ErrorCode_ERROR_OK) { //数据库添加角色基础信息成功 role.SwitchState(model2.ROLE_STATE_DB_ADD_ROLE_SUCCESS, nil) } else if msg.Err == int32(serverproto.ErrorCode_ERROR_ROLE_HAS_CREATE) { //已经成功创建了角色 role.SwitchState(model2.ROLE_STATE_DB_ADD_ROLE_SUCCESS, nil) } else { //数据库添加角色基础信息失败 role.SwitchState(model2.ROLE_STATE_DB_ADD_ROLE_FAILURE, msg.Err) if msg.Err != int32(serverproto.ErrorCode_ERROR_ROLE_ACTIVECODE_ERROR) && msg.Err != int32(serverproto.ErrorCode_ERROR_ROLE_ACTIVECODE_USED) { role.KickNotSave(int32(serverproto.ErrorCode_ERROR_FAIL)) } } }) serverproto.Handle_GAME_SSGetRoleAck = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) { msg := ev.Msg().(*serverproto.SSGetRoleAck) role := model2.RoleMag.GetRole(cliId) if role == nil { return } if msg.Err != int32(serverproto.ErrorCode_ERROR_OK) { util.InfoF("SSGetRoleAck cliid=%v err=%v", cliId, msg.Err) role.LoginAck(serverproto.ErrorCode_ERROR_FAIL) role.KickNotSave(msg.Err) return } //be baned by webgm if msg.Role != nil && msg.Role.RoleBase.BanTime > uint64(util.GetTimeSeconds()) { //if msg.Role != nil && msg.Role.RoleBase.BanTime > 0 { util.InfoF("SSGetRoleAck cliId=%v err=%v baned", cliId, msg.Err) //role.LoginAck(serverproto.ErrorCode_ERROR_ROLE_BANED) //role.KickNotSave(msg.Err) delTime := msg.Role.RoleBase.BanTime - uint64(util.GetTimeSeconds()) retCode := role.(*model2.Role).GetRoleStatistic().GetCheatErrorCode(msg.Role.RoleBase.BanType) role.LoginAck(serverproto.ErrorCode(retCode)) role.(*model2.Role).KickWithSaveAndBan(retCode, delTime) //role.LoginAck(serverproto.ErrorCode_ERROR_ROLE_BANED) //role.(*model2.Role).KickWithSaveAndBan(int32(serverproto.ErrorCode_ERROR_ROLE_BANED), delTime) return } //加载用户数据(role中包括了各个模块的数据加载) if err := role.Load(msg.Role); err != nil { util.ErrorF("SSGetRoleAck cliid=%v err=%v", cliId, err) role.LoginAck(serverproto.ErrorCode_ERROR_FAIL) role.KickNotSave(msg.Err) return } else { //完成登陆流程(专门的协议处理加载完成事件) //role.SwitchState(int32(model2.ROLE_STATE_ONLINE), nil) } }) //加载角色数据完成 serverproto.Handle_GAME_SSGetRoleFinishNtf = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) { msg := ev.Msg().(*serverproto.SSGetRoleFinishNtf) role := model2.RoleMag.GetRole(cliId) if role == nil { return } util.DebugF("uid=%v SSGetRoleFinishNtf msg=%v", role.GetUUid(), msg) //其他系统加载数据时已经对玩家做了踢出操作,这边就不再设置成在线状态 if role.GetState() != model2.ROLE_STATE_ZOMBIE { //完成登陆流程 role.LoginAck(serverproto.ErrorCode_ERROR_OK) role.SwitchState(int32(model2.ROLE_STATE_ONLINE), true) } }) //加载竞技场数据 serverproto.Handle_GAME_SSLoadArenaNtf = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) { msg := ev.Msg().(*serverproto.SSLoadArenaNtf) //util.DebugF("SSLoadArenaNtf msg:%v", msg) role := model2.RoleMag.GetRole(cliId) if role == nil { return } if err := role.LoadOther(msg); err != nil { util.ErrorF("uid=%v SSLoadArenaNtf err=%v", role.GetUUid(), err) role.LoginAck(serverproto.ErrorCode_ERROR_FAIL) role.KickNotSave(int32(serverproto.ErrorCode_ERROR_FAIL)) return } }) ////加载邮件数据通知 from db //serverproto.Handle_GAME_SSLoadMailNtf = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) { // msg := ev.Msg().(*serverproto.SSLoadMailNtf) // util.DebugF("SSLoadMailNtf msg:%v", msg) // // role := model2.RoleMag.GetRole(cliId) // if role == nil { // return // } // // if err := role.LoadOther(msg); err != nil { // util.ErrorF("uid=%v SSLoadMailAck err=%v", role.GetUUid(), err) // role.LoginAck(serverproto.ErrorCode_ERROR_FAIL) // role.KickNotSave(int32(serverproto.ErrorCode_ERROR_FAIL)) // return // } //}) //加载好友系统数据 serverproto.Handle_GAME_SSLoadFriendDataNtf = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) { msg := ev.Msg().(*serverproto.SSLoadFriendDataNtf) util.DebugF("SSLoadFriendDataNtf msg=%v", msg) role := model2.RoleMag.GetRole(cliId) if role == nil { return } if err := role.LoadOther(msg); err != nil { util.ErrorF("uid=%v SSLoadFriendDataNtf err=%v", role.GetUUid(), err) role.LoginAck(serverproto.ErrorCode_ERROR_FAIL) role.KickNotSave(int32(serverproto.ErrorCode_ERROR_FAIL)) return } }) //加载宠物系统数据 serverproto.Handle_GAME_SSLoadPetNtf = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) { msg := ev.Msg().(*serverproto.SSLoadPetNtf) role := model2.RoleMag.GetRole(cliId) if role == nil { return } util.DebugF("uid=%v SSLoadPetNtf petLen=%v", role.GetUUid(), len(msg.Pet.PetList)) if err := role.LoadOther(msg); err != nil { util.ErrorF("uid=%v SSLoadFriendDataNtf err=%v", role.GetUUid(), err) role.LoginAck(serverproto.ErrorCode_ERROR_FAIL) role.KickNotSave(int32(serverproto.ErrorCode_ERROR_FAIL)) return } }) //加载invitation系统数据 serverproto.Handle_GAME_SSLoadInvitationDataNtf = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) { msg := ev.Msg().(*serverproto.SSLoadInvitationDataNtf) role := model2.RoleMag.GetRole(cliId) if role == nil { return } //util.DebugF("uid=%v SSLoadInvitationDataNtf msg=%v", role.GetUUid(), msg) if err := role.LoadOther(msg); err != nil { util.ErrorF("uid=%v SSLoadFriendDataNtf err=%v", role.GetUUid(), err) role.LoginAck(serverproto.ErrorCode_ERROR_FAIL) role.KickNotSave(int32(serverproto.ErrorCode_ERROR_FAIL)) return } }) //加载跨服数据 serverproto.Handle_GAME_SSLoadCrossDataNtf = model.HandleBackendMessage(func(ev rocommon.ProcEvent, cliId model.ClientID) { msg := ev.Msg().(*serverproto.SSLoadCrossDataNtf) role := model2.RoleMag.GetRole(cliId) if role == nil { return } util.DebugF("uid=%v SSLoadCrossDataNtf msg=%v", role.GetUUid(), msg) if err := role.LoadOther(msg); err != nil { util.ErrorF("uid=%v SSLoadCrossDataNtf err=%v", role.GetUUid(), err) role.LoginAck(serverproto.ErrorCode_ERROR_FAIL) role.KickNotSave(int32(serverproto.ErrorCode_ERROR_FAIL)) return } }) }