| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- package user
- import (
- actorRemote "f1-game/internal/actor_remote"
- "f1-game/internal/code"
- "f1-game/internal/constant"
- "f1-game/internal/data"
- "f1-game/internal/extend/token"
- nameActor "f1-game/internal/name/actor"
- nameLocal "f1-game/internal/name/local"
- nameRemote "f1-game/internal/name/remote"
- "f1-game/internal/pb"
- "f1-game/internal/sessions"
- "f1-game/nodes/gate/cache"
- "time"
- cstring "github.com/cherry-game/cherry/extend/string"
- ctime "github.com/cherry-game/cherry/extend/time"
- cfacade "github.com/cherry-game/cherry/facade"
- clog "github.com/cherry-game/cherry/logger"
- "github.com/cherry-game/cherry/net/parser/pomelo"
- cproto "github.com/cherry-game/cherry/net/proto"
- cprofile "github.com/cherry-game/cherry/profile"
- "go.uber.org/zap/zapcore"
- )
- type (
- actorAgent struct {
- pomelo.ActorBase
- agent *pomelo.Agent
- }
- )
- func newChildAgent(agent *pomelo.Agent) *actorAgent {
- return &actorAgent{
- agent: agent,
- }
- }
- func (p *actorAgent) AliasID() string {
- return p.agent.SID()
- }
- func (p *actorAgent) OnInit() {
- p.agent.AddOnClose(p.OnSessionClose)
- p.Local().Register(nameLocal.User_Login, p.login)
- p.Remote().Register(nameRemote.User_SetSession, p.setSession)
- p.Remote().Register(nameRemote.Game_UpdateTimeOffset, p.updateTimeOffset)
- }
- func (p *actorAgent) login(session *cproto.Session, req *pb.UserLoginRequest) {
- if p.agent == nil {
- p.ResponseCode(session, code.AccountLoginBindUserError)
- return
- }
- // debug模式是前端选服,验证gameNodeID 是否传值
- if cprofile.Debug() {
- if req.GameNodeID == "" {
- p.ResponseCode(session, code.NodeGameNodeIDIsEmpty)
- return
- }
- }
- // 验证token
- userToken, errCode := p.validateToken(req.Token)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- // 验证pid 是否配置
- sdkRow := data.SDK.Get(userToken.PID)
- if sdkRow == nil {
- p.ResponseCode(session, code.AccountLoginPIDError)
- return
- }
- // 根据pid openid获取uid
- uid, errCode := actorRemote.CenterPlayer.GetUID(sdkRow.SdkID, userToken.PID, userToken.OpenID)
- if uid < 1 || code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- // 检查game节点是否可以进入
- errCode = checkNodeState(constant.NodeGame, req.GameNodeID, nameActor.GameOps, uid, session.Ip)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- // uid和session绑定
- oldAgent, err := pomelo.Bind(session.Sid, uid)
- if err != nil {
- clog.Warn(err)
- p.ResponseCode(session, code.AccountLoginBindUserError)
- return
- }
- // 踢掉旧的agent
- if oldAgent != nil {
- oldAgent.Kick(upa.duplicateLoginCode, true)
- }
- p.kickGateSession(uid)
- // 在agent存储当前player相关的信息,用于路由、日志记录等
- p.agent.Session().Set(sessions.GameNodeID, cstring.ToString(req.GameNodeID))
- p.agent.Session().Set(sessions.PID, cstring.ToString(userToken.PID))
- p.agent.Session().Set(sessions.OpenID, userToken.OpenID)
- response := &pb.UserLoginResponse{
- Uid: uid,
- Pid: userToken.PID,
- OpenID: userToken.OpenID,
- GameNodeID: req.GameNodeID,
- Params: req.GetParams(), // TODO 后续可以针对 pid读取一些参数返回给客户端
- }
- if clog.Enable(zapcore.DebugLevel) {
- clog.Debugf("user login. gameNodeID = %s, pid = %d, open_id = %s, response = %v",
- req.GameNodeID,
- userToken.PID,
- userToken.OpenID,
- response,
- )
- }
- p.Response(session, response)
- }
- func (p *actorAgent) setSession(req *pb.StrStrList) {
- if p.agent == nil {
- clog.Warnf("agent is nil. sid = %s", p.AliasID())
- return
- }
- for _, param := range req.List {
- if cstring.IsBlank(param.Value) {
- p.agent.Session().Remove(param.Key)
- } else {
- p.agent.Session().Set(param.Key, param.Value)
- }
- }
- // 更新agnet缓存
- cache.UpdateAgent(p.agent)
- // 推送session到目标节点
- for _, param := range req.List {
- if parserFunc, found := upa.GetSyncParser(param.Key); found {
- parserFunc(p, p.agent.Session(), true)
- }
- }
- }
- func (p *actorAgent) validateToken(base64Token string) (*token.Token, int32) {
- userToken, ok := token.DecodeToken(base64Token)
- if !ok || userToken.PID < 1 || len(userToken.OpenID) < 1 {
- clog.Warnf("base64Token = %s", base64Token)
- return nil, code.AccountUnmarshalError
- }
- sdkRow := data.SDK.Get(userToken.PID)
- if sdkRow == nil {
- return nil, code.PIDError
- }
- statusCode, ok := token.Validate(userToken, sdkRow.Salt)
- if !ok {
- return nil, statusCode
- }
- return userToken, code.OK
- }
- func (p *actorAgent) kickGateSession(uid cfacade.UID) {
- // 遍历所有网关节点,踢除旧的session
- uids := []int64{uid}
- sessions.KickUIDS(uids, upa.duplicateLoginCode, true, p.App().NodeID())
- }
- func (p *actorAgent) OnSessionClose(_ *pomelo.Agent) {
- cache.RemoveAgent(p.agent)
- // 推送session到目标节点
- for _, parserFunc := range upa.nodeSyncMap {
- parserFunc(p, p.agent.Session(), false)
- }
- // 释放agenet
- p.agent = nil
- // 自己退出
- p.Exit()
- }
- // 更新时间偏移量
- func (p *actorAgent) updateTimeOffset(req *pb.I64) {
- offset := req.Value
- ctime.AddOffsetTime(time.Duration(offset) * time.Second)
- clog.Warn("[updateTimeOffset] offset = %d, time = %d", offset, ctime.Now().ToSecond())
- }
- func (p *actorAgent) GetPlayerID() int64 {
- return sessions.GetPlayerID(p.agent.Session())
- }
- func (p *actorAgent) GetGameNodeID() string {
- return sessions.GetGameNodeID(p.agent.Session())
- }
- func (p *actorAgent) GetMapNodeID() string {
- return sessions.GetMapNodeID(p.agent.Session())
- }
|