go_dreamfactory/modules/user/model_user.go
2023-07-04 11:38:29 +08:00

402 lines
11 KiB
Go

package user
import (
"fmt"
"go_dreamfactory/comm"
"go_dreamfactory/lego/core"
et "go_dreamfactory/lego/sys/event"
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/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
EventApp *event_v2.App
}
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)
this.EventApp = event_v2.NewApp()
this.EventApp.Listen(comm.EventUserVipChanged, this.ChangeVipExp)
this.EventApp.Listen(comm.EventUserChanged, this.ChangeLevel)
// 通过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
_, err = this.DB.InsertOne(comm.TableUser, user)
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})
return
}
return
}
// 获取用户
func (this *ModelUser) GetUser(uid string) (user *pb.DBUser) {
user = &pb.DBUser{}
// if err := this.Get(uid, user); err != nil {
// this.module.Errorf("GetUser uid:%v err:%v",uid,err)
// return
// }
if this.module.IsCross() {
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("err:%v", err)
}
}
} else {
if err := this.Get(uid, user); err != nil {
this.module.Errorf("err:%v", err)
}
}
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) {
user := this.GetUser(uid)
if user == nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_UserSessionNobeing,
Title: pb.ErrorCode_UserSessionNobeing.ToString(),
}
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(event interface{}, next func(event interface{})) {
ul := event.(*UserListen)
var (
curExp int64
bChange bool
)
vipExp := ul.vipexp
vipLv := ul.viplv
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)
bChange = true
}
if bChange {
update := map[string]interface{}{
"vip": vipLv,
"vipexp": vipExp,
}
if err := this.module.modelUser.Change(ul.session.GetUserId(), update); err != nil {
this.module.Error("玩家Vip等级经验更新",
log.Field{Key: "uid", Value: ul.session.GetUserId()},
log.Field{Key: "vipLv", Value: vipLv},
log.Field{Key: "vipExp", Value: vipExp},
)
return
}
if ul.viplv != vipLv { // 新获得了vip
this.module.ModulePrivilege.AddVipData(ul.session, ul.viplv, vipLv)
}
// 推送玩家vip 经验变化
ul.session.SendMsg(string(this.module.GetType()), UserSubTypeVipChangedPush,
&pb.UserVipChangedPush{
Uid: ul.session.GetUserId(),
VipExp: int64(vipExp),
VipLv: vipLv,
})
}
return
}
// change level
func (this *ModelUser) ChangeLevel(event interface{}, next func(event interface{})) {
ul := event.(*UserListen)
curLv := ul.lv
//下一等级配置
nextLvConf := this.module.configure.GetPlayerlvConf(curLv + 1)
var (
rewards []*cfg.Gameatn
curExp int64
)
curExp = ul.exp
for nextLvConf != nil && curExp >= int64(nextLvConf.Exp) {
curExp = curExp - int64(nextLvConf.Exp)
curLv++
//叠加奖励
rewards = append(rewards, nextLvConf.Reward...)
nextLvConf = this.module.configure.GetPlayerlvConf(curLv + 1)
}
var res int32
if nextLvConf == nil {
curLvConf := this.module.configure.GetPlayerlvConf(curLv)
reward := this.module.globalConf.OverexpReward
if curExp < int64(curLvConf.Exp) {
res = int32(curExp) * reward.N
} else {
yu := int32(curExp) - curLvConf.Exp
res = yu * reward.N
}
// this.module.DispenseRes(ul.session, []*cfg.Gameatn{{A: "attr", T: "gold", N: gold}}, true)
curExp = int64(curLvConf.Exp)
}
// 等级有递增时再更新
if curLv > ul.lv {
update := map[string]interface{}{
"lv": curLv,
"exp": curExp,
}
if err := this.module.modelUser.Change(ul.session.GetUserId(), update); err != nil {
this.module.Error("玩家等级经验更新",
log.Field{Key: "uid", Value: ul.session.GetUserId()},
log.Field{Key: "exp", Value: curExp},
log.Field{Key: "lv", Value: curLv},
)
return
}
module, err2 := this.module.service.GetModule(comm.ModuleSys)
if err2 == nil {
if isys, ok := module.(comm.ISys); ok {
var funcList []string
for _, conf := range this.module.configure.GetOpenCondConf() {
id := isys.ValidCond(ul.session.GetUserId(), conf)
if id != "" {
funcList = append(funcList, id)
}
}
et.TriggerEvent(comm.EventOpenCond, ul.session.GetUserId(), funcList)
isys.CheckLvUpCond(ul.session, curLv) // 校验新功能是否开启
}
}
if err := ul.session.SendMsg(string(this.module.GetType()), UserSubTypeLvChangedPush,
&pb.UserLvChangedPush{Uid: ul.session.GetUserId(), Exp: curExp, Lv: curLv}); err != nil {
this.module.Error("玩家等级变化 UserSubTypeLvChangedPush推送失败",
log.Field{Key: "uid", Value: ul.session.GetUserId()},
log.Field{Key: "exp", Value: curExp},
log.Field{Key: "lv", Value: curLv},
)
}
if errdata := this.module.DispenseRes(ul.session, rewards, true); errdata != nil {
this.module.Error("资源发放",
log.Field{Key: "uid", Value: ul.session.GetUserId()},
log.Field{Key: "rewards", Value: rewards},
)
}
mc, err := this.module.service.GetModule(comm.ModuleChat)
if err != nil {
return
}
if chat, ok := mc.(comm.IChat); ok {
chat.SendSysChatToUser(ul.session, comm.ChatSystem12, curLv, 0, ul.name)
}
} else {
if nextLvConf == nil {
update := map[string]interface{}{
"exp": curExp,
"deposit": res,
}
if err := this.module.modelUser.Change(ul.session.GetUserId(), update); err != nil {
this.module.Error("玩家经验更新",
log.Field{Key: "uid", Value: ul.session.GetUserId()},
log.Field{Key: "exp", Value: curExp},
log.Field{Key: "lv", Value: curLv},
)
return
}
if err := ul.session.SendMsg(string(this.module.GetType()), "reschanged",
&pb.UserResChangedPush{
Gold: ul.Gold,
Ps: ul.Ps,
Vipexp: ul.vipexp,
Diamond: ul.Diamond,
Friend: ul.Friend,
Starcoin: ul.Starcoin,
Arenacoin: ul.Arenacoin,
Moongold: ul.Moongold,
Talent1: ul.Talent1,
Talent2: ul.Talent2,
Talent3: ul.Talent3,
Talent4: ul.Talent4,
Exp: curExp,
Merchantmoney: ul.Merchantmoney,
}); err != nil {
this.module.Error("玩家经验变化 UserResChangedPush推送失败",
log.Field{Key: "uid", Value: ul.session.GetUserId()},
log.Field{Key: "exp", Value: curExp},
log.Field{Key: "lv", Value: curLv},
)
}
}
}
}
// 玩家信息监听
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
}