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.Errorln("创建用户", 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("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) { 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, rewards []*cfg.Gameatn) { var ( curLv int32 = change.Lv nextLvConf *cfg.GamePlayerlvData curExp int64 = change.Exp res int64 ) //下一等级配置 nextLvConf = this.module.configure.GetPlayerlvConf(curLv + 1) if nextLvConf == nil { curLvConf := this.module.configure.GetPlayerlvConf(curLv) reward := this.module.globalConf.OverexpReward if curExp < int64(curLvConf.Exp) { res = curExp * int64(reward.N) } else { yu := int32(curExp) - curLvConf.Exp res = int64(yu * reward.N) } curExp = int64(curLvConf.Exp) } else { 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) } } // 等级有递增时再更新 if curLv > change.Lv { lvchange = true change.Lv = curLv change.Exp = curExp } else { if nextLvConf == nil { change.Deposit += res 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) }) 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 db.IsCross() { if model, err = this.module.GetDBModelByUid(uid, this.TableName); err == nil { if err := this.Get(uid, user); err != nil { this.module.Errorf("err:%v", err) } err = model.Change(uid, update) return } else { this.module.Errorln(err) return } } else { if err := this.Get(uid, user); err != nil { this.module.Errorf("err:%v", err) } } err = this.Change(uid, update) 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 }