/* 免费筹码逻辑 1.每天0点6点12点18点重置免费筹码,过期清零,写入Redis 2.每天免费配额为500,配额为0时,则表示没有免费筹码,不显示使用次数,前端自己判断 3.使用免费筹码下注时,只要下注额大于免费配额,则允许下注,否则提示下注失败,下注成功返回剩余额度 4.免费筹码下注时,记下注次数,不计入下注额度,写下注记录时下注额为0 5.获胜则按照实际下注额返还金币 6.用户登录时,检查是否有免费配额,有则显示具体金额,0也算有效,没有记录则重置免费配额,并写入Redis */ package gamelogic import ( "encoding/json" "fmt" "sync" "time" "bet24.com/log" "bet24.com/redis" "bet24.com/servers/games/luckyfruit_table/common" "bet24.com/servers/games/luckyfruit_table/config" "bet24.com/servers/transaction" ) const FreeChipsKey = "freeChips" type freeChips struct { Chips map[int]int LastHour int //前一次刷新时间 lock *sync.RWMutex changeCallback func() roomInfo *config.RoomInfo } func newFreeChips(roomInfo *config.RoomInfo, callback func()) *freeChips { ret := new(freeChips) ret.lock = &sync.RWMutex{} ret.Chips = make(map[int]int) ret.roomInfo = roomInfo //获得最接近的时间0 6 12 18 ret.LastHour = getNearHour() // 从redis中获取数据 key := FreeChipsKey data, _ := redis.String_Get(common.GetRedisKey(key)) if data == "" { // redis中没有数据 ret.freeChipsToRedis() } else { // redis中有数据 err := json.Unmarshal([]byte(data), ret) if err != nil { log.Release("freeChips json.Unmarshal err:%v", err) } } // 保存回调函数 ret.changeCallback = callback //起一个定时器,固定时间清除数据 ret.startTimer() return ret } func (fc *freeChips) startTimer() { fc.checkFreeChips() go time.AfterFunc(1*time.Minute, fc.startTimer) } // 检查免费筹码数量 func (fc *freeChips) checkFreeChipsNum(userId int) (int, int) { fc.lock.RLock() data, ok := fc.Chips[userId] fc.lock.RUnlock() if ok { return data, fc.LastHour } fc.lock.Lock() //不存在则重置 freeChipsLimit := fc.roomInfo.FreeChipsLimit fc.Chips[userId] = freeChipsLimit fc.lock.Unlock() fc.freeChipsToRedis() go transaction.WriteFreeChipRecord(userId, common.GAMEID, freeChipsLimit, 1) return freeChipsLimit, fc.LastHour } // 扣除免费筹码 func (fc *freeChips) useFreeChips(userId int, bet int) (bool, int) { fc.lock.RLock() data, ok := fc.Chips[userId] fc.lock.RUnlock() if ok { if data >= bet { data -= bet fc.lock.Lock() fc.Chips[userId] = data fc.lock.Unlock() fc.freeChipsToRedis() go transaction.WriteFreeChipRecord(userId, common.GAMEID, bet, -1) return true, data } return false, data } return false, 0 } // 下注失败返还筹码 func (fc *freeChips) addFreeChips(userId int, bet int) { fc.lock.RLock() data, ok := fc.Chips[userId] fc.lock.RUnlock() if ok { data += bet fc.lock.Lock() fc.Chips[userId] = data fc.lock.Unlock() fc.freeChipsToRedis() go transaction.WriteFreeChipRecord(userId, common.GAMEID, bet, 1) } } // 检查免费卷是否需要刷新 func (fc *freeChips) checkFreeChips() { now := time.Now() hour := now.Hour() lastHour := fc.LastHour //每天0点6点12点18点重置免费筹码,重置过,则跳过 if hour == 0 || hour == 6 || hour == 12 || hour == 18 { if lastHour != hour { fc.resetFreeChips() fc.changeCallback() } return } } // 每天0点6点12点18点重置免费筹码 func (fc *freeChips) resetFreeChips() { fc.lock.Lock() fc.Chips = make(map[int]int) fc.LastHour = time.Now().Hour() fc.lock.Unlock() fc.freeChipsToRedis() } func (fc *freeChips) freeChipsToRedis() { key := FreeChipsKey fc.lock.RLock() data, err := json.Marshal(fc) fc.lock.RUnlock() if err != nil { fmt.Println("freeChips json.Marshal err:", err) return } redis.String_Set(common.GetRedisKey(key), string(data)) } func getNearHour() int { now := time.Now() hour := now.Hour() if hour < 6 { return 0 } else if hour < 12 { return 6 } else if hour < 18 { return 12 } else { return 18 } }