go_dreamfactory/modules/user/model_user.go

409 lines
10 KiB
Go

package user
import (
"fmt"
"go_dreamfactory/comm"
"go_dreamfactory/lego/core"
event_v2 "go_dreamfactory/lego/sys/event/v2"
"go_dreamfactory/lego/sys/log"
"go_dreamfactory/modules"
"go_dreamfactory/pb"
"go_dreamfactory/sys/configure"
cfg "go_dreamfactory/sys/configure/structs"
"go_dreamfactory/sys/db"
"go_dreamfactory/utils"
"time"
uuid "github.com/satori/go.uuid"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/x/bsonx"
)
type ModelUser struct {
modules.MCompModel
module *User
}
func (this *ModelUser) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
this.TableName = comm.TableUser
err = this.MCompModel.Init(service, module, comp, options)
this.module = module.(*User)
// 通过uid创建索引
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}},
})
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "name", Value: bsonx.Int32(1)}},
})
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "logintime", Value: bsonx.Int32(1)}},
})
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
Keys: bsonx.Doc{{Key: "merchantmoney", Value: bsonx.Int32(1)}},
})
return
}
func (this *ModelUser) FindByAccount(sid string, account string) (*pb.DBUser, error) {
filter := bson.M{
"sid": sid,
"binduid": account,
}
sr := this.DB.FindOne(comm.TableUser, filter)
var nd *pb.DBUser
err := sr.Decode(&nd)
return nd, err
}
// 查询昵称
func (this *ModelUser) NickNameIsExist(name string) bool {
if err := this.DB.FindOne(comm.TableUser, bson.M{"name": name}).Err(); err != nil {
if err == mongo.ErrNoDocuments { //无记录
return true
}
}
return false
}
// 创建初始用户
func (this *ModelUser) User_Create(user *pb.DBUser) (err error) {
now := configure.Now().Unix()
_id := primitive.NewObjectID().Hex()
user.Id = _id
user.Uid = fmt.Sprintf("%s_%s", user.Sid, _id)
user.Uuid = uuid.NewV4().String()
user.Lv = 1 //初始等级
user.Ctime = now
user.Logintime = now
if _, err = this.DB.InsertOne(comm.TableUser, user); err != nil {
this.module.Error("创建用户", log.Field{Key: "sid", Value: user.Sid}, log.Field{Key: "account", Value: user.Binduid}, log.Field{Key: "err", Value: err.Error()})
return
}
key := fmt.Sprintf("%s:%s", this.TableName, user.Uid)
if err = this.Redis.HMSet(key, user); err != nil {
this.module.Error("创建用户", log.Field{Key: "sid", Value: user.Sid}, log.Field{Key: "account", Value: user.Binduid}, log.Field{Key: "err", Value: err.Error()})
return
}
return
}
// 获取用户
func (this *ModelUser) GetUser(uid string) (user *pb.DBUser, err error) {
user = &pb.DBUser{}
if this.module.IsCross() {
var model *db.DBModel
if model, err = this.module.GetDBModelByUid(uid, this.TableName); err != nil {
this.module.Errorln(err)
} else {
if err = model.Get(uid, user); err != nil {
this.module.Errorf("uid:%s err:%v", uid, err)
}
}
} else {
if err = this.Get(uid, user); err != nil {
this.module.Errorf("uid:%s err:%v", uid, err)
}
}
return
}
// 获取用户
func (this *ModelUser) GetCrossUsers(uids []string) (users []*pb.DBUser, err error) {
var (
stage string
usergroup map[string][]string = make(map[string][]string)
conn *db.DBConn
model *db.DBModel
usersSlice []*pb.DBUser
)
for _, v := range uids {
if stage, err = comm.UidToSTag(v); err != nil {
return
}
usergroup[stage] = append(usergroup[stage], v)
}
for k, v := range usergroup {
if conn, err = db.ServerDBConn(k); err != nil {
return
}
model = db.NewDBModel(this.TableName, conn)
usersSlice = make([]*pb.DBUser, 0)
if _, err = model.Gets(v, &usersSlice); err != nil {
return
}
users = append(users, usersSlice...)
}
return
}
// 设置属性
func (this *ModelUser) updateUserAttr(uid string, data map[string]interface{}) error {
if this.module.IsCross() {
if model, err := this.module.GetDBModelByUid(uid, this.TableName); err != nil {
this.module.Errorln(err)
} else {
if err = model.Change(uid, data); err != nil {
this.module.Errorf("err:%v", err)
}
}
} else {
return this.Change(uid, data)
}
return nil
}
// 是否今天首次登录
func (this *ModelUser) isLoginFirst(timestamp int64) bool {
now := configure.Now()
if timestamp == 0 || timestamp > now.Unix() {
//this.module.Debugf("lastlogin time great now")
return false
}
tt := time.Unix(timestamp, 0)
if !utils.IsToday(timestamp) {
if tt.Before(now) {
return true
}
}
return false
}
// 删除用户数据
func (this *ModelUser) delete(uid string) {
if err := this.DelByUId(uid); err != nil {
log.Errorf("%v", err)
}
}
// 修改玩家名字
func (this *ModelUser) modifyName(uid string, newName string) (errdata *pb.ErrorData) {
if _, err := this.GetUser(uid); err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_UserSessionNobeing,
Title: pb.ErrorCode_UserSessionNobeing.ToString(),
Message: err.Error(),
}
return
}
// 修改名称
update := map[string]interface{}{
"name": newName,
}
if err := this.Change(uid, update); err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_DBError,
Title: pb.ErrorCode_DBError.ToString(),
Message: err.Error(),
}
return
}
return
}
func (this *ModelUser) updateOfflineTime(uid string) {
if err := this.updateUserAttr(uid, map[string]interface{}{"offlinetime": configure.Now().Unix()}); err != nil {
this.module.Errorln(err)
}
}
// change vipexp
func (this *ModelUser) changeVipExp(change *pb.UserResChangedPush) (lvchange bool) {
var (
curExp int64
)
vipExp := change.Vipexp
vipLv := change.Vip
conf := this.module.configure.GetVipConfigureData(vipLv + 1)
if conf == nil {
return
}
curExp = int64(conf.UpExp)
for vipExp >= curExp {
vipLv++
vipExp -= curExp
tmpConf := this.module.configure.GetVipConfigureData(vipLv + 1)
if tmpConf == nil {
vipLv--
vipExp += curExp
break
}
curExp = int64(tmpConf.UpExp)
lvchange = true
}
return
}
// change level
func (this *ModelUser) computeLevel(change *pb.UserResChangedPush) (lvchange bool, loseexp int32, rewards []*cfg.Gameatn) {
var (
curLv int32 = change.Lv
nextLvConf *cfg.GamePlayerlvData
curExp int64 = change.Exp
res int64
)
rewards = make([]*cfg.Gameatn, 0)
for {
nextLvConf = this.module.configure.GetPlayerlvConf(curLv + 1)
if nextLvConf == nil {
break
}
if curExp >= int64(nextLvConf.Exp) {
curExp = curExp - int64(nextLvConf.Exp)
curLv++
//叠加奖励
rewards = append(rewards, nextLvConf.Reward...)
} else {
break
}
}
if nextLvConf == nil { //满级了
curLvConf := this.module.configure.GetPlayerlvConf(curLv)
reward := this.module.globalConf.OverexpReward
if curExp > int64(curLvConf.Exp) {
loseexp = int32(curExp) - curLvConf.Exp
res = int64(loseexp * reward.N)
curExp = int64(curLvConf.Exp)
change.Deposit += res
change.Exp = curExp
}
}
// 等级有递增时再更新
if curLv > change.Lv {
lvchange = true
change.Lv = curLv
change.Exp = curExp
}
return
}
func (this *ModelUser) changelv(session comm.IUserSession, lv int32, exp int64, name string, rewards []*cfg.Gameatn) {
defer this.module.PutUserSession(session)
if err := session.SendMsg(string(this.module.GetType()), UserSubTypeLvChangedPush,
&pb.UserLvChangedPush{Uid: session.GetUserId(), Exp: exp, Lv: lv}); err != nil {
this.module.Error("玩家等级变化 UserSubTypeLvChangedPush推送失败",
log.Field{Key: "uid", Value: session.GetUserId()},
log.Field{Key: "exp", Value: exp},
log.Field{Key: "lv", Value: lv},
)
}
if errdata := this.module.DispenseRes(session, rewards, true); errdata != nil {
this.module.Error("资源发放",
log.Field{Key: "uid", Value: session.GetUserId()},
log.Field{Key: "rewards", Value: rewards},
)
}
this.module.chat.SendSysChatToUser(session, comm.ChatSystem12, lv, 0, name)
go this.module.AsynHandleSession(session.Clone(), func(session comm.IUserSession) {
this.module.ModuleSys.CheckOpenCond(session.Clone(), comm.OpencondTypePlatlv, lv)
this.module.WriteUserLog(session.GetUserId(), comm.GMResAddType, "changelv", rewards)
})
session.Push()
}
func (this *ModelUser) CleanUserMerchantmoney(session comm.IUserSession) (err error) {
var (
model *db.DBModel
update map[string]interface{}
uid string
)
uid = session.GetUserId()
user := &pb.DBUser{}
update = make(map[string]interface{}, 0)
update["profit"] = 0
update["merchantmoney"] = 0
if user.Caravanlv == 0 { // 默认1级
user.Caravanlv = 1
update["caravanlv"] = user.Caravanlv
}
if db.IsCross() {
if model, err = this.module.GetDBModelByUid(uid, this.TableName); err == nil {
if err := this.Get(uid, user); err == nil {
err = model.Change(uid, update)
} else {
this.module.Errorf("err:%v", err)
}
} else {
this.module.Errorln(err)
}
} else {
if err := this.Get(uid, user); err == nil {
err = this.Change(uid, update)
} else {
this.module.Errorf("err:%v", err)
}
}
return
}
// 玩家信息监听
type UserListen struct {
event_v2.Event
session comm.IUserSession
exp int64
lv int32
name string
vipexp int64
viplv int32
Gold int64
Diamond int64
Friend int32
Starcoin int64
Guildcoin int64
Arenacoin int32
Ps int32
Moongold int32
Talent1 int32
Talent2 int32
Talent3 int32
Talent4 int32
Merchantmoney int32
}
func (this *ModelUser) CleanUserConsumeexp(session comm.IUserSession) (err error) {
var (
model *db.DBModel
update map[string]interface{}
uid string
)
uid = session.GetUserId()
user := &pb.DBUser{}
update = make(map[string]interface{}, 0)
update["consumeexp"] = 0
if db.IsCross() {
if model, err = this.module.GetDBModelByUid(uid, this.TableName); err == nil {
if err := this.Get(uid, user); err == nil {
err = model.Change(uid, update)
} else {
this.module.Errorf("err:%v", err)
}
} else {
this.module.Errorln(err)
}
} else {
if err := this.Get(uid, user); err == nil {
err = this.Change(uid, update)
} else {
this.module.Errorf("err:%v", err)
}
}
return
}