Browse Source

离线逻辑,自动过牌/弃牌逻辑

master
tangmingyou 3 years ago
parent
commit
f19582c92e
  1. 2
      README.md
  2. 117
      api/poker.pb.go
  3. 3
      api/poker.proto
  4. 60
      api/proto.js
  5. 4
      data/config.toml
  6. 10
      internal/game/actions.go
  7. 29
      internal/game/event/game_round_end.go
  8. 25
      internal/game/player.go
  9. 28
      internal/game/table.go
  10. 28
      internal/logic/event/offline.go
  11. 6
      internal/logic/event/online.go
  12. 15
      internal/logic/table.go

2
README.md

@ -24,7 +24,7 @@ pkill -f ./texas
TODO List TODO List
### 离线后 ### 离线后
- 牌局结束后,清理离线玩家 - 牌局结束后,清理离线玩家
- 下注超时,页面倒计时、自动操作 - 下注页面倒计时、超时自动操作
- 前端lobby页面显示内容优化 - 前端lobby页面显示内容优化
- lobby界面用户创建新桌面时通知消息,前端拉取新大厅界面, - lobby界面用户创建新桌面时通知消息,前端拉取新大厅界面,
- header头部编辑、退出、账户金额,流水, - header头部编辑、退出、账户金额,流水,

117
api/poker.pb.go

