package parkour import ( "context" "fmt" "go_dreamfactory/comm" "go_dreamfactory/lego/core" "go_dreamfactory/lego/sys/log" "go_dreamfactory/lego/sys/mgo" "go_dreamfactory/modules" "go_dreamfactory/pb" "go_dreamfactory/sys/configure" cfg "go_dreamfactory/sys/configure/structs" "go_dreamfactory/sys/db" "math/rand" "sync" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/x/bsonx" ) ///竞速数据模块 type ModelParkourComp struct { modules.MCompModel module *Parkour refresh time.Time //上一次刷新时间 lock sync.RWMutex users []*Recommend //推荐用户信息 } //组件初始化接口 func (this *ModelParkourComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) { this.TableName = comm.TableParkour this.MCompModel.Init(service, module, comp, opt) this.module = module.(*Parkour) //创建uid索引 this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{ Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}}, }) return } func (this *ModelParkourComp) Start() (err error) { err = this.MCompModel.Start() go this.refreshlist() return } //获取推荐用户 func (this *ModelParkourComp) getrusers(uid string) (recommend []*pb.DBRaceMember, err error) { var ( users []*Recommend mount *cfg.GameBuzkashiMountData ondata bool ) this.lock.RLock() if len(this.users) == 0 { ondata = true } this.lock.RUnlock() if ondata { //没有数据 重新获取 this.refreshlist() } this.lock.RLock() users = make([]*Recommend, 0, len(this.users)) for _, v := range this.users { if v.parkour.Uid != uid { users = append(users, v) } } this.lock.RUnlock() var num int = 6 if len(users) < 6 { num = len(users) } recommend = make([]*pb.DBRaceMember, num) r := rand.New(rand.NewSource(configure.Now().Unix())) for i, v := range r.Perm(num) { if users[v].member == nil { if users[v].user = this.module.ModuleUser.GetUser(users[v].parkour.Uid); users[v].user == nil { continue } if mount, err = this.module.configure.getGameBuzkashiMount(users[v].parkour.Dfmount); err != nil { continue } users[v].member = &pb.DBRaceMember{ Uid: users[v].user.Uid, Name: users[v].user.Name, Avatar: users[v].user.Avatar, Lv: users[v].user.Lv, Mount: users[v].parkour.Dfmount, Maxhp: mount.Hp, Currhp: mount.Hp, } } recommend[i] = users[v].member } return } //刷新推荐列表 func (this *ModelParkourComp) refreshlist() { var ( users []*Recommend c *mongo.Cursor err error ) if c, err = this.DB.Find(core.SqlTable(this.TableName), bson.M{"captainid": ""}, options.Find().SetSort(bson.D{{"integral", -1}}).SetSkip(0).SetLimit(100)); err != nil { this.module.Errorln(err) return } else { result := make([]*pb.DBParkour, 0, c.RemainingBatchLength()) for c.Next(context.Background()) { tmp := &pb.DBParkour{} if err = c.Decode(tmp); err != nil { log.Errorln(err) } else { result = append(result, tmp) } } users = make([]*Recommend, len(result)) for i, v := range result { users[i] = &Recommend{ parkour: v, user: nil, } } this.lock.Lock() this.users = users this.lock.Unlock() } } func (this *ModelParkourComp) queryinfo(uid string) (result *pb.DBParkour, err error) { result = &pb.DBParkour{} if err = this.Get(uid, result); err != nil && err != mgo.MongodbNil { this.module.Errorln(err) return } if err == mgo.MongodbNil { var tuser *pb.DBUser if tuser = this.module.ModuleUser.GetUser(uid); tuser == nil { err = fmt.Errorf("no found udata:%s", uid) return } result = &pb.DBParkour{ Id: primitive.NewObjectID().Hex(), Uid: uid, State: pb.RaceTeamState_resting, Mounts: make(map[string]int32), Invite: make([]*pb.DBRaceInvite, 0), Member: []*pb.DBRaceMember{}, } mid := this.module.ModuleTools.GetGlobalConf().Mounts result.Mounts[mid] = 1 if err = this.Add(uid, result); err != nil { this.module.Errorln(err) return } } err = nil return } func (this *ModelParkourComp) queryinfos(uids []string) (results []*pb.DBParkour, err error) { results = make([]*pb.DBParkour, 0) var ( onfound []string newdata map[string]interface{} = make(map[string]interface{}) ) if onfound, err = this.Gets(uids, &results); err != nil { this.module.Errorln(err) return } if len(onfound) > 0 { for _, v := range onfound { var tuser *pb.DBUser if tuser = this.module.ModuleUser.GetUser(v); tuser == nil { err = fmt.Errorf("no found udata:%s", v) return } temp := &pb.DBParkour{ Id: primitive.NewObjectID().Hex(), Uid: v, State: pb.RaceTeamState_resting, Mounts: make(map[string]int32), Invite: make([]*pb.DBRaceInvite, 0), Member: []*pb.DBRaceMember{}, } mid := this.module.ModuleTools.GetGlobalConf().Mounts // 默认坐骑 temp.Mounts[mid] = 1 newdata[v] = temp } if err = this.Adds(newdata); err != nil { this.module.Errorln(err) return } } return } //更新用户的背包信息 func (this *ModelParkourComp) addUserMounts(uid string, mounts map[string]int32) (result *pb.DBParkour, err error) { var ( model *db.DBModel ) if !this.module.IsCross() { //非跨服 if model, err = this.module.GetCrossDBModel(this.TableName, this.Expired); err != nil { this.module.Errorln(err) } else { result = &pb.DBParkour{} if err = this.Get(uid, result); err != nil && err != mgo.MongodbNil { this.module.Errorln(err) return } if err == mgo.MongodbNil { var tuser *pb.DBUser if tuser = this.module.ModuleUser.GetUser(uid); tuser == nil { err = fmt.Errorf("no found udata:%s", uid) return } result = &pb.DBParkour{ Id: primitive.NewObjectID().Hex(), Uid: uid, State: pb.RaceTeamState_resting, Invite: make([]*pb.DBRaceInvite, 0), Mounts: make(map[string]int32), Member: []*pb.DBRaceMember{}, } mid := this.module.ModuleTools.GetGlobalConf().Mounts result.Mounts[mid] = 1 for k, _ := range mounts { result.Mounts[k] = 0 if result.Dfmount == "" { result.Dfmount = k } } if err = model.Add(uid, result); err != nil { this.module.Errorf("err:%v", err) } } else { for k, _ := range mounts { result.Mounts[k] = 0 } this.Change(uid, map[string]interface{}{ "mounts": result.Mounts, }) } } } else { if result, err = this.queryinfo(uid); err != nil { this.module.Errorln(err) } for k, _ := range mounts { result.Mounts[k] = 0 if result.Dfmount == "" { result.Dfmount = k } } this.Change(uid, map[string]interface{}{ "mounts": result.Mounts, }) } return }