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
}