@ -1458,9 +1458,11 @@ type BetRole struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
BetMin int32 `protobuf:"varint,1,opt,name=betMin,proto3" json:"betMin,omitempty"` // 最低下注额 BetMin int32 `protobuf:"varint,1,opt,name=betMin,proto3" json:"betMin,omitempty"` // 最低下注额
BetMax int32 `protobuf:"varint,2,opt,name=betMax,proto3" json:"betMax,omitempty"` // 最高下注额 BetMax int32 `protobuf:"varint,2,opt,name=betMax,proto3" json:"betMax,omitempty"` // 最高下注额
BetOpts []int32 `protobuf:"varint,13,rep,packed,name=betOpts,proto3" json:"betOpts,omitempty"` // status=[4,6]时下注可操作按钮: 1跟注,2加注(-[0]+),3All-In,4弃牌,5过牌 BetTimeLimit int64 `protobuf:"varint,9,opt,name=betTimeLimit,proto3" json:"betTimeLimit,omitempty"` // 下注限制时间戳,客户端判断本机时间减当前时间-betSecondLimit <= 10则取,否则用直接用剩余秒数
BetSecondLimit int32 `protobuf:"varint,10,opt,name=betSecondLimit,proto3" json:"betSecondLimit,omitempty"` // 下注剩余秒数
BetOpts []int32 `protobuf:"varint,13,rep,packed,name=betOpts,proto3" json:"betOpts,omitempty"` // status=[4,6]时下注可操作按钮: 1跟注,2加注(-[0]+),3All-In,4弃牌,5过牌
} }
func (x *BetRole) Reset() { func (x *BetRole) Reset() {
@ -1509,6 +1511,20 @@ func (x *BetRole) GetBetMax() int32 {
return 0 return 0
} }
func (x *BetRole) GetBetTimeLimit() int64 {
if x != nil {
return x.BetTimeLimit
}
return 0
}
func (x *BetRole) GetBetSecondLimit() int32 {
if x != nil {
return x.BetSecondLimit
}
return 0
}
func (x *BetRole) GetBetOpts() []int32 { func (x *BetRole) GetBetOpts() []int32 {
if x != nil { if x != nil {
return x.BetOpts return x.BetOpts
@ -2095,51 +2111,56 @@ var file_poker_proto_rawDesc = []byte{
0x68, 0x61, 0x6e, 0x64, 0x43, 0x61, 0x72, 0x64, 0x22, 0x2c, 0x0a, 0x04, 0x43, 0x61, 0x72, 0x64, 0x68, 0x61, 0x6e, 0x64, 0x43, 0x61, 0x72, 0x64, 0x22, 0x2c, 0x0a, 0x04, 0x43, 0x61, 0x72, 0x64,
0x12, 0x10, 0x0a, 0x03, 0x64, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x64,
0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x75, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x75, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x73, 0x75, 0x69, 0x74, 0x22, 0x53, 0x0a, 0x07, 0x42, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x52, 0x04, 0x73, 0x75, 0x69, 0x74, 0x22, 0x9f, 0x01, 0x0a, 0x07, 0x42, 0x65, 0x74, 0x52, 0x6f,
0x65, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01,
0x05, 0x52, 0x06, 0x62, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x65, 0x74, 0x28, 0x05, 0x52, 0x06, 0x62, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x65,
0x4d, 0x61, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x62, 0x65, 0x74, 0x4d, 0x61, 0x74, 0x4d, 0x61, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x62, 0x65, 0x74, 0x4d,
0x78, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x61, 0x78, 0x12, 0x22, 0x0a, 0x0c, 0x62, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x4c, 0x69, 0x6d,
0x28, 0x05, 0x52, 0x07, 0x62, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x73, 0x22, 0x4c, 0x0a, 0x08, 0x48, 0x69, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x62, 0x65, 0x74, 0x54, 0x69, 0x6d,
0x61, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x6e, 0x64, 0x18, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x62, 0x65, 0x74, 0x53, 0x65, 0x63,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x6f, 0x6e, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e,
0x61, 0x6e, 0x64, 0x5a, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, 0x61, 0x6e, 0x62, 0x65, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x18,
0x64, 0x5a, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x0a, 0x07, 0x62, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x05, 0x52,
0x28, 0x03, 0x52, 0x05, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0x0e, 0x0a, 0x0c, 0x52, 0x65, 0x71, 0x07, 0x62, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x73, 0x22, 0x4c, 0x0a, 0x08, 0x48, 0x61, 0x6e, 0x64,
0x47, 0x61, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, 0x71, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01,
0x44, 0x69, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x47, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x61, 0x6e, 0x64,
0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x44, 0x69, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x47, 0x61, 0x5a, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, 0x61, 0x6e, 0x64, 0x5a, 0x68,
0x6d, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x5c, 0x0a, 0x0a, 0x52, 0x65, 0x71, 0x42, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x05, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0x0e, 0x0a, 0x0c, 0x52, 0x65, 0x71, 0x47, 0x61, 0x6d,
0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x62, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, 0x71, 0x44, 0x69, 0x73,
0x18, 0x0a, 0x07, 0x62, 0x65, 0x74, 0x43, 0x68, 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x6d, 0x69, 0x73, 0x73, 0x47, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x15, 0x0a,
0x52, 0x07, 0x62, 0x65, 0x74, 0x43, 0x68, 0x69, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x13, 0x52, 0x65, 0x73, 0x44, 0x69, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x47, 0x61, 0x6d, 0x65, 0x54,
0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x5c, 0x0a, 0x0a, 0x52, 0x65, 0x71, 0x42, 0x65, 0x74, 0x74, 0x69,
0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x73, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x4e, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20,
0x63, 0x65, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x01, 0x28, 0x05, 0x52, 0x07, 0x62, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07,
0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x62, 0x65, 0x74, 0x43, 0x68, 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x62,
0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x65, 0x74, 0x43, 0x68, 0x69, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74,
0x31, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x31, 0x12, 0x14, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74,
0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x32, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x6f, 0x72, 0x22, 0x73, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x4e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x50,
0x69, 0x6e, 0x65, 0x32, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x33, 0x18, 0x0d, 0x20, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61,
0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x33, 0x22, 0x3e, 0x0a, 0x10, 0x52, 0x65, 0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x70, 0x6c, 0x61,
0x73, 0x47, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x64, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x12, 0x2a, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x31, 0x18, 0x0b,
0x0a, 0x04, 0x67, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x31, 0x12, 0x14, 0x0a, 0x05, 0x6c,
0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x47, 0x61, 0x6d, 0x65, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x69, 0x6e, 0x65, 0x32, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x65,
0x61, 0x74, 0x75, 0x73, 0x52, 0x04, 0x67, 0x61, 0x6d, 0x65, 0x22, 0x92, 0x01, 0x0a, 0x11, 0x52, 0x32, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x33, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09,
0x65, 0x73, 0x43, 0x61, 0x6c, 0x63, 0x57, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x68, 0x69, 0x70, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x65, 0x33, 0x22, 0x3e, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x47, 0x61,
0x12, 0x40, 0x0a, 0x08, 0x77, 0x69, 0x6e, 0x73, 0x43, 0x68, 0x69, 0x70, 0x18, 0x09, 0x20, 0x03, 0x6d, 0x65, 0x45, 0x6e, 0x64, 0x53, 0x65, 0x74, 0x74, 0x6c, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x67,
0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x43, 0x61, 0x6c, 0x63, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x57, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x68, 0x69, 0x70, 0x2e, 0x57, 0x69, 0x6e, 0x73, 0x43, 0x52, 0x65, 0x73, 0x47, 0x61, 0x6d, 0x65, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75,
0x68, 0x69, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x77, 0x69, 0x6e, 0x73, 0x43, 0x68, 0x73, 0x52, 0x04, 0x67, 0x61, 0x6d, 0x65, 0x22, 0x92, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x43,
0x69, 0x70, 0x1a, 0x3b, 0x0a, 0x0d, 0x57, 0x69, 0x6e, 0x73, 0x43, 0x68, 0x69, 0x70, 0x45, 0x6e, 0x61, 0x6c, 0x63, 0x57, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x68, 0x69, 0x70, 0x12, 0x40, 0x0a,
0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x08, 0x77, 0x69, 0x6e, 0x73, 0x43, 0x68, 0x69, 0x70, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x43, 0x61, 0x6c, 0x63, 0x57, 0x69, 0x6e,
0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6e, 0x65, 0x72, 0x43, 0x68, 0x69, 0x70, 0x2e, 0x57, 0x69, 0x6e, 0x73, 0x43, 0x68, 0x69, 0x70,
0x28, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x47, 0x61, 0x6d, 0x65, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x77, 0x69, 0x6e, 0x73, 0x43, 0x68, 0x69, 0x70, 0x1a,
0x75, 0x6e, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x3b, 0x0a, 0x0d, 0x57, 0x69, 0x6e, 0x73, 0x43, 0x68, 0x69, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79,
0x28, 0x05, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6b,
0x70, 0x69, 0x3b, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x28, 0x0a, 0x10,
0x52, 0x65, 0x73, 0x47, 0x61, 0x6d, 0x65, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64,
0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x61, 0x70, 0x69, 0x3b,
0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (

3
api/poker.proto

@ -167,6 +167,9 @@ message Card {
message BetRole { message BetRole {
int32 betMin = 1; // int32 betMin = 1; //
int32 betMax = 2; // int32 betMax = 2; //
int64 betTimeLimit = 9; // ,-betSecondLimit <= 10
int32 betSecondLimit = 10; //
repeated int32 betOpts = 13; // status=[4,6]: 1,2(-[0]+),3All-In,4,5 repeated int32 betOpts = 13; // status=[4,6]: 1,2(-[0]+),3All-In,4,5
} }

60
api/proto.js

@ -6028,6 +6028,8 @@ export const api = $root.api = (() => {
* @interface IBetRole * @interface IBetRole
* @property {number|null} [betMin] BetRole betMin * @property {number|null} [betMin] BetRole betMin
* @property {number|null} [betMax] BetRole betMax * @property {number|null} [betMax] BetRole betMax
* @property {number|Long|null} [betTimeLimit] BetRole betTimeLimit
* @property {number|null} [betSecondLimit] BetRole betSecondLimit
* @property {Array.<number>|null} [betOpts] BetRole betOpts * @property {Array.<number>|null} [betOpts] BetRole betOpts
*/ */
@ -6063,6 +6065,22 @@ export const api = $root.api = (() => {
*/ */
BetRole.prototype.betMax = 0; BetRole.prototype.betMax = 0;
/**
* BetRole betTimeLimit.
* @member {number|Long} betTimeLimit
* @memberof api.BetRole
* @instance
*/
BetRole.prototype.betTimeLimit = $util.Long ? $util.Long.fromBits(0,0,false) : 0;
/**
* BetRole betSecondLimit.
* @member {number} betSecondLimit
* @memberof api.BetRole
* @instance
*/
BetRole.prototype.betSecondLimit = 0;
/** /**
* BetRole betOpts. * BetRole betOpts.
* @member {Array.<number>} betOpts * @member {Array.<number>} betOpts
@ -6099,6 +6117,10 @@ export const api = $root.api = (() => {
writer.uint32(/* id 1, wireType 0 =*/8).int32(message.betMin); writer.uint32(/* id 1, wireType 0 =*/8).int32(message.betMin);
if (message.betMax != null && Object.hasOwnProperty.call(message, "betMax")) if (message.betMax != null && Object.hasOwnProperty.call(message, "betMax"))
writer.uint32(/* id 2, wireType 0 =*/16).int32(message.betMax); writer.uint32(/* id 2, wireType 0 =*/16).int32(message.betMax);
if (message.betTimeLimit != null && Object.hasOwnProperty.call(message, "betTimeLimit"))
writer.uint32(/* id 9, wireType 0 =*/72).int64(message.betTimeLimit);
if (message.betSecondLimit != null && Object.hasOwnProperty.call(message, "betSecondLimit"))
writer.uint32(/* id 10, wireType 0 =*/80).int32(message.betSecondLimit);
if (message.betOpts != null && message.betOpts.length) { if (message.betOpts != null && message.betOpts.length) {
writer.uint32(/* id 13, wireType 2 =*/106).fork(); writer.uint32(/* id 13, wireType 2 =*/106).fork();
for (let i = 0; i < message.betOpts.length; ++i) for (let i = 0; i < message.betOpts.length; ++i)
@ -6147,6 +6169,14 @@ export const api = $root.api = (() => {
message.betMax = reader.int32(); message.betMax = reader.int32();
break; break;
} }
case 9: {
message.betTimeLimit = reader.int64();
break;
}
case 10: {
message.betSecondLimit = reader.int32();
break;
}
case 13: { case 13: {
if (!(message.betOpts && message.betOpts.length)) if (!(message.betOpts && message.betOpts.length))
message.betOpts = []; message.betOpts = [];
@ -6199,6 +6229,12 @@ export const api = $root.api = (() => {
if (message.betMax != null && message.hasOwnProperty("betMax")) if (message.betMax != null && message.hasOwnProperty("betMax"))
if (!$util.isInteger(message.betMax)) if (!$util.isInteger(message.betMax))
return "betMax: integer expected"; return "betMax: integer expected";
if (message.betTimeLimit != null && message.hasOwnProperty("betTimeLimit"))
if (!$util.isInteger(message.betTimeLimit) && !(message.betTimeLimit && $util.isInteger(message.betTimeLimit.low) && $util.isInteger(message.betTimeLimit.high)))
return "betTimeLimit: integer|Long expected";
if (message.betSecondLimit != null && message.hasOwnProperty("betSecondLimit"))
if (!$util.isInteger(message.betSecondLimit))
return "betSecondLimit: integer expected";
if (message.betOpts != null && message.hasOwnProperty("betOpts")) { if (message.betOpts != null && message.hasOwnProperty("betOpts")) {
if (!Array.isArray(message.betOpts)) if (!Array.isArray(message.betOpts))
return "betOpts: array expected"; return "betOpts: array expected";
@ -6225,6 +6261,17 @@ export const api = $root.api = (() => {
message.betMin = object.betMin | 0; message.betMin = object.betMin | 0;
if (object.betMax != null) if (object.betMax != null)
message.betMax = object.betMax | 0; message.betMax = object.betMax | 0;
if (object.betTimeLimit != null)
if ($util.Long)
(message.betTimeLimit = $util.Long.fromValue(object.betTimeLimit)).unsigned = false;
else if (typeof object.betTimeLimit === "string")
message.betTimeLimit = parseInt(object.betTimeLimit, 10);
else if (typeof object.betTimeLimit === "number")
message.betTimeLimit = object.betTimeLimit;
else if (typeof object.betTimeLimit === "object")
message.betTimeLimit = new $util.LongBits(object.betTimeLimit.low >>> 0, object.betTimeLimit.high >>> 0).toNumber();
if (object.betSecondLimit != null)
message.betSecondLimit = object.betSecondLimit | 0;
if (object.betOpts) { if (object.betOpts) {
if (!Array.isArray(object.betOpts)) if (!Array.isArray(object.betOpts))
throw TypeError(".api.BetRole.betOpts: array expected"); throw TypeError(".api.BetRole.betOpts: array expected");
@ -6253,11 +6300,24 @@ export const api = $root.api = (() => {
if (options.defaults) { if (options.defaults) {
object.betMin = 0; object.betMin = 0;
object.betMax = 0; object.betMax = 0;
if ($util.Long) {
let long = new $util.Long(0, 0, false);
object.betTimeLimit = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
} else
object.betTimeLimit = options.longs === String ? "0" : 0;
object.betSecondLimit = 0;
} }
if (message.betMin != null && message.hasOwnProperty("betMin")) if (message.betMin != null && message.hasOwnProperty("betMin"))
object.betMin = message.betMin; object.betMin = message.betMin;
if (message.betMax != null && message.hasOwnProperty("betMax")) if (message.betMax != null && message.hasOwnProperty("betMax"))
object.betMax = message.betMax; object.betMax = message.betMax;
if (message.betTimeLimit != null && message.hasOwnProperty("betTimeLimit"))
if (typeof message.betTimeLimit === "number")
object.betTimeLimit = options.longs === String ? String(message.betTimeLimit) : message.betTimeLimit;
else
object.betTimeLimit = options.longs === String ? $util.Long.prototype.toString.call(message.betTimeLimit) : options.longs === Number ? new $util.LongBits(message.betTimeLimit.low >>> 0, message.betTimeLimit.high >>> 0).toNumber() : message.betTimeLimit;
if (message.betSecondLimit != null && message.hasOwnProperty("betSecondLimit"))
object.betSecondLimit = message.betSecondLimit;
if (message.betOpts && message.betOpts.length) { if (message.betOpts && message.betOpts.length) {
object.betOpts = []; object.betOpts = [];
for (let j = 0; j < message.betOpts.length; ++j) for (let j = 0; j < message.betOpts.length; ++j)

4
data/config.toml

@ -1,6 +1,7 @@
[http] [http]
host = "" #host = ""
host = "192.168.110.53"
#host = "192.168.3.101" #host = "192.168.3.101"
port = 3999 port = 3999
@ -26,6 +27,7 @@ dbPath = "data/texas-poker.db"
# 新用户赠送筹码 # 新用户赠送筹码
giftChip = 10000 giftChip = 10000
avatarPath = "data/avatar/" avatarPath = "data/avatar/"
betTimeLimit = 120
[game.offline] # 玩家掉线配置 [game.offline] # 玩家掉线配置
# 在房间中 # 在房间中

10
internal/game/actions.go

@ -273,12 +273,16 @@ func SetNextPlayer4Limited(roundStart bool, t *Table, current *Player) {
if nextP.BetMax > nextP.BetMin { // 加注 if nextP.BetMax > nextP.BetMin { // 加注
nextP.BetOpts = append(nextP.BetOpts, 2) nextP.BetOpts = append(nextP.BetOpts, 2)
} }
// TODO 下注倒计时
nextP.BetTimeLimit = time.Now().Add(120 * time.Second)
nextP.AutoBetDelayCanceler = nextP.GameTable.RefAutoBettingDelayQueue.Delay(120*time.Second, nextP.Id)
// TODO 筹码不够跟注时可 all in // TODO 筹码不够跟注时可 all in
// 玩家离线,n秒后自动投注 // 玩家离线,n秒后自动投注
if !nextP.Client.IsOnline() { //if !nextP.Client.IsOnline() {
nextP.OfflineAutoBetDelayCanceler = nextP.GameTable.RefAutoBettingDelayQueue.Delay(60*time.Second, nextP.Id) // nextP.AutoBetDelayCanceler = nextP.GameTable.RefAutoBettingDelayQueue.Delay(60*time.Second, nextP.Id)
} //}
} }
func AllIn4NoLimited(player *Player, betChip int32) proto.Message { func AllIn4NoLimited(player *Player, betChip int32) proto.Message {

29
internal/game/event/game_round_end.go

@ -25,38 +25,23 @@ func handleGameRoundEnd(e *watcher.Event[int32, bool]) {
} }
table.Lock.Lock() table.Lock.Lock()
defer table.Lock.Unlock() defer table.Lock.Unlock()
table.PlayersLock.Lock()
defer table.PlayersLock.Unlock()
notice := true for _, player := range table.Players {
for i, player := range table.Players {
if player == nil { if player == nil {
continue continue
} }
// 移除牌桌上所有离线玩家
if !player.Client.IsOnline() { if !player.Client.IsOnline() {
// 踢了 // 踢了
table.Players[i] = nil found, _ := table.RemovePlayer(player.Id)
// 结算玩家金额 if found {
store.NetAccounts.Get(player.Id).SettlePlayerChip() // 结算玩家金额
// 被踢玩家消息 store.NetAccounts.Get(player.Id).SettlePlayerChip()
// player.Client.Write(&api.ResKickOutTable{})
// 该离线玩家是房主, 房主给到下个位置玩家
if table.MasterId == player.Id {
nextMasterPos := table.NextPlayerPos(i)
if nextMasterPos == i {
// 没有玩家了, 解散牌桌
notice = false
table.Stage = 9
game.LobbyTables.Delete(player.GameTable.TableNo)
return
}
table.MasterId = table.Players[nextMasterPos].Id
} }
} }
} }
// 通知牌桌所有玩家 // 通知牌桌所有玩家
if notice { if 0 < table.PlayerCount() {
table.NoticeGameFullStatus() table.NoticeGameFullStatus()
} }
} }

25
internal/game/player.go

@ -5,6 +5,7 @@ import (
"texas-poker-bk/internal/letter" "texas-poker-bk/internal/letter"
"texas-poker-bk/tool/async" "texas-poker-bk/tool/async"
"texas-poker-bk/tool/collect" "texas-poker-bk/tool/collect"
"time"
) )
var ( var (
@ -18,23 +19,25 @@ type Player struct {
Username string Username string
Avatar string Avatar string
Cards [2]*Card // 手牌 Cards [2]*Card // 手牌
Chip int32 // 玩家筹码 Chip int32 // 玩家筹码
TotalBetChip int32 // 本次游戏已下注筹码 TotalBetChip int32 // 本次游戏已下注筹码
Status int32 // 状态: 1待准备开始,2已准备开始,3等待其他玩家动作,[4第一回合小盲注跟注,5待大盲注,5待小盲注,] 6待跟注,7已弃牌,8结算中 Status int32 // 状态: 1待准备开始,2已准备开始,3等待其他玩家动作,[4第一回合小盲注跟注,5待大盲注,5待小盲注,] 6待跟注,7已弃牌,8结算中
BetOpts []int32 // status=[4,6]时下注可操作按钮: (-2大盲注,-1小盲注) 1跟注,2加注(-[0]+),3All-In,4弃牌,5过牌 BetOpts []int32 // status=[4,6]时下注可操作按钮: (-2大盲注,-1小盲注) 1跟注,2加注(-[0]+),3All-In,4弃牌,5过牌
BetMin int32 // 最低下注额 BetMin int32 // 最低下注额
BetMax int32 // 最高下注额 -1不限 BetMax int32 // 最高下注额 -1不限
RoundBetTimes int32 // 当前回合下注次数 BetTimeLimit time.Time // 下注截止时间
Hand *Hand // 手牌牌型
RoundCheckRaiseOnly bool // 该回合仅过牌下注 RoundBetTimes int32 // 当前回合下注次数
Hand *Hand // 手牌牌型
RoundCheckRaiseOnly bool // 该回合仅过牌下注
GameTable *Table // 当前牌桌 GameTable *Table // 当前牌桌
Client letter.ProtoClient Client letter.ProtoClient
Lock *sync.Mutex Lock *sync.Mutex
StatusLock *sync.Mutex StatusLock *sync.Mutex
OfflineAutoBetDelayCanceler *async.Canceler[int64] AutoBetDelayCanceler *async.Canceler[int64]
} }
func (p *Player) Init() { func (p *Player) Init() {

28
internal/game/table.go

@ -7,6 +7,7 @@ import (
"texas-poker-bk/api" "texas-poker-bk/api"
"texas-poker-bk/tool/async" "texas-poker-bk/tool/async"
"texas-poker-bk/tool/collect" "texas-poker-bk/tool/collect"
"time"
) )
var ( var (
@ -191,8 +192,22 @@ func (t *Table) RemovePlayer(playerId int64) (found bool, player *Player) {
defer t.PlayersLock.Unlock() defer t.PlayersLock.Unlock()
// 从牌桌移除 // 从牌桌移除
for i, p := range t.Players { for i, p := range t.Players {
if p == nil {
continue
}
if p.Id == playerId { if p.Id == playerId {
t.Players[i] = nil t.Players[i] = nil
// 该玩家是房主, 房主给到下个位置玩家
if t.MasterId == player.Id {
nextMasterPos := t.NextPlayerPos(i)
if nextMasterPos != i {
t.MasterId = t.Players[nextMasterPos].Id
} else {
// 没有玩家了, 解散牌桌
t.Stage = 9
LobbyTables.Delete(player.GameTable.TableNo)
}
}
return true, p return true, p
} }
} }
@ -221,11 +236,16 @@ func (t *Table) BuildResGameFullStatus() *api.ResGameFullStatus {
} }
// 牌桌玩家 // 牌桌玩家
resGame.Players = make([]*api.TablePlayer, len(t.Players)) resGame.Players = make([]*api.TablePlayer, len(t.Players))
now := time.Now()
for i, p := range t.Players { for i, p := range t.Players {
if p == nil { if p == nil {
resGame.Players[i] = nil resGame.Players[i] = nil
continue continue
} }
var betSecondLimit int32 = 0
if p.Status == 6 {
betSecondLimit = int32(p.BetTimeLimit.Sub(now).Milliseconds() / 1000)
}
player := &api.TablePlayer{ player := &api.TablePlayer{
Robot: false, Robot: false,
Id: p.Id, Id: p.Id,
@ -238,9 +258,11 @@ func (t *Table) BuildResGameFullStatus() *api.ResGameFullStatus {
TotalBetChip: p.TotalBetChip, TotalBetChip: p.TotalBetChip,
HandCard: make([]*api.Card, 2), HandCard: make([]*api.Card, 2),
BetRole: &api.BetRole{ BetRole: &api.BetRole{
BetMin: p.BetMin, BetMin: p.BetMin,
BetMax: p.BetMax, BetMax: p.BetMax,
BetOpts: p.BetOpts, BetTimeLimit: p.BetTimeLimit.UnixMilli(),
BetSecondLimit: betSecondLimit,
BetOpts: p.BetOpts,
}, },
} }
if p.Hand != nil { if p.Hand != nil {

28
internal/logic/event/offline.go

@ -2,6 +2,7 @@ package event
import ( import (
"fmt" "fmt"
gameDelayer "texas-poker-bk/internal/game/delayer"
"texas-poker-bk/internal/logic/delayer" "texas-poker-bk/internal/logic/delayer"
"texas-poker-bk/internal/logic/store" "texas-poker-bk/internal/logic/store"
"texas-poker-bk/tool/collect" "texas-poker-bk/tool/collect"
@ -33,16 +34,29 @@ func handleOffline(e *watcher.Event[int64, bool]) {
account.OfflineCleanCanceler = delayer.OfflineCleanDelayer.Delay(10*time.Second, account.Id) account.OfflineCleanCanceler = delayer.OfflineCleanDelayer.Delay(10*time.Second, account.Id)
return return
} }
// 牌局未在进行中直接移除玩家并下线
if collect.In(account.Player.GameTable.Stage, 1, 9) { if collect.In(account.Player.GameTable.Stage, 1, 9) {
// 牌局未在进行中直接移除玩家并下线 found, _ := account.Player.GameTable.RemovePlayer(account.Id)
account.Player.GameTable.RemovePlayer(account.Id) if found {
account.SettlePlayerChip() account.SettlePlayerChip()
}
account.OfflineCleanCanceler = delayer.OfflineCleanDelayer.Delay(10*time.Second, account.Id) account.OfflineCleanCanceler = delayer.OfflineCleanDelayer.Delay(10*time.Second, account.Id)
return return
} }
// 判断当前是玩家回合(60s自动过牌/弃牌) // 牌局结束展示时间,10s后再移除玩家
if account.Player.Status == 6 { if account.Player.GameTable.Stage == 7 {
account.Player.GameTable.RefAutoBettingDelayQueue.Delay(60*time.Second, account.Id) accountId := e.Publisher
gameDelayer.GameDelayer.Delay(10*time.Second, func() {
account := store.NetAccounts.Get(accountId)
if account == nil || account.Player == nil || collect.NotIn(account.Player.GameTable.Stage, 1, 7, 9) {
return
}
// 从牌桌移除玩家
found, _ := account.Player.GameTable.RemovePlayer(account.Id)
if found {
account.SettlePlayerChip()
}
account.OfflineCleanCanceler = delayer.OfflineCleanDelayer.Delay(3*time.Second, account.Id)
})
} }
// 待玩家回合时还是offline(自动过牌/弃牌)
} }

6
internal/logic/event/online.go

@ -26,8 +26,8 @@ func handleOnline(e *watcher.Event[int64, bool]) {
return return
} }
// 取消自动下注 // 取消自动下注
if account.Player.OfflineAutoBetDelayCanceler != nil { if account.Player.AutoBetDelayCanceler != nil {
account.Player.OfflineAutoBetDelayCanceler.Cancel() account.Player.AutoBetDelayCanceler.Cancel()
account.Player.OfflineAutoBetDelayCanceler = nil account.Player.AutoBetDelayCanceler = nil
} }
} }

15
internal/logic/table.go

@ -203,8 +203,8 @@ func HandleReqJoinTable(account *session.NetAccount, msg *api.ReqJoinTable) (pro
// HandleReqKickOutTable 踢人 // HandleReqKickOutTable 踢人
func HandleReqKickOutTable(player *game.Player, msg *api.ReqKickOutTable) (proto.Message, error) { func HandleReqKickOutTable(player *game.Player, msg *api.ReqKickOutTable) (proto.Message, error) {
player.GameTable.PlayersLock.Lock() player.GameTable.Lock.Lock()
defer player.GameTable.PlayersLock.Unlock() defer player.GameTable.Lock.Unlock()
if player.GameTable.MasterId != player.Id { if player.GameTable.MasterId != player.Id {
return &api.ResFail{Msg: "不是房主不能踢人"}, nil return &api.ResFail{Msg: "不是房主不能踢人"}, nil
@ -230,8 +230,8 @@ func HandleReqKickOutTable(player *game.Player, msg *api.ReqKickOutTable) (proto
// HandleReqLeaveTable 离开桌面 // HandleReqLeaveTable 离开桌面
func HandleReqLeaveTable(player *game.Player, _ *api.ReqLeaveTable) (proto.Message, error) { func HandleReqLeaveTable(player *game.Player, _ *api.ReqLeaveTable) (proto.Message, error) {
player.GameTable.PlayersLock.Lock() player.GameTable.Lock.Lock()
defer player.GameTable.PlayersLock.Unlock() defer player.GameTable.Lock.Unlock()
if !collect.In(player.GameTable.Stage, 1, 7, 9) { if !collect.In(player.GameTable.Stage, 1, 7, 9) {
return &api.ResFail{Msg: "牌局进行中不能退出"}, nil return &api.ResFail{Msg: "牌局进行中不能退出"}, nil
@ -280,7 +280,7 @@ func HandleReqReadyStart(player *game.Player, _ *api.ReqReadyStart) (proto.Messa
if player.Id == player.GameTable.MasterId { if player.Id == player.GameTable.MasterId {
return &api.ResFail{Msg: "房主不用准备"}, nil return &api.ResFail{Msg: "房主不用准备"}, nil
} }
if !collect.In(player.Status, 1, 8) { if collect.NotIn(player.Status, 1, 8) {
msg := "" msg := ""
switch player.Status { switch player.Status {
case 2: case 2:
@ -457,6 +457,11 @@ func HandleReqBetting(player *game.Player, msg *api.ReqBetting) (proto.Message,
return res, nil return res, nil
} }
// 取消自动下注
if player.AutoBetDelayCanceler != nil {
player.AutoBetDelayCanceler.Cancel()
}
// 记录操作 // 记录操作
table.PlayerBet(player, table.LastPosBetOp, table.LastPosBetChip) table.PlayerBet(player, table.LastPosBetOp, table.LastPosBetChip)

Loading…
Cancel
Save