package tools import ( "fmt" "go_dreamfactory/comm" "go_dreamfactory/lego/core" "go_dreamfactory/lego/core/cbase" "go_dreamfactory/lego/sys/log" "go_dreamfactory/sys/configure" cfg "go_dreamfactory/sys/configure/structs" "sync" ) const ( game_global = "game_global.json" //全局配置表 game_initial = "game_initial.json" //初始化表 //game_gamecolor = "game_gamecolor.json" //颜色表 new_robot = "game_robot.json" game_playerlv = "game_playerlv.json" //玩家等级 game_drop = "game_drop.json" //掉落 new_hero = "game_hero.json" // 签到 game_signreset = "game_signreset.json" game_sign = "game_sign.json" game_item = "game_item.json" game_vip = "game_vip.json" game_equip = "game_equip.json" //装备信息表 game_lottery = "game_lottery.json" game_price = "game_pricegroup.json" game_food = "game_breakingbad.json" ) // /配置管理基础组件 type MCompConfigure struct { cbase.ModuleCompBase module *Tools hlock sync.RWMutex _dropMap map[int32][]*cfg.GameDropData // 掉落表 key 是DiropId _sign map[int32]*cfg.GameSignData // 新掉落表 _group map[int64][]int32 // key 小组ID value cid // 类型为1 的数据 该大组中的小组为权重掉落,必定从N个小组中随机出1个小组 _lotteryType1 map[int32][]*cfg.GameLotteryData // key 大组ID value cid // 类型为2 的数据 有多个小组ID _lotteryType2 map[int32][]*cfg.GameLotteryData // key 大组ID value 小组ID // 小组类型为1 _groupType1 map[int64][]*cfg.GameLotteryData //value cid // 小组类型为2 _groupType2 map[int64][]*cfg.GameLotteryData //value cid //Btype map[int32]int32 Stype map[int64]int32 // subtype SNum map[int64]int32 // 小组产出数量 _price map[int32][]*cfg.GamePricegroupData } // 组件初始化接口 func (this *MCompConfigure) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { err = this.ModuleCompBase.Init(service, module, comp, options) this.module = module.(*Tools) err = this.LoadConfigure(game_global, cfg.NewGameGlobal) err = this.LoadConfigure(game_initial, cfg.NewGameInitial) err = this.LoadConfigure(new_hero, cfg.NewGameHero) err = this.LoadConfigure(game_playerlv, cfg.NewGamePlayerlv) err = this.LoadConfigure(new_robot, cfg.NewGameRobot) err = this.LoadConfigure(game_signreset, cfg.NewGameSignReset) err = this.LoadConfigure(game_equip, cfg.NewGameEquip) err = this.LoadConfigure(game_item, cfg.NewGameItem) err = this.LoadConfigure(game_vip, cfg.NewGameVip) err = this.LoadConfigure(game_food, cfg.NewGameBreakingbad) err = this.LoadConfigure(game_lottery, cfg.NewGameLottery) this._dropMap = make(map[int32][]*cfg.GameDropData, 0) this._sign = make(map[int32]*cfg.GameSignData, 0) configure.RegisterConfigure(game_drop, cfg.NewGameDrop, this.LoadDropData) configure.RegisterConfigure(game_sign, cfg.NewGameSign, this.LoadSignData) configure.RegisterConfigure(game_price, cfg.NewGamePricegroup, this.LoadPriceGroup) this._group = make(map[int64][]int32, 0) this._lotteryType1 = make(map[int32][]*cfg.GameLotteryData, 0) this._lotteryType2 = make(map[int32][]*cfg.GameLotteryData, 0) this._groupType1 = make(map[int64][]*cfg.GameLotteryData, 0) this._groupType2 = make(map[int64][]*cfg.GameLotteryData, 0) //this.Btype = make(map[int32]int32, 0) this.Stype = make(map[int64]int32, 0) this.SNum = make(map[int64]int32, 0) configure.RegisterConfigure(game_lottery, cfg.NewGameLottery, this.LoadGroupData) this.GetGroupDataByLottery(50001001, 1, 1) return } func (this *MCompConfigure) LoadGroupData() { if v, err := this.GetConfigure(game_lottery); err == nil { if configure, ok := v.(*cfg.GameLottery); ok { this.hlock.Lock() defer this.hlock.Unlock() this._group = make(map[int64][]int32, 0) this._lotteryType1 = make(map[int32][]*cfg.GameLotteryData, 0) this._lotteryType2 = make(map[int32][]*cfg.GameLotteryData, 0) this._groupType1 = make(map[int64][]*cfg.GameLotteryData, 0) this._groupType2 = make(map[int64][]*cfg.GameLotteryData, 0) //this.Btype = make(map[int32]int32, 0) this.Stype = make(map[int64]int32, 0) this.SNum = make(map[int64]int32, 0) var itype int32 var groupwt int32 var groupid int32 for _, value := range configure.GetDataList() { if value.Groupid == 0 { value.Groupid = groupid } else { groupid = value.Groupid } key := int64(value.Lotteryid)<<31 + int64(value.Groupid) this._group[key] = append(this._group[key], value.Id) if value.Type == 0 { value.Type = itype } else { itype = value.Type } if value.Groupwt == 0 { value.Groupwt = groupwt } else { groupwt = value.Groupwt } // 数据安全校验 if value.Min > value.Max { log.Errorf("value.Min:%d > value.Max :%d ", value.Min, value.Max) return } if value.VIPmin > value.VIPmax { log.Errorf("value.VIPmin:%d > value.VIPmax :%d ", value.VIPmin, value.VIPmax) return } if value.Playerlvmin > value.Playerlvmax { log.Errorf("value.Playerlvmin:%d > value.Playerlvmax :%d ", value.Playerlvmin, value.Playerlvmax) return } if _, ok := this.Stype[key]; !ok { this.Stype[key] = value.Subtype } if _, ok := this.SNum[key]; !ok { this.SNum[key] = value.Groupnum } if value.Type == 1 { this._lotteryType1[value.Lotteryid] = append(this._lotteryType1[value.Lotteryid], value) } if value.Type == 2 { this._lotteryType2[value.Lotteryid] = append(this._lotteryType2[value.Lotteryid], value) } if this.Stype[key] == 1 { // 小组ID为1 this._groupType1[key] = append(this._groupType1[key], value) } else if this.Stype[key] == 2 { this._groupType2[key] = append(this._groupType2[key], value) } } return } } else { log.Errorf("get LoadGroupData conf err:%v", err) } return } // 实际掉落逻辑 (传入 掉落组ID vip等级 玩家等级 返回获得的道具) func (this *MCompConfigure) GetGroupDataByLottery(lotteryId int32, vipLv int32, lv int32) (items []*cfg.Gameatn) { if _, ok := this._lotteryType1[lotteryId]; !ok { if _, ok := this._lotteryType2[lotteryId]; !ok { this.module.Errorf("not found config lotterId:%d", lotteryId) return } } // 优先校验大组ID 的类型 var ( szW []int32 // 权重数组 szID []int32 // 小组ID 数组 groupID int32 ) this.module.Debugf("config lotterId:%d, vipLv:%d, lv :%d", lotteryId, vipLv, lv) // 随机小组id for _, _data := range this._lotteryType1[lotteryId] { if (_data.Playerlvmax == 0 || (_data.Playerlvmin <= lv && lv <= _data.Playerlvmax)) && (_data.VIPmax == 0 || (_data.VIPmin <= vipLv && vipLv <= _data.VIPmax)) { // 过滤等级等条件 if _data.Groupid != 0 { szW = append(szW, _data.Groupwt) szID = append(szID, _data.Groupid) } } } if len(szW) > 0 { groupID = szID[comm.GetRandW(szW)] // 获得小组ID //fmt.Printf("大组类型为1的,获得小组ID :%d,dropID:%d", groupID, lotteryId) key := int64(lotteryId)<<31 + int64(groupID) // 小组ID 类型判断 if this.Stype[key] == 1 { // 该小组的道具为权重掉落,必定从N个道具中随机出1个道具 for i := 0; i < int(this.SNum[key]); i++ { sztW := make([]int32, 0) sztID := make([]*cfg.GameLotteryData, 0) for _, _data := range this._groupType1[key] { sztW = append(sztW, _data.Itemwt) sztID = append(sztID, _data) } if len(sztW) == 0 { continue } _data := sztID[comm.GetRandW(sztW)] count := comm.GetRandNum(_data.Min, _data.Max) // 随机获得的数量 items = append(items, &cfg.Gameatn{ A: _data.Itemid.A, T: _data.Itemid.T, N: _data.Itemid.N * count, }) } } else if this.Stype[key] == 2 { // 该小组中的道具为概率掉落,每个道具都会随机一次是否会掉落(单位为千分比) for _, _data := range this._groupType2[key] { if _data.Itemwt >= comm.GetRandNum(0, 1000) { // 命中 count := comm.GetRandNum(_data.Min, _data.Max) items = append(items, &cfg.Gameatn{ A: _data.Itemid.A, T: _data.Itemid.T, N: _data.Itemid.N * count, // 小组产出数量 }) } } } } // 每个小组id 都随机取一次 szW = make([]int32, 0) szID = make([]int32, 0) for _, _data := range this._lotteryType2[lotteryId] { if (_data.Playerlvmax == 0 || (_data.Playerlvmin <= lv && lv <= _data.Playerlvmax)) && (_data.VIPmax == 0 || (_data.VIPmin <= vipLv && vipLv <= _data.VIPmax)) { // 过滤等级等条件 if _data.Groupid != 0 { szW = append(szW, _data.Groupwt) szID = append(szID, _data.Groupid) } } } // 类型为2 可能会同时获得多个组id for pos, v := range szW { key := int64(lotteryId)<<31 + int64(szID[pos]) //fmt.Printf("大组类型为2的,获得小组ID :%d,dropID:%d", k, v.Id) if v >= comm.GetRandNum(0, 1000) { // 命中 if this.Stype[key] == 1 { // 随机一组数据 for i := 0; i < int(this.SNum[key]); i++ { sztW := make([]int32, 0) sztID := make([]*cfg.GameLotteryData, 0) for _, _data := range this._groupType1[key] { sztW = append(sztW, _data.Itemwt) sztID = append(sztID, _data) } if len(sztW) > 0 { continue } _data := sztID[comm.GetRandW(sztW)] count := comm.GetRandNum(_data.Min, _data.Max) // 随机获得的数量 items = append(items, &cfg.Gameatn{ A: _data.Itemid.A, T: _data.Itemid.T, N: _data.Itemid.N * count, }) } } else if this.Stype[key] == 2 { for _, _data := range this._groupType2[key] { if _data.Itemwt >= comm.GetRandNum(1, 1000) { // 命中 count := comm.GetRandNum(_data.Min, _data.Max) items = append(items, &cfg.Gameatn{ A: _data.Itemid.A, T: _data.Itemid.T, N: _data.Itemid.N * count, // 小组产出数量 }) } } } } } this.module.Debugf("drop result:%v", items) return } func (this *MCompConfigure) LoadConfigure(name string, fn interface{}) (err error) { return configure.RegisterConfigure(name, fn, nil) } // 加载一个配置文件 func (this *MCompConfigure) LoadDropData() { if v, err := this.GetConfigure(game_drop); err == nil { if configure, ok := v.(*cfg.GameDrop); ok { this.hlock.Lock() defer this.hlock.Unlock() for _, value := range configure.GetDataList() { if value.Condition == 0 { this._dropMap[value.Dropid] = append(this._dropMap[value.Dropid], value) } else { key := value.Condition key = value.Dropid*100 + key this._dropMap[key] = append(this._dropMap[key], value) for _, v1 := range this._dropMap[value.Dropid] { this._dropMap[key] = append(this._dropMap[key], v1) } } } return } } else { log.Errorf("get game_pagoda conf err:%v", err) } return } // 加载多个配置文件 func (this *MCompConfigure) LoadMultiConfigure(confs map[string]interface{}) (err error) { for k, v := range confs { err = configure.RegisterConfigure(k, v, nil) if err != nil { log.Errorf("配置文件:%s解析失败!", k) break } } return } // 读取配置数据 func (this *MCompConfigure) GetConfigure(name string) (v interface{}, err error) { return configure.GetConfigure(name) } // 全局配置 func (this *MCompConfigure) GetGlobalConf() *cfg.GameGlobalData { var ( configure *cfg.GameGlobal ok bool ) if v, err := this.GetConfigure(game_global); err != nil { log.Errorf("get global conf err:%v", err) return nil } else { if configure, ok = v.(*cfg.GameGlobal); !ok { log.Errorf("%T no is *cfg.Game_global", v) return nil } } return configure.GetDataList()[0] // 返回对象信息 } func (this *MCompConfigure) GetGlobalInitConf() (configure *cfg.GameInitial, err error) { var ( v interface{} ok bool ) if v, err = this.GetConfigure(game_initial); err == nil { if configure, ok = v.(*cfg.GameInitial); !ok { err = fmt.Errorf("%T no is *cfg.Game_comInitial", v) return } } return } // 主角等级经验配置列表 func (this *MCompConfigure) GetPlayerlvConfList() (list []*cfg.GamePlayerlvData) { if v, err := this.GetConfigure(game_playerlv); err != nil { return } else { if configure, ok := v.(*cfg.GamePlayerlv); !ok { err = fmt.Errorf("%T no is *cfg.Game_playerlv", v) return } else { if configure != nil { list = configure.GetDataList() } } } return } // 玩家等级经验配置表 func (this *MCompConfigure) GetPlayerlvConf(lv int32) (data *cfg.GamePlayerlvData, err error) { var ( v interface{} ok bool ) if v, err = this.GetConfigure(game_playerlv); err != nil { return } else { if data, ok = v.(*cfg.GamePlayerlv).GetDataMap()[lv]; !ok { err = comm.NewNotFoundConfErr(string(this.module.GetType()), game_playerlv, lv) return } } return } func (this *MCompConfigure) GetDropData(dropId int32) (data []*cfg.GameDropData) { data = this._dropMap[dropId] return } func (this *MCompConfigure) GetDropReward(dropId int32) (result []*cfg.Gameatn) { result = make([]*cfg.Gameatn, 0) data := this.GetDropData(dropId) if len(data) == 0 { return } szW := make([]int32, 0) for _, value := range data { szW = append(szW, value.P) } result = append(result, data[comm.GetRandW(szW)].Prize...) return } // 获取英雄原始星级 func (this *MCompConfigure) GetHeroConfig(heroCfgId string) (conf *cfg.GameHeroData, err error) { if v, err := this.GetConfigure(new_hero); err == nil { if configure, ok := v.(*cfg.GameHero); ok { if v, ok := configure.GetDataMap()[heroCfgId]; ok { return v, nil } } } return nil, comm.NewNotFoundConfErr("英雄模块", new_hero, heroCfgId) } // 获取英雄原始星级 func (this *MCompConfigure) GetHeroConfigStar(heroCfgId string) int32 { if v, err := this.GetConfigure(new_hero); err == nil { if configure, ok := v.(*cfg.GameHero); ok { if v, ok := configure.GetDataMap()[heroCfgId]; ok { return v.Star } } } return 0 } // 获取机器人信息 func (this *MCompConfigure) RandRobotConfig(num int32) (confs []*cfg.GameRobotData, err error) { var ( v interface{} ) confs = make([]*cfg.GameRobotData, num) if v, err = this.GetConfigure(new_robot); err == nil { if configure, ok := v.(*cfg.GameRobot); ok && len(configure.GetDataList()) > 0 { for i, index := range comm.RandShuffle(len(configure.GetDataList()))[:num] { confs[i] = configure.GetDataList()[index] } return } } return nil, comm.NewNotFoundConfErr("工具模块", new_robot, "没有可用机器人") } // 获取签到信息 func (this *MCompConfigure) GetSignConf(day, group int32) *cfg.GameSignData { if v, ok := this._sign[day<<8+group]; ok { return v } return nil } // 获取组id func (this *MCompConfigure) GetSignResetConf(id int32) int32 { if v, err := this.GetConfigure(game_signreset); err == nil { if configure, ok := v.(*cfg.GameSignReset); ok { if configure != nil { return configure.Get(id).Groups } } } return -1 } func (this *MCompConfigure) LoadSignData() { if v, err := this.GetConfigure(game_sign); err == nil { if configure, ok := v.(*cfg.GameSign); ok { this.hlock.Lock() defer this.hlock.Unlock() for _, value := range configure.GetDataList() { this._sign[value.Day<<8+value.Group] = value } return } } else { log.Errorf("get game_sign conf err:%v", err) } return } func (this *MCompConfigure) GetHeroConfigData() (data []*cfg.GameHeroData) { if v, err := this.GetConfigure(new_hero); err == nil { if configure, ok := v.(*cfg.GameHero); ok { return configure.GetDataList() } } return nil } // 读取物品配置 func (this *MCompConfigure) GetItemConfigureData(id string) (item *cfg.GameItemData, err error) { var ( v interface{} ok bool ) if v, err = this.GetConfigure(game_item); err != nil { log.Errorf("err:%v", err) return } else { if item, ok = v.(*cfg.GameItem).GetDataMap()[id]; !ok { err = fmt.Errorf("no found item:%s configure", id) log.Errorf("err:%v", err) return } } return } func (this *MCompConfigure) GetVipConfigureData(lv int32) (item *cfg.GameVipData) { if v, err := this.GetConfigure(game_vip); err == nil { if configure, ok := v.(*cfg.GameVip); ok { item = configure.Get(lv) } } return } func (this *MCompConfigure) GetItemConfigureByType(useType int32) (item []*cfg.GameItemData) { if v, err := this.GetConfigure(game_item); err == nil { for _, v1 := range v.(*cfg.GameItem).GetDataMap() { if v1.Usetype == useType { item = append(item, v1) } } } return } func (this *MCompConfigure) GetEquipmentConfigureById(equipmentId string) (configure *cfg.GameEquipData) { if v, err := this.GetConfigure(game_equip); err == nil { configure = v.(*cfg.GameEquip).Get(equipmentId) return } return } func (this *MCompConfigure) GetAllItemConfigure() (item []*cfg.GameItemData) { if v, err := this.GetConfigure(game_item); err == nil { for _, v1 := range v.(*cfg.GameItem).GetDataMap() { item = append(item, v1) } } return } func (this *MCompConfigure) GetAllEquipmentConfigure() (configure []*cfg.GameEquipData) { if v, err := this.GetConfigure(game_equip); err == nil { for _, v1 := range v.(*cfg.GameEquip).GetDataMap() { configure = append(configure, v1) } return } return } func (this *MCompConfigure) GetLotterConfById(id int32) (data *cfg.GameLotteryData) { if v, err := this.GetConfigure(game_lottery); err == nil { if configure, ok := v.(*cfg.GameLottery); ok { return configure.Get(id) } } return } func (this *MCompConfigure) LoadPriceGroup() { this._price = make(map[int32][]*cfg.GamePricegroupData) if v, err := this.GetConfigure(game_price); err == nil { if configure, ok := v.(*cfg.GamePricegroup); ok { this.hlock.Lock() defer this.hlock.Unlock() for _, value := range configure.GetDataList() { this._price[value.PricegroupId] = append(this._price[value.PricegroupId], value) } return } } else { log.Errorf("get game_price conf err:%v", err) } return } // 获取 func (this *MCompConfigure) GetPriceGroup(pricegroupId int32) (sz []*cfg.GamePricegroupData) { return this._price[pricegroupId] } func (this *MCompConfigure) GetPriceGroupCost(pricegroupId int32, purchase int32) (res []*cfg.Gameatn, err error) { if _, ok := this._price[pricegroupId]; !ok { err = comm.NewNotFoundConfErr("tools", game_price, pricegroupId) return } for _, v := range this._price[pricegroupId] { if v.Purchasemin <= purchase && (purchase <= v.Purchasemax || v.Purchasemax == -1) { res = v.Cost return } } return } func (this *MCompConfigure) GetPriceGroupLen(pricegroupId int32) (count int32, err error) { if _, ok := this._price[pricegroupId]; !ok { err = comm.NewNotFoundConfErr("tools", game_price, pricegroupId) } count = 0 for _, v := range this._price[pricegroupId] { if count < v.Purchasemax { count = v.Purchasemax } } return } func (this *MCompConfigure) GetGrormetLlame(id string) (data int32, err error) { var ( v interface{} ) if v, err = this.GetConfigure(game_food); err == nil { if conf, ok := v.(*cfg.GameBreakingbad); ok { _d := conf.Get(id) if _d != nil { data = _d.Flame if data == 0 { err = comm.NewNotFoundConfErr("gourmet", game_food, id) } return } } } err = comm.NewNotFoundConfErr("gourmet", game_food, id) return }