game_sync/worldsrv/task_login.go

373 lines
12 KiB
Go

package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
"io"
"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
}
// in task.Worker goroutine
func (t *TaskLogin) Call(o *basic.Object) interface{} {
var playerData *model.PlayerData
acc, retCode := model.AccountIsExist(t.GetUsername(), t.GetUsername(), t.GetPassword(), t.GetPlatform(),
t.GetTimeStamp(), t.GetLoginType(), 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
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))
acc, retCode = model.InsertAccount(t.GetUsername(), pwd, t.GetPlatform(), t.GetChannel(), t.GetPromoter(), t.GetParams(),
t.GetDeviceOs(), t.GetInviterId(), t.GetPromoterTree(), t.GetPlatformTag(), t.GetPackage(), t.GetDeviceInfo(), t.BackupPromoter, t.tagkey, t.GetChannelID())
if retCode != common.InsertAccountOk {
return nil
}
var tf bool
playerData, tf = model.CreatePlayerDataOnRegister(acc.Platform, acc.AccountId.Hex(), 0, "", niceIdMgr.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))
acc, retCode = model.InsertTelAccount(t.Username, pwd, t.GetPlatform(), t.GetChannel(), t.GetPromoter(), t.GetParams(),
t.GetInviterId(), t.GetPromoterTree(), "", pwd, t.GetPlatformTag(), t.GetPackage(), t.DeviceInfo,
t.tagkey, t.AccountType, t.GetDeviceOs(), t.GetChannelID())
if retCode != common.InsertAccountOk {
return nil
}
var tf bool
playerData, tf = model.CreatePlayerDataByThird(acc.Platform, acc.AccountId.Hex(), t.Name, t.HeadUrl)
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))
// Username 就是手机号
acc, retCode = model.InsertTelAccount(t.Username, pwd, t.GetPlatform(), t.GetChannel(), t.GetPromoter(), t.GetParams(),
t.GetInviterId(), t.GetPromoterTree(), t.Username, pwd, t.GetPlatformTag(), t.GetPackage(),
t.DeviceInfo, t.tagkey, t.AccountType, t.GetDeviceOs(), t.GetChannelID())
if retCode != common.InsertAccountOk {
return nil
}
var tf bool
name := fmt.Sprintf("mango%v", acc.SnId)
playerData, tf = model.CreatePlayerDataByThird(acc.Platform, acc.AccountId.Hex(), name, t.HeadUrl)
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)
// 账号冻结
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) {
if s == nil || csLogin == nil {
return
}
sclogin := &login_proto.SCLogin{
OpRetCode: code,
ClientParam: string(model.ClinetBuf),
NextDayTs: common.GetDayNextStartTs(time.Now().Unix()),
}
if acc != nil {
now := time.Now()
sclogin.AccId = proto.String(acc.AccountId.Hex())
sclogin.SrvTs = proto.Int64(now.Unix())
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)
}