actor_agent.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. package user
  2. import (
  3. actorRemote "f1-game/internal/actor_remote"
  4. "f1-game/internal/code"
  5. "f1-game/internal/constant"
  6. "f1-game/internal/data"
  7. "f1-game/internal/extend/token"
  8. nameActor "f1-game/internal/name/actor"
  9. nameLocal "f1-game/internal/name/local"
  10. nameRemote "f1-game/internal/name/remote"
  11. "f1-game/internal/pb"
  12. "f1-game/internal/sessions"
  13. "f1-game/nodes/gate/cache"
  14. "time"
  15. cstring "github.com/cherry-game/cherry/extend/string"
  16. ctime "github.com/cherry-game/cherry/extend/time"
  17. cfacade "github.com/cherry-game/cherry/facade"
  18. clog "github.com/cherry-game/cherry/logger"
  19. "github.com/cherry-game/cherry/net/parser/pomelo"
  20. cproto "github.com/cherry-game/cherry/net/proto"
  21. cprofile "github.com/cherry-game/cherry/profile"
  22. "go.uber.org/zap/zapcore"
  23. )
  24. type (
  25. actorAgent struct {
  26. pomelo.ActorBase
  27. agent *pomelo.Agent
  28. }
  29. )
  30. func newChildAgent(agent *pomelo.Agent) *actorAgent {
  31. return &actorAgent{
  32. agent: agent,
  33. }
  34. }
  35. func (p *actorAgent) AliasID() string {
  36. return p.agent.SID()
  37. }
  38. func (p *actorAgent) OnInit() {
  39. p.agent.AddOnClose(p.OnSessionClose)
  40. p.Local().Register(nameLocal.User_Login, p.login)
  41. p.Remote().Register(nameRemote.User_SetSession, p.setSession)
  42. p.Remote().Register(nameRemote.Game_UpdateTimeOffset, p.updateTimeOffset)
  43. }
  44. func (p *actorAgent) login(session *cproto.Session, req *pb.UserLoginRequest) {
  45. if p.agent == nil {
  46. p.ResponseCode(session, code.AccountLoginBindUserError)
  47. return
  48. }
  49. // debug模式是前端选服,验证gameNodeID 是否传值
  50. if cprofile.Debug() {
  51. if req.GameNodeID == "" {
  52. p.ResponseCode(session, code.NodeGameNodeIDIsEmpty)
  53. return
  54. }
  55. }
  56. // 验证token
  57. userToken, errCode := p.validateToken(req.Token)
  58. if code.IsFail(errCode) {
  59. p.ResponseCode(session, errCode)
  60. return
  61. }
  62. // 验证pid 是否配置
  63. sdkRow := data.SDK.Get(userToken.PID)
  64. if sdkRow == nil {
  65. p.ResponseCode(session, code.AccountLoginPIDError)
  66. return
  67. }
  68. // 根据pid openid获取uid
  69. uid, errCode := actorRemote.CenterPlayer.GetUID(sdkRow.SdkID, userToken.PID, userToken.OpenID)
  70. if uid < 1 || code.IsFail(errCode) {
  71. p.ResponseCode(session, errCode)
  72. return
  73. }
  74. // 检查game节点是否可以进入
  75. errCode = checkNodeState(constant.NodeGame, req.GameNodeID, nameActor.GameOps, uid, session.Ip)
  76. if code.IsFail(errCode) {
  77. p.ResponseCode(session, errCode)
  78. return
  79. }
  80. // uid和session绑定
  81. oldAgent, err := pomelo.Bind(session.Sid, uid)
  82. if err != nil {
  83. clog.Warn(err)
  84. p.ResponseCode(session, code.AccountLoginBindUserError)
  85. return
  86. }
  87. // 踢掉旧的agent
  88. if oldAgent != nil {
  89. oldAgent.Kick(upa.duplicateLoginCode, true)
  90. }
  91. p.kickGateSession(uid)
  92. // 在agent存储当前player相关的信息,用于路由、日志记录等
  93. p.agent.Session().Set(sessions.GameNodeID, cstring.ToString(req.GameNodeID))
  94. p.agent.Session().Set(sessions.PID, cstring.ToString(userToken.PID))
  95. p.agent.Session().Set(sessions.OpenID, userToken.OpenID)
  96. response := &pb.UserLoginResponse{
  97. Uid: uid,
  98. Pid: userToken.PID,
  99. OpenID: userToken.OpenID,
  100. GameNodeID: req.GameNodeID,
  101. Params: req.GetParams(), // TODO 后续可以针对 pid读取一些参数返回给客户端
  102. }
  103. if clog.Enable(zapcore.DebugLevel) {
  104. clog.Debugf("user login. gameNodeID = %s, pid = %d, open_id = %s, response = %v",
  105. req.GameNodeID,
  106. userToken.PID,
  107. userToken.OpenID,
  108. response,
  109. )
  110. }
  111. p.Response(session, response)
  112. }
  113. func (p *actorAgent) setSession(req *pb.StrStrList) {
  114. if p.agent == nil {
  115. clog.Warnf("agent is nil. sid = %s", p.AliasID())
  116. return
  117. }
  118. for _, param := range req.List {
  119. if cstring.IsBlank(param.Value) {
  120. p.agent.Session().Remove(param.Key)
  121. } else {
  122. p.agent.Session().Set(param.Key, param.Value)
  123. }
  124. }
  125. // 更新agnet缓存
  126. cache.UpdateAgent(p.agent)
  127. // 推送session到目标节点
  128. for _, param := range req.List {
  129. if parserFunc, found := upa.GetSyncParser(param.Key); found {
  130. parserFunc(p, p.agent.Session(), true)
  131. }
  132. }
  133. }
  134. func (p *actorAgent) validateToken(base64Token string) (*token.Token, int32) {
  135. userToken, ok := token.DecodeToken(base64Token)
  136. if !ok || userToken.PID < 1 || len(userToken.OpenID) < 1 {
  137. clog.Warnf("base64Token = %s", base64Token)
  138. return nil, code.AccountUnmarshalError
  139. }
  140. sdkRow := data.SDK.Get(userToken.PID)
  141. if sdkRow == nil {
  142. return nil, code.PIDError
  143. }
  144. statusCode, ok := token.Validate(userToken, sdkRow.Salt)
  145. if !ok {
  146. return nil, statusCode
  147. }
  148. return userToken, code.OK
  149. }
  150. func (p *actorAgent) kickGateSession(uid cfacade.UID) {
  151. // 遍历所有网关节点,踢除旧的session
  152. uids := []int64{uid}
  153. sessions.KickUIDS(uids, upa.duplicateLoginCode, true, p.App().NodeID())
  154. }
  155. func (p *actorAgent) OnSessionClose(_ *pomelo.Agent) {
  156. cache.RemoveAgent(p.agent)
  157. // 推送session到目标节点
  158. for _, parserFunc := range upa.nodeSyncMap {
  159. parserFunc(p, p.agent.Session(), false)
  160. }
  161. // 释放agenet
  162. p.agent = nil
  163. // 自己退出
  164. p.Exit()
  165. }
  166. // 更新时间偏移量
  167. func (p *actorAgent) updateTimeOffset(req *pb.I64) {
  168. offset := req.Value
  169. ctime.AddOffsetTime(time.Duration(offset) * time.Second)
  170. clog.Warn("[updateTimeOffset] offset = %d, time = %d", offset, ctime.Now().ToSecond())
  171. }
  172. func (p *actorAgent) GetPlayerID() int64 {
  173. return sessions.GetPlayerID(p.agent.Session())
  174. }
  175. func (p *actorAgent) GetGameNodeID() string {
  176. return sessions.GetGameNodeID(p.agent.Session())
  177. }
  178. func (p *actorAgent) GetMapNodeID() string {
  179. return sessions.GetMapNodeID(p.agent.Session())
  180. }