Commit e22ff037 authored by 张振华's avatar 张振华

guess

parent af1ce4be
...@@ -14,12 +14,17 @@ func (c *Guess) Exec_Start(payload *pkt.GuessGameStart, tx *types.Transaction, i ...@@ -14,12 +14,17 @@ func (c *Guess) Exec_Start(payload *pkt.GuessGameStart, tx *types.Transaction, i
return action.GameStart(payload) return action.GameStart(payload)
} }
func (c *Guess) Exec_Continue(payload *pkt.PBGameContinue, tx *types.Transaction, index int) (*types.Receipt, error) { func (c *Guess) Exec_Bet(payload *pkt.GuessGameBet, tx *types.Transaction, index int) (*types.Receipt, error) {
action := NewAction(c, tx, index) action := NewAction(c, tx, index)
return action.GameContinue(payload) return action.GameBet(payload)
} }
func (c *Guess) Exec_Quit(payload *pkt.PBGameQuit, tx *types.Transaction, index int) (*types.Receipt, error) { func (c *Guess) Exec_Publish(payload *pkt.GuessGamePublish, tx *types.Transaction, index int) (*types.Receipt, error) {
action := NewAction(c, tx, index) action := NewAction(c, tx, index)
return action.GameQuit(payload) return action.GamePublish(payload)
}
func (c *Guess) Exec_Abort(payload *pkt.GuessGameAbort, tx *types.Transaction, index int) (*types.Receipt, error) {
action := NewAction(c, tx, index)
return action.GameAbort(payload)
} }
\ No newline at end of file
...@@ -10,6 +10,8 @@ import ( ...@@ -10,6 +10,8 @@ import (
"github.com/33cn/chain33/client" "github.com/33cn/chain33/client"
"sort" "sort"
"strconv" "strconv"
"strings"
"time"
"github.com/33cn/chain33/account" "github.com/33cn/chain33/account"
"github.com/33cn/chain33/common" "github.com/33cn/chain33/common"
...@@ -24,10 +26,18 @@ const ( ...@@ -24,10 +26,18 @@ const (
ListASC = int32(1) ListASC = int32(1)
DefaultCount = int32(20) //默认一次取多少条记录 DefaultCount = int32(20) //默认一次取多少条记录
MaxBets = 10000
MaxBetsNumber = 100000 MaxBetsNumber = 100000
MaxHeight = 1000000000 MaxHeight = 10000000000
MinBetBlockNum = 720
MinBetTimeInterval = "2h" //2h
MinBetTimeoutNum = 8640
MinBetTimeoutInterval = "24h" //24h
MIN_PLAY_VALUE = 10 * types.Coin MIN_PLAY_VALUE = 10 * types.Coin
//DefaultStyle = pkt.PlayStyleDefault //DefaultStyle = pkt.PlayStyleDefault
MinOneBet = 1
) )
type Action struct { type Action struct {
...@@ -198,7 +208,7 @@ func (action *Action) saveGame(game *pkt.GuessGame) (kvset []*types.KeyValue) { ...@@ -198,7 +208,7 @@ func (action *Action) saveGame(game *pkt.GuessGame) (kvset []*types.KeyValue) {
return kvset return kvset
} }
func (action *Action) getIndex(game *pkt.PokerBull) int64 { func (action *Action) getIndex() int64 {
return action.height*types.MaxTxsPerBlock + int64(action.index) return action.height*types.MaxTxsPerBlock + int64(action.index)
} }
...@@ -210,10 +220,14 @@ func (action *Action) GetReceiptLog(game *pkt.GuessGame) *types.ReceiptLog { ...@@ -210,10 +220,14 @@ func (action *Action) GetReceiptLog(game *pkt.GuessGame) *types.ReceiptLog {
log.Ty = pkt.TyLogGuessGameStart log.Ty = pkt.TyLogGuessGameStart
} else if game.Status == pkt.GuessGameActionBet { } else if game.Status == pkt.GuessGameActionBet {
log.Ty = pkt.TyLogGuessGameBet log.Ty = pkt.TyLogGuessGameBet
} else if game.Status == pkt.GuessGameActionStopBet {
log.Ty = pkt.TyLogGuessGameStopBet
} else if game.Status == pkt.GuessGameActionAbort { } else if game.Status == pkt.GuessGameActionAbort {
log.Ty = pkt.TyLogGuessGameAbort log.Ty = pkt.TyLogGuessGameAbort
} else if game.Status == pkt.GuessGameActionPublish { } else if game.Status == pkt.GuessGameActionPublish {
log.Ty = pkt.TyLogGuessGamePublish log.Ty = pkt.TyLogGuessGamePublish
} else if game.Status == pkt.GuessGameActionTimeOut {
log.Ty = pkt.TyLogGuessGameTimeout
} }
r.GameId = game.GameId r.GameId = game.GameId
...@@ -222,7 +236,7 @@ func (action *Action) GetReceiptLog(game *pkt.GuessGame) *types.ReceiptLog { ...@@ -222,7 +236,7 @@ func (action *Action) GetReceiptLog(game *pkt.GuessGame) *types.ReceiptLog {
return log return log
} }
func (action *Action) readGame(id string) (*pkt.PokerBull, error) { func (action *Action) readGame(id string) (*pkt.GuessGame, error) {
data, err := action.db.Get(Key(id)) data, err := action.db.Get(Key(id))
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -479,7 +493,7 @@ func (action *Action) newGame(gameId string, start *pkt.GuessGameStart) (*pkt.Gu ...@@ -479,7 +493,7 @@ func (action *Action) newGame(gameId string, start *pkt.GuessGameStart) (*pkt.Gu
Expire: start.Expire, Expire: start.Expire,
ExpireHeight: start.ExpireHeight, ExpireHeight: start.ExpireHeight,
//AdminAddr: action.fromaddr, //AdminAddr: action.fromaddr,
BetsNumber: 0,
//Index: action.getIndex(game), //Index: action.getIndex(game),
} }
...@@ -539,81 +553,60 @@ func (action *Action) GameStart(start *pkt.GuessGameStart) (*types.Receipt, erro ...@@ -539,81 +553,60 @@ func (action *Action) GameStart(start *pkt.GuessGameStart) (*types.Receipt, erro
if start.MaxHeight >= MaxHeight { if start.MaxHeight >= MaxHeight {
logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr, logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr,
"err", fmt.Sprintf("The maximum height number is %d", MaxHeight)) "err", fmt.Sprintf("The maximum height number is %d which is less thanstart.MaxHeight %d", MaxHeight, start.MaxHeight))
return nil, types.ErrInvalidParam return nil, types.ErrInvalidParam
} }
if start.MaxBetsNumber >= MaxBetsNumber { if start.MaxBetsNumber >= MaxBetsNumber {
logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr, logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr,
"err", fmt.Sprintf("The maximum bets number is %d", MaxBetsNumber)) "err", fmt.Sprintf("The maximum bets number is %d which is less than start.MaxBetsNumber %d", MaxBetsNumber, start.MaxBetsNumber))
return nil, types.ErrInvalidParam return nil, types.ErrInvalidParam
} }
gameId := common.ToHex(action.txhash) if len(start.Topic) == 0 || len(start.Options) == 0 {
/* logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr,
if !action.CheckExecAccountBalance(action.fromaddr, start.GetValue()*POKERBULL_LEVERAGE_MAX, 0) { "err", fmt.Sprintf("Illegal parameters,Topic:%s | options: %s | category: %s", start.Topic, start.Options, start.Category))
logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr, "id", gameId, "err", types.ErrNoBalance) return nil, types.ErrInvalidParam
return nil, types.ErrNoBalance
} }
if action.checkPlayerExistInGame() { if _, ok := getOptions(start.Options); !ok {
logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr, "err", "Address is already in a game") logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr,
return nil, fmt.Errorf("Address is already in a game") "err", fmt.Sprintf("The options is illegal:%s", start.Options))
}*/ return nil, types.ErrInvalidParam
}
var game *pkt.GuessGame = nil if !action.CheckTime() {
/* logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr,
ids, err := queryGameListByStatusAndPlayer(action.localDB, pkt.PBGameActionStart, start.PlayerNum, start.Value) "err", fmt.Sprintf("The height and time parameters are illegal:MaxTime %s MaxHeight %d Expire %s, ExpireHeight %d", start.MaxTime, start.MaxHeight, start.Expire, start.ExpireHeight))
if err != nil || len(ids) == 0 { return nil, types.ErrInvalidParam
if err != types.ErrNotFound { }
return nil, err
}
game, err = action.newGame(gameId, start) if len(start.Symbol) == 0 {
if err != nil { start.Symbol = "bty"
return nil, err }
}
} else { if len(start.Exec) == 0 {
game = action.selectGameFromIds(ids, start.GetValue()) start.Exec = "coins"
if game == nil { }
// 如果也没有匹配到游戏,则按照最低赌注创建
game, err = action.newGame(gameId, start) if start.OneBet < MinOneBet {
if err != nil { start.OneBet = MinOneBet
return nil, err }
}
} if start.MaxBets >= MaxBets {
}*/ start.MaxBets = MaxBets
}
gameId := common.ToHex(action.txhash)
var game *pkt.GuessGame = nil
game, err := action.newGame(gameId, start) game, err := action.newGame(gameId, start)
if err != nil { if err != nil {
return nil, err return nil, err
} }
game.StartTime = action.blocktime game.StartTime = action.blocktime
game.AdminAddr = action.fromaddr game.AdminAddr = action.fromaddr
game.Index = action.getIndex()
game.Status = pkt.GuessGameActionStart
// 如果人数达标,则发牌计算斗牛结果
if len(game.Players) == int(game.PlayerNum) {
logsH, kvH, err := action.settleAccount(action.fromaddr, game)
if err != nil {
return nil, err
}
logs = append(logs, logsH...)
kv = append(kv, kvH...)
game.PrevIndex = game.Index
game.Index = action.getIndex(game)
game.Status = pkt.PBGameActionContinue // 更新游戏状态
game.PreStatus = pkt.PBGameActionStart
game.IsWaiting = false
} else {
receipt, err := action.coinsAccount.ExecFrozen(action.fromaddr, action.execaddr, start.GetValue()*POKERBULL_LEVERAGE_MAX) //冻结子账户资金, 最后一位玩家不需要冻结
if err != nil {
logger.Error("GameCreate.ExecFrozen", "addr", action.fromaddr, "execaddr", action.execaddr, "amount", start.GetValue(), "err", err.Error())
return nil, err
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
}
receiptLog := action.GetReceiptLog(game) receiptLog := action.GetReceiptLog(game)
logs = append(logs, receiptLog) logs = append(logs, receiptLog)
kv = append(kv, action.saveGame(game)...) kv = append(kv, action.saveGame(game)...)
...@@ -640,157 +633,351 @@ func getPlayerFromAddress(players []*pkt.PBPlayer, addr string) *pkt.PBPlayer { ...@@ -640,157 +633,351 @@ func getPlayerFromAddress(players []*pkt.PBPlayer, addr string) *pkt.PBPlayer {
return nil return nil
} }
func (action *Action) GameContinue(pbcontinue *pkt.PBGameContinue) (*types.Receipt, error) { func (action *Action) GameBet(pbBet *pkt.GuessGameBet) (*types.Receipt, error) {
var logs []*types.ReceiptLog var logs []*types.ReceiptLog
var kv []*types.KeyValue var kv []*types.KeyValue
game, err := action.readGame(pbcontinue.GetGameId()) game, err := action.readGame(pbBet.GetGameId())
if err != nil { if err != nil {
logger.Error("GameContinue", "addr", action.fromaddr, "execaddr", action.execaddr, "get game failed", logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "get game failed",
pbcontinue.GetGameId(), "err", err) pbBet.GetGameId(), "err", err)
return nil, err return nil, err
} }
if game.Status != pkt.PBGameActionContinue { if game.Status != pkt.GuessGameActionStart && game.Status != pkt.GuessGameActionBet && game.Status != pkt.GuessGameActionStopBet{
logger.Error("GameContinue", "addr", action.fromaddr, "execaddr", action.execaddr, "Status error", logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "Status error",
pbcontinue.GetGameId()) game.GetStatus())
return nil, err return nil, errors.New("ErrGameStatus")
}
if action.RefreshStatusByTime(game) {
receiptLog := action.GetReceiptLog(game)
logs = append(logs, receiptLog)
kv = append(kv, action.saveGame(game)...)
return &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}, nil
}
//更新游戏状态
game.Status = pkt.GuessGameActionBet
//检查竞猜选项是否合法
options, legal := getOptions(game.GetOptions())
if !legal || len(options) == 0{
logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "Game Options illegal",
game.GetOptions())
return nil, types.ErrInvalidParam
}
if !isLegalOption(options, pbBet.GetOption()) {
logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "Option illegal",
pbBet.GetOption())
return nil, types.ErrInvalidParam
}
//检查下注金额是否超限,如果超限,按最大值
if pbBet.GetBetsNum() > game.GetMaxBets() {
pbBet.BetsNum = game.GetMaxBets()
} }
// 检查余额,庄家检查闲家数量倍数的资金 if game.BetsNumber + pbBet.GetBetsNum() > game.MaxBetsNumber {
checkValue := game.GetValue() * POKERBULL_LEVERAGE_MAX logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "MaxBetsNumber over limit",
if action.fromaddr == game.DealerAddr { game.MaxBetsNumber, "current Bets Number", game.BetsNumber)
checkValue = checkValue * int64(game.PlayerNum-1) return nil, types.ErrInvalidParam
} }
// 检查余额账户余额
checkValue := int64(game.GetOneBet() * pbBet.BetsNum)
if !action.CheckExecAccountBalance(action.fromaddr, checkValue, 0) { if !action.CheckExecAccountBalance(action.fromaddr, checkValue, 0) {
logger.Error("GameContinue", "addr", action.fromaddr, "execaddr", action.execaddr, "id", logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "id",
pbcontinue.GetGameId(), "err", types.ErrNoBalance) pbBet.GetGameId(), "err", types.ErrNoBalance)
return nil, types.ErrNoBalance return nil, types.ErrNoBalance
} }
// 寻找对应玩家 receipt, err := action.coinsAccount.ExecFrozen(action.fromaddr, action.execaddr, checkValue)
pbplayer := getPlayerFromAddress(game.Players, action.fromaddr) if err != nil {
if pbplayer == nil { logger.Error("GameCreate.ExecFrozen", "addr", action.fromaddr, "execaddr", action.execaddr, "amount", checkValue, "err", err.Error())
logger.Error("GameContinue", "addr", action.fromaddr, "execaddr", action.execaddr, "get game player failed", return nil, err
pbcontinue.GetGameId(), "err", types.ErrNotFound)
return nil, types.ErrNotFound
} }
if pbplayer.Ready {
logger.Error("GameContinue", "addr", action.fromaddr, "execaddr", action.execaddr, "player has been ready", bet := &pkt.GuessBet{ Option: pbBet.GetOption(), BetsNumber: pbBet.BetsNum}
pbcontinue.GetGameId(), "player", pbplayer.Address) player := &pkt.GuessPlayer{ Addr: action.fromaddr, Bet: bet}
return nil, fmt.Errorf("player %s has been ready", pbplayer.Address) game.Plays = append(game.Plays, player)
exist := false
for i := 0; i < len(game.Bets); i ++ {
if game.Bets[i].Option == pbBet.GetOption() {
exist = true
game.Bets[i].BetsNumber += pbBet.GetBetsNum()
}
} }
//发牌随机数取txhash if !exist {
txrng, err := action.genTxRnd(action.txhash) game.Bets = append(game.Bets, bet)
}
game.BetsNumber += pbBet.GetBetsNum()
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
receiptLog := action.GetReceiptLog(game)
logs = append(logs, receiptLog)
kv = append(kv, action.saveGame(game)...)
return &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}, nil
}
func (action *Action) GamePublish(publish *pkt.GuessGamePublish) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kv []*types.KeyValue
game, err := action.readGame(publish.GetGameId())
if err != nil { if err != nil {
logger.Error("GamePublish", "addr", action.fromaddr, "execaddr", action.execaddr, "get game failed",
publish.GetGameId(), "err", err)
return nil, err return nil, err
} }
pbplayer.TxHash = txrng
pbplayer.Ready = true
if getReadyPlayerNum(game.Players) == int(game.PlayerNum) { //只有adminAddr可以发起publish
logsH, kvH, err := action.settleAccount(action.fromaddr, game) if game.AdminAddr != action.fromaddr {
if err != nil { logger.Error("GamePublish", "addr", action.fromaddr, "execaddr", action.execaddr, "fromAddr is not adminAddr",
return nil, err action.fromaddr, "adminAddr", game.AdminAddr)
return nil, types.ErrInvalidParam
}
if game.Status != pkt.GuessGameActionStart && game.Status != pkt.GuessGameActionBet && game.Status != pkt.GuessGameActionStopBet{
logger.Error("GamePublish", "addr", action.fromaddr, "execaddr", action.execaddr, "Status error",
game.GetStatus())
return nil, errors.New("ErrGameStatus")
}
//检查竞猜选项是否合法
options, legal := getOptions(game.GetOptions())
if !legal || len(options) == 0{
logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "Game Options illegal",
game.GetOptions())
return nil, types.ErrInvalidParam
}
if !isLegalOption(options, publish.GetResult()) {
logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "Option illegal",
publish.GetResult())
return nil, types.ErrInvalidParam
}
game.Status = pkt.GuessGameActionPublish
game.Result = publish.Result
//先遍历所有下注数据,对于输家,转移资金到Admin账户合约地址;
for i := 0; i < len(game.Plays); i++ {
player := game.Plays[i]
//if player.Bet.Option != game.Result {
value := int64(player.Bet.BetsNumber * game.OneBet)
receipt, err := action.coinsAccount.ExecTransfer(player.Addr, game.AdminAddr, action.execaddr, value)
if err != nil {
action.coinsAccount.ExecFrozen(game.AdminAddr, action.execaddr, value) // rollback
logger.Error("GamePublish", "addr", game.AdminAddr, "execaddr", action.execaddr,
"amount", value, "err", err)
return nil, err
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
//}
}
//计算竞猜正确的筹码总数
totalBetsNumber := uint32(0)
winBetsNumber := uint32(0)
for j := 0; j < len(game.Bets); j++ {
if game.Bets[j].Option == game.Result {
winBetsNumber = game.Bets[j].BetsNumber
} }
logs = append(logs, logsH...) totalBetsNumber += game.Bets[j].BetsNumber
kv = append(kv, kvH...) }
game.PrevIndex = game.Index
game.Index = action.getIndex(game) //再遍历赢家,按照投注占比分配所有筹码
game.IsWaiting = false for j := 0; j < len(game.Plays); j++ {
game.PreStatus = pkt.PBGameActionContinue player := game.Plays[j]
} else { if player.Bet.Option == game.Result {
receipt, err := action.coinsAccount.ExecFrozen(action.fromaddr, action.execaddr, game.GetValue()*POKERBULL_LEVERAGE_MAX) //冻结子账户资金,最后一位玩家不需要冻结 value := int64(player.Bet.BetsNumber * totalBetsNumber * game.OneBet/ winBetsNumber)
if err != nil { receipt, err := action.coinsAccount.ExecTransfer(game.AdminAddr, player.Addr, action.execaddr, value)
logger.Error("GameCreate.ExecFrozen", "addr", action.fromaddr, "execaddr", action.execaddr, "amount", game.GetValue(), "err", err.Error()) if err != nil {
return nil, err action.coinsAccount.ExecFrozen(player.Addr, action.execaddr, value) // rollback
logger.Error("GamePublish", "addr", player.Addr, "execaddr", action.execaddr,
"amount", value, "err", err)
return nil, err
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
} }
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
game.IsWaiting = true
} }
receiptLog := action.GetReceiptLog(game) receiptLog := action.GetReceiptLog(game)
logs = append(logs, receiptLog) logs = append(logs, receiptLog)
kv = append(kv, action.saveGame(game)...) kv = append(kv, action.saveGame(game)...)
return &types.Receipt{types.ExecOk, kv, logs}, nil return &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}, nil
} }
func (action *Action) GameQuit(pbend *pkt.PBGameQuit) (*types.Receipt, error) { func (action *Action) GameAbort(pbend *pkt.GuessGameAbort) (*types.Receipt, error) {
var logs []*types.ReceiptLog var logs []*types.ReceiptLog
var kv []*types.KeyValue var kv []*types.KeyValue
game, err := action.readGame(pbend.GetGameId()) game, err := action.readGame(pbend.GetGameId())
if err != nil { if err != nil {
logger.Error("GameEnd", "addr", action.fromaddr, "execaddr", action.execaddr, "get game failed", logger.Error("GameAbort", "addr", action.fromaddr, "execaddr", action.execaddr, "get game failed",
pbend.GetGameId(), "err", err) pbend.GetGameId(), "err", err)
return nil, err return nil, err
} }
// 如果游戏没有开始,激活冻结账户 //根据区块链高度或时间刷新游戏状态。
if game.IsWaiting { action.RefreshStatusByTime(game)
if game.Status == pkt.PBGameActionStart {
for _, player := range game.Players {
receipt, err := action.coinsAccount.ExecActive(player.Address, action.execaddr, game.GetValue()*POKERBULL_LEVERAGE_MAX)
if err != nil {
logger.Error("GameSettleDealer.ExecActive", "addr", player.Address, "execaddr", action.execaddr, "amount", game.GetValue(),
"err", err)
continue
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
}
} else if game.Status == pkt.PBGameActionContinue {
for _, player := range game.Players {
if !player.Ready {
continue
}
receipt, err := action.coinsAccount.ExecActive(player.Address, action.execaddr, game.GetValue()*POKERBULL_LEVERAGE_MAX) //如果游戏超时,则任何地址都可以Abort,否则只有创建游戏的地址可以Abort
if err != nil { if game.Status != pkt.GuessGameActionTimeOut {
logger.Error("GameSettleDealer.ExecActive", "addr", player.Address, "execaddr", action.execaddr, "amount", game.GetValue(), if game.AdminAddr != action.fromaddr {
"err", err) logger.Error("GameAbort", "addr", action.fromaddr, "execaddr", action.execaddr, "Only admin can abort",
continue action.fromaddr, "status", game.Status)
} return nil, err
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
}
} }
game.IsWaiting = false
} }
game.PreStatus = game.Status
game.Status = pkt.PBGameActionQuit //激活冻结账户
game.PrevIndex = game.Index for i := 0; i < len(game.Plays); i++ {
player := game.Plays[i]
value := int64(player.Bet.BetsNumber * game.OneBet)
receipt, err := action.coinsAccount.ExecActive(player.Addr, action.execaddr, )
if err != nil {
logger.Error("GameAbort", "addr", player.Addr, "execaddr", action.execaddr, "amount", value, "err", err)
continue
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
}
game.Status = pkt.GuessGameActionAbort
game.Index = action.getIndex(game) game.Index = action.getIndex(game)
game.QuitTime = action.blocktime
game.QuitTxHash = common.ToHex(action.txhash)
receiptLog := action.GetReceiptLog(game) receiptLog := action.GetReceiptLog(game)
logs = append(logs, receiptLog) logs = append(logs, receiptLog)
kv = append(kv, action.saveGame(game)...) kv = append(kv, action.saveGame(game)...)
return &types.Receipt{types.ExecOk, kv, logs}, nil return &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}, nil
} }
type HandSlice []*pkt.PBHand func getOptions(strOptions string) (options []string, legal bool){
legal = true
items := strings.Split(strOptions, ";")
for i := 0 ; i < len(items); i++ {
item := strings.Split(items[i],":")
for j := 0; j < len(options); j++ {
if item[0] == options[j] {
legal = false
return
}
}
func (h HandSlice) Len() int { options = append(options, item[0])
return len(h) }
return options, legal
} }
func (h HandSlice) Swap(i, j int) { func isLegalOption(options []string, option string) bool {
h[i], h[j] = h[j], h[i] for i := 0; i < len(options); i++ {
if options[i] == option {
return true
}
}
return false
} }
func (h HandSlice) Less(i, j int) bool { func (action *Action) RefreshStatusByTime(game *pkt.GuessGame) bool {
if i >= h.Len() || j >= h.Len() { // 检查区块高度是否超过最大下注高度限制,看是否可以下注
logger.Error("length error. slice length:", h.Len(), " compare lenth: ", i, " ", j) if game.GetMaxHeight() <= action.height {
logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "Height over limit",
action.height, "MaxHeight", game.GetMaxHeight())
if game.GetExpireHeight() > action.height {
game.Status = pkt.GuessGameActionStopBet
} else {
game.Status = pkt.GuessGameActionTimeOut
}
return true
} }
if h[i] == nil || h[j] == nil { // 检查区块高度是否超过下注时间限制,看是否可以下注
logger.Error("nil pointer at ", i, " ", j) if len(game.GetMaxTime()) > 0 {
tMax, err := time.Parse("2006-01-02 15:04:05", game.GetMaxTime())
if err != nil {
logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "Parse MaxTime failed",
game.GetMaxTime())
return false
}
tExpire, err := time.Parse("2006-01-02 15:04:05", game.GetExpire())
if err != nil {
logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "Parse Expire failed",
game.GetExpire())
return false
}
tNow := time.Now()
if tNow.After(tMax) {
logger.Error("GameBet", "addr", action.fromaddr, "execaddr", action.execaddr, "Time over MaxTime",
game.GetMaxTime())
if tNow.After(tExpire) {
game.Status = pkt.GuessGameActionTimeOut
} else {
game.Status = pkt.GuessGameActionStopBet
}
return true
}
} }
return CompareResult(h[i], h[j]) return false
} }
func (action *Action) CheckTime(start *pkt.GuessGameStart) bool {
MinBetTimeInterval = 2 //2h
MinBetTimeoutInterval = 24 //24h
if action.height + MinBetBlockNum > start.MaxHeight || start.MaxHeight + MinBetTimeoutNum > start.ExpireHeight {
return false
}
tNow := time.Now()
d1, _ := time.ParseDuration(MinBetTimeInterval)
d2, _ := time.ParseDuration(MinBetTimeoutInterval)
if len(start.GetMaxTime()) == 0 {
tNow.Add(d1)
start.MaxTime = tNow.Format("2006-01-02 15:04:05")
}
if len(start.GetExpire()) == 0 {
tMax, _ := time.Parse("2006-01-02 15:04:05", start.GetMaxTime())
tMax.Add(d2)
start.Expire = tMax.Format("2006-01-02 15:04:05")
}
tMax, err := time.Parse("2006-01-02 15:04:05", start.GetMaxTime())
if err != nil {
logger.Error("CheckTime", "addr", action.fromaddr, "execaddr", action.execaddr, "Parse MaxTime failed",
start.GetMaxTime())
return false
}
tExpire, err := time.Parse("2006-01-02 15:04:05", start.GetExpire())
if err != nil {
logger.Error("CheckTime", "addr", action.fromaddr, "execaddr", action.execaddr, "Parse Expire failed",
start.GetExpire())
return false
}
if tMax.After(tNow.Add(d1)) && tExpire.After(tMax.Add(d2)){
return true
}
return false
}
\ No newline at end of file
...@@ -14,7 +14,7 @@ import ( ...@@ -14,7 +14,7 @@ import (
func init() { func init() {
pluginmgr.Register(&pluginmgr.PluginBase{ pluginmgr.Register(&pluginmgr.PluginBase{
Name: types.PokerBullX, Name: types.GuessX,
ExecName: executor.GetName(), ExecName: executor.GetName(),
Exec: executor.Init, Exec: executor.Init,
Cmd: commands.GuessCmd, Cmd: commands.GuessCmd,
......
...@@ -14,7 +14,7 @@ message GuessGame { ...@@ -14,7 +14,7 @@ message GuessGame {
string category = 6; //分类 string category = 6; //分类
string options = 7; //选项 string options = 7; //选项
string maxTime = 8; //截止下注时间 string maxTime = 8; //截止下注时间
uint32 maxHeight = 9; //截止下注的块高 int64 maxHeight = 9; //截止下注的块高
string symbol = 10; //bty或者具体token string symbol = 10; //bty或者具体token
string exec = 11; //coins或者token string exec = 11; //coins或者token
uint32 oneBet = 12; //一注等于多少bty或者token uint32 oneBet = 12; //一注等于多少bty或者token
...@@ -23,17 +23,18 @@ message GuessGame { ...@@ -23,17 +23,18 @@ message GuessGame {
uint32 fee = 15; //收取费用,不带则表示不收费 uint32 fee = 15; //收取费用,不带则表示不收费
string feeAddr = 16; //收费地址 string feeAddr = 16; //收费地址
string expire = 17; //游戏过期时间 string expire = 17; //游戏过期时间
uint32 expireHeight = 18; //游戏过期区块高度 int64 expireHeight = 18; //游戏过期区块高度
string adminAddr = 19; //游戏创建者地址,只有该地址可以开奖 string adminAddr = 19; //游戏创建者地址,只有该地址可以开奖
uint32 betsNumber = 20; //已下注数,如果数量达到maxBetsNumber,则不允许再下注 uint32 betsNumber = 20; //已下注数,如果数量达到maxBetsNumber,则不允许再下注
repeated GuessPlayer plays = 21; //参与游戏下注的玩家投注信息 repeated GuessPlayer plays = 21; //参与游戏下注的玩家投注信息
string result = 22; string result = 22;
repeated GuessBet bets = 23; repeated GuessBet bets = 23;
int64 index = 24;
} }
message GuessPlayer { message GuessPlayer {
string addr = 1; string addr = 1;
repeated GuessBet bets = 2; GuessBet bet = 2;
} }
message GuessBet { message GuessBet {
...@@ -145,7 +146,7 @@ message GuessGameStart{ ...@@ -145,7 +146,7 @@ message GuessGameStart{
string options = 2; string options = 2;
string category = 3; string category = 3;
string maxTime = 4; string maxTime = 4;
uint32 maxHeight = 5; int64 maxHeight = 5;
string symbol = 6; string symbol = 6;
string exec = 7; string exec = 7;
uint32 oneBet = 8; uint32 oneBet = 8;
...@@ -154,7 +155,7 @@ message GuessGameStart{ ...@@ -154,7 +155,7 @@ message GuessGameStart{
uint64 fee = 11; uint64 fee = 11;
string feeAddr = 12; string feeAddr = 12;
string expire = 13; string expire = 13;
uint32 expireHeight = 14; int64 expireHeight = 14;
} }
//参与游戏下注 //参与游戏下注
......
...@@ -10,7 +10,7 @@ import ( ...@@ -10,7 +10,7 @@ import (
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
pb "github.com/33cn/plugin/plugin/dapp/guess/types" pb "github.com/33cn/plugin/plugin/dapp/guess/types"
"github.com/33cn/plugin/plugin/dapp/pokerbull/executor" "github.com/33cn/plugin/plugin/dapp/guess/executor"
) )
func (c *channelClient) GuessStart(ctx context.Context, head *pb.GuessGameStart) (*types.UnsignTx, error) { func (c *channelClient) GuessStart(ctx context.Context, head *pb.GuessGameStart) (*types.UnsignTx, error) {
......
...@@ -13,8 +13,10 @@ const ( ...@@ -13,8 +13,10 @@ const (
GuessGameActionStart = iota + 1 GuessGameActionStart = iota + 1
GuessGameActionBet GuessGameActionBet
GuessGameActionStopBet
GuessGameActionAbort GuessGameActionAbort
GuessGameActionPublish GuessGameActionPublish
GuessGameActionTimeOut
) )
const ( const (
...@@ -31,8 +33,10 @@ const ( ...@@ -31,8 +33,10 @@ const (
TyLogGuessGameStart = 901 TyLogGuessGameStart = 901
TyLogGuessGameBet = 902 TyLogGuessGameBet = 902
TyLogGuessGameAbort = 903 TyLogGuessGameStopBet = 903
TyLogGuessGamePublish = 904 TyLogGuessGameAbort = 904
TyLogGuessGamePublish = 905
TyLogGuessGameTimeout = 906
) )
//包的名字可以通过配置文件来配置 //包的名字可以通过配置文件来配置
......
...@@ -33,7 +33,7 @@ type GuessGame struct { ...@@ -33,7 +33,7 @@ type GuessGame struct {
Category string `protobuf:"bytes,6,opt,name=category,proto3" json:"category,omitempty"` Category string `protobuf:"bytes,6,opt,name=category,proto3" json:"category,omitempty"`
Options string `protobuf:"bytes,7,opt,name=options,proto3" json:"options,omitempty"` Options string `protobuf:"bytes,7,opt,name=options,proto3" json:"options,omitempty"`
MaxTime string `protobuf:"bytes,8,opt,name=maxTime,proto3" json:"maxTime,omitempty"` MaxTime string `protobuf:"bytes,8,opt,name=maxTime,proto3" json:"maxTime,omitempty"`
MaxHeight uint32 `protobuf:"varint,9,opt,name=maxHeight,proto3" json:"maxHeight,omitempty"` MaxHeight int64 `protobuf:"varint,9,opt,name=maxHeight,proto3" json:"maxHeight,omitempty"`
Symbol string `protobuf:"bytes,10,opt,name=symbol,proto3" json:"symbol,omitempty"` Symbol string `protobuf:"bytes,10,opt,name=symbol,proto3" json:"symbol,omitempty"`
Exec string `protobuf:"bytes,11,opt,name=exec,proto3" json:"exec,omitempty"` Exec string `protobuf:"bytes,11,opt,name=exec,proto3" json:"exec,omitempty"`
OneBet uint32 `protobuf:"varint,12,opt,name=oneBet,proto3" json:"oneBet,omitempty"` OneBet uint32 `protobuf:"varint,12,opt,name=oneBet,proto3" json:"oneBet,omitempty"`
...@@ -42,12 +42,13 @@ type GuessGame struct { ...@@ -42,12 +42,13 @@ type GuessGame struct {
Fee uint32 `protobuf:"varint,15,opt,name=fee,proto3" json:"fee,omitempty"` Fee uint32 `protobuf:"varint,15,opt,name=fee,proto3" json:"fee,omitempty"`
FeeAddr string `protobuf:"bytes,16,opt,name=feeAddr,proto3" json:"feeAddr,omitempty"` FeeAddr string `protobuf:"bytes,16,opt,name=feeAddr,proto3" json:"feeAddr,omitempty"`
Expire string `protobuf:"bytes,17,opt,name=expire,proto3" json:"expire,omitempty"` Expire string `protobuf:"bytes,17,opt,name=expire,proto3" json:"expire,omitempty"`
ExpireHeight uint32 `protobuf:"varint,18,opt,name=expireHeight,proto3" json:"expireHeight,omitempty"` ExpireHeight int64 `protobuf:"varint,18,opt,name=expireHeight,proto3" json:"expireHeight,omitempty"`
AdminAddr string `protobuf:"bytes,19,opt,name=adminAddr,proto3" json:"adminAddr,omitempty"` AdminAddr string `protobuf:"bytes,19,opt,name=adminAddr,proto3" json:"adminAddr,omitempty"`
BetsNumber uint32 `protobuf:"varint,20,opt,name=betsNumber,proto3" json:"betsNumber,omitempty"` BetsNumber uint32 `protobuf:"varint,20,opt,name=betsNumber,proto3" json:"betsNumber,omitempty"`
Plays []*GuessPlayer `protobuf:"bytes,21,rep,name=plays,proto3" json:"plays,omitempty"` Plays []*GuessPlayer `protobuf:"bytes,21,rep,name=plays,proto3" json:"plays,omitempty"`
Result string `protobuf:"bytes,22,opt,name=result,proto3" json:"result,omitempty"` Result string `protobuf:"bytes,22,opt,name=result,proto3" json:"result,omitempty"`
Bets []*GuessBet `protobuf:"bytes,23,rep,name=bets,proto3" json:"bets,omitempty"` Bets []*GuessBet `protobuf:"bytes,23,rep,name=bets,proto3" json:"bets,omitempty"`
Index int64 `protobuf:"varint,24,opt,name=index,proto3" json:"index,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
...@@ -134,7 +135,7 @@ func (m *GuessGame) GetMaxTime() string { ...@@ -134,7 +135,7 @@ func (m *GuessGame) GetMaxTime() string {
return "" return ""
} }
func (m *GuessGame) GetMaxHeight() uint32 { func (m *GuessGame) GetMaxHeight() int64 {
if m != nil { if m != nil {
return m.MaxHeight return m.MaxHeight
} }
...@@ -197,7 +198,7 @@ func (m *GuessGame) GetExpire() string { ...@@ -197,7 +198,7 @@ func (m *GuessGame) GetExpire() string {
return "" return ""
} }
func (m *GuessGame) GetExpireHeight() uint32 { func (m *GuessGame) GetExpireHeight() int64 {
if m != nil { if m != nil {
return m.ExpireHeight return m.ExpireHeight
} }
...@@ -239,12 +240,19 @@ func (m *GuessGame) GetBets() []*GuessBet { ...@@ -239,12 +240,19 @@ func (m *GuessGame) GetBets() []*GuessBet {
return nil return nil
} }
func (m *GuessGame) GetIndex() int64 {
if m != nil {
return m.Index
}
return 0
}
type GuessPlayer struct { type GuessPlayer struct {
Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"`
Bets []*GuessBet `protobuf:"bytes,2,rep,name=bets,proto3" json:"bets,omitempty"` Bet *GuessBet `protobuf:"bytes,2,opt,name=bet,proto3" json:"bet,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
} }
func (m *GuessPlayer) Reset() { *m = GuessPlayer{} } func (m *GuessPlayer) Reset() { *m = GuessPlayer{} }
...@@ -279,9 +287,9 @@ func (m *GuessPlayer) GetAddr() string { ...@@ -279,9 +287,9 @@ func (m *GuessPlayer) GetAddr() string {
return "" return ""
} }
func (m *GuessPlayer) GetBets() []*GuessBet { func (m *GuessPlayer) GetBet() *GuessBet {
if m != nil { if m != nil {
return m.Bets return m.Bet
} }
return nil return nil
} }
...@@ -1398,7 +1406,7 @@ type GuessGameStart struct { ...@@ -1398,7 +1406,7 @@ type GuessGameStart struct {
Options string `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"` Options string `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"`
Category string `protobuf:"bytes,3,opt,name=category,proto3" json:"category,omitempty"` Category string `protobuf:"bytes,3,opt,name=category,proto3" json:"category,omitempty"`
MaxTime string `protobuf:"bytes,4,opt,name=maxTime,proto3" json:"maxTime,omitempty"` MaxTime string `protobuf:"bytes,4,opt,name=maxTime,proto3" json:"maxTime,omitempty"`
MaxHeight uint32 `protobuf:"varint,5,opt,name=maxHeight,proto3" json:"maxHeight,omitempty"` MaxHeight int64 `protobuf:"varint,5,opt,name=maxHeight,proto3" json:"maxHeight,omitempty"`
Symbol string `protobuf:"bytes,6,opt,name=symbol,proto3" json:"symbol,omitempty"` Symbol string `protobuf:"bytes,6,opt,name=symbol,proto3" json:"symbol,omitempty"`
Exec string `protobuf:"bytes,7,opt,name=exec,proto3" json:"exec,omitempty"` Exec string `protobuf:"bytes,7,opt,name=exec,proto3" json:"exec,omitempty"`
OneBet uint32 `protobuf:"varint,8,opt,name=oneBet,proto3" json:"oneBet,omitempty"` OneBet uint32 `protobuf:"varint,8,opt,name=oneBet,proto3" json:"oneBet,omitempty"`
...@@ -1407,7 +1415,7 @@ type GuessGameStart struct { ...@@ -1407,7 +1415,7 @@ type GuessGameStart struct {
Fee uint64 `protobuf:"varint,11,opt,name=fee,proto3" json:"fee,omitempty"` Fee uint64 `protobuf:"varint,11,opt,name=fee,proto3" json:"fee,omitempty"`
FeeAddr string `protobuf:"bytes,12,opt,name=feeAddr,proto3" json:"feeAddr,omitempty"` FeeAddr string `protobuf:"bytes,12,opt,name=feeAddr,proto3" json:"feeAddr,omitempty"`
Expire string `protobuf:"bytes,13,opt,name=expire,proto3" json:"expire,omitempty"` Expire string `protobuf:"bytes,13,opt,name=expire,proto3" json:"expire,omitempty"`
ExpireHeight uint32 `protobuf:"varint,14,opt,name=expireHeight,proto3" json:"expireHeight,omitempty"` ExpireHeight int64 `protobuf:"varint,14,opt,name=expireHeight,proto3" json:"expireHeight,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
...@@ -1466,7 +1474,7 @@ func (m *GuessGameStart) GetMaxTime() string { ...@@ -1466,7 +1474,7 @@ func (m *GuessGameStart) GetMaxTime() string {
return "" return ""
} }
func (m *GuessGameStart) GetMaxHeight() uint32 { func (m *GuessGameStart) GetMaxHeight() int64 {
if m != nil { if m != nil {
return m.MaxHeight return m.MaxHeight
} }
...@@ -1529,7 +1537,7 @@ func (m *GuessGameStart) GetExpire() string { ...@@ -1529,7 +1537,7 @@ func (m *GuessGameStart) GetExpire() string {
return "" return ""
} }
func (m *GuessGameStart) GetExpireHeight() uint32 { func (m *GuessGameStart) GetExpireHeight() int64 {
if m != nil { if m != nil {
return m.ExpireHeight return m.ExpireHeight
} }
...@@ -2892,105 +2900,106 @@ func init() { ...@@ -2892,105 +2900,106 @@ func init() {
func init() { proto.RegisterFile("guess.proto", fileDescriptor_7574406c5d3430e8) } func init() { proto.RegisterFile("guess.proto", fileDescriptor_7574406c5d3430e8) }
var fileDescriptor_7574406c5d3430e8 = []byte{ var fileDescriptor_7574406c5d3430e8 = []byte{
// 1562 bytes of a gzipped FileDescriptorProto // 1573 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0xcf, 0x6e, 0xdb, 0x46, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x58, 0x5f, 0x6f, 0x13, 0x47,
0x13, 0xb7, 0x48, 0x51, 0x7f, 0x46, 0x96, 0x6c, 0x6f, 0x12, 0x87, 0x08, 0x3e, 0x7c, 0x30, 0x18, 0x10, 0x8f, 0x7d, 0x3e, 0xff, 0x19, 0xc7, 0x4e, 0xb2, 0x40, 0x58, 0xa1, 0xaa, 0x4a, 0x8f, 0x14,
0x7f, 0x89, 0xf3, 0xa1, 0x09, 0x0a, 0x19, 0x48, 0x9b, 0x16, 0x28, 0x60, 0x26, 0x68, 0x1c, 0x20, 0x42, 0x55, 0x50, 0x95, 0x48, 0xb4, 0xb4, 0x52, 0xa5, 0x1c, 0x48, 0x04, 0x09, 0x21, 0xb3, 0xa1,
0x08, 0x94, 0x75, 0x8a, 0xf4, 0x4a, 0x4b, 0x1b, 0x87, 0x88, 0x44, 0xca, 0x24, 0x95, 0x48, 0xb7, 0xa2, 0xaf, 0x17, 0x7b, 0x09, 0x27, 0xec, 0x3b, 0xe7, 0xee, 0x0c, 0xf1, 0x5b, 0xd5, 0x7e, 0x82,
0xa2, 0x7d, 0x81, 0xf6, 0xd0, 0x27, 0xe8, 0x73, 0xf5, 0xdc, 0x47, 0xe8, 0xb5, 0xd8, 0x99, 0x5d, 0x3e, 0xf4, 0x13, 0x54, 0xea, 0xb7, 0xea, 0x73, 0x3f, 0x42, 0x5f, 0xab, 0x9d, 0xd9, 0xf5, 0xed,
0x71, 0x49, 0x53, 0x72, 0x1c, 0xe4, 0xd8, 0xdb, 0xce, 0xce, 0xec, 0xec, 0xfc, 0xdd, 0xf9, 0x91, 0x5d, 0xce, 0x86, 0x20, 0xde, 0xfa, 0xb6, 0xb3, 0x33, 0x3b, 0x3b, 0x7f, 0x77, 0x7e, 0x77, 0xd0,
0xd0, 0x39, 0x9b, 0x89, 0x34, 0x7d, 0x30, 0x4d, 0xe2, 0x2c, 0x66, 0x4e, 0xb6, 0x98, 0x8a, 0xf4, 0x3d, 0x9d, 0xc9, 0x34, 0xbd, 0x37, 0x4d, 0xe2, 0x2c, 0x66, 0x6e, 0x36, 0x9f, 0xca, 0xf4, 0xc6,
0xd6, 0x4e, 0x96, 0x04, 0x51, 0x1a, 0x0c, 0xb3, 0x30, 0x8e, 0x88, 0xe3, 0xfd, 0xea, 0x40, 0xfb, 0x56, 0x96, 0x04, 0x51, 0x1a, 0x0c, 0xb3, 0x30, 0x8e, 0x88, 0xe3, 0xfd, 0xe5, 0x42, 0xe7, 0xb1,
0xa9, 0x94, 0x7c, 0x1a, 0x4c, 0x04, 0xdb, 0x85, 0xc6, 0x59, 0x30, 0x11, 0xcf, 0x46, 0x6e, 0x6d, 0x92, 0x7c, 0x1c, 0x4c, 0x24, 0xdb, 0x86, 0xe6, 0x69, 0x30, 0x91, 0x4f, 0x46, 0xbc, 0xb6, 0x53,
0xaf, 0x76, 0xd0, 0xe6, 0x8a, 0x92, 0xfb, 0x69, 0x16, 0x64, 0xb3, 0xd4, 0xb5, 0xf6, 0x6a, 0x07, 0xdb, 0xeb, 0x08, 0x4d, 0xa9, 0xfd, 0x34, 0x0b, 0xb2, 0x59, 0xca, 0xeb, 0x3b, 0xb5, 0xbd, 0x9e,
0x5d, 0xae, 0x28, 0xf6, 0x1f, 0x68, 0xa7, 0x59, 0x90, 0x64, 0xaf, 0xc2, 0x89, 0x70, 0xed, 0xbd, 0xd0, 0x14, 0xfb, 0x0c, 0x3a, 0x69, 0x16, 0x24, 0xd9, 0x8b, 0x70, 0x22, 0xb9, 0xb3, 0x53, 0xdb,
0xda, 0x81, 0xcd, 0xf3, 0x0d, 0xb6, 0x07, 0x1d, 0x22, 0xe6, 0xc7, 0x41, 0xfa, 0xd6, 0xad, 0xa3, 0x73, 0x44, 0xbe, 0xc1, 0x76, 0xa0, 0x4b, 0xc4, 0xf9, 0x51, 0x90, 0xbe, 0xe6, 0x0d, 0x54, 0x69,
0x4a, 0x73, 0x8b, 0x5d, 0x07, 0x27, 0x8b, 0xa7, 0xe1, 0xd0, 0x75, 0x90, 0x47, 0x04, 0xbb, 0x05, 0x6f, 0xb1, 0xab, 0xe0, 0x66, 0xf1, 0x34, 0x1c, 0x72, 0x17, 0x79, 0x44, 0xb0, 0x1b, 0xd0, 0x1e,
0xad, 0x61, 0x90, 0x89, 0xb3, 0x38, 0x59, 0xb8, 0x0d, 0x64, 0x2c, 0x69, 0xe6, 0x42, 0x33, 0x9e, 0x06, 0x99, 0x3c, 0x8d, 0x93, 0x39, 0x6f, 0x22, 0x63, 0x41, 0x33, 0x0e, 0xad, 0x78, 0xaa, 0xec,
0x4a, 0xfb, 0x53, 0xb7, 0x89, 0x2c, 0x4d, 0x4a, 0xce, 0x24, 0x98, 0xa3, 0x25, 0x2d, 0xe2, 0x28, 0x4f, 0x79, 0x0b, 0x59, 0x86, 0x54, 0x9c, 0x49, 0x70, 0x8e, 0x96, 0xb4, 0x89, 0xa3, 0x49, 0x65,
0x52, 0x5a, 0x39, 0x09, 0xe6, 0xc7, 0x22, 0x3c, 0x7b, 0x9b, 0xb9, 0x6d, 0x74, 0x20, 0xdf, 0x40, 0xe5, 0x24, 0x38, 0x3f, 0x92, 0xe1, 0xe9, 0xeb, 0x8c, 0x77, 0xc8, 0xca, 0xc5, 0x06, 0xfa, 0x36,
0xdf, 0x16, 0x93, 0xd3, 0x78, 0xec, 0x02, 0xf9, 0x4c, 0x14, 0x63, 0x50, 0x17, 0x73, 0x31, 0x74, 0x9f, 0x9c, 0xc4, 0x63, 0x0e, 0xe4, 0x33, 0x51, 0x8c, 0x41, 0x43, 0x9e, 0xcb, 0x21, 0xef, 0xe2,
0x3b, 0xb8, 0x8b, 0x6b, 0x29, 0x1b, 0x47, 0xc2, 0x17, 0x99, 0xbb, 0x49, 0x71, 0x20, 0x4a, 0xdd, 0x2e, 0xae, 0x95, 0x6c, 0x1c, 0x49, 0x5f, 0x66, 0x7c, 0x9d, 0xe2, 0x40, 0x94, 0xbe, 0xdb, 0x97,
0xed, 0x8b, 0x2c, 0x75, 0xbb, 0xc8, 0xd0, 0x24, 0xdb, 0x87, 0xae, 0x5a, 0xbe, 0x98, 0x4d, 0x4e, 0x59, 0xca, 0x7b, 0xc8, 0x30, 0x24, 0xdb, 0x85, 0x9e, 0x5e, 0x3e, 0x9b, 0x4d, 0x4e, 0x64, 0xc2,
0x45, 0xe2, 0xf6, 0x90, 0x5f, 0xdc, 0x64, 0xdb, 0x60, 0xbf, 0x11, 0xc2, 0xdd, 0x42, 0x9e, 0x5c, 0xfb, 0xc8, 0x2f, 0x6e, 0xb2, 0x4d, 0x70, 0x5e, 0x49, 0xc9, 0x37, 0x90, 0xa7, 0x96, 0x4a, 0xe3,
0x4a, 0x8d, 0x6f, 0x84, 0x38, 0x1a, 0x8d, 0x12, 0x77, 0x9b, 0xbc, 0x51, 0xa4, 0xb4, 0x41, 0xcc, 0x2b, 0x29, 0x0f, 0x47, 0xa3, 0x84, 0x6f, 0x92, 0x37, 0x9a, 0x54, 0x36, 0xc8, 0xf3, 0x69, 0x98,
0xa7, 0x61, 0x22, 0xdc, 0x1d, 0xb2, 0x97, 0x28, 0xe6, 0xc1, 0x26, 0xad, 0x94, 0xa3, 0x0c, 0x95, 0x48, 0xbe, 0x45, 0xf6, 0x12, 0xc5, 0x3c, 0x58, 0xa7, 0x95, 0x76, 0x94, 0xa1, 0xa3, 0x85, 0x3d,
0x15, 0xf6, 0x64, 0x24, 0x82, 0xd1, 0x24, 0x8c, 0x50, 0xef, 0x35, 0x3c, 0x9e, 0x6f, 0xb0, 0xff, 0x15, 0x89, 0x60, 0x34, 0x09, 0x23, 0xd4, 0x7b, 0x05, 0x8f, 0xe7, 0x1b, 0xec, 0x73, 0x80, 0x93,
0x02, 0x9c, 0xe6, 0x86, 0x5e, 0xc7, 0xf3, 0xc6, 0x0e, 0x3b, 0x00, 0x67, 0x3a, 0x0e, 0x16, 0xa9, 0xdc, 0xd0, 0xab, 0x68, 0x8c, 0xb5, 0xc3, 0xf6, 0xc0, 0x9d, 0x8e, 0x83, 0x79, 0xca, 0xaf, 0xed,
0x7b, 0x63, 0xcf, 0x3e, 0xe8, 0xf4, 0xd9, 0x03, 0xac, 0xaa, 0x07, 0x58, 0x3e, 0x83, 0x71, 0xb0, 0x38, 0x7b, 0xdd, 0x7d, 0x76, 0x0f, 0xab, 0xea, 0x1e, 0x96, 0xcf, 0x60, 0x1c, 0xcc, 0x65, 0x22,
0x10, 0x09, 0x27, 0x01, 0x69, 0x63, 0x22, 0xd2, 0xd9, 0x38, 0x73, 0x77, 0xc9, 0x46, 0xa2, 0xd8, 0x48, 0x40, 0xd9, 0x98, 0xc8, 0x74, 0x36, 0xce, 0xf8, 0x36, 0xd9, 0x48, 0x14, 0xbb, 0x09, 0x0d,
0x6d, 0xa8, 0x4b, 0x7d, 0xee, 0x4d, 0x54, 0xb0, 0x65, 0x2a, 0xf0, 0x45, 0xc6, 0x91, 0xe9, 0x7d, 0xa5, 0x8f, 0x5f, 0x47, 0x05, 0x1b, 0xb6, 0x02, 0x5f, 0x66, 0x02, 0x99, 0xaa, 0x28, 0xc2, 0x68,
0x0f, 0x1d, 0x43, 0xa5, 0xcc, 0x43, 0x20, 0xcd, 0xa5, 0x8a, 0xc4, 0xf5, 0x52, 0x8f, 0xb5, 0x4e, 0x24, 0xcf, 0x39, 0x47, 0x0f, 0x88, 0xf0, 0x1e, 0x41, 0xd7, 0xba, 0x48, 0x65, 0x27, 0x50, 0x4e,
0x8f, 0x0f, 0x2d, 0xbd, 0x83, 0x89, 0xc3, 0x3a, 0xd1, 0x85, 0x4d, 0x54, 0xc9, 0x65, 0xab, 0xec, 0x50, 0x9d, 0xe2, 0x9a, 0x7d, 0x01, 0xce, 0x89, 0xcc, 0xb0, 0x44, 0x2b, 0x94, 0x2b, 0x9e, 0xe7,
0xb2, 0xf7, 0xb7, 0x0d, 0xed, 0x41, 0xfc, 0x4e, 0x24, 0xfe, 0x6c, 0x3c, 0xfe, 0xc8, 0xf6, 0x70, 0x43, 0xdb, 0x6c, 0x60, 0x32, 0xb1, 0x76, 0x4c, 0xb1, 0x13, 0x55, 0x0a, 0x43, 0xbd, 0x1c, 0x06,
0x3e, 0x67, 0x7b, 0xbc, 0x0f, 0xc6, 0x33, 0x81, 0xed, 0x61, 0x73, 0x22, 0xd8, 0x3e, 0x38, 0x53, 0xef, 0x5f, 0x07, 0x3a, 0x83, 0xf8, 0x8d, 0x4c, 0xfc, 0xd9, 0x78, 0xfc, 0x81, 0x2d, 0xe3, 0x7e,
0x69, 0x12, 0xf6, 0x46, 0xa7, 0xdf, 0x53, 0xde, 0x0f, 0x7c, 0x34, 0x94, 0x13, 0x93, 0xdd, 0x83, 0xca, 0x96, 0x79, 0x1b, 0x8c, 0x67, 0x12, 0x5b, 0xc6, 0x11, 0x44, 0xb0, 0x5d, 0x70, 0xa7, 0xca,
0xe6, 0x14, 0x03, 0x28, 0x1b, 0xc5, 0x8c, 0xd2, 0xc0, 0x57, 0xb9, 0xd2, 0x7c, 0x69, 0x26, 0x2d, 0x24, 0xec, 0x97, 0xee, 0x7e, 0x5f, 0x3b, 0x3f, 0xf0, 0xd1, 0x50, 0x41, 0x4c, 0x76, 0x07, 0x5a,
0x5f, 0xcc, 0x26, 0xd8, 0x3b, 0x0e, 0xcf, 0x37, 0xa4, 0x22, 0xca, 0x5e, 0xea, 0xb6, 0x4b, 0x8a, 0x53, 0x0c, 0x9f, 0x6a, 0x1e, 0x3b, 0x03, 0x03, 0x5f, 0xe7, 0xcf, 0xf0, 0x95, 0x99, 0xb4, 0x7c,
0x38, 0xee, 0x73, 0xcd, 0x97, 0xf6, 0x86, 0xd1, 0x48, 0xcc, 0xb1, 0x93, 0x6c, 0x4e, 0x04, 0xaa, 0x36, 0x9b, 0x60, 0x3f, 0xb9, 0x22, 0xdf, 0x50, 0x8a, 0x28, 0xa3, 0x29, 0xef, 0x94, 0x14, 0x09,
0x4f, 0xc4, 0xfb, 0x67, 0xc8, 0xe9, 0x50, 0x14, 0x96, 0x1b, 0xb2, 0xd9, 0xcf, 0x67, 0x21, 0x85, 0xdc, 0x17, 0x86, 0x9f, 0x67, 0x13, 0xac, 0x6c, 0xa2, 0xfa, 0x44, 0xbe, 0x7d, 0x82, 0x9c, 0x2e,
0x68, 0x13, 0x99, 0x4b, 0x5a, 0x66, 0x07, 0xd7, 0x14, 0xa0, 0x2e, 0x06, 0xc8, 0xd8, 0x91, 0xfc, 0x45, 0x61, 0xb1, 0xa1, 0x1e, 0x80, 0xb3, 0x59, 0x48, 0x21, 0x5a, 0x47, 0xe6, 0x82, 0x56, 0xd9,
0x91, 0x08, 0xc6, 0x22, 0xc1, 0x7a, 0xee, 0x11, 0x3f, 0xdf, 0x91, 0x37, 0x87, 0xe9, 0xeb, 0x20, 0xc1, 0x35, 0x05, 0xa8, 0x87, 0x01, 0xb2, 0x76, 0x14, 0x7f, 0x24, 0x83, 0xb1, 0x4c, 0xb0, 0xc6,
0xcc, 0xc2, 0xe8, 0x0c, 0x9b, 0xab, 0xc5, 0xf3, 0x0d, 0x65, 0xd7, 0x09, 0x25, 0x6e, 0x5b, 0xb9, 0xfb, 0xc4, 0xcf, 0x77, 0xd4, 0xcd, 0x61, 0xfa, 0x32, 0x08, 0xb3, 0x30, 0x3a, 0xc5, 0x86, 0x6b,
0xad, 0x37, 0xbc, 0x9f, 0x6b, 0xd0, 0x18, 0xf8, 0xc7, 0x41, 0x34, 0x92, 0x6e, 0x0d, 0x83, 0x64, 0x8b, 0x7c, 0x43, 0xdb, 0x75, 0x4c, 0x89, 0xdb, 0xd4, 0x6e, 0x9b, 0x0d, 0xef, 0xd7, 0x1a, 0x34,
0x94, 0xba, 0xb5, 0x3d, 0xfb, 0xc0, 0xe1, 0x44, 0x18, 0x35, 0xae, 0x92, 0xae, 0x6a, 0xdc, 0x85, 0x07, 0xfe, 0x51, 0x10, 0x8d, 0x94, 0x5b, 0xc3, 0x20, 0x19, 0xa5, 0xbc, 0xb6, 0xe3, 0xec, 0xb9,
0xa6, 0xac, 0x51, 0x91, 0xa6, 0x98, 0xf2, 0x36, 0xd7, 0x24, 0x86, 0x27, 0x7d, 0x1d, 0x46, 0x98, 0x82, 0x08, 0xab, 0xee, 0x75, 0xd2, 0x75, 0xdd, 0x73, 0x68, 0xa9, 0x0a, 0x95, 0x69, 0x8a, 0x29,
0xea, 0x16, 0x27, 0x42, 0x06, 0x60, 0x2c, 0xde, 0x8b, 0x24, 0x38, 0xa3, 0x3c, 0x3b, 0x7c, 0x49, 0xef, 0x08, 0x43, 0x62, 0x78, 0xd2, 0x97, 0x61, 0x84, 0xa9, 0x6e, 0x0b, 0x22, 0x54, 0x00, 0xc6,
0x7b, 0x1f, 0xa0, 0xa5, 0xd3, 0xc5, 0x6e, 0x83, 0xf3, 0x36, 0x88, 0x94, 0x15, 0x9d, 0x7e, 0x77, 0xf2, 0xad, 0x4c, 0x82, 0x53, 0xca, 0xb3, 0x2b, 0x16, 0xb4, 0xf7, 0x0e, 0xda, 0x26, 0x5d, 0xec,
0x99, 0x05, 0x69, 0x23, 0x27, 0x9e, 0x79, 0xb9, 0x55, 0xbc, 0x7c, 0x17, 0x1a, 0x19, 0xc5, 0x91, 0x26, 0xb8, 0xaf, 0x83, 0x48, 0x5b, 0xd1, 0xdd, 0xef, 0x2d, 0xb2, 0xa0, 0x6c, 0x14, 0xc4, 0xb3,
0x0a, 0x51, 0x51, 0xd2, 0xa8, 0x44, 0x04, 0xa3, 0x85, 0x36, 0x0a, 0x09, 0xef, 0x8f, 0x9a, 0xbc, 0x2f, 0xaf, 0x17, 0x2f, 0xdf, 0x86, 0x66, 0x46, 0x71, 0xa4, 0x42, 0xd4, 0x94, 0x32, 0x2a, 0x91,
0x99, 0xeb, 0xae, 0xfd, 0x88, 0x9b, 0x77, 0xa1, 0xf1, 0x21, 0x8c, 0x22, 0xd5, 0x45, 0x6d, 0xae, 0xc1, 0x68, 0x6e, 0x8c, 0x42, 0xc2, 0xfb, 0xb3, 0xa6, 0x6e, 0x16, 0xa6, 0x93, 0x3f, 0xe0, 0xe6,
0xa8, 0x82, 0x7b, 0x76, 0xd1, 0x3d, 0x79, 0x86, 0xb2, 0xa5, 0x8a, 0x5f, 0x51, 0xec, 0x0e, 0xf4, 0x6d, 0x68, 0xbe, 0x0b, 0xa3, 0x48, 0x77, 0x51, 0x47, 0x68, 0xaa, 0xe0, 0x9e, 0x53, 0x74, 0x4f,
0x68, 0xf5, 0xbc, 0x18, 0x98, 0xd2, 0xae, 0xf7, 0x08, 0x9a, 0xaa, 0xea, 0x57, 0xe4, 0xc8, 0x85, 0x9d, 0xa1, 0x6c, 0xe9, 0xe2, 0xd7, 0x14, 0xbb, 0x05, 0x7d, 0x5a, 0x3d, 0x2d, 0x06, 0xa6, 0xb4,
0xe6, 0x34, 0x0e, 0xa3, 0x4c, 0x59, 0xe5, 0x70, 0x4d, 0x7a, 0x7f, 0xd6, 0x60, 0x73, 0xe0, 0xcb, 0xeb, 0x3d, 0x80, 0x96, 0xae, 0xfa, 0x25, 0x39, 0xe2, 0xd0, 0x9a, 0xc6, 0x61, 0x94, 0x69, 0xab,
0xa1, 0x77, 0x84, 0xe3, 0x90, 0xfd, 0x1f, 0x1c, 0x6c, 0x3d, 0x6c, 0xed, 0xfc, 0x71, 0x23, 0x99, 0x5c, 0x61, 0x48, 0xef, 0xef, 0x1a, 0xac, 0x0f, 0x7c, 0x35, 0x08, 0x0f, 0x71, 0x44, 0xb2, 0xaf,
0x13, 0xc9, 0x39, 0xde, 0xe0, 0x24, 0xc2, 0x0e, 0xa1, 0x35, 0x8c, 0xa3, 0x2c, 0x8c, 0x66, 0x02, 0xc0, 0xc5, 0xd6, 0xc3, 0xd6, 0xce, 0x1f, 0x3c, 0x92, 0x39, 0x56, 0x9c, 0xa3, 0x35, 0x41, 0x22,
0xf5, 0x76, 0xfa, 0x37, 0x0a, 0xe2, 0x8f, 0x15, 0xf3, 0x78, 0x83, 0x2f, 0x05, 0xd9, 0x5d, 0xa8, 0xec, 0x00, 0xda, 0xc3, 0x38, 0xca, 0xc2, 0x68, 0x26, 0xf5, 0x0b, 0x74, 0xad, 0x20, 0xfe, 0x50,
0xcb, 0xd2, 0xc5, 0x20, 0x74, 0xfa, 0x3b, 0x85, 0x03, 0x2f, 0x67, 0xa1, 0x54, 0x8f, 0x02, 0xd2, 0x33, 0x8f, 0xd6, 0xc4, 0x42, 0x90, 0xdd, 0x86, 0x86, 0x2a, 0x5d, 0x0c, 0x42, 0x77, 0x7f, 0xab,
0x92, 0xf3, 0x99, 0x48, 0x28, 0x23, 0x65, 0x4b, 0x5e, 0x4a, 0x8e, 0xb4, 0x04, 0x45, 0x58, 0x0f, 0x70, 0xe0, 0xf9, 0x2c, 0x54, 0xea, 0x51, 0x40, 0x59, 0x72, 0x36, 0x93, 0x09, 0x65, 0xa4, 0x6c,
0xac, 0x6c, 0x81, 0xed, 0xe6, 0x70, 0x2b, 0x5b, 0xf8, 0x4d, 0xf5, 0x62, 0x78, 0x47, 0xd0, 0x31, 0xc9, 0x73, 0xc5, 0x51, 0x96, 0xa0, 0x08, 0xeb, 0x43, 0x3d, 0x9b, 0x63, 0xbb, 0xb9, 0xa2, 0x9e,
0x4c, 0xcf, 0x5f, 0x92, 0x9a, 0xf9, 0x92, 0x14, 0x1a, 0xdf, 0x2a, 0x35, 0xbe, 0x77, 0x00, 0xbd, 0xcd, 0xfd, 0x96, 0x7e, 0x31, 0xbc, 0x43, 0xe8, 0x5a, 0xa6, 0xe7, 0x2f, 0x49, 0xcd, 0x7e, 0x49,
0xa2, 0x3b, 0xab, 0xde, 0x3f, 0x6f, 0x1f, 0x20, 0xf7, 0x63, 0xa5, 0xd4, 0xff, 0xb4, 0x49, 0xe8, 0x0a, 0x8d, 0x5f, 0x2f, 0x35, 0xbe, 0xb7, 0x07, 0xfd, 0xa2, 0x3b, 0xcb, 0xde, 0x3f, 0x6f, 0x17,
0xc3, 0x4a, 0xb1, 0xdf, 0x2d, 0xd8, 0x5a, 0x22, 0x12, 0x95, 0x9c, 0xfb, 0xc5, 0xe4, 0xdc, 0x30, 0x20, 0xf7, 0x63, 0xa9, 0xd4, 0x97, 0xc6, 0x24, 0xf4, 0x61, 0xa9, 0xd8, 0x1f, 0x75, 0xd8, 0x58,
0x1f, 0xfc, 0x8a, 0xfc, 0xdc, 0x05, 0xfb, 0x54, 0x64, 0x2a, 0x35, 0xd7, 0xca, 0xc2, 0xbe, 0x90, 0xa0, 0x14, 0x9d, 0x9c, 0xbb, 0xc5, 0xe4, 0x5c, 0xb3, 0xdf, 0xfb, 0x8a, 0xfc, 0xdc, 0xb6, 0x87,
0xa2, 0x52, 0x42, 0xea, 0x0d, 0x4e, 0xe3, 0x44, 0x27, 0xe5, 0x82, 0xde, 0x23, 0xc9, 0x94, 0x7a, 0xc3, 0x95, 0xb2, 0xb0, 0x2f, 0x95, 0xa8, 0x92, 0x50, 0x7a, 0x83, 0x93, 0x38, 0x31, 0x49, 0xb9,
0x51, 0x8a, 0x1d, 0x42, 0x73, 0x3a, 0x3b, 0x1d, 0x87, 0xea, 0xb5, 0xee, 0xf4, 0x6f, 0x96, 0x0f, 0xa0, 0xf7, 0x50, 0x31, 0x95, 0x5e, 0x94, 0x62, 0x07, 0xd0, 0x9a, 0xce, 0x4e, 0xc6, 0xa1, 0x7e,
0x0c, 0x88, 0x7d, 0xbc, 0xc1, 0xb5, 0xa4, 0xbc, 0x83, 0xd2, 0xe9, 0x54, 0xdf, 0x51, 0x99, 0xd1, 0xad, 0xbb, 0xfb, 0xd7, 0xcb, 0x07, 0x06, 0xc4, 0x3e, 0x5a, 0x13, 0x46, 0x52, 0xdd, 0x41, 0xe9,
0x06, 0x4e, 0xa2, 0x42, 0x46, 0x7f, 0xb2, 0xa1, 0x57, 0x74, 0x38, 0x87, 0x4f, 0x35, 0x13, 0x3e, 0x74, 0xab, 0xef, 0xa8, 0xcc, 0x68, 0x13, 0x27, 0x51, 0x21, 0xa3, 0xbf, 0x38, 0xd0, 0x2f, 0x3a,
0x19, 0x10, 0xc9, 0x2a, 0x42, 0x24, 0x13, 0x58, 0xd9, 0x17, 0x81, 0x95, 0x86, 0x4f, 0xf5, 0x35, 0x9c, 0x43, 0xaa, 0x9a, 0x0d, 0xa9, 0x2c, 0xd8, 0x54, 0x2f, 0xc2, 0x26, 0x1b, 0x6c, 0x39, 0x17,
0xf0, 0xc9, 0x59, 0x0d, 0x9f, 0x1a, 0x95, 0xf0, 0xa9, 0x59, 0x09, 0x9f, 0x5a, 0xab, 0xe0, 0x53, 0xc1, 0x96, 0x81, 0x54, 0x8d, 0x15, 0x90, 0xca, 0x5d, 0x0e, 0xa9, 0x9a, 0x95, 0x90, 0xaa, 0x55,
0xfb, 0x12, 0xf8, 0x04, 0x6b, 0xe0, 0x93, 0x9c, 0x2d, 0xf5, 0x0b, 0xf0, 0x69, 0x73, 0x15, 0x7c, 0x09, 0xa9, 0xda, 0xcb, 0x20, 0x55, 0xe7, 0x3d, 0x90, 0x0a, 0x56, 0x40, 0x2a, 0x35, 0x5b, 0x1a,
0xea, 0xae, 0x85, 0x4f, 0xbd, 0x8b, 0xf0, 0xc9, 0xfb, 0x11, 0x36, 0xcd, 0x2a, 0x5a, 0x87, 0x07, 0x17, 0x20, 0xd5, 0xfa, 0x32, 0x48, 0xd5, 0x5b, 0x09, 0xa9, 0xfa, 0x17, 0x21, 0x95, 0xf7, 0x33,
0x14, 0xda, 0xb0, 0x0a, 0x68, 0xc3, 0x85, 0xa6, 0xc2, 0x16, 0x18, 0xfe, 0x2e, 0xd7, 0xa4, 0xec, 0xac, 0xdb, 0x55, 0xb4, 0x0a, 0x0f, 0x68, 0xb4, 0x51, 0x2f, 0xa0, 0x0d, 0x0e, 0x2d, 0x8d, 0x2d,
0xb5, 0x62, 0xd1, 0xad, 0x6c, 0x0f, 0x1f, 0xb6, 0xcb, 0xd5, 0xb6, 0xce, 0x0e, 0x63, 0x44, 0x2d, 0x30, 0xfc, 0x3d, 0x61, 0x48, 0xd5, 0x6b, 0xc5, 0xa2, 0x5b, 0xda, 0x1e, 0x3e, 0x6c, 0x96, 0xab,
0x61, 0x98, 0xf7, 0xb5, 0x71, 0xdb, 0xda, 0x66, 0x54, 0xd5, 0x68, 0xe9, 0x6a, 0xf4, 0xce, 0xe1, 0x6d, 0x95, 0x1d, 0xd6, 0x88, 0x5a, 0x40, 0x33, 0xef, 0x3b, 0xeb, 0xb6, 0x95, 0xcd, 0xa8, 0xab,
0x36, 0x1e, 0xa0, 0x46, 0x7e, 0x1e, 0xa6, 0x99, 0xbf, 0xa0, 0x81, 0x79, 0x14, 0x8d, 0x06, 0x4b, 0xb1, 0x6e, 0xaa, 0xd1, 0x3b, 0x83, 0x9b, 0x78, 0x80, 0x1a, 0xf9, 0x69, 0x98, 0x66, 0xfe, 0x9c,
0xcc, 0x90, 0x03, 0xa2, 0x5a, 0x19, 0x10, 0xad, 0x7e, 0x70, 0x72, 0xf8, 0x60, 0x1b, 0xf0, 0xc1, 0x06, 0xe6, 0x61, 0x34, 0x1a, 0x2c, 0x30, 0x43, 0x0e, 0x88, 0x6a, 0x65, 0x40, 0xb4, 0xfc, 0xc1,
0x7b, 0xa5, 0x1f, 0x6a, 0x2e, 0x86, 0x71, 0x32, 0xba, 0x32, 0x08, 0xab, 0xd6, 0x7a, 0x04, 0x3b, 0xc9, 0xe1, 0x83, 0x63, 0x83, 0xc1, 0x17, 0xe6, 0xa1, 0x16, 0x72, 0x18, 0x27, 0xa3, 0x4b, 0x83,
0xa4, 0x15, 0x51, 0xc8, 0x25, 0xaa, 0x97, 0x2a, 0x2c, 0x53, 0xc5, 0x77, 0xd0, 0x35, 0x0d, 0x4b, 0xb0, 0x6a, 0xad, 0x87, 0xb0, 0x45, 0x5a, 0x11, 0x85, 0xbc, 0x47, 0xf5, 0x42, 0x45, 0xdd, 0x56,
0xd9, 0x7d, 0x89, 0x94, 0x70, 0xa9, 0x26, 0xe5, 0xb5, 0xc2, 0xd3, 0x4d, 0x62, 0x5c, 0xcb, 0x78, 0xf1, 0x23, 0xf4, 0x6c, 0xc3, 0x52, 0x76, 0x57, 0x21, 0x25, 0x5c, 0xea, 0x49, 0x79, 0xa5, 0xf0,
0xef, 0x60, 0xcb, 0x88, 0xe5, 0xb3, 0xe8, 0x4d, 0xbc, 0xd2, 0x00, 0x8d, 0x81, 0x2d, 0x03, 0x03, 0x74, 0x93, 0x98, 0x30, 0x32, 0xde, 0x1b, 0xd8, 0xb0, 0x62, 0xf9, 0x24, 0x7a, 0x15, 0x2f, 0x35,
0xe7, 0xfe, 0xda, 0xd5, 0xfe, 0xd6, 0x4d, 0x63, 0x0f, 0xa1, 0xc3, 0xc5, 0x74, 0xac, 0x2e, 0x63, 0xc0, 0x20, 0xe0, 0xba, 0x85, 0x80, 0x73, 0x7f, 0x9d, 0x6a, 0x7f, 0x1b, 0xb6, 0xb1, 0x07, 0xd0,
0xfb, 0x50, 0x97, 0xaa, 0xd5, 0x7b, 0xba, 0xad, 0xed, 0xd4, 0x48, 0x97, 0x23, 0xd7, 0xfb, 0x02, 0x15, 0x72, 0x3a, 0xd6, 0x97, 0xb1, 0x5d, 0x68, 0x28, 0xd5, 0xfa, 0x3d, 0xdd, 0x34, 0x76, 0x1a,
0xb6, 0x4b, 0x16, 0xe2, 0x48, 0x25, 0xa3, 0xc8, 0xc9, 0x36, 0xd7, 0xa4, 0xf7, 0x08, 0xb6, 0x8c, 0xa4, 0x2b, 0x90, 0xeb, 0x7d, 0x0d, 0x9b, 0x25, 0x0b, 0x71, 0xa4, 0x92, 0x51, 0xe4, 0x64, 0x47,
0x2b, 0x64, 0x6d, 0xb0, 0x3b, 0xe0, 0x48, 0xae, 0x8e, 0xc7, 0xc5, 0x7b, 0x88, 0xed, 0xfd, 0x66, 0x18, 0xd2, 0x7b, 0x00, 0x1b, 0xd6, 0x15, 0xaa, 0x36, 0xd8, 0x2d, 0x70, 0x15, 0xd7, 0xc4, 0xe3,
0x41, 0x97, 0x8b, 0xa1, 0x08, 0xa7, 0x99, 0x32, 0xf0, 0xaa, 0x59, 0xd6, 0x11, 0xb2, 0x8d, 0x08, 0xe2, 0x3d, 0xc4, 0xf6, 0x7e, 0xaf, 0x43, 0x4f, 0xc8, 0xa1, 0x0c, 0xa7, 0x99, 0x36, 0xf0, 0xb2,
0x55, 0x46, 0xa2, 0x08, 0x47, 0x9d, 0x32, 0x1c, 0x2d, 0x54, 0x68, 0xa3, 0xa2, 0x42, 0x69, 0x8c, 0x59, 0x36, 0x11, 0x72, 0xac, 0x08, 0x55, 0x46, 0xa2, 0x08, 0x47, 0xdd, 0x32, 0x1c, 0x2d, 0x54,
0x36, 0x4b, 0x63, 0x34, 0x87, 0x99, 0xad, 0x32, 0xcc, 0x74, 0x73, 0x20, 0xde, 0xa6, 0x80, 0x99, 0x68, 0xb3, 0xa2, 0x42, 0x69, 0x8c, 0xb6, 0x4a, 0x63, 0x34, 0x87, 0x99, 0xed, 0x32, 0xcc, 0xe4,
0xb8, 0x7b, 0x09, 0x40, 0xa1, 0x0c, 0x40, 0xc7, 0xb0, 0xad, 0x42, 0xf2, 0xe9, 0xdf, 0xe7, 0x1f, 0x39, 0x10, 0xef, 0x50, 0xc0, 0x6c, 0xdc, 0xbd, 0x00, 0xa0, 0x50, 0x06, 0xa0, 0x63, 0xd8, 0xd4,
0x1d, 0x15, 0xef, 0x17, 0x5b, 0x4d, 0xdd, 0x13, 0xfa, 0xfe, 0xe0, 0xe2, 0xfc, 0xca, 0xe3, 0x65, 0x21, 0xf9, 0xf8, 0x6f, 0xf6, 0x0f, 0x8e, 0x8a, 0xf7, 0x9b, 0xa3, 0xa7, 0xee, 0x31, 0x7d, 0x7f,
0xfd, 0xe7, 0xce, 0xbf, 0x03, 0xe6, 0xf2, 0x01, 0x73, 0x02, 0x5d, 0xfd, 0xc9, 0x4a, 0x29, 0xb8, 0x08, 0x79, 0x76, 0xe9, 0xf1, 0xb2, 0xfa, 0x73, 0xe7, 0x12, 0x03, 0xa6, 0xf7, 0x7f, 0x19, 0x30,
0xea, 0x84, 0x61, 0xea, 0xc3, 0x98, 0xc6, 0x0b, 0x7d, 0x07, 0xdf, 0x53, 0x99, 0xc5, 0xb9, 0xb2, 0xbd, 0xd2, 0x80, 0x39, 0x86, 0x9e, 0xf9, 0x64, 0xa5, 0x14, 0x5c, 0x76, 0xc2, 0x30, 0xfd, 0xd1,
0x56, 0xad, 0xf7, 0x18, 0x76, 0xe8, 0xd3, 0x9b, 0x06, 0xcb, 0xa5, 0x36, 0x54, 0x4e, 0x97, 0x6f, 0x4d, 0xe3, 0x05, 0xd7, 0xde, 0x1d, 0x9d, 0x59, 0x9c, 0x2b, 0x2b, 0xd5, 0x7a, 0x0f, 0x61, 0x8b,
0x61, 0x6b, 0xe0, 0x6b, 0xcc, 0xb8, 0x5e, 0x85, 0x8a, 0x2b, 0x3d, 0xab, 0x72, 0xe9, 0x7d, 0x25, 0x3e, 0xbc, 0x69, 0xb0, 0xbc, 0xd7, 0x86, 0xca, 0xe9, 0xf2, 0x03, 0x6c, 0x0c, 0x7c, 0x83, 0x19,
0x41, 0xe2, 0x4b, 0xfc, 0xc4, 0xbb, 0xda, 0xc1, 0x87, 0x12, 0x83, 0xe2, 0x6b, 0x75, 0xb5, 0x73, 0x57, 0xab, 0xd0, 0x71, 0xa5, 0x67, 0x55, 0x2d, 0xbd, 0x6f, 0x15, 0x48, 0x7c, 0x8e, 0x9f, 0x78,
0xaf, 0x0d, 0xb4, 0xf9, 0x59, 0x27, 0xcc, 0x13, 0xb8, 0xbe, 0x54, 0xfc, 0xe9, 0x43, 0xe6, 0x89, 0x97, 0x3b, 0x78, 0x5f, 0x61, 0x50, 0x7c, 0xad, 0x2e, 0x77, 0xee, 0xa5, 0x85, 0x36, 0x3f, 0xe9,
0x31, 0xee, 0xf5, 0x9c, 0xf9, 0xb2, 0x3c, 0x67, 0x76, 0xcb, 0x98, 0xb2, 0x34, 0x6a, 0xfa, 0x7f, 0x84, 0x79, 0x04, 0x57, 0x17, 0x8a, 0x3f, 0x7e, 0xc8, 0x3c, 0xb2, 0xc6, 0xbd, 0x99, 0x33, 0xdf,
0xd5, 0xc0, 0xc1, 0xff, 0x81, 0xec, 0x21, 0x40, 0xde, 0xe6, 0xac, 0x1a, 0x48, 0xdf, 0xd2, 0x5f, 0x94, 0xe7, 0xcc, 0x76, 0x19, 0x53, 0x96, 0x46, 0xcd, 0xfe, 0x3f, 0x35, 0x70, 0xf1, 0x1f, 0x21,
0xf8, 0x3f, 0x44, 0x69, 0x78, 0x16, 0xbd, 0x9a, 0x7b, 0x1b, 0xac, 0x6f, 0xfc, 0x4c, 0xa9, 0x42, 0xbb, 0x0f, 0x90, 0xb7, 0x39, 0xab, 0x06, 0xd2, 0x37, 0xcc, 0x17, 0xfe, 0x4f, 0x51, 0x1a, 0x9e,
0xd4, 0x55, 0x67, 0xf4, 0x5d, 0x04, 0x68, 0xaa, 0xc1, 0x75, 0xd5, 0xb9, 0x6f, 0x14, 0xcc, 0xd2, 0x46, 0x2f, 0xce, 0xbd, 0x35, 0xb6, 0x6f, 0xfd, 0x4c, 0xa9, 0x42, 0xd4, 0x55, 0x67, 0xcc, 0x5d,
0xf0, 0x66, 0x15, 0xca, 0xae, 0x38, 0x7b, 0xda, 0xc0, 0xdf, 0x9a, 0x87, 0xff, 0x04, 0x00, 0x00, 0x04, 0x68, 0xaa, 0xc1, 0x75, 0xd5, 0xb9, 0xef, 0x35, 0xcc, 0x32, 0xf0, 0x66, 0x19, 0xca, 0xae,
0xff, 0xff, 0x2f, 0x04, 0xb4, 0x95, 0xff, 0x14, 0x00, 0x00, 0x38, 0x7b, 0xd2, 0xc4, 0x5f, 0x9d, 0x07, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0xe4, 0x81, 0xc1,
0x51, 0x13, 0x15, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
......
...@@ -18,40 +18,6 @@ func init() { ...@@ -18,40 +18,6 @@ func init() {
} }
// exec // exec
type PokerBullType struct {
types.ExecTypeBase
}
func NewType() *PokerBullType {
c := &PokerBullType{}
c.SetChild(c)
return c
}
func (t *PokerBullType) GetPayload() types.Message {
return &PBGameAction{}
}
func (t *PokerBullType) GetTypeMap() map[string]int32 {
return map[string]int32{
"Start": PBGameActionStart,
"Continue": PBGameActionContinue,
"Quit": PBGameActionQuit,
"Query": PBGameActionQuery,
}
}
func (t *PokerBullType) GetLogMap() map[int64]*types.LogInfo {
return map[int64]*types.LogInfo{
TyLogPBGameStart: {reflect.TypeOf(ReceiptPBGame{}), "TyLogPBGameStart"},
TyLogPBGameContinue: {reflect.TypeOf(ReceiptPBGame{}), "TyLogPBGameContinue"},
TyLogPBGameQuit: {reflect.TypeOf(ReceiptPBGame{}), "TyLogPBGameQuit"},
TyLogPBGameQuery: {reflect.TypeOf(ReceiptPBGame{}), "TyLogPBGameQuery"},
}
}
// exec
type GuessType struct { type GuessType struct {
types.ExecTypeBase types.ExecTypeBase
} }
...@@ -68,20 +34,23 @@ func (t *GuessType) GetPayload() types.Message { ...@@ -68,20 +34,23 @@ func (t *GuessType) GetPayload() types.Message {
func (t *GuessType) GetTypeMap() map[string]int32 { func (t *GuessType) GetTypeMap() map[string]int32 {
return map[string]int32{ return map[string]int32{
"Start": PBGameActionStart, "Start": GuessGameActionStart,
"Continue": PBGameActionContinue, "Bet": GuessGameActionBet,
"Quit": PBGameActionQuit, "Abort": GuessGameActionAbort,
"Query": PBGameActionQuery, "Publish": GuessGameActionPublish,
} }
} }
func (t *PokerBullType) GetLogMap() map[int64]*types.LogInfo { func (t *GuessType) GetLogMap() map[int64]*types.LogInfo {
return map[int64]*types.LogInfo{ return map[int64]*types.LogInfo{
TyLogPBGameStart: {reflect.TypeOf(ReceiptPBGame{}), "TyLogPBGameStart"}, TyLogGuessGameStart: {reflect.TypeOf(ReceiptGuessGame{}), "TyLogGuessGameStart"},
TyLogPBGameContinue: {reflect.TypeOf(ReceiptPBGame{}), "TyLogPBGameContinue"}, TyLogGuessGameBet: {reflect.TypeOf(ReceiptGuessGame{}), "TyLogGuessGameBet"},
TyLogPBGameQuit: {reflect.TypeOf(ReceiptPBGame{}), "TyLogPBGameQuit"}, TyLogGuessGameStopBet: {reflect.TypeOf(ReceiptGuessGame{}), "TyLogGuessGameStopBet"},
TyLogPBGameQuery: {reflect.TypeOf(ReceiptPBGame{}), "TyLogPBGameQuery"}, TyLogGuessGameAbort: {reflect.TypeOf(ReceiptGuessGame{}), "TyLogGuessGameAbort"},
TyLogGuessGamePublish: {reflect.TypeOf(ReceiptGuessGame{}), "TyLogGuessGamePublish"},
TyLogGuessGameTimeout: {reflect.TypeOf(ReceiptGuessGame{}), "TyLogGuessGameTimeout"},
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment