package main import ( "crypto/md5" "encoding/hex" "fmt" "github.com/golang-jwt/jwt/v4" "io" "mongo.games.com/game/webapi" "strconv" "strings" "time" "github.com/globalsign/mgo/bson" "mongo.games.com/goserver/core/basic" "mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/netlib" "mongo.games.com/goserver/core/task" "mongo.games.com/game/common" "mongo.games.com/game/model" "mongo.games.com/game/mq" "mongo.games.com/game/proto" login_proto "mongo.games.com/game/protocol/login" server_proto "mongo.games.com/game/protocol/server" "mongo.games.com/game/srvdata" ) type TaskLogin struct { *login_proto.CSLogin *netlib.Session Sid int64 BackupPromoter string flag login_proto.OpResultCode tagkey int32 codeValid bool isFirstLogin bool } // in task.Worker goroutine func (t *TaskLogin) Call(o *basic.Object) interface{} { var playerData *model.PlayerData //token验证 claims, err := webapi.ParseJwtWithClaims([]byte(common.Config.AppId), t.Token) if err != nil { return nil } logger.Logger.Tracef("TaskLogin ParseJwtWithClaims: claims:%v", claims.(jwt.MapClaims)) username := (claims.(jwt.MapClaims))["Username"].(string) //expire := (claims.(jwt.MapClaims))["Exp"] //timeStamp := (claims.(jwt.MapClaims))["Timestamp"] acc, retCode := model.AccountIsExist(username, username, t.GetPassword(), t.GetPlatform(), t.GetTimeStamp(), common.LoginTypePlatformToken, t.tagkey, false, t.codeValid) switch retCode { case common.LoginOk: t.flag = login_proto.OpResultCode_OPRC_Sucess case common.LoginPasswordError, common.LoginTypeNoExist, common.LoginError: t.flag = login_proto.OpResultCode_OPRC_LoginPassError case common.LoginTelCodeExpire: t.flag = login_proto.OpResultCode_OPRC_TelCodeExpire case common.LoginFreeze: t.flag = login_proto.OpResultCode_OPRC_AccountBeFreeze case common.LoginNew: t.flag = login_proto.OpResultCode_OPRC_Login_CreateAccError t.isFirstLogin = true switch t.GetLoginType() { case common.LoginTypeGuest: // 游客 raw := fmt.Sprintf("%v%v", t.GetUsername(), common.GetAppId()) h := md5.New() io.WriteString(h, raw) pwd := hex.EncodeToString(h.Sum(nil)) clientVer := t.GetClientVer() if clientVer < 0 { clientVer = model.GameParamData.ClientVersion } acc, retCode = model.InsertAccount(&model.InsertAccountParam{ Platform: t.GetPlatform(), UserName: t.GetUsername(), Password: pwd, TelPassword: pwd, Channel: t.GetChannel(), Params: t.GetParams(), DeviceOs: t.GetDeviceOs(), DeviceInfo: t.GetDeviceInfo(), ChannelId: t.GetChannelID(), AccountType: 0, Tel: "", ClientVer: clientVer, }) if retCode != common.InsertAccountOk { return nil } var tf bool playerData, tf = model.InsertPlayerData(&model.InsertPlayerDataParam{ Plt: acc.Platform, AccId: acc.AccountId.Hex(), NickName: "", HeadUrl: GetRobHeadUrlIdx(), }) if playerData == nil || !tf { return nil } t.flag = login_proto.OpResultCode_OPRC_Sucess case common.LoginTypeGoogle: // google,facebook raw := fmt.Sprintf("%v%v", t.GetUsername(), common.GetAppId()) h := md5.New() io.WriteString(h, raw) pwd := hex.EncodeToString(h.Sum(nil)) clientVer := t.GetClientVer() if clientVer < 0 { clientVer = model.GameParamData.ClientVersion } acc, retCode = model.InsertAccount(&model.InsertAccountParam{ Platform: t.GetPlatform(), UserName: t.GetUsername(), Password: pwd, TelPassword: pwd, Channel: t.GetChannel(), Params: t.GetParams(), DeviceOs: t.GetDeviceOs(), DeviceInfo: t.GetDeviceInfo(), ChannelId: t.GetChannelID(), AccountType: t.GetAccountType(), Tel: "", ClientVer: clientVer, }) if retCode != common.InsertAccountOk { return nil } var tf bool playerData, tf = model.InsertPlayerData(&model.InsertPlayerDataParam{ Plt: acc.Platform, AccId: acc.AccountId.Hex(), NickName: t.GetName(), HeadUrl: t.GetHeadUrl(), }) if playerData == nil || !tf { return nil } t.flag = login_proto.OpResultCode_OPRC_Sucess case common.LoginTypeTelCode: // 需要验证码正确 if !t.codeValid { t.flag = login_proto.OpResultCode_OPRC_TelCodeError } else { // 随机密码 raw := fmt.Sprintf("%v%v", bson.NewObjectId().Hex(), common.GetAppId()) h := md5.New() io.WriteString(h, raw) pwd := hex.EncodeToString(h.Sum(nil)) clientVer := t.GetClientVer() if clientVer < 0 { clientVer = model.GameParamData.ClientVersion } // Username 就是手机号 acc, retCode = model.InsertAccount(&model.InsertAccountParam{ Platform: t.GetPlatform(), UserName: t.GetUsername(), Password: pwd, TelPassword: pwd, Channel: t.GetChannel(), Params: t.GetParams(), DeviceOs: t.GetDeviceOs(), DeviceInfo: t.GetDeviceInfo(), ChannelId: t.GetChannelID(), AccountType: t.GetAccountType(), Tel: t.GetUsername(), ClientVer: clientVer, }) if retCode != common.InsertAccountOk { return nil } var tf bool name := fmt.Sprintf("mango%v", acc.SnId) playerData, tf = model.InsertPlayerData(&model.InsertPlayerDataParam{ Plt: acc.Platform, AccId: acc.AccountId.Hex(), NickName: name, HeadUrl: t.GetHeadUrl(), }) if playerData == nil || !tf { return nil } t.flag = login_proto.OpResultCode_OPRC_Sucess } } if t.flag == login_proto.OpResultCode_OPRC_Sucess && playerData != nil { // playerData != nil 表示新用户 // 新账号奖励 err := model.UpdatePlayerCoin(playerData.Platform, playerData.SnId, playerData.Coin+int64(model.GameParamData.NewPlayerCoin), 0, 0, time.Now().Unix(), time.Now().Unix(), 0, playerData.ShopID) if err == nil { // 新号赠送日志 if !playerData.IsRob { mq.Write(model.GenerateSystemFreeGive( playerData.SnId, playerData.Name, playerData.Platform, playerData.Channel, model.SystemFreeGive_GiveType_NewPlayer, model.SystemFreeGive_CoinType_Coin, int64(model.GameParamData.NewPlayerCoin))) } // 帐变记录 log := model.NewCoinLogEx(&model.CoinLogParam{ Platform: playerData.Platform, SnID: playerData.SnId, Channel: playerData.Channel, ChangeType: common.BillTypeCoin, ChangeNum: int64(model.GameParamData.NewPlayerCoin), RemainNum: playerData.Coin + int64(model.GameParamData.NewPlayerCoin), Add: 0, LogType: common.GainWay_NewPlayer, GameID: 0, GameFreeID: 0, BaseCoin: 0, Operator: "", Remark: "", }) if log != nil { mq.Write(log) } } // 发送绑定手机号奖励 if t.GetAccountType() == common.AccountTypeTel { freeFunc := func(coin int64, diamond int64, item map[int32]int64) { err := model.UpdatePlayerCoin(playerData.Platform, playerData.SnId, playerData.Coin+coin, playerData.Diamond+diamond, 0, time.Now().Unix(), time.Now().Unix(), 0, playerData.ShopID) if err == nil { // 金币 if coin > 0 { if !playerData.IsRob { mq.Write(model.GenerateSystemFreeGive( playerData.SnId, playerData.Name, playerData.Platform, playerData.Channel, model.SystemFreeGive_GiveType_BindTel, model.SystemFreeGive_CoinType_Coin, coin)) } // 帐变记录 log := model.NewCoinLogEx(&model.CoinLogParam{ Platform: playerData.Platform, SnID: playerData.SnId, Channel: playerData.Channel, ChangeType: common.BillTypeCoin, ChangeNum: coin, RemainNum: playerData.Coin + coin, Add: 0, LogType: common.GainWay_BindTel, GameID: 0, GameFreeID: 0, BaseCoin: 0, Operator: "", Remark: "", }) if log != nil { mq.Write(log) } } // 钻石 if diamond > 0 { if !playerData.IsRob { mq.Write(model.GenerateSystemFreeGive( playerData.SnId, playerData.Name, playerData.Platform, playerData.Channel, model.SystemFreeGive_GiveType_BindTel, model.SystemFreeGive_CoinType_Diamond, diamond)) } // 帐变记录 log := model.NewCoinLogEx(&model.CoinLogParam{ Platform: playerData.Platform, SnID: playerData.SnId, Channel: playerData.Channel, ChangeType: common.BillTypeDiamond, ChangeNum: diamond, RemainNum: playerData.Diamond + diamond, Add: 0, LogType: common.GainWay_BindTel, GameID: 0, GameFreeID: 0, BaseCoin: 0, Operator: "", Remark: "", }) if log != nil { mq.Write(log) } } //todo道具 } } var coin, diamond int64 items := map[int32]int64{} for k, v := range PlatformMgrSingleton.GetPlatform(acc.Platform).BindTelReward { switch k { case 1: // 金币 coin += v case 2: // 钻石 diamond += v default: // 道具 items[k] = items[k] + v } } freeFunc(coin, diamond, items) } } } return acc } // in laucher goroutine func (t *TaskLogin) Done(i interface{}, tt task.Task) { acc, _ := i.(*model.Account) SCLogin(t.Session, t.Sid, t.CSLogin, acc, t.flag, t.isFirstLogin) // 账号冻结 if t.flag == login_proto.OpResultCode_OPRC_AccountBeFreeze { ssDis := &login_proto.SSDisconnect{ SessionId: proto.Int64(t.Sid), Type: proto.Int32(common.KickReason_Freeze), } proto.SetDefaults(ssDis) t.Send(int(login_proto.GatePacketID_PACKET_SS_DICONNECT), ssDis) } // 登录成功 if t.flag == login_proto.OpResultCode_OPRC_Sucess { // 标记当前玩家登录成功,断开其它连接 lss := LoginStateMgrSington.LoginFinish(t.GetUsername(), t.GetPlatform(), t.Sid, acc, t.tagkey) if len(lss) != 0 { for k, ls := range lss { ssDis := &login_proto.SSDisconnect{ SessionId: proto.Int64(k), Type: proto.Int32(common.KickReason_OtherLogin), } proto.SetDefaults(ssDis) t.Send(int(server_proto.SSPacketID_PACKET_SS_DICONNECT), ssDis) logger.Logger.Warnf("==========顶号 oldsid:%v newsid:%v", k, t.Sid) LoginStateMgrSington.Logout(ls) //todo:game->rehold } } } else { //清理登录状态 LoginStateMgrSington.LogoutBySid(t.Sid) } } func SCLogin(s *netlib.Session, sid int64, csLogin *login_proto.CSLogin, acc *model.Account, code login_proto.OpResultCode, isFirstLogin bool) { if s == nil || csLogin == nil { return } sclogin := &login_proto.SCLogin{ OpRetCode: code, ClientParam: string(model.ClinetBuf), NextDayTs: common.GetDayNextStartTs(time.Now().Unix()), IsNewUser: isFirstLogin, } if acc != nil { now := time.Now() sclogin.AccId = proto.String(acc.AccountId.Hex()) sclogin.SrvTs = proto.Int64(now.Unix()) sclogin.SnId = acc.SnId if code == login_proto.OpResultCode_OPRC_Sucess { acc.LastLoginTime = now acc.LoginTimes++ //获取平台名称 if acc.Platform != common.Platform_Rob { if csLogin.LoginType == common.LoginTypeTelCode { sclogin.Token = acc.TelPassWord // 密码和appid } // 版本号 deviceOs := csLogin.GetDeviceOs() packVers := srvdata.GetPackVers(csLogin.GetPlatformTag()) if deviceOs != "" && packVers != nil { if cvers, ok := packVers[deviceOs]; ok { sclogin.MinApkVer = proto.Int32(cvers.MinResVer) sclogin.LatestApkVer = proto.Int32(cvers.LatestApkVer) sclogin.MinApkVer = proto.Int32(cvers.MinApkVer) sclogin.LatestResVer = proto.Int32(cvers.LatestResVer) } } gameVers := srvdata.GetPackVers(csLogin.GetPlatformTag()) if gameVers != nil { for k, v := range gameVers { token := strings.Split(k, ",") if len(token) == 2 && token[1] == deviceOs { if gameId, err := strconv.Atoi(token[0]); err == nil { sclogin.SubGameVer = append(sclogin.SubGameVer, &login_proto.GameVer{ GameId: proto.Int(gameId), MinApkVer: proto.Int32(v.MinApkVer), LatestApkVer: proto.Int32(v.LatestApkVer), MinResVer: proto.Int32(v.MinResVer), LatestResVer: proto.Int32(v.LatestResVer), }) } } } } // 游戏配置 gps := PlatformMgrSingleton.GetGameFrees(acc.Platform) for _, v := range gps { if v.Status { if v.DbGameFree.GetGameRule() != 0 { // 平台游戏 lgi := &login_proto.LoginGameInfo{ GameId: proto.Int32(v.DbGameFree.GetGameId()), LogicId: proto.Int32(v.DbGameFree.GetId()), } sclogin.GameInfo = append(sclogin.GameInfo, lgi) } else { // 三方游戏 sclogin.ThrGameId = append(sclogin.ThrGameId, v.DbGameFree.Id) } } } // 开关 cfg := PlatformMgrSingleton.GetEntrySwitch(acc.Platform) if cfg != nil { for _, vv := range cfg { sclogin.GameSwitch = append(sclogin.GameSwitch, &login_proto.EntrySwitch{ Index: vv.Index, Switch: vv.Switch, }) } } // 比例 ct, cr := PlatformMgrSingleton.GetCurrencyByPackageTag(csLogin.PlatformTag) sclogin.CurrencyType = ct sclogin.CurrencyRatio = cr } } } proto.SetDefaults(sclogin) common.SendToGate(sid, int(login_proto.LoginPacketID_PACKET_SC_LOGIN), sclogin, s) logger.Logger.Tracef("SCLogin %v", sclogin) }