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) } // 最大等级经验封顶 curLvConf := this.module.configure.GetPlayerlvConf(curLv) if curExp > int64(curLvConf.Exp) { if nextLvConf == nil { 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, } 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{Exp: curExp}); 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 }