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 }