| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- package prizewheel
- import (
- "encoding/json"
- "math/rand"
- "sync"
- "time"
- "bet24.com/log"
- "bet24.com/servers/common"
- "bet24.com/servers/coreservice/jackpot"
- "bet24.com/servers/coreservice/serviceconfig"
- inventory "bet24.com/servers/micros/item_inventory/proto"
- item "bet24.com/servers/micros/item_inventory/proto"
- )
- type prizewheelmgr struct {
- prizes []*Prize
- totalChance int
- lock *sync.RWMutex
- UserList map[int]*userPrize
- RecordList []*userPrizeRecord
- }
- type userPrize struct {
- UserId int //用户ID
- Times int //次数
- Crdate int //时间戳
- }
- type userPrizeRecord struct {
- UserId int //用户ID
- NickName string //昵称
- WheelId int //转盘ID
- Items []item.ItemPack //奖励
- Crdate int //时间戳
- }
- func newPrizeWheelManager() *prizewheelmgr {
- pm := new(prizewheelmgr)
- pm.UserList = make(map[int]*userPrize)
- pm.lock = &sync.RWMutex{}
- pm.loadPrizes()
- pm.loadRecord()
- pm.checkDayRefresh()
- log.Debug("prizewheelmgr manager running")
- return pm
- }
- func (pm *prizewheelmgr) loadPrizes() {
- // 从数据库加载配置信息
- pm.prizes = getList()
- //TODO:从数据库获取奖池金额
- pm.totalChance = 0
- for _, v := range pm.prizes {
- pm.totalChance += v.Chance
- }
- }
- func (pm *prizewheelmgr) loadRecord() {
- records := getRecord()
- pm.lock.Lock()
- defer pm.lock.Unlock()
- pm.RecordList = append(pm.RecordList, records...)
- }
- func (pm *prizewheelmgr) checkDayRefresh() {
- ticker := time.NewTicker(10 * time.Minute)
- go func(t *time.Ticker) {
- lastCheck := common.GetTimeStamp()
- for { //循环
- select {
- case <-t.C:
- now := common.GetTimeStamp()
- if !common.IsSameDay(lastCheck, now) {
- pm.refreshUserList()
- }
- lastCheck = now
- }
- }
- }(ticker)
- }
- // 0点过后去数据库刷新在线玩家数据
- func (pm *prizewheelmgr) refreshUserList() {
- dayIndex := common.GetDayIndex(common.GetTimeStamp())
- pm.lock.Lock()
- defer pm.lock.Unlock()
- for _, v := range pm.UserList {
- //过期了
- if common.GetDayIndex(v.Crdate) < dayIndex {
- v.Times = 0
- }
- }
- }
- func (pm *prizewheelmgr) onUserEnter(userId int) {
- //TODO: 去数据库获取今日剩余抽奖次数 count
- u := new(userPrize)
- u.UserId = userId
- u.Times, u.Crdate = getInfo(userId)
- //判断是否过期,过期清零
- if common.GetDayIndex(u.Crdate) < common.GetDayIndex(common.GetTimeStamp()) {
- u.Times = 0
- }
- pm.lock.Lock()
- pm.UserList[userId] = u
- pm.lock.Unlock()
- }
- func (pm *prizewheelmgr) onUserExit(userId int) {
- pm.lock.Lock()
- defer pm.lock.Unlock()
- delete(pm.UserList, userId)
- }
- func (pm *prizewheelmgr) getPrizes() []*Prize {
- pm.lock.RLock()
- defer pm.lock.RUnlock()
- return pm.prizes
- }
- func (pm *prizewheelmgr) getWheelTimes(userId int) (int, int, int) {
- pm.lock.RLock()
- u, ok := pm.UserList[userId]
- pm.lock.RUnlock()
- if !ok {
- u = new(userPrize)
- u.UserId = userId
- u.Times, u.Crdate = getInfo(userId)
- //判断是否过期,过期清零
- if common.GetDayIndex(u.Crdate) < common.GetDayIndex(common.GetTimeStamp()) {
- u.Times = 0
- }
- pm.lock.Lock()
- pm.UserList[userId] = u
- pm.lock.Unlock()
- }
- return u.Times, serviceconfig.SpecialCfg.PrizeTimes, serviceconfig.SpecialCfg.PrizeCost
- }
- // 摇奖,返回中奖结果
- func (pm *prizewheelmgr) wheel(userId, count int, nickName, ipAddress string) ([]*Prize, string) {
- var ret []*Prize
- if count <= 0 {
- log.Debug("prizewheelmgr.wheel count <= 0")
- return ret, "转盘不可用"
- }
- pm.lock.RLock()
- u, ok := pm.UserList[userId]
- pm.lock.RUnlock()
- if !ok {
- log.Debug("prizewheelmgr.wheel userId(%d) is not exist, count=%d", userId, count)
- return ret, "无效数据"
- }
- //是否还有抽奖次数
- if count > serviceconfig.SpecialCfg.PrizeTimes-u.Times {
- log.Debug("prizewheelmgr.wheel count <= %d", u.Times)
- return ret, "没有抽奖次数"
- }
- //lotteryCount, consumeAmount, amount := count, count, 0
- //
- //// 先判断抽奖券是否足够
- //if item := inventory.GetUserLottery(userId); item != nil {
- // // 抽奖券不够,有多少扣多少
- // if item.Count < count {
- // lotteryCount = item.Count
- // }
- //
- // consumeAmount = count - lotteryCount
- //}
- //
- //// 再判断金币是否足够
- //if consumeAmount > 0 {
- // // 去数据库扣钱
- // amount = consumeAmount * serviceconfig.SpecialCfg.PrizeCost
- //
- // if _, gold, _ := cash.GetMoney(userId); gold < amount {
- // return ret, "金币不足"
- // }
- //}
- //
- ////扣减抽奖券
- //if lotteryCount > 0 {
- // if success, _ := inventory.ConsumeLottery(userId, lotteryCount); !success {
- // amount = count * serviceconfig.SpecialCfg.PrizeCost
- // }
- //}
- //
- ////扣减金币
- //if amount > 0 {
- // reduceGoldFailed := cash.ReduceMoney(userId, amount, common.LOGTYPE_PRIZEWHEEL_CONSUME,
- // "幸运抽奖", "幸运抽奖", ipAddress)
- // if reduceGoldFailed != 1 {
- // return ret, "金币不足"
- // }
- //}
- //加上抽奖次数
- u.Times += count
- //TODO: 通知数据库扣减抽奖次数
- go updateInfo(userId, u.Times)
- for i := 0; i < count; i++ {
- p := pm.getRandomPrize()
- if p == nil {
- continue
- }
- ret = append(ret, p)
- }
- go pm.sendAwards(userId, nickName, ret)
- return ret, "OK"
- }
- func (pm *prizewheelmgr) getRandomPrize() *Prize {
- if pm.totalChance == 0 {
- log.Debug("prizewheelmgr.getRandomPrize() totalChance == 0")
- return nil
- }
- result := rand.Intn(pm.totalChance)
- current := 0
- for _, v := range pm.prizes {
- if result < current+v.Chance {
- return v
- }
- current += v.Chance
- }
- log.Debug("prizewheelmgr.getRandomPrize() no result error current = %d,result = %d,totalChance = %d", current, result, pm.totalChance)
- return nil
- }
- func (pm *prizewheelmgr) dump(param1, param2 string) {
- log.Debug("-------------------------------")
- log.Debug("prizewheelmgr.dump %s %s", param1, param2)
- defer func() {
- log.Debug("+++++++++++++++++++++++++++++++")
- log.Debug("")
- }()
- for _, v := range pm.prizes {
- log.Debug(" %d:%d:%v", v.Id, v.Chance, v.Items)
- }
- }
- func (pm *prizewheelmgr) sendAwards(userId int, nickName string, prizes []*Prize) {
- if len(prizes) == 0 {
- log.Debug("prizewheelmgr.sendAwards[%d] no prizes", userId)
- return
- }
- var items []item.ItemPack
- for _, v := range prizes {
- for _, i := range v.Items {
- if i.ItemId == item.Item_Gold {
- go jackpot.ModifyJackpot(0, -i.Count, userId, "中奖", false)
- go pm.addRecord(userId, v.Id, nickName, v.Items)
- }
- }
- items = append(items, v.Items...)
- }
- inventory.AddItems(userId, items, "彩票刮奖", common.LOGTYPE_PRIZEWHEEL_GIFT)
- }
- func (pm *prizewheelmgr) addRecord(userId, wheelId int, nickName string, items []item.ItemPack) {
- pm.lock.Lock()
- //只保留最近50条
- if len(pm.RecordList) >= 50 {
- pm.RecordList = append(pm.RecordList[:0], pm.RecordList[1:]...)
- }
- pm.RecordList = append(pm.RecordList, &userPrizeRecord{
- UserId: userId,
- NickName: nickName,
- WheelId: wheelId,
- Items: items,
- Crdate: common.GetTimeStamp(),
- })
- pm.lock.Unlock()
- buff, err := json.Marshal(items)
- if err != nil {
- log.Error("prizeWheelMgr.SendAwards userId[%d] wheelId[%d] items=%v", userId, wheelId, items)
- return
- }
- //添加记录
- addRecord(userId, wheelId, string(buff))
- }
- func (pm *prizewheelmgr) getRecord() []*userPrizeRecord {
- pm.lock.RLock()
- defer pm.lock.RUnlock()
- return pm.RecordList
- }
|