package guildgve 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/sys/db" "go_dreamfactory/utils" "sync" ) type ModelUniongve struct { modules.MCompModel module *GuildGve conflock sync.RWMutex bossconf *pb.DBGuildGveBossConf } 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.TableGuildgve this.module = module.(*GuildGve) return } func (this *ModelUniongve) Start() (err error) { err = this.MCompModel.Start() event.RegisterGO(core.Event_ServiceStartEnd, func() { err = this.loadGlobalBoos() }) return } // 批量查询工会信息 func (this *ModelUniongve) querySociatys(guildids []string) (result []*pb.DBGuildGve, err error) { result = make([]*pb.DBGuildGve, 0) if _, err = this.Gets(guildids, &result); err != nil && err != mgo.MongodbNil { this.module.Errorln(err) return } err = nil return } // 获取用户全部的埋点数据 func (this *ModelUniongve) getGuildGve(guildid string) (results *pb.DBGuildGve, err error) { var ( confs *pb.DBGuildGveBossConf conf *cfg.GameGuildBossData ) results = &pb.DBGuildGve{ Boos: make([]*pb.DBGuildGveBoss, 0), } if err = this.GetByID(guildid, 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.DBGuildGve{ Guildid: guildid, Currstage: 0, Rtime: confs.Rtime, Boos: make([]*pb.DBGuildGveBoss, 0), } for _, v := range confs.Boos { if conf, err = this.module.configure.getguildbossByid(v); err != nil { return } results.Boos = append(results.Boos, &pb.DBGuildGveBoss{ Boosid: v, Hp: conf.Hp, Record: make([]*pb.DBGveRecord, 0), }) } err = this.Add(guildid, results) } return } func (this *ModelUniongve) updateGuildGve(data *pb.DBGuildGve) (err error) { if err = this.ChangeById(data.Guildid, 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.DBGuildGveBossConf = &pb.DBGuildGveBossConf{} ) 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.DBGuildGveBossConf, err error) { var ( bossconf *pb.DBGuildGveBossConf ) this.conflock.RLock() bossconf = this.bossconf this.conflock.RUnlock() if bossconf == nil || !utils.IsSameWeek(bossconf.Rtime) { if bossconf, err = this.refreshGlobalBoos(); err != nil { return } this.conflock.Lock() this.bossconf = bossconf this.conflock.Unlock() } conf = bossconf return } // 刷新全局配置 func (this *ModelUniongve) refreshGlobalBoos() (conf *pb.DBGuildGveBossConf, 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.DBGuildGveBossConf{ 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, map[string]interface{}{ "rtime": conf.Rtime, "boos": conf.Boos, }) return } // 分布式锁 func (this *ModelUniongve) userlock(id string) (result *redis.RedisMutex, err error) { return this.DBModel.Redis.NewRedisMutex(fmt.Sprintf("lockuniongve:%s", id)) } // boos 血量变化推送 func (this *ModelUniongve) booshpchangepush(unionid string, info *pb.DBGuildGve) { var ( members []*pb.SociatyMemberInfo users []string = make([]string, 0) errdata *pb.ErrorData ) if members, errdata = this.module.sociaty.MembersBySociatyId(unionid); errdata != nil { this.module.Debug("获取工会成员列表!", log.Field{Key: "errdata", Value: errdata}) return } for _, v := range members { users = append(users, v.Uid) } this.module.SendMsgToUsers(string(this.module.GetType()), "booschange", &pb.GuildGveBoosChangePush{ Info: info, }, users...) } // 击杀boos func (this *ModelUniongve) booskill(unionid string, boosid int32, info *pb.DBGuildGve) { var ( conf *cfg.GameGuildBossData members []*pb.SociatyMemberInfo users []string = make([]string, 0) errdata *pb.ErrorData err error ) if conf, err = this.module.configure.getguildbossByid(boosid); err != nil { this.module.Errorln(err) return } if members, errdata = this.module.sociaty.MembersBySociatyId(unionid); errdata != nil { this.module.Debug("获取工会成员列表!", log.Field{Key: "errdata", Value: errdata}) 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.modelGuildGve.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 = conf.Hp v.Record = make([]*pb.DBGveRecord, 0) } if err = this.updateGuildGve(info); err != nil { this.module.Errorln(err) return } this.module.SendMsgToUsers(string(this.module.GetType()), "stagechange", &pb.GuildGveStageChangePush{ Info: info, }, users...) } // boos 信息变化推送 func (this *ModelUniongve) infochangepush(unionid string, info *pb.DBGuildGve) { var ( members []*pb.SociatyMemberInfo users []string = make([]string, 0) errdata *pb.ErrorData ) if members, errdata = this.module.sociaty.MembersBySociatyId(unionid); errdata != nil { this.module.Debug("获取工会成员列表!", log.Field{Key: "errdata", Value: errdata}) return } for _, v := range members { users = append(users, v.Uid) } this.module.SendMsgToUsers(string(this.module.GetType()), "infochange", &pb.GuildGveInfoChangePush{ Info: info, }, users...) } // 更新埋点数据到db中 func (this *ModelUniongve) guildgveModel() (model *guildgveModel, err error) { var ( conn *db.DBConn m *db.DBModel ) if db.IsCross() { model = &guildgveModel{module: this.module, model: this.DBModel} } else { if conn, err = db.Cross(); err != nil { return } m = db.NewDBModel(this.TableName, conn) model = &guildgveModel{module: this.module, model: m} } return } // 埋点专属模型 会封装特殊的数据转换接口 type guildgveModel struct { module *GuildGve model *db.DBModel } // 分布式锁 func (this *guildgveModel) userlock(id string) (result *redis.RedisMutex, err error) { return this.model.Redis.NewRedisMutex(fmt.Sprintf("lockuniongve:%s", id)) } // 获取用户全部的埋点数据 func (this *guildgveModel) getGuildGve(guildid string) (results *pb.DBGuildGve, err error) { results = &pb.DBGuildGve{ Boos: make([]*pb.DBGuildGveBoss, 0), } if err = this.model.GetByID(guildid, results); err != nil { this.module.Errorln(err) return } return } func (this *guildgveModel) updateGuildGve(data *pb.DBGuildGve) (err error) { if err = this.model.ChangeById(data.Guildid, 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 }