package uniongve import ( "fmt" "go_dreamfactory/comm" "go_dreamfactory/lego/core" "go_dreamfactory/lego/sys/event" "go_dreamfactory/lego/sys/log" "go_dreamfactory/lego/sys/mgo" "go_dreamfactory/lego/sys/redis" "go_dreamfactory/modules" "go_dreamfactory/pb" "go_dreamfactory/sys/configure" cfg "go_dreamfactory/sys/configure/structs" "go_dreamfactory/utils" "sync" ) type ModelUniongve struct { modules.MCompModel module *UnionGve conflock sync.RWMutex bossconf *pb.DBUnionGveBossConf } func (this *ModelUniongve) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { err = this.MCompModel.Init(service, module, comp, options) this.TableName = comm.TableUniongve this.module = module.(*UnionGve) return } func (this *ModelUniongve) Start() (err error) { err = this.MCompModel.Start() event.RegisterGO(core.Event_ServiceStartEnd, func() { err = this.loadGlobalBoos() }) return } // 获取用户全部的埋点数据 func (this *ModelUniongve) getUnionGve(unionid string) (results *pb.DBUnionGve, err error) { var ( confs *pb.DBUnionGveBossConf conf *cfg.GameGuildBossData ) results = &pb.DBUnionGve{} if err = this.Get(unionid, results); err != nil && err != mgo.MongodbNil { this.module.Errorln(err) return } if err == mgo.MongodbNil { if confs, err = this.getGlobalBoos(); err != nil { return } results = &pb.DBUnionGve{ Unionid: unionid, Currstage: 0, Rtime: confs.Rtime, Boos: make([]*pb.DBUnionGveBoss, 0), } for _, v := range confs.Boos { if conf, err = this.module.configure.getguildbossByid(v); err != nil { return } results.Boos = append(results.Boos, &pb.DBUnionGveBoss{ Boosid: v, Hp: conf.Hp, Record: make([]*pb.DBGveRecord, 0), }) } err = this.Add(unionid, results) } return } func (this *ModelUniongve) updateUnionGve(data *pb.DBUnionGve) (err error) { if err = this.Change(data.Unionid, map[string]interface{}{ "fire": data.Fire, "notice": data.Notice, "currstage": data.Currstage, "rtime": data.Rtime, "kills": data.Kills, "lastkilltime": data.Lastkilltime, "rank": data.Rank, "boos": data.Boos, }); err != nil { this.module.Error("更新用户任务数据 错误!", log.Field{Key: "err", Value: err.Error()}) return } return } // 刷新全局配置 func (this *ModelUniongve) loadGlobalBoos() (err error) { var ( bossconf *pb.DBUnionGveBossConf = &pb.DBUnionGveBossConf{} ) if err = this.module.ModuleTools.GetGlobalData(UnionGveBoosCoonfKey, bossconf); err != nil && err != mgo.MongodbNil { this.module.Errorln(err) return } if err == mgo.MongodbNil { _, err = this.refreshGlobalBoos() return } this.conflock.Lock() this.bossconf = bossconf this.conflock.Unlock() return } func (this *ModelUniongve) getGlobalBoos() (conf *pb.DBUnionGveBossConf, err error) { var ( bossconf *pb.DBUnionGveBossConf ) this.conflock.RLock() bossconf = this.bossconf this.conflock.Unlock() if bossconf == nil || !utils.IsSameWeek(bossconf.Rtime) { if bossconf, err = this.refreshGlobalBoos(); err != nil { return } } return } // 刷新全局配置 func (this *ModelUniongve) refreshGlobalBoos() (conf *pb.DBUnionGveBossConf, err error) { var ( booss []*cfg.GameGuildBossData rands []int ) if booss, err = this.module.configure.getguildboss(); err != nil { return } if len(booss) < 5 { err = fmt.Errorf("guildboss no data!") return } rands = comm.RandShuffle(len(booss)) conf = &pb.DBUnionGveBossConf{ Key: UnionGveBoosCoonfKey, Rtime: configure.Now().Unix(), Boos: make([]int32, 5), } for i := 0; i < 5; i++ { conf.Boos[i] = booss[rands[i]].BossId } this.conflock.Lock() this.bossconf = conf this.conflock.Unlock() this.module.ModuleTools.UpdateGlobalData(UnionGveBoosCoonfKey, conf) return } // 分布式锁 func (this *ModelUniongve) userlock(id string) (result *redis.RedisMutex, err error) { return this.DBModel.Redis.NewRedisMutex(fmt.Sprintf("uniongve:%s", id)) } // boos 血量变化推送 func (this *ModelUniongve) booshpchangepush(unionid string, info *pb.DBUnionGve) { var ( members []*pb.SociatyMemberInfo users []string = make([]string, 0) ) members = this.module.sociaty.MembersBySociatyId(unionid) if members == nil || len(members) == 0 { this.module.Error("MembersBySociatyId is nil !") return } for _, v := range members { users = append(users, v.Uid) } this.module.SendMsgToUsers(string(this.module.GetType()), "booschange", &pb.UniongveBoosChangePush{ Info: info, }) } // 击杀boos func (this *ModelUniongve) booskill(unionid string, boosid int32, info *pb.DBUnionGve) { var ( conf *cfg.GameGuildBossData members []*pb.SociatyMemberInfo users []string = make([]string, 0) err error ) if conf, err = this.module.configure.getguildbossByid(boosid); err != nil { this.module.Errorln(err) return } members = this.module.sociaty.MembersBySociatyId(unionid) if members == nil || len(members) == 0 { this.module.Error("MembersBySociatyId is nil !") return } for _, v := range members { users = append(users, v.Uid) } this.module.mail.SendMailToUsers(users, "Guild_Boss", conf.KillReward, nil) for _, v := range info.Boos { if v.Hp > 0 { return } } lock, _ := this.module.modelUniongve.userlock(unionid) err = lock.Lock() if err != nil { this.module.Error("公会战分布式锁 err!", log.Field{Key: "Unionid", Value: unionid}, log.Field{Key: "err", Value: err.Error()}) return } defer lock.Unlock() info.Currstage++ for _, v := range info.Boos { if conf, err = this.module.configure.getguildbossByNext(v.Boosid, info.Currstage); err != nil { this.module.Errorln(err) return } v.Boosid = conf.BossId v.Hp = v.Hp v.Record = make([]*pb.DBGveRecord, 0) } if err = this.updateUnionGve(info); err != nil { this.module.Errorln(err) return } this.module.SendMsgToUsers(string(this.module.GetType()), "stagechange", &pb.UniongveStageChangePush{ Info: info, }) } // boos 信息变化推送 func (this *ModelUniongve) infochangepush(unionid string, info *pb.DBUnionGve) { var ( members []*pb.SociatyMemberInfo users []string = make([]string, 0) ) members = this.module.sociaty.MembersBySociatyId(unionid) if members == nil || len(members) == 0 { this.module.Error("MembersBySociatyId is nil !") return } for _, v := range members { users = append(users, v.Uid) } this.module.SendMsgToUsers(string(this.module.GetType()), "infochange", &pb.UniongveInfoChangePush{ Info: info, }) }