package signinwheel import ( "encoding/json" "fmt" "math/rand" "strconv" "strings" "time" "bet24.com/log" "bet24.com/servers/common" "bet24.com/servers/coreservice/broadcast" "bet24.com/servers/coreservice/video" inventory "bet24.com/servers/micros/item_inventory/proto" item "bet24.com/servers/micros/item_inventory/proto" cash "bet24.com/servers/micros/money/proto" user "bet24.com/servers/micros/userservices/proto" ) func (sc *SigninWheelConfig) getResult() (int, int, []item.ItemPack) { base, mul := 0, 0 var items []item.ItemPack rd := rand.Intn(sc.totalBaseChance) for i := len(sc.Base) - 1; i >= 0; i-- { if rd >= sc.Base[i].Chance { base = sc.Base[i].Param break } } rd = rand.Intn(sc.totalMultipleChance) for i := len(sc.Multiple) - 1; i >= 0; i-- { if rd >= sc.Multiple[i].Chance { mul = sc.Multiple[i].Param if sc.Multiple[i].Count > 0 { items = append(items, item.ItemPack{ItemId: sc.Multiple[i].ItemId, Count: sc.Multiple[i].Count}) } break } } items = append(items, item.ItemPack{ItemId: item.Item_Gold, Count: base * mul}) return base, mul, items } func newSigninWheelManager() *signinwheelmgr { sm := new(signinwheelmgr) sm.newMgr = newNewManager() sm.loadInfo() return sm } type signinwheelmgr struct { config SigninWheelConfig history []SigninWheelHistory config_client SigninWheelConfig newMgr *newmanager } func (sm *signinwheelmgr) loadInfo() { if sm.newMgr.isAvailable() { sm.config = sm.newMgr.getConfig() sm.config_client = sm.newMgr.getConfig() sm.history = getHistory() return } configStr := getSigninWheelConfig() err := json.Unmarshal([]byte(configStr), &sm.config) if err != nil { log.Debug("signinwheelmgr.loadInfo unmarshal failed %s", configStr) return } /* sort.Slice(sm.config.Base, func(i, j int) bool { return sm.config.Base[i].Param < sm.config.Base[j].Param }) sort.Slice(sm.config.Multiple, func(i, j int) bool { return sm.config.Multiple[i].Param < sm.config.Multiple[j].Param }) */ d, _ := json.Marshal(sm.config) json.Unmarshal(d, &sm.config_client) //log.Debug("signinwheelmgr.loadInfo client = %s", string(d)) // 把概率转换成区间 base := 0 for i := 0; i < len(sm.config.Base); i++ { if sm.config.Base[i].ItemId == 0 { sm.config.Base[i].ItemId = item.Item_Gold sm.config_client.Base[i].ItemId = item.Item_Gold } tmp := sm.config.Base[i].Chance sm.config.Base[i].Chance = base base += tmp sm.config_client.Base[i].Chance = 0 } sm.config.totalBaseChance = base base = 0 for i := 0; i < len(sm.config.Multiple); i++ { tmp := sm.config.Multiple[i].Chance sm.config.Multiple[i].Chance = base base += tmp sm.config_client.Multiple[i].Chance = 0 } sm.config.totalMultipleChance = base sm.history = getHistory() time.AfterFunc(10*time.Minute, sm.loadInfo) } func (sm *signinwheelmgr) canSignin(userId int, ipAddress string, checkOnly bool) bool { if sm.newMgr.isAvailable() { if checkOnly { return true } if !cash.ReduceMoney(userId, sm.newMgr.getCost(), common.LOGTYPE_SIGNIN_WHEEL, "signinwheel", "wheel", ipAddress) { log.Release("signinwheelmgr.wheel userId[%d] cost[%d] not enough gold", userId, sm.newMgr.getCost()) return false } return true } return !common.IsSameDay(getUserLastSignin(userId), common.GetTimeStamp()) } func (sm *signinwheelmgr) getSigninWheelInfo(userId int) UserSiginWheelInfo { _, myPlayTimes, sysPlayTimes, _ := video.GetInfo(userId, video.Video_Sign) return UserSiginWheelInfo{ CanSignin: sm.canSignin(userId, "", true), SigninWheelConfig: sm.config_client, MyPlayTimes: myPlayTimes, SysPlayTimes: sysPlayTimes, } } func (sm *signinwheelmgr) doSignin(userId int, ipAddress string, userGold int) (SigninWheelResult, int) { var ret SigninWheelResult if len(sm.config.Base) == 0 { log.Debug("signinwheelmgr.doSignin failed no config") return ret, 0 } success, myPlayTimes := false, 0 if !sm.canSignin(userId, ipAddress, false) { success, myPlayTimes, _ = video.Play(userId, video.Video_Sign) if !success { return ret, myPlayTimes } } userGold -= sm.newMgr.getCost() // 可以签到,取随机base和multiple if sm.newMgr.isAvailable() { ret.Base, ret.Multiple, ret.Items = sm.newMgr.getResult(userGold) } else { ret.Base, ret.Multiple, ret.Items = sm.config.getResult() } if ret.Base == 0 { log.Debug("signinwheelmgr.doSignin base == 0") return ret, myPlayTimes } time.AfterFunc(time.Second*8, func() { if success := inventory.AddItems(userId, ret.Items, "signinwheel", common.LOGTYPE_SEND_SIGN); !success { return } // 没有广播消息 if len(sm.newMgr.configInfo.MsgLottery) <= 0 && len(sm.newMgr.configInfo.MsgLotteryAndGold) <= 0 { return } lottery, gold, broadcastMsg := 0, 0, "" // 碎片≥5的时候展示内容,金币≥5000时展示内容 for _, v := range ret.Items { if v.ItemId == item.Item_Gold { gold += v.Count } } if gold >= 5000 { broadcastMsg = strings.ReplaceAll(sm.newMgr.configInfo.MsgLotteryAndGold, "碎片数量", fmt.Sprintf("%d", lottery)) broadcastMsg = strings.ReplaceAll(broadcastMsg, "金币数量", fmt.Sprintf("%d
", gold)) } else if lottery >= 5 && gold > 0 { broadcastMsg = strings.ReplaceAll(sm.newMgr.configInfo.MsgLotteryAndGold, "碎片数量", fmt.Sprintf("%d", lottery)) broadcastMsg = strings.ReplaceAll(broadcastMsg, "金币数量", fmt.Sprintf("%d
", gold)) } else if lottery >= 5 { broadcastMsg = strings.ReplaceAll(sm.newMgr.configInfo.MsgLottery, "碎片数量", fmt.Sprintf("%d
", lottery)) } // 没有可广播的消息 if len(broadcastMsg) <= 0 { return } // 获取用户信息 if userInfo := user.GetUserInfo(userId); userInfo != nil { broadcastMsg = strings.ReplaceAll(broadcastMsg, "玩家昵称", fmt.Sprintf("%s", userInfo.NickName)) } go broadcast.SendBroadcast(userId, 0, 0, broadcastMsg, "") }) // 写入签到记录 go sm.doSigninAndUpdateHistory(userId, ret.Base, ret.Multiple, 0, ret.Items) return ret, myPlayTimes } func (sm *signinwheelmgr) doSigninAndUpdateHistory(userId, base, multiple, itemId int, items []item.ItemPack) { // 如果是空Items if len(items) == 0 { return } userSigninWheel(userId, base, multiple, 0, items) sm.history = getHistory() } func (sm *signinwheelmgr) getHistory() []SigninWheelHistory { var ret []SigninWheelHistory for _, v := range sm.history { u := user.GetUserInfo(v.UserId) if u == nil { log.Error("siginwheel.getHistory userId=%d ==> %+v", v.UserId, v) continue } ret = append(ret, SigninWheelHistory{ UserId: v.UserId, NickName: u.NickName, FaceId: u.FaceId, FaceUrl: u.FaceUrl, SigninWheelResult: v.SigninWheelResult, }) } return ret } func (sm *signinwheelmgr) dumpSys(param string) { log.Release("-------------------------------") log.Release("signinwheelmgr.dumpSys %s", param) defer func() { log.Release("+++++++++++++++++++++++++++++++") log.Release("") }() d, _ := json.Marshal(sm.config) log.Release(string(d)) log.Release("totalChance = %d,%d", sm.config.totalBaseChance, sm.config.totalMultipleChance) d, _ = json.Marshal(sm.config_client) log.Release(string(d)) } func (sm *signinwheelmgr) dumpUser(param string) { log.Release("-------------------------------") log.Release("signinwheelmgr.dumpUser %s", param) defer func() { log.Release("+++++++++++++++++++++++++++++++") log.Release("") }() var userId int var err error if userId, err = strconv.Atoi(param); err != nil { log.Release("atoi error %v", err) return } log.Release("user last signin time %d", getUserLastSignin(userId)) } func (sm *signinwheelmgr) dumpHistory() { log.Release("-------------------------------") log.Release("signinwheelmgr.dumpHistory") defer func() { log.Release("+++++++++++++++++++++++++++++++") log.Release("") }() for _, v := range sm.history { log.Release(" %s,%d*%d=%d", v.NickName, v.Base, v.Multiple, v.Base*v.Multiple) } } func (sm *signinwheelmgr) test(param string) { log.Release("-------------------------------") log.Release("signinwheelmgr.test") defer func() { log.Release("+++++++++++++++++++++++++++++++") log.Release("") }() if !sm.newMgr.isAvailable() { log.Release("new manager not available") return } var testCount int var err error if testCount, err = strconv.Atoi(param); err != nil { log.Release("atoi error %v", err) return } initGold := 0 for i := 0; i < testCount; i++ { initGold -= sm.newMgr.getCost() gold := initGold if gold < 0 { gold = 1 } _, _, items := sm.newMgr.getResult(gold) for _, v := range items { if v.ItemId == 1 { initGold += v.Count } } } log.Release(" after [%d] rolls ,gold = %d", testCount, initGold) } func (sm *signinwheelmgr) testLevel(param string) { log.Release("-------------------------------") log.Release("signinwheelmgr.testLevel") defer func() { log.Release("+++++++++++++++++++++++++++++++") log.Release("") }() if !sm.newMgr.isAvailable() { log.Release("new manager not available") return } testCount := 100000 level := 0 var err error if level, err = strconv.Atoi(param); err != nil { for i := 0; i < sm.newMgr.getMaxLevel(); i++ { result := sm.getLevelResult(level, testCount) d, _ := json.Marshal(result) log.Release(" level[%d] after [%d] rolls ,result = %s", i, testCount, string(d)) } return } result := sm.getLevelResult(level, testCount) d, _ := json.Marshal(result) log.Release(" after [%d] rolls ,result = %s", testCount, string(d)) } func (sm *signinwheelmgr) getLevelResult(level int, testCount int) []*item.ItemPack { gold := sm.newMgr.getGoldByLevel(level) var results []*item.ItemPack for i := 0; i < testCount; i++ { _, _, items := sm.newMgr.getResult(gold) if len(items) == 0 { continue } for _, v := range items { if v.Count == 0 { continue } found := false for _, r := range results { if r.ItemId == v.ItemId { r.Count += v.Count found = true break } } if !found { results = append(results, &item.ItemPack{ItemId: v.ItemId, Count: v.Count}) } } } return results }