package controller import ( "context" "fmt" mhayaGin "github.com/mhaya/components/gin" mhayaTime "github.com/mhaya/extend/time" cfacade "github.com/mhaya/facade" "github.com/mhaya/game/game_cluster/internal/code" "github.com/mhaya/game/game_cluster/internal/constant" "github.com/mhaya/game/game_cluster/internal/data" "github.com/mhaya/game/game_cluster/internal/mdb" "github.com/mhaya/game/game_cluster/internal/param" "github.com/mhaya/game/game_cluster/internal/token" "github.com/mhaya/game/game_cluster/nodes/web/sdk" mhayaLogger "github.com/mhaya/logger" mhayaActor "github.com/mhaya/net/actor" "github.com/mhaya/net/parser/pomelo" "time" ) type Controller struct { mhayaGin.BaseController Users } type ( Users struct { pomelo.ActorBase } User struct { pomelo.ActorBase childExitTime time.Duration } ) func (p *Users) GetChildActor(userName string) (cfacade.IActor, bool) { childActor, ok := p.Child().Get(userName) if !ok { var err error childActor, err = p.Child().Create(userName, &User{}) if err != nil { return nil, false } } return childActor, true } func (cu *User) OnInit() { cu.childExitTime = time.Minute * 5 cu.Timer().Add(10*time.Second, cu.sessionClose) } func (cu *User) sessionClose() { deadline := time.Now().Add(-cu.childExitTime).Unix() if cu.LastAt() < deadline { cu.Exit() } } func (p *Controller) Init() { group := p.Group("/") group.POST("/auth", p.auth) group.POST("/login", p.login) group.POST("/start", p.start) group.POST("/guide", p.guide) group.POST("/roll", p.roll) group.POST("/lottery", p.lottery) group.POST("/getLotteryConfig", p.getLotteryConfig) group.POST("/signIn", p.signIn) group.POST("/signInList", p.signInList) group.POST("/rank", p.rank) group.POST("/invite", p.invite) group.POST("/inviteRewardRatio", p.inviteRewardRatio) group.POST("/inviteClaimRatio", p.inviteClaimRatio) group.POST("/share", p.share) group.POST("/claim", p.claim) group.POST("/weeklyRankConfig", p.weeklyRankConfig) group.POST("/jump", p.jump) group.POST("/savex", p.savex) group.POST("/savetonwall", p.savetonwall) group.POST("/getLevel", p.getLevel) group.POST("/cashOut", p.cashOut) group.POST("/setPwd", p.setPwd) group.POST("/cashOutList", p.cashOutList) system := mhayaActor.NewSystem() system.SetApp(p.App) parentActor := &Users{} system.CreateActor(p.App.NodeId(), parentActor) p.Users = *parentActor } func (p *Controller) Auth(c *mhayaGin.Context) (*token.Token, int32) { tokenString := c.GetHeader(constant.Token) if tokenString == "" { return nil, code.AccountTokenValidateFail } userToken, ok := token.DecodeToken(tokenString) if ok == false { return nil, code.AccountTokenValidateFail } platformRow := data.SdkConfig.Get(userToken.PID) if platformRow == nil { return nil, code.AccountTokenValidateFail } _, ok = token.Validate(userToken, platformRow.Salt) if ok == false { return nil, code.AccountTokenValidateFail } oldToken := mdb.RDB.Get(context.Background(), fmt.Sprintf("%v:%v", constant.Token, userToken.OpenID)).Val() if oldToken != tokenString { return nil, code.AccountTokenValidateFail } return userToken, code.OK } // login 根据pid获取sdkConfig,与第三方进行帐号登陆效验 func (p *Controller) auth(c *mhayaGin.Context) { var pa param.LoginReq //body := c.GetBody() if err := c.BindJSON(&pa); err != nil { mhayaLogger.Warnf("if login err {. params=%s", pa) code.RenderResult(c, code.PIDError) return } config := data.SdkConfig.Get(pa.Pid) if config == nil { mhayaLogger.Warnf("if platformConfig == nil {. params=%s", c.GetParams()) code.RenderResult(c, code.LoginError) return } sdkInvoke, err := sdk.GetInvoke(config.ID) if err != nil { mhayaLogger.Warnf("[pid = %d] get invoke error. params=%s", pa.Pid, pa) code.RenderResult(c, code.PIDError) return } params := c.GetParams(true) params["openid"] = pa.OpenID params["platform"] = pa.Platform params["channel"] = pa.Channel params["ip"] = c.ClientIP() // invoke login sdkInvoke.Login(config, params, func(statusCode int32, result sdk.Params, error ...error) { if code.IsFail(statusCode) { mhayaLogger.Warnf("login validate fail. code = %d, params = %s", statusCode, c.GetParams()) if len(error) > 0 { mhayaLogger.Warnf("code = %d, error = %s", statusCode, error[0]) } code.RenderResult(c, statusCode) return } if result == nil { mhayaLogger.Warnf("callback result map is nil. params= %s", c.GetParams()) code.RenderResult(c, code.LoginError) return } openId, found := result.GetString("open_id") if found == false { mhayaLogger.Warnf("callback result map not found `open_id`. result = %s", result) code.RenderResult(c, code.LoginError) return } playerId, found := result.GetString("player_id") if found == false { mhayaLogger.Warnf("callback result map not found `open_id`. result = %s", result) code.RenderResult(c, code.LoginError) return } targetPath, found := result.GetString("target_path") if found == false { mhayaLogger.Warnf("callback result map not found `targetPath`. result = %s", result) code.RenderResult(c, code.LoginError) return } //重新获取认证 需要断天原来服务器 oldToken := mdb.RDB.Get(context.Background(), fmt.Sprintf("%v:%v", constant.Token, openId)).Val() if len(oldToken) > 0 { userToken, ok := token.DecodeToken(oldToken) if ok == false { return } //如果分配在不同节点需要断开原来服务器 if userToken.TargetPath != targetPath { ctl, ok := p.GetChildActor(userToken.PlayerID) if !ok { return } ctl.Call(userToken.TargetPath, "sessionClose", nil) } } base64Token := token.New(pa.Pid, openId, playerId, targetPath, "", config.Salt).ToBase64() err = mdb.RDB.Set(context.Background(), fmt.Sprintf("%v:%v", constant.Token, openId), base64Token, mhayaTime.SecondsPerWeek*time.Second).Err() if err != nil { mhayaLogger.Warnf("callback result set token err. result = %s", result) code.RenderResult(c, code.LoginError) return } code.RenderResult(c, code.OK, base64Token) }) }