package sdk import ( "context" "fmt" "github.com/go-redis/redis/v8" jsoniter "github.com/json-iterator/go" mhayaGin "github.com/mhaya/components/gin" cerror "github.com/mhaya/error" cstring "github.com/mhaya/extend/string" 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/guid" "github.com/mhaya/game/game_cluster/internal/mdb" "github.com/mhaya/game/game_cluster/internal/mdb/models" "github.com/mhaya/game/game_cluster/internal/param" sessionKey "github.com/mhaya/game/game_cluster/internal/session_key" initdata "github.com/mhaya/game/game_cluster/internal/third/tg_sign" "github.com/mhaya/game/game_cluster/internal/token" clog "github.com/mhaya/logger" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "sort" "time" ) type quickSdk struct { app cfacade.IApplication } func (quickSdk) SdkId() int { return QuickSDK } func (p quickSdk) Login(config *data.SdkConfigRow, params Params, callback Callback) { openid, found := params.GetString("openid") if found == false || cstring.IsBlank(openid) { err := cerror.Error("openid is nil") callback(code.LoginError, nil, err) return } ip, found := params.GetString("ip") if found == false || cstring.IsBlank(ip) { err := cerror.Error("ip is nil") callback(code.LoginError, nil, err) return } plt, found := params.GetString("platform") if found == false || cstring.IsBlank(plt) { err := cerror.Error("platform is nil") callback(code.LoginError, nil, err) return } channel, found := params.GetString("channel") if found == false || cstring.IsBlank(channel) { err := cerror.Error("channel is nil") callback(code.LoginError, nil, err) return } sign, _ := params.GetString("sign") req := ¶m.LoginReq{ OpenID: openid, IP: ip, Platform: plt, Channel: channel, Sign: sign, } account, err := AccountRegisterOrLogin(req) if err > 0 { callback(code.LoginError, nil) return } nodeId, ok := SetNode(p.app) if code.IsFail(ok) { clog.Warnf("[RegisterAccount] openID = %s,nodeID=%v, errCode = %v", openid, nodeId, err) callback(code.LoginError, nil) return } targetPath := cfacade.NewChildPath(nodeId, "player"+nodeId, account.UserName) callback(code.OK, map[string]interface{}{ sessionKey.PlayerID: account.UserName, //返回 quick的uid做为 open id sessionKey.OpenID: openid, sessionKey.TargetPath: targetPath, "account": account, }) } func (p quickSdk) Reconnect(token *token.Token) (int32, *token.Token) { list := p.app.Discovery().ListByType("game") targetPath, err := cfacade.ToActorPath(token.TargetPath) if err != nil { clog.Warnf("[Reconnect] Target path error. targetPath = %v, error = %v", token.TargetPath, err) return code.AccountAuthFail, nil } isNew := false for _, v := range list { if v.GetNodeId() == targetPath.NodeID { isNew = true break } } if !isNew { nodeId, ok := SetNode(p.app) if code.IsFail(ok) { clog.Warnf("[RegisterAccount] openID = %s,nodeID=%v, errCode = %v", token.OpenID, nodeId, err) return code.AccountAuthFail, nil } path := cfacade.NewChildPath(nodeId, "player"+nodeId, token.PlayerID) token.TargetPath = path } return code.OK, token } func (p quickSdk) PayCallback(config *data.SdkConfigRow, c *mhayaGin.Context) { // TODO 这里实现quick sdk 支付回调的逻辑 c.RenderHTML("FAIL") } func AccountRegisterOrLogin(req *param.LoginReq) (*models.Account, int32) { var account models.Account ctx := context.Background() acc, err := mdb.RDB.Get(ctx, fmt.Sprintf("%v:%v", constant.CNameAccount, req.OpenID)).Bytes() if err != nil && err != redis.Nil { clog.Debugf("[Account] AccountRegisterOrLogin error: %v", err) } findFilter := bson.M{"openId": req.OpenID} if len(acc) > 0 { err = jsoniter.Unmarshal(acc, &account) if err != nil { clog.Debugf("[Account] unmarshal AccountRegisterOrLogin data error: %v", err) return nil, code.LoginError } } else { err = mdb.MDB.Collection(constant.CNameAccount).FindOne(context.Background(), findFilter).Decode(&account) if err != nil && err != mongo.ErrNoDocuments { clog.Errorf("Failed to AccountRegisterOrLogin select err request: %v err = %v", req, err.Error()) return nil, code.LoginError } } // todo 测试代码 curLvID, _ := mdb.RDB.Get(context.Background(), constant.RocketLvKey).Int() if curLvID < 100 { curLvID = 100 mdb.RDB.Set(context.Background(), constant.RocketLvKey, curLvID, 0) } user := initdata.GetUserInfo(req.Sign) //设置IP 规则 num, ok := models.SetPlayerBlacklistIpRecord(req.IP, req.OpenID) if ok { clog.Errorf("Failed to SetPlayerBlacklistIpRecord err request: %v,num:%v", req, num) return nil, code.LoginError } if account.OpenId != "" { if account.Platform == "on" { //统计新注册 models.SetAppointDailyRecordNewUserRegisterHash(req.Platform, req.Channel, account.UserName, account.JoinIp, mhayaTime.CreateFromTimestamp(account.JoinTime).Unix(), models.DailyRecordNewRegistered) } if (len(user.Username) > 0 && account.Account != user.Username) || user.IsPremium != account.IsPremium || req.IP != account.LoginIp || account.Platform != req.Platform { account.Account = user.Username account.IsPremium = user.IsPremium account.LoginIp = req.IP account.Platform = req.Platform //mdb.MDB.Collection(constant.CNameAccount).UpdateOne(context.Background(), findFilter, bson.M{"$set": bson.M{"platform": req.Platform, "account": user.Username, "isPremium": user.IsPremium, "loginIp": req.IP}}) jsonData, _ := jsoniter.Marshal(&account) err = mdb.RDB.Set(context.Background(), fmt.Sprintf("%v:%v", constant.CNameAccount, account.OpenId), jsonData, time.Hour*3*24).Err() err = mdb.RDB.HSet(ctx, constant.NewAccounts, account.OpenId, 0).Err() if err != nil { clog.Errorf("Failed to AccountRegisterOrLogin request: %v err = %v", account, err.Error()) return nil, code.LoginError } } return &account, code.OK } devAccountTable := &models.Account{ UserName: guid.Next(), OpenId: req.OpenID, Platform: req.Platform, Channel: req.Channel, Account: user.Username, IsPremium: user.IsPremium, IsNew: true, LoginIp: req.IP, JoinIp: req.IP, JoinTime: mhayaTime.Now().Unix(), } player := models.NewPlayer(token.New(req.Pid, req.OpenID, devAccountTable.UserName, "", "", "")) jsonData, err := jsoniter.Marshal(&player) if err != nil { clog.Errorf("Failed to AccountRegisterOrLogin request: %v err = %v", devAccountTable, err.Error()) return nil, code.LoginError } err = mdb.RDB.Set(ctx, fmt.Sprintf("%v:%v", constant.CNamePlayer, req.OpenID), jsonData, time.Hour*3*24).Err() if err != nil { clog.Errorf("Failed to AccountRegisterOrLogin request: %v err = %v", devAccountTable, err.Error()) return nil, code.LoginError } jsonData, err = jsoniter.Marshal(&devAccountTable) if err != nil { clog.Errorf("Failed to AccountRegisterOrLogin request: %v err = %v", devAccountTable, err.Error()) return nil, code.LoginError } err = mdb.RDB.Set(context.Background(), fmt.Sprintf("%v:%v", constant.CNameAccount, devAccountTable.OpenId), jsonData, time.Hour*3*24).Err() if err != nil { clog.Errorf("Failed to AccountRegisterOrLogin request: %v err = %v", devAccountTable, err.Error()) return nil, code.LoginError } err = mdb.RDB.HSet(ctx, constant.NewAccounts, devAccountTable.OpenId, 1).Err() if err != nil { clog.Errorf("Failed to AccountRegisterOrLogin request: %v err = %v", devAccountTable, err.Error()) return nil, code.LoginError } /* _, err = mdb.MDB.Collection(constant.CNameAccount).InsertOne(context.Background(), devAccountTable) if err != nil { clog.Errorf("Failed to AccountRegisterOrLogin request: %v err = %v", devAccountTable, err.Error()) return nil, code.LoginError }*/ //统计新注册 models.SetDailyRecordNewUserRegisterHash(req.Platform, req.Channel, devAccountTable.UserName, req.IP, models.DailyRecordNewRegistered) // 新用户触发币安升级逻辑 // 当前级别 lvID, _ := mdb.RDB.Get(context.Background(), constant.RocketLvKey).Int() userNum := mdb.RDB.IncrBy(context.Background(), constant.TotalUserKey, 1).Val() /* // 当前用户数 userNum, _ := mdb.MDB.Collection(constant.CNamePlayer).CountDocuments(context.Background(), bson.M{})*/ roConfig := data.RocketLvConfig.GetAll() // 当前经验 var curExperience int64 // 当前升级所需经验 var curLvNeed int64 keys := []int{} for _, row := range roConfig { keys = append(keys, row.ID) } sort.Ints(keys) for _, id := range keys { lvRow := roConfig[id] if id == lvID { curLvNeed = int64(lvRow.LvNeed) break } curExperience += int64(lvRow.LvNeed) } //curLvID, _ := mdb.RDB.Get(context.Background(), constant.RocketLvKey).Int() //if curLvID < 100 { // curLvID = 100 //} if userNum-curExperience >= curLvNeed { // 触发升级 // 并发控制 if lvID == curLvID { mdb.RDB.Set(context.Background(), constant.RocketLvKey, curLvID+1, 0) } } return devAccountTable, code.OK }