You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
5.5 KiB
217 lines
5.5 KiB
|
1 year ago
|
package crash
|
||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"server/call"
|
||
|
|
"server/common"
|
||
|
|
"server/db"
|
||
|
|
"server/game"
|
||
|
|
"server/pb"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
timewheel "github.com/liangdas/mqant/module/modules/timer"
|
||
|
|
)
|
||
|
|
|
||
|
|
type Table struct {
|
||
|
|
*game.Table
|
||
|
|
Result int64
|
||
|
|
StartFlyTime int64
|
||
|
|
FlyTime int
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewTable() game.SubTable {
|
||
|
|
t := &Table{}
|
||
|
|
return t
|
||
|
|
}
|
||
|
|
|
||
|
|
func (t *Table) Init(table *game.Table) {
|
||
|
|
t.Table = table
|
||
|
|
table.NewMillionSubTable()
|
||
|
|
table.MillionSubTableInter = t
|
||
|
|
}
|
||
|
|
|
||
|
|
func (t *Table) Reset() {
|
||
|
|
t.StartFlyTime = 0
|
||
|
|
t.FlyTime = 0
|
||
|
|
t.MillionSubTable.Reset()
|
||
|
|
}
|
||
|
|
|
||
|
|
func (t *Table) Enter(player *game.Player) {
|
||
|
|
player.SubPlayer = NewPlayer(player)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (t *Table) StartGame() {
|
||
|
|
dur := t.Config.BetTime
|
||
|
|
t.OperateTimeout = dur*1000 + time.Now().UnixMilli()
|
||
|
|
t.StartFlyingTimer(time.Duration(dur) * time.Second)
|
||
|
|
resp := &pb.CrashMsgGameStartResp{
|
||
|
|
TimeLeft: int64(dur),
|
||
|
|
}
|
||
|
|
t.Broadcast(int(pb.GameProtocol_GameStartResp), resp)
|
||
|
|
}
|
||
|
|
|
||
|
|
// SettleResult 获取结算结果
|
||
|
|
func (t *Table) SettleResult() {
|
||
|
|
// diff := time.Now().UnixMilli() - t.StartFlyTime
|
||
|
|
// t.Debug("fly diff:%v", diff)
|
||
|
|
t.Result = GetOdds(int64(t.FlyTime)) + 100
|
||
|
|
t.Debug("result:%v", t.Result)
|
||
|
|
l := len(t.History)
|
||
|
|
t.History = append([]int64{t.Result}, t.History...)
|
||
|
|
if l >= MaxHistoryLen {
|
||
|
|
t.History = t.History[:MaxHistoryLen]
|
||
|
|
}
|
||
|
|
if call.IsMainServer(game.ThisGameID) {
|
||
|
|
db.Redis().SetJsonData(common.GetRedisKeyGameResult(game.ThisGameID, t.Room.RoomId()), t.History)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (t *Table) Settle() {
|
||
|
|
t.Debug("settle")
|
||
|
|
t.SettleResult()
|
||
|
|
dur := t.Config.SettleTime * 1000
|
||
|
|
t.SettleGameTimer(time.Duration(dur) * time.Millisecond)
|
||
|
|
now := time.Now().UnixMilli()
|
||
|
|
t.OperateTimeout = now + dur
|
||
|
|
for _, v := range t.GetSeats() {
|
||
|
|
p := v.(*game.Player).SubPlayer.(*Player)
|
||
|
|
p.MillionSettle()
|
||
|
|
}
|
||
|
|
for _, v := range t.GetSeats() {
|
||
|
|
p := v.(*game.Player).SubPlayer.(*Player)
|
||
|
|
resp := &pb.CrashMsgGameSettleResp{
|
||
|
|
TimeLeft: dur,
|
||
|
|
Result: t.Result,
|
||
|
|
SettleAmount: p.FinalSettle,
|
||
|
|
}
|
||
|
|
p.Send(int(pb.GameProtocol_GameSettleResp), resp)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetResult 返回开奖区域
|
||
|
|
func (t *Table) GetResult() (string, string) {
|
||
|
|
res := fmt.Sprintf("%v", t.Result)
|
||
|
|
return res, res
|
||
|
|
}
|
||
|
|
|
||
|
|
// MaxSeats 返回最大座位数
|
||
|
|
func (t *Table) MaxSeats() int {
|
||
|
|
return game.MillionMaxSeat
|
||
|
|
}
|
||
|
|
|
||
|
|
func (t *Table) Destroy() {
|
||
|
|
t.Debug("sub Destroy")
|
||
|
|
}
|
||
|
|
|
||
|
|
// StartFlyingTimer 火箭飞行计时器
|
||
|
|
func (t *Table) StartFlyingTimer(dur time.Duration) {
|
||
|
|
t.Timer = fmt.Sprintf("flying_%v", t.TableId())
|
||
|
|
timewheel.GetTimeWheel().AddTimerCustom(dur, t.Timer, nil, func(arge interface{}) {
|
||
|
|
t.Debug("flying timer callback")
|
||
|
|
t.PutQueue("nf", t.Fly)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// Fly 火箭开始飞行
|
||
|
|
func (t *Table) Fly() {
|
||
|
|
t.Debug("start flying")
|
||
|
|
waterCon := call.GetConfigWaterReal(game.ThisGameID, t.Room.RoomId())
|
||
|
|
rtp := waterCon.Rtp
|
||
|
|
if waterCon.Value > waterCon.WaterUp {
|
||
|
|
rtp = waterCon.UpRtp
|
||
|
|
} else if waterCon.Value < waterCon.WaterLower {
|
||
|
|
rtp = waterCon.DownRtp
|
||
|
|
}
|
||
|
|
t.FlyTime = t.CalFlyingTime(rtp)
|
||
|
|
|
||
|
|
t.StartFlyTime = time.Now().UnixMilli()
|
||
|
|
t.Status = pb.GameStatus_GameStatusSpecial
|
||
|
|
t.Timer = fmt.Sprintf("fly_%v", t.TableId())
|
||
|
|
|
||
|
|
// t.OperateTimeout = t.StartFlyTime
|
||
|
|
dur := time.Duration(t.FlyTime) * time.Millisecond
|
||
|
|
timewheel.GetTimeWheel().AddTimerCustom(dur, t.Timer, nil, func(arge interface{}) {
|
||
|
|
t.Put("nf", func() {
|
||
|
|
t.DelaySettle()
|
||
|
|
})
|
||
|
|
})
|
||
|
|
t.Debug("flyTime:%v", t.FlyTime)
|
||
|
|
t.Broadcast(int(pb.CrashProtocol_CrashFlyingStartResp), &pb.GameCommonResp{})
|
||
|
|
// 设定玩家自动退出
|
||
|
|
for _, v := range t.GetSeats() {
|
||
|
|
p := v.(*game.Player).SubPlayer.(*Player)
|
||
|
|
p.AutoCashoutOdd = p.SetAutoCashoutOdd
|
||
|
|
if p.AutoCashoutOdd == 0 || p.TotalBet == 0 {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
p.AutoCashoutTimer = fmt.Sprintf("autocashout%v", p.UID)
|
||
|
|
timewheel.GetTimeWheel().AddTimerCustom(time.Duration(GetFlyTime(p.AutoCashoutOdd-100))*time.Millisecond, p.AutoCashoutTimer, nil, func(arge interface{}) {
|
||
|
|
t.PutQueue("nf", func() {
|
||
|
|
p.AutoCashOut()
|
||
|
|
})
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (t *Table) CalFlyingTime(rtp int64) int {
|
||
|
|
t.Debug("CalFlyingTime rtp:%v", rtp)
|
||
|
|
var odd int64 = 100
|
||
|
|
origin := t.Ran.Int63n(MaxWeight) // 随机一个数
|
||
|
|
for i := int64(100); i <= MaxOdd; i++ { // 判断随机数落在哪个权重区间
|
||
|
|
total := rtp * MaxWeight / i / 100 // 由于rtp为万分位,i为扩大了一百倍的倍率,所以分母需要再除以100
|
||
|
|
if origin >= total {
|
||
|
|
odd = i
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
odd -= 100 // 获取的倍数为赢的额外倍数
|
||
|
|
|
||
|
|
period := GetFlyTime(odd)
|
||
|
|
t.Debug("period:%v,odd:%v", period, odd)
|
||
|
|
if period <= 0 {
|
||
|
|
return t.Ran.Intn(95) + 5
|
||
|
|
}
|
||
|
|
return int(period)
|
||
|
|
}
|
||
|
|
|
||
|
|
// CalOdds 计算赔率
|
||
|
|
func (t *Table) CalOdds() (odds int64) {
|
||
|
|
now := time.Now().UnixMilli()
|
||
|
|
diff := now - t.StartFlyTime
|
||
|
|
return GetOdds(diff)
|
||
|
|
}
|
||
|
|
|
||
|
|
// DelaySettle 判断是否延迟结算
|
||
|
|
func (t *Table) DelaySettle() {
|
||
|
|
// 当前还未退出的真实玩家为0,延长飞行时间
|
||
|
|
// if t.CountRealPlayings() == 0 && t.FlyTime < MaxFlyTime {
|
||
|
|
// // 延迟飞行不会飞到jackpot
|
||
|
|
// mf := MaxFlyTime - t.FlyTime - 100
|
||
|
|
// if mf <= 0 {
|
||
|
|
// t.Table.Settle()
|
||
|
|
// return
|
||
|
|
// }
|
||
|
|
// if mf > 3000 {
|
||
|
|
// mf = 3000
|
||
|
|
// }
|
||
|
|
// t.FlyTime += t.Ran.Intn(mf)
|
||
|
|
// now := time.Now().UnixMilli()
|
||
|
|
// diff := int64(t.FlyTime) - (now - t.StartFlyTime)
|
||
|
|
// if t.FlyTime > MaxFlyTime {
|
||
|
|
// diff = int64(MaxFlyTime) - (now - t.StartFlyTime)
|
||
|
|
// }
|
||
|
|
// t.Debug("fly delay:%v,diff:%v", t.FlyTime, diff)
|
||
|
|
// t.Timer = fmt.Sprintf("table%vdelaySettle", t.TableId())
|
||
|
|
// if diff <= 0 {
|
||
|
|
// t.Table.Settle()
|
||
|
|
// } else {
|
||
|
|
// timewheel.GetTimeWheel().AddTimerCustom(time.Duration(diff)*time.Millisecond, t.Timer, nil, func(arge interface{}) {
|
||
|
|
// t.Put("settle")
|
||
|
|
// })
|
||
|
|
// }
|
||
|
|
// return
|
||
|
|
// }
|
||
|
|
t.Table.Settle()
|
||
|
|
}
|