402 lines
11 KiB
Go
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 gold int32
|
|
if nextLvConf == nil {
|
|
curLvConf := this.module.configure.GetPlayerlvConf(curLv)
|
|
reward := this.module.globalConf.OverexpReward
|
|
|
|
if curExp < int64(curLvConf.Exp) {
|
|
gold = int32(curExp) * reward
|
|
} else {
|
|
yu := int32(curExp) - curLvConf.Exp
|
|
gold = yu * reward
|
|
}
|
|
|
|
// 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": gold,
|
|
}
|
|
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
|
|
}
|