| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506 |
- package model
- import (
- "math/rand"
- "rocommon"
- "rocommon/service"
- "rocommon/util"
- "roserver/baseserver"
- "roserver/baseserver/model"
- "roserver/serverproto"
- "runtime/debug"
- "time"
- "unsafe"
- )
- //状态机枚举
- const (
- ROLE_STATE_ONLINE = 1 //在线
- ROLE_STATE_OFFLINE = 2 //离线
- ROLE_STATE_PULLING_LIST = 3 //拉取角色信息
- ROLE_STATE_PULLED_LIST = 4 //拉去角色列表完成(从db返回信息)
- ROLE_STATE_CREATE = 5 //正在创建角色
- ROLE_STATE_CREATE_SUCCESS = 6 //创建角色成功
- ROLE_STATE_CREATE_FAILURE = 7 //创建角色失败
- ROLE_STATE_DB_ADD_ROLE_SUCCESS = 8 //数据库添加角色信息成功
- ROLE_STATE_DB_ADD_ROLE_FAILURE = 9 //数据库添加角色信息失败
- ROLE_STATE_SELECT_ROLE = 10
- ROLE_STATE_SELECT_ROLE_SUCCESS = 11 //选择角色成功
- ROLE_STATE_SELECT_ROLE_FAILURE = 12 //选择角色失败
- ROLE_STATE_ZOMBIE = 13
- )
- //状态机执行信息
- //拉取角色信息
- var pullingRoleList = func(r *model.StateMachineCore, data interface{}) int32 {
- parent := unsafe.Pointer(r)
- return (*Role)(parent).pullingRoleList()
- //return ROLE_STATE_PULLING_LIST
- }
- var pulledRoleList = func(r *model.StateMachineCore, data interface{}) int32 {
- parent := unsafe.Pointer(r)
- return (*Role)(parent).pulledRoleList()
- //return ROLE_STATE_PULLED_LIST
- }
- var createRole = func(r *model.StateMachineCore, data interface{}) int32 {
- parent := unsafe.Pointer(r)
- return (*Role)(parent).createRole()
- //return ROLE_STATE_CREATE
- }
- var createDbRoleSuccess = func(r *model.StateMachineCore, data interface{}) int32 {
- parent := unsafe.Pointer(r)
- return (*Role)(parent).createDbRoleSuccess()
- //return ROLE_STATE_DB_ADD_ROLE_SUCCESS
- }
- var createDbRoleFailure = func(r *model.StateMachineCore, data interface{}) int32 {
- parent := unsafe.Pointer(r)
- return (*Role)(parent).createDbRoleFailure(data)
- //return ROLE_STATE_DB_ADD_ROLE_FAILURE
- }
- var SelectingRole = func(r *model.StateMachineCore, data interface{}) int32 {
- parent := unsafe.Pointer(r)
- return (*Role)(parent).SelectingRole()
- //return ROLE_STATE_SELECT_ROLE
- }
- var SelectRoleSuccess = func(r *model.StateMachineCore, data interface{}) int32 {
- parent := unsafe.Pointer(r)
- return (*Role)(parent).SelectRoleSuccess()
- //return ROLE_STATE_SELECT_ROLE_SUCCESS
- }
- var RoleOnline = func(r *model.StateMachineCore, data interface{}) int32 {
- parent := unsafe.Pointer(r)
- return (*Role)(parent).RoleOnline(data)
- }
- var RoleOffline = func(r *model.StateMachineCore, data interface{}) int32 {
- parent := unsafe.Pointer(r)
- return (*Role)(parent).RoleOffline()
- //return ROLE_STATE_OFFLINE
- }
- func (this *Role) pullingRoleList() int32 {
- util.DebugF("pullingRoleList... %v,%v", this.cliID, this.UuidList)
- //选择DB节点
- this.dbNode = model.SelectServiceNode(model.SERVICE_NODE_TYPE_DB_STR, 0)
- this.setUUid(0) //获取成功后会再次赋值
- //发送获取角色信息消息给db服务器
- msg := &serverproto.SSAccountGetRoleListReq{
- ChannelId: this.cliID.SessID,
- OpenId: this.openId,
- //ZoneId: int32(service.GetServiceConfig().Node.Zone),
- }
- //使用服务器选择的服务器使用
- if this.selectZone > 0 {
- msg.ZoneId = this.selectZone
- } else {
- msg.ZoneId = int32(service.GetServiceConfig().Node.Zone)
- }
- ret := this.SendDb(msg)
- if !ret {
- ackMsg := &serverproto.SCLoginAck{
- Error: int32(serverproto.ErrorCode_ERROR_FAIL),
- }
- this.ReplayGate(ackMsg, true)
- return ROLE_STATE_ZOMBIE
- }
- return ROLE_STATE_PULLING_LIST
- }
- func (this *Role) pulledRoleList() int32 {
- util.DebugF("pulledRoleList... %v,%v", this.cliID, this.UuidList)
- //角色信息不存在则创建角色信息
- if len(this.UuidList) <= 0 {
- if service.GetServiceConfig().Node.RobotMode == 2 {
- this.LoginAck(serverproto.ErrorCode_ERROR_ROLE_CAN_NOT_REGISTER)
- return ROLE_STATE_ZOMBIE
- } else {
- if service.GetServiceConfig().Node.AuthMode == AUTHMODE_ACTIVE {
- this.LoginAck(serverproto.ErrorCode_ERROR_ROLE_NOT_FOUND_NEED_ACTIVE_CODE)
- } else {
- this.LoginAck(serverproto.ErrorCode_ERROR_ROLE_NOT_FOUND)
- }
- }
- return ROLE_STATE_PULLED_LIST
- } else {
- //默认选择第一个,如果后续做成多角色系统,由客户端发起选择操作
- this.SetSelectUUid(this.UuidList[0])
- //this.SwitchState(ROLE_STATE_SELECT_ROLE, nil)
- return ROLE_STATE_SELECT_ROLE
- }
- }
- func (this *Role) createRole() int32 {
- this.setUUid(model.GenerateUidByZone(int(this.GetSelectZone())))
- //生成唯一索引ID失败
- if this.GetUUid() <= 0 {
- msg := &serverproto.SCCreateRoleAck{
- Error: int32(serverproto.ErrorCode_ERROR_FAIL),
- }
- util.InfoF("createRole err uid invalid!!!")
- this.ReplayGate(msg, true)
- return ROLE_STATE_CREATE_FAILURE
- }
- RoleMag.Resolve(this)
- data := this.base.roleBase
- msg := &serverproto.SSAddRoleBaseReq{}
- //初始化创建角色数据
- msg.Base = &serverproto.RoleBase{
- Id: this.uuid,
- Coin: 0, //默认值通过配置表处理
- Rmb: 0,
- NickName: "",
- Sex: data.Sex,
- Country: data.Country,
- GuideId: 0,
- RoleData: &serverproto.RoleData{
- HeroData: &serverproto.HeroData{
- Id: 1,
- BaseLevel: 1,
- ConfigId: data.RoleData.HeroData.ConfigId,
- IsBattle: true,
- Skill: &serverproto.RoleSkill{},
- Slot: &serverproto.SlotData{
- HeroId: 1,
- },
- SkillEquipSlot: &serverproto.SkillEquipSlotData{
- HeroId: 1,
- },
- },
- },
- FashionData: data.FashionData,
- }
- //激活码
- msg.ActiveCode = this.activeCode
- msg.OpenId = this.GetOpenId()
- msg.SubPlatform = this.GetSubPlatform()
- msg.Zone = this.GetSelectZone()
- this.SendDb(msg)
- return ROLE_STATE_CREATE
- }
- type OpenIdServeNode struct {
- ServerId int32
- HeadFrameId int32
- Level int32
- JobCfgId int32
- Gender int32
- NickName string
- }
- func (this *Role) createDbRoleSuccess() int32 {
- //todo...流程上有问题,这边需要返回成功才能做后续操作
- //角色基本信息添加成功后再添加到openId对应的玩家列表中(多角色登录处理)
- msg := &serverproto.SSAccountAddRoleNtf{}
- accRole := &serverproto.AccountRole{}
- accRole.Uid = this.GetUUid()
- accRole.OpenId = this.GetOpenId()
- accRole.RegisterTime = util.GetTimeMilliseconds()
- if this.GetSelectZone() > 0 {
- accRole.ZoneId = this.GetSelectZone()
- } else {
- accRole.ZoneId = int32(service.GetServiceConfig().Node.Zone)
- }
- msg.Roles = append(msg.Roles, accRole)
- util.DebugF("uid=%v SSAccountAddRoleNtf send to db ", accRole.Uid)
- this.SendDb(msg)
- //todo...
- // 默认选择创建的角色,后续做成多角色的话需要客户端发起选择角色操作
- // 注意以后合区操作
- this.UuidList = append(this.UuidList, this.GetUUid())
- this.UuidRoleList[this.GetUUid()] = accRole
- this.SetSelectUUid(this.GetUUid())
- this.setUUid(this.GetUUid())
- //创建角色成功后发送给roweb服务器记录当前openID登录的服务器信息
- this.registerServerList(0, 1)
- //创建角色成功,发送给客户端用户sdk处理
- createMsg := &serverproto.SCCreateRoleAck{
- Error: int32(serverproto.ErrorCode_ERROR_OK),
- CreateRoleTime: accRole.RegisterTime,
- Uid: accRole.Uid,
- Gender: this.GetRoleBase().GetRoleSex(),
- }
- this.ReplayGate(createMsg, true)
- this.roleTask.AddTypeCnt(serverproto.TaskType_Eve_Login_Day, 1)
- return ROLE_STATE_SELECT_ROLE
- }
- func (this *Role) createDbRoleFailure(data interface{}) int32 {
- msg := &serverproto.SCCreateRoleAck{}
- //msg.Error = data.(int32)
- msg.Error = int32(serverproto.ErrorCode_ERROR_FAIL)
- //log.Println("[createDbRoleFailure]")
- util.InfoF("createDbRoleFailure")
- this.ReplayGate(msg, true)
- return ROLE_STATE_CREATE_FAILURE
- }
- func (this *Role) SelectingRole() int32 {
- //检查合法性
- valid := false
- for _, data := range this.UuidList {
- if data == this.SelectedUuid {
- valid = true
- break
- }
- }
- if !valid {
- this.LoginAck(serverproto.ErrorCode_ERROR_FAIL)
- util.InfoF("select role not found uuid=%v", this.SelectedUuid)
- return ROLE_STATE_ZOMBIE
- }
- this.setUUid(this.SelectedUuid)
- return ROLE_STATE_SELECT_ROLE_SUCCESS
- }
- func (this *Role) SelectRoleSuccess() int32 {
- //非创建流程时,此时才获得角色的uuid
- RoleMag.Resolve(this)
- //缓存数据处理
- if !this.reLogin {
- //获取角色信息其他信息
- msg := &serverproto.SSGetRoleReq{
- RoleRegisterTime: this.RegisterTime,
- }
- this.SendDb(msg)
- } else {
- //数据在缓存中,直接切换成在线状态
- //this.LoginAck(serverproto.ErrorCode_ERROR_OK)
- return ROLE_STATE_ONLINE
- }
- return ROLE_STATE_SELECT_ROLE_SUCCESS
- }
- func (this *Role) RoleOnline(data interface{}) int32 {
- if !this.isLoad {
- this.KickNotSave(int32(serverproto.ErrorCode_ERROR_FAIL))
- return ROLE_STATE_ZOMBIE
- }
- //be baned by webgm
- banTime := this.isBan()
- if banTime > 0 {
- this.LoginAck(serverproto.ErrorCode_ERROR_ROLE_BANED)
- this.KickWithSaveAndBan(int32(serverproto.ErrorCode_ERROR_ROLE_BANED), banTime)
- return ROLE_STATE_ZOMBIE
- }
- this.LoginAck(serverproto.ErrorCode_ERROR_OK)
- this.tmpState = true
- //每日5点重置
- if this.isDailyReset() {
- this.DailyReset(false)
- }
- this.GetRoleBase().SetLastLoginTime()
- //记录最近在线玩家列表
- RoleMag.AddFIFOList(this.GetUUid())
- //如果是从离线池中获取,停止离线定时器
- this.offlineTimer.Cancel()
- //启动数据保存定时器
- nowTime := util.GetTimeMilliseconds()
- this.saveTimer.Reset(nowTime, roleSaveTimeout, false)
- this.mysqlLogSaveTimer.Reset(nowTime, mysqlSaveTimeout, false)
- this.onlineProcess(this.reLogin)
- //断线重连时不需要重新下发
- //if data == nil || data.(bool) {
- // this.StartupProto()
- //}
- //暂时处理成全量下发
- this.StartupProto()
- //获取创建角色时的奖励
- //新注册的系统邮件需求
- this.createRoleReward()
- this.registerServerList(this.GetRoleBase().RoleData().HeadFrameId, this.GetRoleLevel())
- ///////////////////////////////
- //通知social,玩家上线
- this.playerSocialOnline()
- //上线请求公会信息//不一定是重登陆,有可能是顶号
- /*//客户端确定会发,不需要做保底
- reqMsg := &serverproto.SSOnlineGuildInfoReq{}
- reqMsg.Uid = this.GetUUid()
- reqMsg.GuildId = this.GetRoleGuildId()
- reqMsg.IsRelogin = true
- this.SendGuild(reqMsg)
- */
- if this.reLogin {
- this.playerGuildOnline(1)
- }
- this.reLogin = false
- if runeExplore := this.GetRoleRune(); runeExplore != nil {
- runeExplore.RuneExploreEndAward()
- }
- util.InfoF("uuid=%v RoleOnline", this.uuid)
- return ROLE_STATE_ONLINE
- }
- func (this *Role) RoleOffline() int32 {
- ////发送logout给客户端
- //ntf := &serverproto.SCLogoutNtf{
- // Error: int32(serverproto.ErrorCode_ERROR_OK),
- //}
- //this.ReplayGate(ntf, true)
- //log.Println("[RoleOffline]SSUserKickNtf sessionID:",this.CliID().SessID)
- if this.GetState() != ROLE_STATE_ONLINE {
- return ROLE_STATE_ZOMBIE
- }
- //通知gate踢人,并且不再反向通知logic服务器
- kickNtf := &serverproto.SSUserKickNtf{
- Error: int32(serverproto.ErrorCode_ERROR_OK),
- ClientId: this.CliID().SessID,
- }
- this.ReplayGate(kickNtf, false)
- this.GetRoleBase().OfflineOnlineTimeProcess()
- //设置离线时间
- onlineDuration := this.GetRoleBase().SetLastLoginTime()
- //更新简介信息中的离线时间
- this.GetRoleBase().UpdatePlayerBriefInfo(true)
- //this.Save() 主update中会进行离线超时保存操作,避免每次下线都进行数据库保存操作
- this.saveTimer.Cancel()
- //避免大批量离线操作
- this.offlineTimer.Reset(util.GetTimeMilliseconds(), roleOfflineTimeout+time.Duration(rand.Int31n(500)), false)
- ///////////////////////////////
- model.ElasticPutLogInfo(&model.ElasticLogST{
- Uid: this.GetUUid(),
- NickName: this.GetNickName(),
- OpenId: this.GetOpenId(),
- LogType: "RoleOffline",
- LogDesc: "RoleOffline",
- Param1: int(onlineDuration / 1000), //当前在线时间
- })
- this.MysqlLogNtf(serverproto.MysqlLogType_LType_Offline, []int32{int32(onlineDuration / 1000)}, 0)
- //通知social,玩家下线
- this.playerSocialOffline()
- //玩家离开世界boss
- this.PlayerBattleBossOffline()
- //离开aoi地图
- //客户端没有发送离开协议,直接断开网络处理(下次重新进入,还是说需要断线重连后也在AOI地图中)
- this.playerMapOffline()
- //下线公会处理
- this.playerGuildOnline(2)
- // battle下线处理
- this.playerBattleOffline()
- //注册到服务器列表(获取最近登录的服务器)
- this.registerServerList(this.GetRoleBase().RoleData().HeadFrameId, this.GetRoleLevel())
- //netease log
- nLog := &NeteaseLogCreateRole{
- OnlineTime: int(onlineDuration / 1000),
- }
- nLog.Log(this)
- //log.Println("role offline uid:", this.GetUUid())
- return ROLE_STATE_OFFLINE
- }
- func (this *Role) createRoleReward() {
- //获取创建角色时的奖励
- //新注册的系统邮件需求
- if this.base.roleBase != nil && !this.base.roleBase.CreateReward {
- this.base.roleBase.CreateReward = true
- this.base.SetDirty(true)
- this.GetRoleMail().AddMail(17, serverproto.MailType_MailType_System,
- model.GlobalCreateRoleMailReward, nil, "", "")
- this.roleBag.AddItemList(model.GlobalCreateItemList, AddItemST{AddFrom: AddFrom_CreateRole, Notify: true})
- }
- }
- func (this *Role) LoginAck(err serverproto.ErrorCode) {
- ack := &serverproto.SCLoginAck{
- ClientId: this.cliID.SessID,
- Error: int32(err),
- }
- if err == serverproto.ErrorCode_ERROR_OK {
- this.ReplayGate(ack, false) //gate需要做特殊处理使用
- }
- this.ReplayGate(ack, true)
- }
- func (this *Role) registerServerList(headFrameId, level int32) {
- if headFrameId == 0 {
- //注册日志,添加到elasticsearch
- model.ElasticPutLogInfo(&model.ElasticLogST{
- Uid: this.GetUUid(),
- NickName: this.GetNickName(),
- OpenId: this.GetOpenId(),
- LogType: "RoleRegister",
- LogDesc: "RoleOnline",
- })
- }
- jobCfgId := this.GetRoleBase().RoleData().HeroData.ConfigId
- if headFrameId == 0 {
- headFrameId = this.GetRoleBase().RoleData().HeadFrameId
- }
- zoneId := int32(service.GetServiceConfig().Node.Zone)
- if this.GetSelectZone() > 0 {
- zoneId = this.GetSelectZone()
- }
- gender := this.GetRoleBase().GetRoleSex() //1 female 2 male
- nickName := this.GetNickName()
- //tmpOpenId := model.ConvertPlatform(this.GetOpenId(), this.GetPlatform())
- urlPath := "/serverlist/add?openid=" + this.GetOpenId()
- uuid := this.GetUUid()
- go func() {
- defer func() {
- //打印奔溃信息
- if err := recover(); err != nil {
- util.InfoF("onError data=%v \n%s\n", err, string(debug.Stack()))
- }
- }()
- tmpRequest := &rocommon.HTTPRequest{}
- tmpRequest.ReqCodecName = "httpform"
- tmpRequest.ReqMsg = OpenIdServeNode{
- ServerId: zoneId,
- HeadFrameId: headFrameId,
- Level: level, //默认1级
- //RecordTime: uint32(util.GetTimeSeconds()),
- JobCfgId: jobCfgId,
- Gender: gender,
- NickName: nickName,
- }
- parm := GetHttpNodeParam()
- httpNode := baseserver.CreateHttpConnector(parm)
- err := httpNode.(rocommon.HTTPConnector).Request("POST", urlPath, tmpRequest)
- if err != nil {
- util.InfoF("uid=%v http Request err=%v", uuid, err)
- }
- }()
- }
- //礼包码获取奖励
- func (this *Role) GetGiftReward(giftCode string) {
- }
|