package signinwheel import ( "encoding/json" "math/rand" "os" "time" "bet24.com/log" item "bet24.com/servers/micros/item_inventory/proto" platformconfig "bet24.com/servers/micros/platformconfig/proto" ) const config_key = "signinwheel_config" const refresh_config_sec = 600 type config_awards struct { Inner []config_param Outer []config_param } type chance_level struct { Min int Max int Chances []int pools []int } func (cl *chance_level) isIn(gold int) bool { return gold >= cl.Min && gold <= cl.Max } func (cl *chance_level) initPool() { cl.pools = []int{} for k := 0; k < len(cl.Chances); k++ { v := cl.Chances[k] for i := 0; i < v; i++ { cl.pools = append(cl.pools, k) } } } func (cl *chance_level) getIndex() int { if len(cl.pools) == 0 { return 0 } idx := rand.Intn(len(cl.pools)) return cl.pools[idx] } type config_chance struct { Chance int Levels []chance_level } func (cc *config_chance) getIndex(userGold int) int { levelIndex := len(cc.Levels) - 1 for i := 0; i < len(cc.Levels); i++ { if cc.Levels[i].isIn(userGold) { levelIndex = i break } } return cc.Levels[levelIndex].getIndex() } func (cc *config_chance) initPool() { for i := 0; i < len(cc.Levels); i++ { cc.Levels[i].initPool() } } type config_chances struct { Inner []config_chance Outer []config_chance innerPool []int outerPool []int } func (cc *config_chances) initPool() { cc.innerPool = []int{} cc.outerPool = []int{} for k := 0; k < len(cc.Inner); k++ { cc.Inner[k].initPool() v := cc.Inner[k] for i := 0; i < v.Chance; i++ { cc.innerPool = append(cc.innerPool, k) } } for k := 0; k < len(cc.Outer); k++ { cc.Outer[k].initPool() v := cc.Outer[k] for i := 0; i < v.Chance; i++ { cc.outerPool = append(cc.outerPool, k) } } } func (cc *config_chances) getInnerIndex(userGold int) int { // 先随机取一组 if len(cc.innerPool) == 0 { return 0 } idx := cc.innerPool[rand.Intn(len(cc.innerPool))] return cc.Inner[idx].getIndex(userGold) } func (cc *config_chances) getOuterIndex(userGold int) int { // 先随机取一组 if len(cc.outerPool) == 0 { return 0 } idx := cc.outerPool[rand.Intn(len(cc.outerPool))] return cc.Outer[idx].getIndex(userGold) } type config_struct struct { Cost int MsgLotteryAndGold string // 广播,兑换奖券、金币 (玩家在转盘游戏中赢得了100个金币和200个话费碎片) MsgLottery string // 广播,兑换奖券(玩家在转盘游戏中赢得了200个话费碎片) Awards config_awards Configs config_chances } func (cs *config_struct) initPool() { cs.Configs.initPool() } func (cs *config_struct) getItems(userGold int) []item.ItemPack { var ret []item.ItemPack // inner idx := cs.Configs.getInnerIndex(userGold) if idx >= len(cs.Awards.Inner) { idx = len(cs.Awards.Inner) - 1 } if cs.Awards.Inner[idx].Count > 0 { ret = append(ret, item.ItemPack{ItemId: cs.Awards.Inner[idx].ItemId, Count: cs.Awards.Inner[idx].Count}) } // outer idx = cs.Configs.getOuterIndex(userGold) if idx >= len(cs.Awards.Outer) { idx = len(cs.Awards.Outer) - 1 } if cs.Awards.Outer[idx].Count > 0 { ret = append(ret, item.ItemPack{ItemId: cs.Awards.Outer[idx].ItemId, Count: cs.Awards.Outer[idx].Count}) } return ret } type newmanager struct { configInfo config_struct } func newNewManager() *newmanager { ret := new(newmanager) ret.loadConfig() return ret } func (nm *newmanager) isAvailable() bool { return nm.configInfo.Cost > 0 } func (nm *newmanager) getCost() int { return nm.configInfo.Cost } func (nm *newmanager) loadConfig() { defer func() { time.AfterFunc(refresh_config_sec*time.Second, nm.loadConfig) }() configString := platformconfig.GetConfig(config_key) if configString == "" { data, err := os.ReadFile("fishconf/signinwheel.json") if err != nil { log.Release("signinwheel.newmanager.loadData read signinwheel failed") return } configString = string(data) platformconfig.SetConfig(config_key, configString) } else { log.Debug("signinwheel.newmanager loading config from redis") } err := json.Unmarshal([]byte(configString), &nm.configInfo) if err != nil { log.Release("signinwheel.newmanager.loadData Unmarshal signinwheel failed err:%v", err) return } nm.configInfo.initPool() } func (nm *newmanager) getConfig() SigninWheelConfig { return SigninWheelConfig{Cost: nm.configInfo.Cost, Multiple: nm.configInfo.Awards.Inner, Base: nm.configInfo.Awards.Outer} } func (nm *newmanager) getResult(userGold int) (int, int, []item.ItemPack) { base, mul := 1, 1 items := nm.configInfo.getItems(userGold) return mul, base, items } // base: outer // multiple: inner func (nm *newmanager) getGoldByLevel(level int) int { if level < 0 { level = 0 } maxLevel := len(nm.configInfo.Configs.Inner[0].Levels) - 1 if level > maxLevel { level = maxLevel } return nm.configInfo.Configs.Inner[0].Levels[level].Min + 1 } func (nm *newmanager) getMaxLevel() int { return len(nm.configInfo.Configs.Inner[0].Levels) }