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.Error("创建用户", 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("uid:%s err:%v", uid, err) } } } else { if err = this.Get(uid, user); err != nil { this.module.Errorf("uid:%s err:%v", uid, err) } } return } // 获取用户 func (this *ModelUser) GetCrossUsers(uids []string) (users []*pb.DBUser, err error) { var ( stage string usergroup map[string][]string = make(map[string][]string) conn *db.DBConn model *db.DBModel usersSlice []*pb.DBUser ) for _, v := range uids { if stage, err = comm.UidToSTag(v); err != nil { return } usergroup[stage] = append(usergroup[stage], v) } for k, v := range usergroup { if conn, err = db.ServerDBConn(k); err != nil { return } model = db.NewDBModel(this.TableName, conn) usersSlice = make([]*pb.DBUser, 0) if _, err = model.Gets(v, &usersSlice); err != nil { return } users = append(users, usersSlice...) } 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, loseexp int32, rewards []*cfg.Gameatn) { var ( curLv int32 = change.Lv nextLvConf *cfg.GamePlayerlvData curExp int64 = change.Exp res int64 ) rewards = make([]*cfg.Gameatn, 0) for { nextLvConf = this.module.configure.GetPlayerlvConf(curLv + 1) if nextLvConf == nil { break } if curExp >= int64(nextLvConf.Exp) { curExp = curExp - int64(nextLvConf.Exp) curLv++ //叠加奖励 rewards = append(rewards, nextLvConf.Reward...) } else { break } } if nextLvConf == nil { //满级了 curLvConf := this.module.configure.GetPlayerlvConf(curLv) reward := this.module.globalConf.OverexpReward if curExp > int64(curLvConf.Exp) { loseexp = int32(curExp) - curLvConf.Exp res = int64(loseexp * reward.N) curExp = int64(curLvConf.Exp) change.Deposit += res change.Exp = curExp } } // 等级有递增时再更新 if curLv > change.Lv { lvchange = true change.Lv = curLv 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) this.module.WriteUserLog(session.GetUserId(), "changelv", rewards) }) 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 user.Caravanlv == 0 { // 默认1级 user.Caravanlv = 1 update["caravanlv"] = user.Caravanlv } 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 }