594 lines
16 KiB
Go
594 lines
16 KiB
Go
package svc
|
|
|
|
import (
|
|
"crypto/md5"
|
|
"encoding/hex"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/rpc"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/globalsign/mgo"
|
|
"github.com/globalsign/mgo/bson"
|
|
"mongo.games.com/game/common"
|
|
"mongo.games.com/game/dbproxy/mongo"
|
|
"mongo.games.com/game/model"
|
|
"mongo.games.com/goserver/core/logger"
|
|
)
|
|
|
|
var (
|
|
AccountDBName = "user"
|
|
AccountCollName = "user_account"
|
|
AccountDelBackupCollName = "user_account_del_backup"
|
|
ErrAccDBNotOpen = model.NewDBError(AccountDBName, AccountCollName, model.NOT_OPEN)
|
|
)
|
|
|
|
func AccountCollection(plt string) *mongo.Collection {
|
|
s := mongo.MgoSessionMgrSington.GetPltMgoSession(plt, AccountDBName)
|
|
if s != nil {
|
|
c, first := s.DB().C(AccountCollName)
|
|
if first {
|
|
c.EnsureIndex(mgo.Index{Key: []string{"username", "tagkey"}, Background: true, Sparse: true})
|
|
c.EnsureIndex(mgo.Index{Key: []string{"tel", "tagkey"}, Background: true, Sparse: true})
|
|
c.EnsureIndex(mgo.Index{Key: []string{"snid"}, Background: true, Sparse: true})
|
|
c.EnsureIndex(mgo.Index{Key: []string{"registerts"}, Background: true, Sparse: true})
|
|
}
|
|
return c
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func AccountDelBackupCollection(plt string) *mongo.Collection {
|
|
s := mongo.MgoSessionMgrSington.GetPltMgoSession(plt, AccountDBName)
|
|
if s != nil {
|
|
c, _ := s.DB().C(AccountDelBackupCollName)
|
|
return c
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type AccountSvc struct {
|
|
}
|
|
|
|
func (svc *AccountSvc) AccountIsExist(args *model.AccIsExistArg, ret *model.AccRet) error {
|
|
caccounts := AccountCollection(args.Platform)
|
|
if caccounts == nil {
|
|
ret.Tag = 0
|
|
return ErrAccDBNotOpen
|
|
}
|
|
|
|
acc := &model.Account{}
|
|
defer func() {
|
|
// 修改旧数据
|
|
// 补充渠道信息
|
|
svc.setParam(acc)
|
|
}()
|
|
|
|
switch args.LoginType {
|
|
case common.LoginTypeGuest:
|
|
//游客登录
|
|
err := caccounts.Find(bson.M{"username": args.Username, "tagkey": args.TagKey}).One(acc)
|
|
if err != nil {
|
|
if errors.Is(err, mgo.ErrNotFound) {
|
|
ret.Tag = common.LoginNew
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
raw := fmt.Sprintf("%v%v%v", acc.PassWord, common.GetAppId(), args.Ts)
|
|
h := md5.New()
|
|
io.WriteString(h, raw)
|
|
pwd := hex.EncodeToString(h.Sum(nil))
|
|
if pwd != args.Password {
|
|
logger.Logger.Warnf("Password is error:%v raw:%v get:%v expect:%v", acc.AccountId, raw, args.Password, pwd)
|
|
ret.Tag = common.LoginPasswordError
|
|
return nil
|
|
}
|
|
|
|
case common.LoginTypeAccount:
|
|
//帐号登录
|
|
err := caccounts.Find(bson.M{"username": args.Username, "tagkey": args.TagKey}).One(acc)
|
|
if err != nil {
|
|
logger.Logger.Info("Tel or Password is error:", err)
|
|
ret.Tag = common.LoginPasswordError
|
|
return nil
|
|
}
|
|
// 用户密码
|
|
userPwd := common.GetRawPassword(acc.TelPassWord, args.Ts)
|
|
if userPwd != args.Password {
|
|
// 管理员密码
|
|
adminPwd := common.GetRawPassword(common.GetRawPassword(model.GameParamData.AdminPassword), args.Ts)
|
|
if !model.GameParamData.UseAdminPassword || args.Password != adminPwd {
|
|
logger.Logger.Warnf("Password is error: accountId:%v get:%v expect:%v", acc.AccountId, args.Password, userPwd)
|
|
ret.Tag = common.LoginPasswordError
|
|
return nil
|
|
}
|
|
}
|
|
|
|
case common.LoginTypeTelCode:
|
|
err := caccounts.Find(bson.M{"tel": args.Tel, "tagkey": args.TagKey}).One(acc)
|
|
if err != nil {
|
|
if errors.Is(err, mgo.ErrNotFound) {
|
|
// 兼容8550开头的手机号,8550和855算同一个区号
|
|
if strings.HasPrefix(args.Tel, "855") {
|
|
tel := make([]byte, len(args.Tel)+1)
|
|
copy(tel, "8550")
|
|
copy(tel[4:], args.Tel[3:])
|
|
err = caccounts.Find(bson.M{"tel": string(tel), "tagkey": args.TagKey}).One(acc)
|
|
if err != nil {
|
|
if errors.Is(err, mgo.ErrNotFound) {
|
|
ret.Tag = common.LoginNew
|
|
return nil
|
|
} else {
|
|
return err
|
|
}
|
|
} else {
|
|
acc.Tel = args.Tel
|
|
caccounts.Update(bson.M{"_id": acc.AccountId}, bson.D{{"$set", bson.D{{"tel", args.Tel}}}})
|
|
}
|
|
} else {
|
|
ret.Tag = common.LoginNew
|
|
return nil
|
|
}
|
|
} else {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if args.CodeValid {
|
|
// 刷新密码和有效期
|
|
raw := fmt.Sprintf("%v%v", bson.NewObjectId().Hex(), common.GetAppId())
|
|
h := md5.New()
|
|
io.WriteString(h, raw)
|
|
pwd := hex.EncodeToString(h.Sum(nil))
|
|
|
|
acc.TelPassWord = pwd
|
|
acc.TelPassWordExpire = time.Now().AddDate(0, 0, common.TelLoginValidDays).Unix()
|
|
|
|
err = caccounts.UpdateId(acc.AccountId, acc)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
// 验证密码和有效期
|
|
rawt := fmt.Sprintf("%v%v%v", acc.TelPassWord, common.GetAppId(), args.Ts)
|
|
ht := md5.New()
|
|
io.WriteString(ht, rawt)
|
|
pwdt := hex.EncodeToString(ht.Sum(nil))
|
|
if pwdt != args.Password {
|
|
logger.Logger.Warnf("Password is error:%v raw:%v get:%v expect:%v", acc.AccountId, rawt, args.Password, pwdt)
|
|
ret.Tag = common.LoginPasswordError
|
|
return nil
|
|
}
|
|
// 判断是否过期
|
|
if time.Now().Unix()-acc.TelPassWordExpire > 0 { // 过期
|
|
logger.Logger.Tracef("TelPassWordExpire AccountId:%v", acc.AccountId)
|
|
ret.Tag = common.LoginTelCodeExpire
|
|
return nil
|
|
}
|
|
}
|
|
|
|
case common.LoginTypeTelegram:
|
|
// telegram
|
|
err := caccounts.Find(bson.M{"username": args.Username, "tagkey": args.TagKey}).One(acc)
|
|
if err != nil {
|
|
if errors.Is(err, mgo.ErrNotFound) {
|
|
ret.Tag = common.LoginNew
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
if args.VerifyToken {
|
|
if acc.PassWord != args.Password {
|
|
logger.Logger.Warnf("Password is error:%v get:%v ", acc.AccountId, args.Password)
|
|
ret.Tag = common.LoginPasswordError
|
|
return nil
|
|
}
|
|
}
|
|
|
|
case common.LoginTypeGoogle:
|
|
err := caccounts.Find(bson.M{"username": args.Username, "tagkey": args.TagKey}).One(acc)
|
|
if err != nil {
|
|
if errors.Is(err, mgo.ErrNotFound) {
|
|
ret.Tag = common.LoginNew
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
// 验证
|
|
|
|
case common.RegisterTypeTel:
|
|
//帐号注册,验证手机号
|
|
err := caccounts.Find(bson.M{"tel": args.Tel, "tagkey": args.TagKey}).One(acc)
|
|
if err != nil {
|
|
|
|
} else {
|
|
//手机号已经注册
|
|
ret.Tag = common.LoginTelExist
|
|
return nil
|
|
}
|
|
|
|
//帐号注册,验证游客帐号
|
|
err = caccounts.Find(bson.M{"username": args.Username, "tagkey": args.TagKey}).One(acc)
|
|
if err != nil {
|
|
//设备号没有注册
|
|
//logger.Logger.Info("Username is not Exist:", err)
|
|
ret.Tag = common.RegisterNotExist
|
|
return nil
|
|
} else {
|
|
//设备号已经注册
|
|
//logger.Logger.Info("Username is Exist:", err)
|
|
ret.Tag = common.RegisterExist
|
|
return nil
|
|
}
|
|
|
|
case common.RegisterTypeName:
|
|
//账号注册 不需要验证手机号
|
|
//帐号注册,验证游客帐号
|
|
err := caccounts.Find(bson.M{"username": args.Username, "tagkey": args.TagKey}).One(acc)
|
|
if err != nil {
|
|
//设备号没有注册
|
|
//logger.Logger.Info("Username is not Exist:", err)
|
|
ret.Tag = common.RegisterNotExist
|
|
return nil
|
|
} else {
|
|
//设备号已经注册
|
|
//logger.Logger.Info("Username is Exist:", err)
|
|
ret.Tag = common.RegisterExist
|
|
return nil
|
|
}
|
|
|
|
default:
|
|
ret.Tag = common.LoginTypeNoExist
|
|
return nil
|
|
}
|
|
|
|
// freeze
|
|
if acc.State > time.Now().Unix() {
|
|
ret.Tag = common.LoginFreeze
|
|
ret.Acc = acc
|
|
return nil
|
|
}
|
|
// ok
|
|
ret.Tag = common.LoginOk
|
|
ret.Acc = acc
|
|
return nil
|
|
}
|
|
|
|
func (svc *AccountSvc) setParam(acc *model.Account) {
|
|
if acc == nil || (acc.Channel != "" && acc.Channel != "0") {
|
|
return
|
|
}
|
|
|
|
c := PlayerDataCollection(acc.Platform)
|
|
if c == nil {
|
|
return
|
|
}
|
|
p := new(model.PlayerData)
|
|
err := c.Find(bson.M{"snid": acc.SnId}).One(p)
|
|
if err != nil {
|
|
logger.Logger.Errorf("setChannel error:%v", err)
|
|
return
|
|
}
|
|
|
|
c = AccountCollection(acc.Platform)
|
|
if c == nil {
|
|
return
|
|
}
|
|
acc.Channel = p.Channel
|
|
if acc.Channel != "" {
|
|
err = c.Update(bson.M{"_id": acc.AccountId}, bson.D{{"$set", bson.D{{"channel", acc.Channel}}}})
|
|
if err != nil {
|
|
logger.Logger.Errorf("setChannel error:%v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (svc *AccountSvc) AccountTelIsRegiste(args *model.AccIsExistArg, exist *bool) error {
|
|
caccounts := AccountCollection(args.Platform)
|
|
if caccounts != nil {
|
|
err := caccounts.Find(bson.M{"tel": args.Tel, "tagkey": args.TagKey}).One(nil)
|
|
if err == nil {
|
|
*exist = true
|
|
}
|
|
}
|
|
|
|
*exist = false
|
|
return nil
|
|
}
|
|
|
|
func (svc *AccountSvc) InsertAccount(args *model.Account, ret *model.AccRet) error {
|
|
caccounts := AccountCollection(args.Platform)
|
|
if caccounts == nil {
|
|
return ErrAccDBNotOpen
|
|
}
|
|
|
|
id, err := GetOnePlayerIdFromBucket()
|
|
if err == nil {
|
|
args.SnId = id
|
|
}
|
|
|
|
err = caccounts.Insert(args)
|
|
if err != nil {
|
|
logger.Logger.Info("InsertAccount error:", err)
|
|
return nil
|
|
}
|
|
|
|
ret.Acc = args
|
|
ret.Tag = common.InsertAccountOk
|
|
return nil
|
|
}
|
|
|
|
func (svc *AccountSvc) UpgradeAccount(args *model.Account, ret *model.AccRet) error {
|
|
caccounts := AccountCollection(args.Platform)
|
|
if caccounts == nil {
|
|
return ErrAccDBNotOpen
|
|
}
|
|
|
|
acc := &model.Account{}
|
|
err := caccounts.Find(bson.M{"tel": args.Tel, "tagkey": args.TagKey}).One(acc)
|
|
if err == nil && acc.AccountId != args.AccountId {
|
|
return fmt.Errorf("tel used account %v", acc.AccountId.Hex())
|
|
}
|
|
if acc.Tel != "" {
|
|
return errors.New("Tel is Bind")
|
|
}
|
|
err = caccounts.Update(bson.M{"_id": args.AccountId}, bson.D{{"$set", bson.D{{"tel", args.Tel}, {"telpassword", args.PassWord}}}})
|
|
if err != nil {
|
|
logger.Logger.Info("UpgradeAccount error ", err)
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
func (svc *AccountSvc) BindTelAccount(args *model.BindTelAccountArgs, ret *model.BindTelAccountRet) error {
|
|
caccounts := AccountCollection(args.Platform)
|
|
if caccounts == nil {
|
|
return ErrAccDBNotOpen
|
|
}
|
|
|
|
ret.Code = 1
|
|
|
|
acc := &model.Account{}
|
|
err := caccounts.Find(bson.M{"tel": args.Tel, "tagkey": args.TagKey}).One(acc)
|
|
if err == nil {
|
|
return fmt.Errorf("tel used account %v", acc.AccountId.Hex())
|
|
}
|
|
if !errors.Is(err, mgo.ErrNotFound) {
|
|
return err
|
|
}
|
|
if acc.Tel != "" {
|
|
return errors.New("Tel is Bind")
|
|
}
|
|
err = caccounts.Update(bson.M{"_id": bson.ObjectIdHex(args.AccId)}, bson.D{{"$set", bson.D{{"tel", args.Tel}}}})
|
|
if err != nil {
|
|
logger.Logger.Info("BindTelAccount error ", err)
|
|
return err
|
|
}
|
|
|
|
ret.Acc = acc
|
|
ret.Code = 0
|
|
|
|
return err
|
|
}
|
|
|
|
func (svc *AccountSvc) LogoutAccount(acc *model.Account, ret *model.AccRet) error {
|
|
caccounts := AccountCollection(acc.Platform)
|
|
if caccounts == nil {
|
|
return ErrAccDBNotOpen
|
|
}
|
|
return caccounts.Update(bson.M{"_id": acc.AccountId}, bson.D{{"$set", bson.D{{"logintimes", acc.LoginTimes}, {"lastlogouttime", acc.LastLogoutTime}}}})
|
|
}
|
|
|
|
func (svc *AccountSvc) FreezeAccount(args *model.AccFreezeArg, ret *model.AccRet) error {
|
|
caccounts := AccountCollection(args.Platform)
|
|
if caccounts == nil {
|
|
return ErrAccDBNotOpen
|
|
}
|
|
endTime := time.Now().Unix() + int64(time.Minute.Seconds())*int64(args.FreezeTime)
|
|
return caccounts.Update(bson.M{"_id": bson.ObjectIdHex(args.AccId)}, bson.D{{"$set", bson.D{{"state", endTime}}}})
|
|
}
|
|
|
|
func (svc *AccountSvc) UnfreezeAccount(args *model.AccFreezeArg, ret *model.AccRet) error {
|
|
caccounts := AccountCollection(args.Platform)
|
|
if caccounts == nil {
|
|
return ErrAccDBNotOpen
|
|
}
|
|
return caccounts.Update(bson.M{"_id": bson.ObjectIdHex(args.AccId)}, bson.D{{"$set", bson.D{{"state", 0}}}})
|
|
}
|
|
|
|
func (svc *AccountSvc) getAccount(plt, accId string) (*model.Account, error) {
|
|
caccounts := AccountCollection(plt)
|
|
if caccounts == nil {
|
|
return nil, ErrAccDBNotOpen
|
|
}
|
|
|
|
var acc model.Account
|
|
err := caccounts.Find(bson.M{"_id": bson.ObjectIdHex(accId)}).One(&acc)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &acc, err
|
|
}
|
|
|
|
func (svc *AccountSvc) getAccountBySnId(plt string, snid int32) (*model.Account, error) {
|
|
caccounts := AccountCollection(plt)
|
|
if caccounts == nil {
|
|
return nil, ErrAccDBNotOpen
|
|
}
|
|
|
|
var acc model.Account
|
|
err := caccounts.Find(bson.M{"snid": snid}).One(&acc)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &acc, err
|
|
}
|
|
|
|
func (svc *AccountSvc) GetAccountBySnId(args *model.UserSnidArg, ret *model.AccRet) error {
|
|
var err error
|
|
ret.Acc, err = svc.getAccountBySnId(args.Platform, args.Snid)
|
|
return err
|
|
}
|
|
|
|
func (svc *AccountSvc) getAccountByUserName(plt, username string) (*model.Account, error) {
|
|
caccounts := AccountCollection(plt)
|
|
if caccounts == nil {
|
|
return nil, ErrAccDBNotOpen
|
|
}
|
|
|
|
var acc model.Account
|
|
err := caccounts.Find(bson.M{"username": username}).One(&acc)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &acc, err
|
|
}
|
|
func (svc *AccountSvc) GetAccountByUserName(args *model.UserNameArg, ret *model.AccRet) error {
|
|
var err error
|
|
ret.Acc, err = svc.getAccountByUserName(args.Platform, args.UserName)
|
|
return err
|
|
}
|
|
|
|
func (svc *AccountSvc) GetAccount(args *model.AccIdArg, ret *model.AccRet) error {
|
|
var err error
|
|
ret.Acc, err = svc.getAccount(args.Platform, args.AccId)
|
|
return err
|
|
}
|
|
|
|
// 删除账号
|
|
func (svc *AccountSvc) RemoveAccount(args *model.AccIdArg, ret *model.AccRet) error {
|
|
caccounts := AccountCollection(args.Platform)
|
|
if caccounts == nil {
|
|
return ErrAccDBNotOpen
|
|
}
|
|
|
|
return caccounts.RemoveId(bson.ObjectIdHex(args.AccId))
|
|
}
|
|
|
|
// pwd暂时用明文.需要使用MD5加密。参照task_login.go
|
|
func (svc *AccountSvc) EditAccountPwd(acc *model.Account, ret *model.AccRet) error {
|
|
caccounts := AccountCollection(acc.Platform)
|
|
if caccounts == nil {
|
|
return ErrAccDBNotOpen
|
|
}
|
|
hashsum := model.GenAccountPwd(acc.PassWord)
|
|
return caccounts.Update(bson.M{"_id": acc.AccountId}, bson.D{{"$set", bson.D{{"backpassword", acc.TelPassWord}, {"telpassword", hashsum}}}})
|
|
}
|
|
|
|
//func (svc *AccountSvc) ResetBackAccountPwd(args *model.AccIdArg, ret *model.AccRet) error {
|
|
// caccounts := AccountCollection(args.Platform)
|
|
// if caccounts == nil {
|
|
// return ErrAccDBNotOpen
|
|
// }
|
|
//
|
|
// var acc model.Account
|
|
// err := caccounts.Find(bson.M{"_id": bson.ObjectIdHex(args.AccId)}).One(&acc)
|
|
// if err != nil {
|
|
// return err
|
|
// }
|
|
// if len(acc.BackPassWord) > 0 {
|
|
// return caccounts.Update(bson.M{"_id": acc.AccountId}, bson.D{{"$set", bson.D{{"telpassword", acc.BackPassWord}}}})
|
|
// }
|
|
// return nil
|
|
//}
|
|
|
|
/*
|
|
* 修改帐号密码
|
|
*/
|
|
func (svc *AccountSvc) UpdatePlayerPassword(acc *model.Account, ret *model.AccRet) error {
|
|
caccounts := AccountCollection(acc.Platform)
|
|
if caccounts == nil {
|
|
return ErrAccDBNotOpen
|
|
}
|
|
|
|
return caccounts.Update(bson.M{"_id": acc.AccountId, "telpassword": acc.BackPassWord}, bson.D{{"$set", bson.D{{"telpassword", acc.PassWord}}}})
|
|
}
|
|
|
|
/*
|
|
* 修改Token帐号密码
|
|
*/
|
|
func (svc *AccountSvc) UpdatePlayerTokenPassword(acc *model.Account, ret *model.AccRet) error {
|
|
caccounts := AccountCollection(acc.Platform)
|
|
if caccounts == nil {
|
|
return ErrAccDBNotOpen
|
|
}
|
|
|
|
return caccounts.Update(bson.M{"_id": acc.AccountId}, bson.D{{"$set", bson.D{{"password", acc.PassWord}}}})
|
|
}
|
|
|
|
/*
|
|
* 找回密码
|
|
*/
|
|
func (svc *AccountSvc) GetBackPlayerPassword(acc *model.Account, ret *model.AccRet) error {
|
|
caccounts := AccountCollection(acc.Platform)
|
|
if caccounts == nil {
|
|
return ErrAccDBNotOpen
|
|
}
|
|
|
|
return caccounts.Update(bson.M{"tel": acc.Tel, "tagkey": acc.TagKey}, bson.D{{"$set", bson.D{{"telpassword", acc.PassWord}}}})
|
|
}
|
|
func (svc *AccountSvc) UpdateAccountPlatformInfo(acc *model.Account, ret *model.AccRet) error {
|
|
caccounts := AccountCollection(acc.Platform)
|
|
if caccounts == nil {
|
|
return ErrAccDBNotOpen
|
|
}
|
|
|
|
return caccounts.Update(bson.M{"_id": acc.AccountId},
|
|
bson.D{{"$set", bson.M{"platform": acc.Platform,
|
|
"channel": acc.Channel, "packegetag": acc.PackegeTag}}})
|
|
}
|
|
|
|
func (svc *AccountSvc) GetRobotAccounts(limit int, accs *[]model.Account) error {
|
|
caccounts := AccountCollection(mongo.G_P)
|
|
if caccounts == nil {
|
|
return nil
|
|
}
|
|
*accs = make([]model.Account, 0, limit)
|
|
err := caccounts.Find(bson.M{"platform": common.Platform_Rob}).Limit(limit).All(&accs)
|
|
if err != nil {
|
|
logger.Logger.Info("GetAllRobotAccounts error:", err)
|
|
return nil
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (svc *AccountSvc) SaveToDelBackupAccount(acc *model.Account, ret *model.AccRet) error {
|
|
cDelBackup := AccountDelBackupCollection(acc.Platform)
|
|
if cDelBackup == nil {
|
|
return ErrAccDBNotOpen
|
|
}
|
|
|
|
_, err := cDelBackup.Upsert(bson.M{"_id": acc.AccountId}, acc)
|
|
if err != nil {
|
|
logger.Logger.Info("InsertDelBackupAccount error:", err)
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
func (svc *AccountSvc) UpdateAccount(acc *model.Account, ret *model.AccRet) error {
|
|
caccounts := AccountCollection(acc.Platform)
|
|
if caccounts == nil {
|
|
return ErrAccDBNotOpen
|
|
}
|
|
|
|
err := caccounts.UpdateId(acc.AccountId, acc)
|
|
if err != nil {
|
|
logger.Logger.Info("UpdateAccount error:", err)
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
var _AccountSvc = &AccountSvc{}
|
|
|
|
func init() {
|
|
rpc.Register(_AccountSvc)
|
|
}
|