From 6dc682f30d1f2c7adaabe7c0d4d0d7fd662baebc Mon Sep 17 00:00:00 2001 From: tangmingyou <234767776@qq.com> Date: Fri, 3 Feb 2023 17:47:26 +0800 Subject: [PATCH] game start,dismiss,ready,blind --- api/operation.go | 8 + api/poker.pb.go | 641 ++++++++++++---- api/poker.proto | 31 +- api/proto.js | 1207 ++++++++++++++++++++++++++++++- internal/game/game.go | 36 +- internal/game/player.go | 8 +- internal/game/table.go | 61 +- internal/server/ws.go | 22 +- internal/server/wsroute.go | 11 +- internal/service/auth.go | 5 +- internal/service/store/store.go | 9 +- internal/service/table.go | 199 +++-- internal/session/net_client.go | 28 +- 13 files changed, 2001 insertions(+), 265 deletions(-) diff --git a/api/operation.go b/api/operation.go index 8ad65e5..88d95a3 100644 --- a/api/operation.go +++ b/api/operation.go @@ -38,9 +38,17 @@ var protoInstances = []proto.Message{ &ResGameFullStatus{}, &ReqReadyStart{}, + &ReqCancelReady{}, &ReqKickOutTable{}, &ResKickOutTable{}, + + &ReqDismissGameTable{}, + &ResDismissGameTable{}, + &ReqGameStart{}, + + &ResBigBlindChip{}, + &ResSmallBlindChip{}, } var ( diff --git a/api/poker.pb.go b/api/poker.pb.go index 4e7c8c1..b2c1cec 100644 --- a/api/poker.pb.go +++ b/api/poker.pb.go @@ -351,8 +351,9 @@ type ResIdentity struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Status int32 `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"` - Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` + Id int64 `protobuf:"varint,3,opt,name=id,proto3" json:"id,omitempty"` + Username string `protobuf:"bytes,4,opt,name=username,proto3" json:"username,omitempty"` + Avatar string `protobuf:"bytes,5,opt,name=avatar,proto3" json:"avatar,omitempty"` } func (x *ResIdentity) Reset() { @@ -387,16 +388,23 @@ func (*ResIdentity) Descriptor() ([]byte, []int) { return file_poker_proto_rawDescGZIP(), []int{6} } -func (x *ResIdentity) GetStatus() int32 { +func (x *ResIdentity) GetId() int64 { if x != nil { - return x.Status + return x.Id } return 0 } -func (x *ResIdentity) GetMsg() string { +func (x *ResIdentity) GetUsername() string { if x != nil { - return x.Msg + return x.Username + } + return "" +} + +func (x *ResIdentity) GetAvatar() string { + if x != nil { + return x.Avatar } return "" } @@ -858,6 +866,45 @@ func (*ReqReadyStart) Descriptor() ([]byte, []int) { return file_poker_proto_rawDescGZIP(), []int{15} } +// 取消准备 +type ReqCancelReady struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ReqCancelReady) Reset() { + *x = ReqCancelReady{} + if protoimpl.UnsafeEnabled { + mi := &file_poker_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReqCancelReady) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReqCancelReady) ProtoMessage() {} + +func (x *ReqCancelReady) ProtoReflect() protoreflect.Message { + mi := &file_poker_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReqCancelReady.ProtoReflect.Descriptor instead. +func (*ReqCancelReady) Descriptor() ([]byte, []int) { + return file_poker_proto_rawDescGZIP(), []int{16} +} + // 房主踢人 type ReqKickOutTable struct { state protoimpl.MessageState @@ -870,7 +917,7 @@ type ReqKickOutTable struct { func (x *ReqKickOutTable) Reset() { *x = ReqKickOutTable{} if protoimpl.UnsafeEnabled { - mi := &file_poker_proto_msgTypes[16] + mi := &file_poker_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -883,7 +930,7 @@ func (x *ReqKickOutTable) String() string { func (*ReqKickOutTable) ProtoMessage() {} func (x *ReqKickOutTable) ProtoReflect() protoreflect.Message { - mi := &file_poker_proto_msgTypes[16] + mi := &file_poker_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -896,7 +943,7 @@ func (x *ReqKickOutTable) ProtoReflect() protoreflect.Message { // Deprecated: Use ReqKickOutTable.ProtoReflect.Descriptor instead. func (*ReqKickOutTable) Descriptor() ([]byte, []int) { - return file_poker_proto_rawDescGZIP(), []int{16} + return file_poker_proto_rawDescGZIP(), []int{17} } func (x *ReqKickOutTable) GetPlayerId() int64 { @@ -916,7 +963,7 @@ type ResKickOutTable struct { func (x *ResKickOutTable) Reset() { *x = ResKickOutTable{} if protoimpl.UnsafeEnabled { - mi := &file_poker_proto_msgTypes[17] + mi := &file_poker_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -929,7 +976,7 @@ func (x *ResKickOutTable) String() string { func (*ResKickOutTable) ProtoMessage() {} func (x *ResKickOutTable) ProtoReflect() protoreflect.Message { - mi := &file_poker_proto_msgTypes[17] + mi := &file_poker_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -942,7 +989,7 @@ func (x *ResKickOutTable) ProtoReflect() protoreflect.Message { // Deprecated: Use ResKickOutTable.ProtoReflect.Descriptor instead. func (*ResKickOutTable) Descriptor() ([]byte, []int) { - return file_poker_proto_rawDescGZIP(), []int{17} + return file_poker_proto_rawDescGZIP(), []int{18} } type ReqGameAction struct { @@ -957,7 +1004,7 @@ type ReqGameAction struct { func (x *ReqGameAction) Reset() { *x = ReqGameAction{} if protoimpl.UnsafeEnabled { - mi := &file_poker_proto_msgTypes[18] + mi := &file_poker_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -970,7 +1017,7 @@ func (x *ReqGameAction) String() string { func (*ReqGameAction) ProtoMessage() {} func (x *ReqGameAction) ProtoReflect() protoreflect.Message { - mi := &file_poker_proto_msgTypes[18] + mi := &file_poker_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -983,7 +1030,7 @@ func (x *ReqGameAction) ProtoReflect() protoreflect.Message { // Deprecated: Use ReqGameAction.ProtoReflect.Descriptor instead. func (*ReqGameAction) Descriptor() ([]byte, []int) { - return file_poker_proto_rawDescGZIP(), []int{18} + return file_poker_proto_rawDescGZIP(), []int{19} } func (x *ReqGameAction) GetAction() int32 { @@ -1009,7 +1056,7 @@ type ResGameAction struct { func (x *ResGameAction) Reset() { *x = ResGameAction{} if protoimpl.UnsafeEnabled { - mi := &file_poker_proto_msgTypes[19] + mi := &file_poker_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1022,7 +1069,7 @@ func (x *ResGameAction) String() string { func (*ResGameAction) ProtoMessage() {} func (x *ResGameAction) ProtoReflect() protoreflect.Message { - mi := &file_poker_proto_msgTypes[19] + mi := &file_poker_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1035,7 +1082,7 @@ func (x *ResGameAction) ProtoReflect() protoreflect.Message { // Deprecated: Use ResGameAction.ProtoReflect.Descriptor instead. func (*ResGameAction) Descriptor() ([]byte, []int) { - return file_poker_proto_rawDescGZIP(), []int{19} + return file_poker_proto_rawDescGZIP(), []int{20} } // 查询玩家当前游戏状态 @@ -1048,7 +1095,7 @@ type ReqGameFullStatus struct { func (x *ReqGameFullStatus) Reset() { *x = ReqGameFullStatus{} if protoimpl.UnsafeEnabled { - mi := &file_poker_proto_msgTypes[20] + mi := &file_poker_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1061,7 +1108,7 @@ func (x *ReqGameFullStatus) String() string { func (*ReqGameFullStatus) ProtoMessage() {} func (x *ReqGameFullStatus) ProtoReflect() protoreflect.Message { - mi := &file_poker_proto_msgTypes[20] + mi := &file_poker_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1074,7 +1121,7 @@ func (x *ReqGameFullStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use ReqGameFullStatus.ProtoReflect.Descriptor instead. func (*ReqGameFullStatus) Descriptor() ([]byte, []int) { - return file_poker_proto_rawDescGZIP(), []int{20} + return file_poker_proto_rawDescGZIP(), []int{21} } type ResGameFullStatus struct { @@ -1095,7 +1142,7 @@ type ResGameFullStatus struct { func (x *ResGameFullStatus) Reset() { *x = ResGameFullStatus{} if protoimpl.UnsafeEnabled { - mi := &file_poker_proto_msgTypes[21] + mi := &file_poker_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1108,7 +1155,7 @@ func (x *ResGameFullStatus) String() string { func (*ResGameFullStatus) ProtoMessage() {} func (x *ResGameFullStatus) ProtoReflect() protoreflect.Message { - mi := &file_poker_proto_msgTypes[21] + mi := &file_poker_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1121,7 +1168,7 @@ func (x *ResGameFullStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use ResGameFullStatus.ProtoReflect.Descriptor instead. func (*ResGameFullStatus) Descriptor() ([]byte, []int) { - return file_poker_proto_rawDescGZIP(), []int{21} + return file_poker_proto_rawDescGZIP(), []int{22} } func (x *ResGameFullStatus) GetInGame() bool { @@ -1198,7 +1245,7 @@ type TablePlayer struct { func (x *TablePlayer) Reset() { *x = TablePlayer{} if protoimpl.UnsafeEnabled { - mi := &file_poker_proto_msgTypes[22] + mi := &file_poker_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1211,7 +1258,7 @@ func (x *TablePlayer) String() string { func (*TablePlayer) ProtoMessage() {} func (x *TablePlayer) ProtoReflect() protoreflect.Message { - mi := &file_poker_proto_msgTypes[22] + mi := &file_poker_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1224,7 +1271,7 @@ func (x *TablePlayer) ProtoReflect() protoreflect.Message { // Deprecated: Use TablePlayer.ProtoReflect.Descriptor instead. func (*TablePlayer) Descriptor() ([]byte, []int) { - return file_poker_proto_rawDescGZIP(), []int{22} + return file_poker_proto_rawDescGZIP(), []int{23} } func (x *TablePlayer) GetRobot() bool { @@ -1295,7 +1342,7 @@ type Card struct { func (x *Card) Reset() { *x = Card{} if protoimpl.UnsafeEnabled { - mi := &file_poker_proto_msgTypes[23] + mi := &file_poker_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1308,7 +1355,7 @@ func (x *Card) String() string { func (*Card) ProtoMessage() {} func (x *Card) ProtoReflect() protoreflect.Message { - mi := &file_poker_proto_msgTypes[23] + mi := &file_poker_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1321,7 +1368,7 @@ func (x *Card) ProtoReflect() protoreflect.Message { // Deprecated: Use Card.ProtoReflect.Descriptor instead. func (*Card) Descriptor() ([]byte, []int) { - return file_poker_proto_rawDescGZIP(), []int{23} + return file_poker_proto_rawDescGZIP(), []int{24} } func (x *Card) GetDot() int32 { @@ -1338,6 +1385,218 @@ func (x *Card) GetSuit() string { return "" } +// 开始游戏 +type ReqGameStart struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ReqGameStart) Reset() { + *x = ReqGameStart{} + if protoimpl.UnsafeEnabled { + mi := &file_poker_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReqGameStart) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReqGameStart) ProtoMessage() {} + +func (x *ReqGameStart) ProtoReflect() protoreflect.Message { + mi := &file_poker_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReqGameStart.ProtoReflect.Descriptor instead. +func (*ReqGameStart) Descriptor() ([]byte, []int) { + return file_poker_proto_rawDescGZIP(), []int{25} +} + +// 扣除大盲注 +type ResBigBlindChip struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Chip int32 `protobuf:"varint,1,opt,name=chip,proto3" json:"chip,omitempty"` +} + +func (x *ResBigBlindChip) Reset() { + *x = ResBigBlindChip{} + if protoimpl.UnsafeEnabled { + mi := &file_poker_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResBigBlindChip) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResBigBlindChip) ProtoMessage() {} + +func (x *ResBigBlindChip) ProtoReflect() protoreflect.Message { + mi := &file_poker_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResBigBlindChip.ProtoReflect.Descriptor instead. +func (*ResBigBlindChip) Descriptor() ([]byte, []int) { + return file_poker_proto_rawDescGZIP(), []int{26} +} + +func (x *ResBigBlindChip) GetChip() int32 { + if x != nil { + return x.Chip + } + return 0 +} + +// 扣除小盲注消息, 然后发牌 +type ResSmallBlindChip struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Chip int32 `protobuf:"varint,1,opt,name=chip,proto3" json:"chip,omitempty"` +} + +func (x *ResSmallBlindChip) Reset() { + *x = ResSmallBlindChip{} + if protoimpl.UnsafeEnabled { + mi := &file_poker_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResSmallBlindChip) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResSmallBlindChip) ProtoMessage() {} + +func (x *ResSmallBlindChip) ProtoReflect() protoreflect.Message { + mi := &file_poker_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResSmallBlindChip.ProtoReflect.Descriptor instead. +func (*ResSmallBlindChip) Descriptor() ([]byte, []int) { + return file_poker_proto_rawDescGZIP(), []int{27} +} + +func (x *ResSmallBlindChip) GetChip() int32 { + if x != nil { + return x.Chip + } + return 0 +} + +// 解散房间 +type ReqDismissGameTable struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ReqDismissGameTable) Reset() { + *x = ReqDismissGameTable{} + if protoimpl.UnsafeEnabled { + mi := &file_poker_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReqDismissGameTable) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReqDismissGameTable) ProtoMessage() {} + +func (x *ReqDismissGameTable) ProtoReflect() protoreflect.Message { + mi := &file_poker_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReqDismissGameTable.ProtoReflect.Descriptor instead. +func (*ReqDismissGameTable) Descriptor() ([]byte, []int) { + return file_poker_proto_rawDescGZIP(), []int{28} +} + +type ResDismissGameTable struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ResDismissGameTable) Reset() { + *x = ResDismissGameTable{} + if protoimpl.UnsafeEnabled { + mi := &file_poker_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResDismissGameTable) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResDismissGameTable) ProtoMessage() {} + +func (x *ResDismissGameTable) ProtoReflect() protoreflect.Message { + mi := &file_poker_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResDismissGameTable.ProtoReflect.Descriptor instead. +func (*ResDismissGameTable) Descriptor() ([]byte, []int) { + return file_poker_proto_rawDescGZIP(), []int{29} +} + var File_poker_proto protoreflect.FileDescriptor var file_poker_proto_rawDesc = []byte{ @@ -1360,87 +1619,99 @@ var file_poker_proto_rawDesc = []byte{ 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22, 0x23, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x37, 0x0a, 0x0b, 0x52, 0x65, 0x73, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, - 0x73, 0x67, 0x22, 0x0e, 0x0a, 0x0c, 0x52, 0x65, 0x71, 0x4c, 0x6f, 0x62, 0x62, 0x79, 0x56, 0x69, - 0x65, 0x77, 0x22, 0x37, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x4c, 0x6f, 0x62, 0x62, 0x79, 0x56, 0x69, - 0x65, 0x77, 0x12, 0x27, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x6f, 0x62, 0x62, 0x79, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0x8c, 0x01, 0x0a, 0x0a, - 0x4c, 0x6f, 0x62, 0x62, 0x79, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x4e, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75, - 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, - 0x75, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x4e, 0x75, 0x6d, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x4e, 0x75, 0x6d, 0x12, 0x2a, - 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x6f, 0x62, 0x62, 0x79, 0x50, 0x6c, 0x61, 0x79, 0x65, - 0x72, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x22, 0x67, 0x0a, 0x0b, 0x4c, 0x6f, - 0x62, 0x62, 0x79, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x62, - 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, - 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, - 0x74, 0x61, 0x72, 0x22, 0x42, 0x0a, 0x0e, 0x52, 0x65, 0x71, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x12, - 0x16, 0x0a, 0x06, 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x06, 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x73, 0x22, 0x2a, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x4e, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x4e, 0x6f, 0x22, 0x28, 0x0a, 0x0c, 0x52, 0x65, 0x71, 0x4a, 0x6f, 0x69, 0x6e, 0x54, 0x61, + 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x51, 0x0a, 0x0b, 0x52, 0x65, 0x73, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x22, 0x0e, 0x0a, 0x0c, + 0x52, 0x65, 0x71, 0x4c, 0x6f, 0x62, 0x62, 0x79, 0x56, 0x69, 0x65, 0x77, 0x22, 0x37, 0x0a, 0x0c, + 0x52, 0x65, 0x73, 0x4c, 0x6f, 0x62, 0x62, 0x79, 0x56, 0x69, 0x65, 0x77, 0x12, 0x27, 0x0a, 0x06, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x4c, 0x6f, 0x62, 0x62, 0x79, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x06, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0x8c, 0x01, 0x0a, 0x0a, 0x4c, 0x6f, 0x62, 0x62, 0x79, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x12, 0x1c, + 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x12, 0x1a, 0x0a, 0x08, + 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x4e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, + 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x4e, 0x75, 0x6d, 0x12, 0x2a, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, + 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x4c, 0x6f, 0x62, 0x62, 0x79, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x07, 0x70, 0x6c, 0x61, + 0x79, 0x65, 0x72, 0x73, 0x22, 0x67, 0x0a, 0x0b, 0x4c, 0x6f, 0x62, 0x62, 0x79, 0x50, 0x6c, 0x61, + 0x79, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x05, 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x22, 0x42, 0x0a, + 0x0e, 0x52, 0x65, 0x71, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x6f, 0x62, + 0x6f, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x72, 0x6f, 0x62, 0x6f, 0x74, + 0x73, 0x22, 0x2a, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x22, 0x0f, 0x0a, - 0x0d, 0x52, 0x65, 0x71, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x0f, - 0x0a, 0x0d, 0x52, 0x65, 0x71, 0x52, 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x22, - 0x2d, 0x0a, 0x0f, 0x52, 0x65, 0x71, 0x4b, 0x69, 0x63, 0x6b, 0x4f, 0x75, 0x74, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x22, 0x11, - 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x4b, 0x69, 0x63, 0x6b, 0x4f, 0x75, 0x74, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x22, 0x3b, 0x0a, 0x0d, 0x52, 0x65, 0x71, 0x47, 0x61, 0x6d, 0x65, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x68, - 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x68, 0x69, 0x70, 0x22, 0x0f, - 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x47, 0x61, 0x6d, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0x13, 0x0a, 0x11, 0x52, 0x65, 0x71, 0x47, 0x61, 0x6d, 0x65, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x22, 0x8a, 0x02, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x47, 0x61, 0x6d, 0x65, - 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e, - 0x47, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x6e, 0x47, 0x61, - 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x12, 0x1c, 0x0a, 0x09, - 0x67, 0x61, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x09, 0x67, 0x61, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x68, - 0x69, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x68, 0x69, 0x70, 0x12, 0x1e, - 0x0a, 0x0a, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x12, 0x1a, - 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x0a, 0x70, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x43, 0x61, 0x72, 0x64, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x61, 0x72, 0x64, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x43, 0x61, 0x72, 0x64, 0x12, 0x2a, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, - 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, - 0x73, 0x22, 0xd2, 0x01, 0x0a, 0x0b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x6c, 0x61, 0x79, 0x65, - 0x72, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x05, 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x63, - 0x68, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x68, 0x69, 0x70, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x61, 0x73, 0x74, 0x65, - 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x12, - 0x25, 0x0a, 0x08, 0x68, 0x61, 0x6e, 0x64, 0x43, 0x61, 0x72, 0x64, 0x18, 0x08, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x61, 0x72, 0x64, 0x52, 0x08, 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, 0x6f, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x73, 0x75, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x73, 0x75, 0x69, 0x74, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x61, 0x70, 0x69, 0x3b, 0x61, 0x70, - 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x22, 0x28, 0x0a, + 0x0c, 0x52, 0x65, 0x71, 0x4a, 0x6f, 0x69, 0x6e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x22, 0x0f, 0x0a, 0x0d, 0x52, 0x65, 0x71, 0x4c, 0x65, + 0x61, 0x76, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x52, 0x65, 0x71, 0x52, + 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x22, 0x10, 0x0a, 0x0e, 0x52, 0x65, 0x71, + 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x79, 0x22, 0x2d, 0x0a, 0x0f, 0x52, + 0x65, 0x71, 0x4b, 0x69, 0x63, 0x6b, 0x4f, 0x75, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x22, 0x11, 0x0a, 0x0f, 0x52, 0x65, + 0x73, 0x4b, 0x69, 0x63, 0x6b, 0x4f, 0x75, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x3b, 0x0a, + 0x0d, 0x52, 0x65, 0x71, 0x47, 0x61, 0x6d, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, + 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x68, 0x69, 0x70, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x68, 0x69, 0x70, 0x22, 0x0f, 0x0a, 0x0d, 0x52, 0x65, + 0x73, 0x47, 0x61, 0x6d, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x13, 0x0a, 0x11, 0x52, + 0x65, 0x71, 0x47, 0x61, 0x6d, 0x65, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x22, 0x8a, 0x02, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x47, 0x61, 0x6d, 0x65, 0x46, 0x75, 0x6c, 0x6c, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e, 0x47, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x6e, 0x47, 0x61, 0x6d, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x67, 0x61, 0x6d, 0x65, + 0x53, 0x74, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x67, 0x61, 0x6d, + 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x68, 0x69, 0x70, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x68, 0x69, 0x70, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x70, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x43, 0x61, 0x72, 0x64, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x43, 0x61, 0x72, 0x64, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x43, 0x61, 0x72, + 0x64, 0x12, 0x2a, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x0a, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x22, 0xd2, 0x01, + 0x0a, 0x0b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x14, 0x0a, + 0x05, 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x72, 0x6f, + 0x62, 0x6f, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x68, 0x69, 0x70, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x68, 0x69, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x06, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x12, 0x25, 0x0a, 0x08, 0x68, + 0x61, 0x6e, 0x64, 0x43, 0x61, 0x72, 0x64, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x43, 0x61, 0x72, 0x64, 0x52, 0x08, 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, 0x6f, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x73, 0x75, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x75, 0x69, 0x74, + 0x22, 0x0e, 0x0a, 0x0c, 0x52, 0x65, 0x71, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x22, 0x25, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x42, 0x69, 0x67, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x43, + 0x68, 0x69, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x68, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x04, 0x63, 0x68, 0x69, 0x70, 0x22, 0x27, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x53, 0x6d, + 0x61, 0x6c, 0x6c, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x70, 0x12, 0x12, 0x0a, 0x04, + 0x63, 0x68, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x68, 0x69, 0x70, + 0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, 0x71, 0x44, 0x69, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x47, 0x61, + 0x6d, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x44, 0x69, + 0x73, 0x6d, 0x69, 0x73, 0x73, 0x47, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x0b, + 0x5a, 0x09, 0x2e, 0x2f, 0x61, 0x70, 0x69, 0x3b, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -1455,39 +1726,45 @@ func file_poker_proto_rawDescGZIP() []byte { return file_poker_proto_rawDescData } -var file_poker_proto_msgTypes = make([]protoimpl.MessageInfo, 24) +var file_poker_proto_msgTypes = make([]protoimpl.MessageInfo, 30) var file_poker_proto_goTypes = []interface{}{ - (*ProtoWrap)(nil), // 0: api.ProtoWrap - (*Ping)(nil), // 1: api.Ping - (*Pong)(nil), // 2: api.Pong - (*ResSuccess)(nil), // 3: api.ResSuccess - (*ResFail)(nil), // 4: api.ResFail - (*ReqIdentity)(nil), // 5: api.ReqIdentity - (*ResIdentity)(nil), // 6: api.ResIdentity - (*ReqLobbyView)(nil), // 7: api.ReqLobbyView - (*ResLobbyView)(nil), // 8: api.ResLobbyView - (*LobbyTable)(nil), // 9: api.LobbyTable - (*LobbyPlayer)(nil), // 10: api.LobbyPlayer - (*ReqCreateTable)(nil), // 11: api.ReqCreateTable - (*ResCreateTable)(nil), // 12: api.ResCreateTable - (*ReqJoinTable)(nil), // 13: api.ReqJoinTable - (*ReqLeaveTable)(nil), // 14: api.ReqLeaveTable - (*ReqReadyStart)(nil), // 15: api.ReqReadyStart - (*ReqKickOutTable)(nil), // 16: api.ReqKickOutTable - (*ResKickOutTable)(nil), // 17: api.ResKickOutTable - (*ReqGameAction)(nil), // 18: api.ReqGameAction - (*ResGameAction)(nil), // 19: api.ResGameAction - (*ReqGameFullStatus)(nil), // 20: api.ReqGameFullStatus - (*ResGameFullStatus)(nil), // 21: api.ResGameFullStatus - (*TablePlayer)(nil), // 22: api.TablePlayer - (*Card)(nil), // 23: api.Card + (*ProtoWrap)(nil), // 0: api.ProtoWrap + (*Ping)(nil), // 1: api.Ping + (*Pong)(nil), // 2: api.Pong + (*ResSuccess)(nil), // 3: api.ResSuccess + (*ResFail)(nil), // 4: api.ResFail + (*ReqIdentity)(nil), // 5: api.ReqIdentity + (*ResIdentity)(nil), // 6: api.ResIdentity + (*ReqLobbyView)(nil), // 7: api.ReqLobbyView + (*ResLobbyView)(nil), // 8: api.ResLobbyView + (*LobbyTable)(nil), // 9: api.LobbyTable + (*LobbyPlayer)(nil), // 10: api.LobbyPlayer + (*ReqCreateTable)(nil), // 11: api.ReqCreateTable + (*ResCreateTable)(nil), // 12: api.ResCreateTable + (*ReqJoinTable)(nil), // 13: api.ReqJoinTable + (*ReqLeaveTable)(nil), // 14: api.ReqLeaveTable + (*ReqReadyStart)(nil), // 15: api.ReqReadyStart + (*ReqCancelReady)(nil), // 16: api.ReqCancelReady + (*ReqKickOutTable)(nil), // 17: api.ReqKickOutTable + (*ResKickOutTable)(nil), // 18: api.ResKickOutTable + (*ReqGameAction)(nil), // 19: api.ReqGameAction + (*ResGameAction)(nil), // 20: api.ResGameAction + (*ReqGameFullStatus)(nil), // 21: api.ReqGameFullStatus + (*ResGameFullStatus)(nil), // 22: api.ResGameFullStatus + (*TablePlayer)(nil), // 23: api.TablePlayer + (*Card)(nil), // 24: api.Card + (*ReqGameStart)(nil), // 25: api.ReqGameStart + (*ResBigBlindChip)(nil), // 26: api.ResBigBlindChip + (*ResSmallBlindChip)(nil), // 27: api.ResSmallBlindChip + (*ReqDismissGameTable)(nil), // 28: api.ReqDismissGameTable + (*ResDismissGameTable)(nil), // 29: api.ResDismissGameTable } var file_poker_proto_depIdxs = []int32{ 9, // 0: api.ResLobbyView.tables:type_name -> api.LobbyTable 10, // 1: api.LobbyTable.players:type_name -> api.LobbyPlayer - 23, // 2: api.ResGameFullStatus.publicCard:type_name -> api.Card - 22, // 3: api.ResGameFullStatus.players:type_name -> api.TablePlayer - 23, // 4: api.TablePlayer.handCard:type_name -> api.Card + 24, // 2: api.ResGameFullStatus.publicCard:type_name -> api.Card + 23, // 3: api.ResGameFullStatus.players:type_name -> api.TablePlayer + 24, // 4: api.TablePlayer.handCard:type_name -> api.Card 5, // [5:5] is the sub-list for method output_type 5, // [5:5] is the sub-list for method input_type 5, // [5:5] is the sub-list for extension type_name @@ -1694,7 +1971,7 @@ func file_poker_proto_init() { } } file_poker_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReqKickOutTable); i { + switch v := v.(*ReqCancelReady); i { case 0: return &v.state case 1: @@ -1706,7 +1983,7 @@ func file_poker_proto_init() { } } file_poker_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResKickOutTable); i { + switch v := v.(*ReqKickOutTable); i { case 0: return &v.state case 1: @@ -1718,7 +1995,7 @@ func file_poker_proto_init() { } } file_poker_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReqGameAction); i { + switch v := v.(*ResKickOutTable); i { case 0: return &v.state case 1: @@ -1730,7 +2007,7 @@ func file_poker_proto_init() { } } file_poker_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResGameAction); i { + switch v := v.(*ReqGameAction); i { case 0: return &v.state case 1: @@ -1742,7 +2019,7 @@ func file_poker_proto_init() { } } file_poker_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReqGameFullStatus); i { + switch v := v.(*ResGameAction); i { case 0: return &v.state case 1: @@ -1754,7 +2031,7 @@ func file_poker_proto_init() { } } file_poker_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResGameFullStatus); i { + switch v := v.(*ReqGameFullStatus); i { case 0: return &v.state case 1: @@ -1766,7 +2043,7 @@ func file_poker_proto_init() { } } file_poker_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TablePlayer); i { + switch v := v.(*ResGameFullStatus); i { case 0: return &v.state case 1: @@ -1778,6 +2055,18 @@ func file_poker_proto_init() { } } file_poker_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TablePlayer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_poker_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Card); i { case 0: return &v.state @@ -1789,6 +2078,66 @@ func file_poker_proto_init() { return nil } } + file_poker_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReqGameStart); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_poker_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResBigBlindChip); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_poker_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResSmallBlindChip); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_poker_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReqDismissGameTable); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_poker_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResDismissGameTable); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -1796,7 +2145,7 @@ func file_poker_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_poker_proto_rawDesc, NumEnums: 0, - NumMessages: 24, + NumMessages: 30, NumExtensions: 0, NumServices: 0, }, diff --git a/api/poker.proto b/api/poker.proto index a06f4c9..13d6a6b 100644 --- a/api/poker.proto +++ b/api/poker.proto @@ -40,8 +40,9 @@ message ReqIdentity { } message ResIdentity { - int32 status = 1; - string msg = 2; + int64 id = 3; + string username = 4; + string avatar = 5; } // 大厅消息 ============= begin @@ -88,11 +89,14 @@ message ReqJoinTable { // 离开房间 message ReqLeaveTable { - } // 玩家准备开始 message ReqReadyStart { +} +// 取消准备 +message ReqCancelReady { + } // 房主踢人 @@ -148,3 +152,24 @@ message Card { } // 加入游戏 ============= end + +// 开始游戏 +message ReqGameStart { + +} + +// 扣除大盲注 +message ResBigBlindChip { + int32 chip = 1; +} + +// 扣除小盲注消息, 然后发牌 +message ResSmallBlindChip { + int32 chip = 1; +} + +// 解散房间 +message ReqDismissGameTable { +} +message ResDismissGameTable { +} \ No newline at end of file diff --git a/api/proto.js b/api/proto.js index 7ff0152..36731a7 100644 --- a/api/proto.js +++ b/api/proto.js @@ -1394,8 +1394,9 @@ export const api = $root.api = (() => { * Properties of a ResIdentity. * @memberof api * @interface IResIdentity - * @property {number|null} [status] ResIdentity status - * @property {string|null} [msg] ResIdentity msg + * @property {number|Long|null} [id] ResIdentity id + * @property {string|null} [username] ResIdentity username + * @property {string|null} [avatar] ResIdentity avatar */ /** @@ -1414,20 +1415,28 @@ export const api = $root.api = (() => { } /** - * ResIdentity status. - * @member {number} status + * ResIdentity id. + * @member {number|Long} id * @memberof api.ResIdentity * @instance */ - ResIdentity.prototype.status = 0; + ResIdentity.prototype.id = $util.Long ? $util.Long.fromBits(0,0,false) : 0; /** - * ResIdentity msg. - * @member {string} msg + * ResIdentity username. + * @member {string} username + * @memberof api.ResIdentity + * @instance + */ + ResIdentity.prototype.username = ""; + + /** + * ResIdentity avatar. + * @member {string} avatar * @memberof api.ResIdentity * @instance */ - ResIdentity.prototype.msg = ""; + ResIdentity.prototype.avatar = ""; /** * Creates a new ResIdentity instance using the specified properties. @@ -1453,10 +1462,12 @@ export const api = $root.api = (() => { ResIdentity.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); - if (message.status != null && Object.hasOwnProperty.call(message, "status")) - writer.uint32(/* id 1, wireType 0 =*/8).int32(message.status); - if (message.msg != null && Object.hasOwnProperty.call(message, "msg")) - writer.uint32(/* id 2, wireType 2 =*/18).string(message.msg); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 3, wireType 0 =*/24).int64(message.id); + if (message.username != null && Object.hasOwnProperty.call(message, "username")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.username); + if (message.avatar != null && Object.hasOwnProperty.call(message, "avatar")) + writer.uint32(/* id 5, wireType 2 =*/42).string(message.avatar); return writer; }; @@ -1491,12 +1502,16 @@ export const api = $root.api = (() => { while (reader.pos < end) { let tag = reader.uint32(); switch (tag >>> 3) { - case 1: { - message.status = reader.int32(); + case 3: { + message.id = reader.int64(); break; } - case 2: { - message.msg = reader.string(); + case 4: { + message.username = reader.string(); + break; + } + case 5: { + message.avatar = reader.string(); break; } default: @@ -1534,12 +1549,15 @@ export const api = $root.api = (() => { ResIdentity.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; - if (message.status != null && message.hasOwnProperty("status")) - if (!$util.isInteger(message.status)) - return "status: integer expected"; - if (message.msg != null && message.hasOwnProperty("msg")) - if (!$util.isString(message.msg)) - return "msg: string expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isInteger(message.id) && !(message.id && $util.isInteger(message.id.low) && $util.isInteger(message.id.high))) + return "id: integer|Long expected"; + if (message.username != null && message.hasOwnProperty("username")) + if (!$util.isString(message.username)) + return "username: string expected"; + if (message.avatar != null && message.hasOwnProperty("avatar")) + if (!$util.isString(message.avatar)) + return "avatar: string expected"; return null; }; @@ -1555,10 +1573,19 @@ export const api = $root.api = (() => { if (object instanceof $root.api.ResIdentity) return object; let message = new $root.api.ResIdentity(); - if (object.status != null) - message.status = object.status | 0; - if (object.msg != null) - message.msg = String(object.msg); + if (object.id != null) + if ($util.Long) + (message.id = $util.Long.fromValue(object.id)).unsigned = false; + else if (typeof object.id === "string") + message.id = parseInt(object.id, 10); + else if (typeof object.id === "number") + message.id = object.id; + else if (typeof object.id === "object") + message.id = new $util.LongBits(object.id.low >>> 0, object.id.high >>> 0).toNumber(); + if (object.username != null) + message.username = String(object.username); + if (object.avatar != null) + message.avatar = String(object.avatar); return message; }; @@ -1576,13 +1603,23 @@ export const api = $root.api = (() => { options = {}; let object = {}; if (options.defaults) { - object.status = 0; - object.msg = ""; + if ($util.Long) { + let long = new $util.Long(0, 0, false); + object.id = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.id = options.longs === String ? "0" : 0; + object.username = ""; + object.avatar = ""; } - if (message.status != null && message.hasOwnProperty("status")) - object.status = message.status; - if (message.msg != null && message.hasOwnProperty("msg")) - object.msg = message.msg; + if (message.id != null && message.hasOwnProperty("id")) + if (typeof message.id === "number") + object.id = options.longs === String ? String(message.id) : message.id; + else + object.id = options.longs === String ? $util.Long.prototype.toString.call(message.id) : options.longs === Number ? new $util.LongBits(message.id.low >>> 0, message.id.high >>> 0).toNumber() : message.id; + if (message.username != null && message.hasOwnProperty("username")) + object.username = message.username; + if (message.avatar != null && message.hasOwnProperty("avatar")) + object.avatar = message.avatar; return object; }; @@ -3579,6 +3616,181 @@ export const api = $root.api = (() => { return ReqReadyStart; })(); + api.ReqCancelReady = (function() { + + /** + * Properties of a ReqCancelReady. + * @memberof api + * @interface IReqCancelReady + */ + + /** + * Constructs a new ReqCancelReady. + * @memberof api + * @classdesc Represents a ReqCancelReady. + * @implements IReqCancelReady + * @constructor + * @param {api.IReqCancelReady=} [properties] Properties to set + */ + function ReqCancelReady(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Creates a new ReqCancelReady instance using the specified properties. + * @function create + * @memberof api.ReqCancelReady + * @static + * @param {api.IReqCancelReady=} [properties] Properties to set + * @returns {api.ReqCancelReady} ReqCancelReady instance + */ + ReqCancelReady.create = function create(properties) { + return new ReqCancelReady(properties); + }; + + /** + * Encodes the specified ReqCancelReady message. Does not implicitly {@link api.ReqCancelReady.verify|verify} messages. + * @function encode + * @memberof api.ReqCancelReady + * @static + * @param {api.IReqCancelReady} message ReqCancelReady message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ReqCancelReady.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + return writer; + }; + + /** + * Encodes the specified ReqCancelReady message, length delimited. Does not implicitly {@link api.ReqCancelReady.verify|verify} messages. + * @function encodeDelimited + * @memberof api.ReqCancelReady + * @static + * @param {api.IReqCancelReady} message ReqCancelReady message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ReqCancelReady.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ReqCancelReady message from the specified reader or buffer. + * @function decode + * @memberof api.ReqCancelReady + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {api.ReqCancelReady} ReqCancelReady + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ReqCancelReady.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.api.ReqCancelReady(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ReqCancelReady message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof api.ReqCancelReady + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {api.ReqCancelReady} ReqCancelReady + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ReqCancelReady.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ReqCancelReady message. + * @function verify + * @memberof api.ReqCancelReady + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ReqCancelReady.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + return null; + }; + + /** + * Creates a ReqCancelReady message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof api.ReqCancelReady + * @static + * @param {Object.} object Plain object + * @returns {api.ReqCancelReady} ReqCancelReady + */ + ReqCancelReady.fromObject = function fromObject(object) { + if (object instanceof $root.api.ReqCancelReady) + return object; + return new $root.api.ReqCancelReady(); + }; + + /** + * Creates a plain object from a ReqCancelReady message. Also converts values to other types if specified. + * @function toObject + * @memberof api.ReqCancelReady + * @static + * @param {api.ReqCancelReady} message ReqCancelReady + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ReqCancelReady.toObject = function toObject() { + return {}; + }; + + /** + * Converts this ReqCancelReady to JSON. + * @function toJSON + * @memberof api.ReqCancelReady + * @instance + * @returns {Object.} JSON object + */ + ReqCancelReady.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for ReqCancelReady + * @function getTypeUrl + * @memberof api.ReqCancelReady + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + ReqCancelReady.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/api.ReqCancelReady"; + }; + + return ReqCancelReady; + })(); + api.ReqKickOutTable = (function() { /** @@ -5599,6 +5811,937 @@ export const api = $root.api = (() => { return Card; })(); + api.ReqGameStart = (function() { + + /** + * Properties of a ReqGameStart. + * @memberof api + * @interface IReqGameStart + */ + + /** + * Constructs a new ReqGameStart. + * @memberof api + * @classdesc Represents a ReqGameStart. + * @implements IReqGameStart + * @constructor + * @param {api.IReqGameStart=} [properties] Properties to set + */ + function ReqGameStart(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Creates a new ReqGameStart instance using the specified properties. + * @function create + * @memberof api.ReqGameStart + * @static + * @param {api.IReqGameStart=} [properties] Properties to set + * @returns {api.ReqGameStart} ReqGameStart instance + */ + ReqGameStart.create = function create(properties) { + return new ReqGameStart(properties); + }; + + /** + * Encodes the specified ReqGameStart message. Does not implicitly {@link api.ReqGameStart.verify|verify} messages. + * @function encode + * @memberof api.ReqGameStart + * @static + * @param {api.IReqGameStart} message ReqGameStart message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ReqGameStart.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + return writer; + }; + + /** + * Encodes the specified ReqGameStart message, length delimited. Does not implicitly {@link api.ReqGameStart.verify|verify} messages. + * @function encodeDelimited + * @memberof api.ReqGameStart + * @static + * @param {api.IReqGameStart} message ReqGameStart message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ReqGameStart.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ReqGameStart message from the specified reader or buffer. + * @function decode + * @memberof api.ReqGameStart + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {api.ReqGameStart} ReqGameStart + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ReqGameStart.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.api.ReqGameStart(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ReqGameStart message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof api.ReqGameStart + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {api.ReqGameStart} ReqGameStart + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ReqGameStart.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ReqGameStart message. + * @function verify + * @memberof api.ReqGameStart + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ReqGameStart.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + return null; + }; + + /** + * Creates a ReqGameStart message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof api.ReqGameStart + * @static + * @param {Object.} object Plain object + * @returns {api.ReqGameStart} ReqGameStart + */ + ReqGameStart.fromObject = function fromObject(object) { + if (object instanceof $root.api.ReqGameStart) + return object; + return new $root.api.ReqGameStart(); + }; + + /** + * Creates a plain object from a ReqGameStart message. Also converts values to other types if specified. + * @function toObject + * @memberof api.ReqGameStart + * @static + * @param {api.ReqGameStart} message ReqGameStart + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ReqGameStart.toObject = function toObject() { + return {}; + }; + + /** + * Converts this ReqGameStart to JSON. + * @function toJSON + * @memberof api.ReqGameStart + * @instance + * @returns {Object.} JSON object + */ + ReqGameStart.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for ReqGameStart + * @function getTypeUrl + * @memberof api.ReqGameStart + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + ReqGameStart.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/api.ReqGameStart"; + }; + + return ReqGameStart; + })(); + + api.ResBigBlindChip = (function() { + + /** + * Properties of a ResBigBlindChip. + * @memberof api + * @interface IResBigBlindChip + * @property {number|null} [chip] ResBigBlindChip chip + */ + + /** + * Constructs a new ResBigBlindChip. + * @memberof api + * @classdesc Represents a ResBigBlindChip. + * @implements IResBigBlindChip + * @constructor + * @param {api.IResBigBlindChip=} [properties] Properties to set + */ + function ResBigBlindChip(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ResBigBlindChip chip. + * @member {number} chip + * @memberof api.ResBigBlindChip + * @instance + */ + ResBigBlindChip.prototype.chip = 0; + + /** + * Creates a new ResBigBlindChip instance using the specified properties. + * @function create + * @memberof api.ResBigBlindChip + * @static + * @param {api.IResBigBlindChip=} [properties] Properties to set + * @returns {api.ResBigBlindChip} ResBigBlindChip instance + */ + ResBigBlindChip.create = function create(properties) { + return new ResBigBlindChip(properties); + }; + + /** + * Encodes the specified ResBigBlindChip message. Does not implicitly {@link api.ResBigBlindChip.verify|verify} messages. + * @function encode + * @memberof api.ResBigBlindChip + * @static + * @param {api.IResBigBlindChip} message ResBigBlindChip message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ResBigBlindChip.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.chip != null && Object.hasOwnProperty.call(message, "chip")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.chip); + return writer; + }; + + /** + * Encodes the specified ResBigBlindChip message, length delimited. Does not implicitly {@link api.ResBigBlindChip.verify|verify} messages. + * @function encodeDelimited + * @memberof api.ResBigBlindChip + * @static + * @param {api.IResBigBlindChip} message ResBigBlindChip message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ResBigBlindChip.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ResBigBlindChip message from the specified reader or buffer. + * @function decode + * @memberof api.ResBigBlindChip + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {api.ResBigBlindChip} ResBigBlindChip + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ResBigBlindChip.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.api.ResBigBlindChip(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.chip = reader.int32(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ResBigBlindChip message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof api.ResBigBlindChip + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {api.ResBigBlindChip} ResBigBlindChip + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ResBigBlindChip.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ResBigBlindChip message. + * @function verify + * @memberof api.ResBigBlindChip + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ResBigBlindChip.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.chip != null && message.hasOwnProperty("chip")) + if (!$util.isInteger(message.chip)) + return "chip: integer expected"; + return null; + }; + + /** + * Creates a ResBigBlindChip message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof api.ResBigBlindChip + * @static + * @param {Object.} object Plain object + * @returns {api.ResBigBlindChip} ResBigBlindChip + */ + ResBigBlindChip.fromObject = function fromObject(object) { + if (object instanceof $root.api.ResBigBlindChip) + return object; + let message = new $root.api.ResBigBlindChip(); + if (object.chip != null) + message.chip = object.chip | 0; + return message; + }; + + /** + * Creates a plain object from a ResBigBlindChip message. Also converts values to other types if specified. + * @function toObject + * @memberof api.ResBigBlindChip + * @static + * @param {api.ResBigBlindChip} message ResBigBlindChip + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ResBigBlindChip.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.defaults) + object.chip = 0; + if (message.chip != null && message.hasOwnProperty("chip")) + object.chip = message.chip; + return object; + }; + + /** + * Converts this ResBigBlindChip to JSON. + * @function toJSON + * @memberof api.ResBigBlindChip + * @instance + * @returns {Object.} JSON object + */ + ResBigBlindChip.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for ResBigBlindChip + * @function getTypeUrl + * @memberof api.ResBigBlindChip + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + ResBigBlindChip.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/api.ResBigBlindChip"; + }; + + return ResBigBlindChip; + })(); + + api.ResSmallBlindChip = (function() { + + /** + * Properties of a ResSmallBlindChip. + * @memberof api + * @interface IResSmallBlindChip + * @property {number|null} [chip] ResSmallBlindChip chip + */ + + /** + * Constructs a new ResSmallBlindChip. + * @memberof api + * @classdesc Represents a ResSmallBlindChip. + * @implements IResSmallBlindChip + * @constructor + * @param {api.IResSmallBlindChip=} [properties] Properties to set + */ + function ResSmallBlindChip(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ResSmallBlindChip chip. + * @member {number} chip + * @memberof api.ResSmallBlindChip + * @instance + */ + ResSmallBlindChip.prototype.chip = 0; + + /** + * Creates a new ResSmallBlindChip instance using the specified properties. + * @function create + * @memberof api.ResSmallBlindChip + * @static + * @param {api.IResSmallBlindChip=} [properties] Properties to set + * @returns {api.ResSmallBlindChip} ResSmallBlindChip instance + */ + ResSmallBlindChip.create = function create(properties) { + return new ResSmallBlindChip(properties); + }; + + /** + * Encodes the specified ResSmallBlindChip message. Does not implicitly {@link api.ResSmallBlindChip.verify|verify} messages. + * @function encode + * @memberof api.ResSmallBlindChip + * @static + * @param {api.IResSmallBlindChip} message ResSmallBlindChip message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ResSmallBlindChip.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.chip != null && Object.hasOwnProperty.call(message, "chip")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.chip); + return writer; + }; + + /** + * Encodes the specified ResSmallBlindChip message, length delimited. Does not implicitly {@link api.ResSmallBlindChip.verify|verify} messages. + * @function encodeDelimited + * @memberof api.ResSmallBlindChip + * @static + * @param {api.IResSmallBlindChip} message ResSmallBlindChip message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ResSmallBlindChip.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ResSmallBlindChip message from the specified reader or buffer. + * @function decode + * @memberof api.ResSmallBlindChip + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {api.ResSmallBlindChip} ResSmallBlindChip + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ResSmallBlindChip.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.api.ResSmallBlindChip(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.chip = reader.int32(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ResSmallBlindChip message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof api.ResSmallBlindChip + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {api.ResSmallBlindChip} ResSmallBlindChip + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ResSmallBlindChip.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ResSmallBlindChip message. + * @function verify + * @memberof api.ResSmallBlindChip + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ResSmallBlindChip.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.chip != null && message.hasOwnProperty("chip")) + if (!$util.isInteger(message.chip)) + return "chip: integer expected"; + return null; + }; + + /** + * Creates a ResSmallBlindChip message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof api.ResSmallBlindChip + * @static + * @param {Object.} object Plain object + * @returns {api.ResSmallBlindChip} ResSmallBlindChip + */ + ResSmallBlindChip.fromObject = function fromObject(object) { + if (object instanceof $root.api.ResSmallBlindChip) + return object; + let message = new $root.api.ResSmallBlindChip(); + if (object.chip != null) + message.chip = object.chip | 0; + return message; + }; + + /** + * Creates a plain object from a ResSmallBlindChip message. Also converts values to other types if specified. + * @function toObject + * @memberof api.ResSmallBlindChip + * @static + * @param {api.ResSmallBlindChip} message ResSmallBlindChip + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ResSmallBlindChip.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.defaults) + object.chip = 0; + if (message.chip != null && message.hasOwnProperty("chip")) + object.chip = message.chip; + return object; + }; + + /** + * Converts this ResSmallBlindChip to JSON. + * @function toJSON + * @memberof api.ResSmallBlindChip + * @instance + * @returns {Object.} JSON object + */ + ResSmallBlindChip.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for ResSmallBlindChip + * @function getTypeUrl + * @memberof api.ResSmallBlindChip + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + ResSmallBlindChip.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/api.ResSmallBlindChip"; + }; + + return ResSmallBlindChip; + })(); + + api.ReqDismissGameTable = (function() { + + /** + * Properties of a ReqDismissGameTable. + * @memberof api + * @interface IReqDismissGameTable + */ + + /** + * Constructs a new ReqDismissGameTable. + * @memberof api + * @classdesc Represents a ReqDismissGameTable. + * @implements IReqDismissGameTable + * @constructor + * @param {api.IReqDismissGameTable=} [properties] Properties to set + */ + function ReqDismissGameTable(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Creates a new ReqDismissGameTable instance using the specified properties. + * @function create + * @memberof api.ReqDismissGameTable + * @static + * @param {api.IReqDismissGameTable=} [properties] Properties to set + * @returns {api.ReqDismissGameTable} ReqDismissGameTable instance + */ + ReqDismissGameTable.create = function create(properties) { + return new ReqDismissGameTable(properties); + }; + + /** + * Encodes the specified ReqDismissGameTable message. Does not implicitly {@link api.ReqDismissGameTable.verify|verify} messages. + * @function encode + * @memberof api.ReqDismissGameTable + * @static + * @param {api.IReqDismissGameTable} message ReqDismissGameTable message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ReqDismissGameTable.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + return writer; + }; + + /** + * Encodes the specified ReqDismissGameTable message, length delimited. Does not implicitly {@link api.ReqDismissGameTable.verify|verify} messages. + * @function encodeDelimited + * @memberof api.ReqDismissGameTable + * @static + * @param {api.IReqDismissGameTable} message ReqDismissGameTable message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ReqDismissGameTable.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ReqDismissGameTable message from the specified reader or buffer. + * @function decode + * @memberof api.ReqDismissGameTable + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {api.ReqDismissGameTable} ReqDismissGameTable + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ReqDismissGameTable.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.api.ReqDismissGameTable(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ReqDismissGameTable message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof api.ReqDismissGameTable + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {api.ReqDismissGameTable} ReqDismissGameTable + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ReqDismissGameTable.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ReqDismissGameTable message. + * @function verify + * @memberof api.ReqDismissGameTable + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ReqDismissGameTable.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + return null; + }; + + /** + * Creates a ReqDismissGameTable message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof api.ReqDismissGameTable + * @static + * @param {Object.} object Plain object + * @returns {api.ReqDismissGameTable} ReqDismissGameTable + */ + ReqDismissGameTable.fromObject = function fromObject(object) { + if (object instanceof $root.api.ReqDismissGameTable) + return object; + return new $root.api.ReqDismissGameTable(); + }; + + /** + * Creates a plain object from a ReqDismissGameTable message. Also converts values to other types if specified. + * @function toObject + * @memberof api.ReqDismissGameTable + * @static + * @param {api.ReqDismissGameTable} message ReqDismissGameTable + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ReqDismissGameTable.toObject = function toObject() { + return {}; + }; + + /** + * Converts this ReqDismissGameTable to JSON. + * @function toJSON + * @memberof api.ReqDismissGameTable + * @instance + * @returns {Object.} JSON object + */ + ReqDismissGameTable.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for ReqDismissGameTable + * @function getTypeUrl + * @memberof api.ReqDismissGameTable + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + ReqDismissGameTable.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/api.ReqDismissGameTable"; + }; + + return ReqDismissGameTable; + })(); + + api.ResDismissGameTable = (function() { + + /** + * Properties of a ResDismissGameTable. + * @memberof api + * @interface IResDismissGameTable + */ + + /** + * Constructs a new ResDismissGameTable. + * @memberof api + * @classdesc Represents a ResDismissGameTable. + * @implements IResDismissGameTable + * @constructor + * @param {api.IResDismissGameTable=} [properties] Properties to set + */ + function ResDismissGameTable(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Creates a new ResDismissGameTable instance using the specified properties. + * @function create + * @memberof api.ResDismissGameTable + * @static + * @param {api.IResDismissGameTable=} [properties] Properties to set + * @returns {api.ResDismissGameTable} ResDismissGameTable instance + */ + ResDismissGameTable.create = function create(properties) { + return new ResDismissGameTable(properties); + }; + + /** + * Encodes the specified ResDismissGameTable message. Does not implicitly {@link api.ResDismissGameTable.verify|verify} messages. + * @function encode + * @memberof api.ResDismissGameTable + * @static + * @param {api.IResDismissGameTable} message ResDismissGameTable message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ResDismissGameTable.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + return writer; + }; + + /** + * Encodes the specified ResDismissGameTable message, length delimited. Does not implicitly {@link api.ResDismissGameTable.verify|verify} messages. + * @function encodeDelimited + * @memberof api.ResDismissGameTable + * @static + * @param {api.IResDismissGameTable} message ResDismissGameTable message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ResDismissGameTable.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ResDismissGameTable message from the specified reader or buffer. + * @function decode + * @memberof api.ResDismissGameTable + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {api.ResDismissGameTable} ResDismissGameTable + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ResDismissGameTable.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.api.ResDismissGameTable(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ResDismissGameTable message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof api.ResDismissGameTable + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {api.ResDismissGameTable} ResDismissGameTable + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ResDismissGameTable.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ResDismissGameTable message. + * @function verify + * @memberof api.ResDismissGameTable + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ResDismissGameTable.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + return null; + }; + + /** + * Creates a ResDismissGameTable message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof api.ResDismissGameTable + * @static + * @param {Object.} object Plain object + * @returns {api.ResDismissGameTable} ResDismissGameTable + */ + ResDismissGameTable.fromObject = function fromObject(object) { + if (object instanceof $root.api.ResDismissGameTable) + return object; + return new $root.api.ResDismissGameTable(); + }; + + /** + * Creates a plain object from a ResDismissGameTable message. Also converts values to other types if specified. + * @function toObject + * @memberof api.ResDismissGameTable + * @static + * @param {api.ResDismissGameTable} message ResDismissGameTable + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ResDismissGameTable.toObject = function toObject() { + return {}; + }; + + /** + * Converts this ResDismissGameTable to JSON. + * @function toJSON + * @memberof api.ResDismissGameTable + * @instance + * @returns {Object.} JSON object + */ + ResDismissGameTable.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for ResDismissGameTable + * @function getTypeUrl + * @memberof api.ResDismissGameTable + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + ResDismissGameTable.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/api.ResDismissGameTable"; + }; + + return ResDismissGameTable; + })(); + return api; })(); diff --git a/internal/game/game.go b/internal/game/game.go index 7663027..2aab40f 100644 --- a/internal/game/game.go +++ b/internal/game/game.go @@ -2,6 +2,12 @@ package game import ( "math/rand" + "sync" +) + +const ( + BigBlindChip int32 = 2 // 大盲注金额 + SmallBlinds int32 = BigBlindChip / 2 // 小盲注金额 ) // Dealer 发牌员, 有打乱的一副牌 @@ -10,11 +16,22 @@ type Dealer struct { // cardList *collect.LinkedList[Card] cards []*Card index int + lock *sync.Mutex +} + +func NewDealer() *Dealer { + return &Dealer{ + cards: make([]*Card, 52), + index: 0, + lock: new(sync.Mutex), + } } func (d *Dealer) Init() *Dealer { + d.lock.Lock() + defer d.lock.Unlock() + d.index = 0 - d.cards = make([]*Card, 52) // 初始化一副牌,13张牌 for i := 0; i < 13; i++ { // 4 种花色 @@ -29,23 +46,22 @@ func (d *Dealer) Init() *Dealer { // Deal 发牌堆第一张牌 func (d *Dealer) Deal() *Card { + d.lock.Lock() + defer d.lock.Unlock() + card := d.cards[d.index] d.index++ return card } -// disorder 洗牌 +// disorder 乱序洗牌 func disorder(cards []*Card) { length := len(cards) - // 洗13次 - for i := 0; i < 13; i++ { + // 洗52次 + for i := 0; i < length; i++ { for j := 0; j < length; j++ { - repIdx := rand.Intn(length) - cards[i], cards[repIdx] = cards[repIdx], cards[i] + repIdx := (rand.Intn(length) + rand.Intn(length)) / 2 + cards[j], cards[repIdx] = cards[repIdx], cards[j] } } } - -func NewDealer() *Dealer { - return new(Dealer).Init() -} diff --git a/internal/game/player.go b/internal/game/player.go index 0770b77..bb06a04 100644 --- a/internal/game/player.go +++ b/internal/game/player.go @@ -1,6 +1,7 @@ package game import ( + "sync" "texas-poker-bk/internal/letter" ) @@ -11,12 +12,13 @@ type Player struct { Avatar string Cards [2]*Card // 手牌 Chip int32 // 玩家筹码 - Status int32 // 状态: 1待准备开始,2已准备开始,3等待其他玩家动作,4待大盲注,5待小盲注,6待跟注,7已弃 + Status int32 // 状态: 1待准备开始,2已准备开始,3等待其他玩家动作,4小盲注跟注, [5待大盲注,5待小盲注,] 6待跟注,7已弃牌 GameTable *Table // 当前牌桌 ProtoWriter letter.ProtoWriter + Lock *sync.Mutex } -func NewPlayer() *Player { - return &Player{} +func (p *Player) Init() { + p.Lock = new(sync.Mutex) } diff --git a/internal/game/table.go b/internal/game/table.go index afe5dc3..a90e114 100644 --- a/internal/game/table.go +++ b/internal/game/table.go @@ -11,24 +11,59 @@ type Table struct { TableNo int32 // 牌桌编号 MasterId int64 // 房主Id RoundTimes int32 // 回合次数 - Stage int32 // 游戏阶段: 1等待玩家准备;2下大盲注;3下小盲注;4发公共牌;5发第四张公共牌,轮流下注;6发第五张公共牌,轮流下注,7比牌结算 + Stage int32 // 游戏阶段: 1等待玩家准备;2游戏开始(自动扣大小盲注,发牌,轮流下注) [2(开始发牌)下大盲注;3下小盲注;4发公共牌;] 5发第四张公共牌,轮流下注;6发第五张公共牌,轮流下注,7比牌结算,9已解散 - chip int32 // 牌桌当前筹码 + Chip int32 // 牌桌当前筹码 robotChip int32 // 牌桌当前机器人下注筹码 Dealer *Dealer // 发牌员 PublicCards [5]*Card // 公共牌 - PlayerNum int32 // 玩家数 - RobotNum int32 // 机器人数 - Players []*Player // 玩家 - Robots []*Robot - BigBlindsPos int32 // 大盲注位 + PlayerNum int32 // 玩家数 + RobotNum int32 // 机器人数 + Players []*Player // 玩家 + Robots []*Robot + BigBlindPos int // 大盲注位 + SmallBlindPos int // 小盲注位 PlayersLock *sync.Mutex ChipLock *sync.Mutex // 桌面筹码更新锁 // TODO game logs7 } +func (t *Table) PlayerCount() int32 { + var count int32 = 0 + for _, p := range t.Players { + if p != nil { + count++ + } + } + return count +} + +func (t *Table) NextPosPlayer(current int) int { + for i := current; i < len(t.Players); i++ { + if t.Players[i] == nil { + continue + } + return i + } + for i, p := range t.Players { + if p != nil { + return i + } + } + return 0 +} + +func (t *Table) FindPlayerPos(player *Player) int32 { + for i, p := range t.Players { + if p != nil && p.Id == player.Id { + return int32(i) + } + } + return -1 +} + func (t *Table) JoinPlayer(player *Player) error { t.PlayersLock.Lock() defer t.PlayersLock.Unlock() @@ -48,7 +83,7 @@ func (t *Table) BuildResGameFullStatus() *api.ResGameFullStatus { resGame.InGame = collect.In(t.Stage, 2, 3, 4, 5, 6, 7) resGame.TableNo = t.TableNo resGame.GameStage = t.Stage - resGame.Chip = t.chip + resGame.Chip = t.Chip resGame.RoundTimes = t.RoundTimes // 公共牌 @@ -93,12 +128,18 @@ func (t *Table) BuildResGameFullStatus() *api.ResGameFullStatus { } func (t *Table) NoticeGameFullStatus() { - resGame := t.BuildResGameFullStatus() - // 发送当前游戏状态消息到牌桌所有用户 for _, player := range t.Players { if player != nil && player.ProtoWriter != nil { + resGame := t.BuildResGameFullStatus() resGame.PlayerId = player.Id + // 只返回自己的手牌 TODO 结算时全部返回 + for _, p := range resGame.Players { + if p != nil && p.Id != player.Id { + p.HandCard[0] = nil + p.HandCard[1] = nil + } + } player.ProtoWriter.Write(resGame) } } diff --git a/internal/server/ws.go b/internal/server/ws.go index 1a09284..89a4972 100644 --- a/internal/server/ws.go +++ b/internal/server/ws.go @@ -47,6 +47,20 @@ func upgradeWs(resWriter http.ResponseWriter, req *http.Request) (*websocket.Con return upgrader.Upgrade(resWriter, req, nil) } +const ( + // Time allowed to write a message to the peer. + writeWait = 10 * time.Second + + // Time allowed to read the next pong message from the peer. + pongWait = 60 * time.Second + + // Send pings to peer with this period. Must be less than pongWait. + pingPeriod = (pongWait * 9) / 10 + + // Maximum message size allowed from peer. + maxMessageSize = 512 +) + // 处理新建的websocket func handleNetClient(client *session.NetClient) { //defer (func() { @@ -57,12 +71,16 @@ func handleNetClient(client *session.NetClient) { //var player *session.Player // https://github.com/gorilla/websocket/blob/a68708917c6a4f06314ab4e52493cc61359c9d42/examples/chat/conn.go#L50 - client.Conn.SetReadLimit(1024 * 1024) - //err := client.Conn.SetWriteDeadline(time.Now().Add(time.Millisecond * 50)) + client.Conn.SetReadLimit(maxMessageSize) + // TODO readDeadLine 读取超时后关闭连接 + // err := client.Conn.SetReadDeadline(time.Now().Add(pongWait)) //if err != nil { // log.Printf("set deadline error: %v", err) // return //} + client.Conn.SetPongHandler(func(string) error { + return client.Conn.SetReadDeadline(time.Now().Add(pongWait)) + }) // TODO 1分钟后过期 for { diff --git a/internal/server/wsroute.go b/internal/server/wsroute.go index 48a82d0..d631a3d 100644 --- a/internal/server/wsroute.go +++ b/internal/server/wsroute.go @@ -23,13 +23,20 @@ func init() { // 获取牌桌当前所有状态 HandleNetPlayerMsg(&api.ReqGameFullStatus{}, service.HandleReqGameFullStatus) // 加入桌面 - HandleNetAccountMsg(&api.ReqJoinTable{}, service.HandleJoinTable) + HandleNetAccountMsg(&api.ReqJoinTable{}, service.HandleReqJoinTable) // 踢人 HandleNetPlayerMsg(&api.ReqKickOutTable{}, service.HandleReqKickOutTable) // 离开房间 HandleNetPlayerMsg(&api.ReqLeaveTable{}, service.HandleReqLeaveTable) - + // 解散房间 + HandleNetPlayerMsg(&api.ReqDismissGameTable{}, service.HandleReqDismissGameTable) + // 玩家准备 + HandleNetPlayerMsg(&api.ReqReadyStart{}, service.HandleReqReadyStart) + // 玩家取消准备 + HandleNetPlayerMsg(&api.ReqCancelReady{}, service.HandleReqCancelReady) + // 开始游戏 + HandleNetPlayerMsg(&api.ReqGameStart{}, service.HandleReqGameStart) } func checkExistsTypeHandler(op int32, err error) { diff --git a/internal/service/auth.go b/internal/service/auth.go index ed564ba..14b9805 100644 --- a/internal/service/auth.go +++ b/internal/service/auth.go @@ -179,11 +179,10 @@ func HandleReqIdentity(client *session.NetClient, msg *api.ReqIdentity) (proto.M Lock: &sync.Mutex{}, } // TODO 查询 DB 账户余额 - account = store.SaveNetAccounts(account) + account = store.SaveAndTryRecoverNetAccounts(account) client.Account = account // response - res := &api.ResIdentity{Status: 200, Msg: "ok"} - // client.Write(res) + res := &api.ResIdentity{Id: subject.Id, Username: subject.Name, Avatar: subject.Avatar} return res, nil } diff --git a/internal/service/store/store.go b/internal/service/store/store.go index 1810491..e8838b5 100644 --- a/internal/service/store/store.go +++ b/internal/service/store/store.go @@ -14,7 +14,7 @@ var ( LobbyTables map[int32]*game.Table lobbyLock *sync.Mutex - // NetAccounts 存储一下在线用户 + // NetAccounts 存储一下在线用户, TODO 连接终端,未在牌局或牌局未开始中回收账号,机器人代打后回收账号 NetAccounts map[int64]*session.NetAccount accountLock *sync.Mutex ) @@ -39,8 +39,8 @@ func SaveNewTable(table *game.Table) error { return nil } -// SaveNetAccounts 保存一下在线账户映射关系 TODO 处理断线、重连问题 -func SaveNetAccounts(account *session.NetAccount) *session.NetAccount { +// SaveAndTryRecoverNetAccounts 保存一下在线账户映射关系 TODO 处理断线、重连问题 +func SaveAndTryRecoverNetAccounts(account *session.NetAccount) *session.NetAccount { accountLock.Lock() defer accountLock.Unlock() current := NetAccounts[account.Id] @@ -50,5 +50,8 @@ func SaveNetAccounts(account *session.NetAccount) *session.NetAccount { } // 掉线重连的用户, TODO 重复登录的用户 current.Client = account.Client + if current.Player != nil { + current.Player.ProtoWriter = account.Client + } return current } diff --git a/internal/service/table.go b/internal/service/table.go index 2af3e45..a5f8344 100644 --- a/internal/service/table.go +++ b/internal/service/table.go @@ -30,13 +30,14 @@ func HandleReqCreateTable(account *session.NetAccount, msg *api.ReqCreateTable) Dealer: game.NewDealer(), PublicCards: [5]*game.Card{&game.Card{Dot: 0, Suit: 3}, &game.Card{Dot: 1, Suit: 3}, nil, nil, nil}, - PlayerNum: playerNum + 1, - RobotNum: robotNum, - Players: make([]*game.Player, playerNum+1), - Robots: make([]*game.Robot, robotNum), - BigBlindsPos: 0, - PlayersLock: &sync.Mutex{}, - ChipLock: &sync.Mutex{}, + PlayerNum: playerNum + 1, + RobotNum: robotNum, + Players: make([]*game.Player, playerNum+1), + Robots: make([]*game.Robot, robotNum), + BigBlindPos: 0, + SmallBlindPos: 0, + PlayersLock: &sync.Mutex{}, + ChipLock: &sync.Mutex{}, } // 房主 [0] @@ -50,6 +51,7 @@ func HandleReqCreateTable(account *session.NetAccount, msg *api.ReqCreateTable) GameTable: table, ProtoWriter: account.Client, } + owner.Init() // 扣除DB账户余额 TODO 账户金额限制 account.DecrementBalance(500) account.Player = owner // 挂载 player 到 account 上 @@ -109,8 +111,8 @@ func HandleReqLobbyView(account *session.NetAccount, msg *api.ReqLobbyView) (pro return res, nil } -// HandleJoinTable 加入牌桌 -func HandleJoinTable(account *session.NetAccount, msg *api.ReqJoinTable) (proto.Message, error) { +// HandleReqJoinTable 加入牌桌 +func HandleReqJoinTable(account *session.NetAccount, msg *api.ReqJoinTable) (proto.Message, error) { account.Lock.Lock() defer account.Lock.Unlock() @@ -121,9 +123,14 @@ func HandleJoinTable(account *session.NetAccount, msg *api.ReqJoinTable) (proto. // TODO 账户余额限制 table := store.LobbyTables[msg.TableNo] + table.ChipLock.Lock() + defer table.ChipLock.Unlock() if table == nil { return &api.ResFail{Msg: "牌桌不存在"}, nil } + if table.Stage != 1 { + return &api.ResFail{Msg: "牌桌正在进行中"}, nil + } player := &game.Player{ Id: account.Id, Username: account.UserName, @@ -134,7 +141,7 @@ func HandleJoinTable(account *session.NetAccount, msg *api.ReqJoinTable) (proto. GameTable: table, ProtoWriter: account.Client, } - + player.Init() err := table.JoinPlayer(player) if err != nil { return nil, err @@ -149,34 +156,6 @@ func HandleJoinTable(account *session.NetAccount, msg *api.ReqJoinTable) (proto. return &api.ResSuccess{}, nil } -// HandleLeaveTable 离开牌桌 -func HandleLeaveTable(account session.NetAccount, msg *api.ReqCreateTable) (proto.Message, error) { - account.Lock.Lock() - defer account.Lock.Unlock() - // 结算, player -> nil - if account.Player == nil { - return &api.ResFail{Msg: "当前未加入牌桌"}, nil - } - // 根据玩家游戏状态判断可否退出 - switch account.Player.Status { - case 1, 2, 7: // 未在游戏中 可退出 - // 结算金额 - account.IncrementBalance(account.Player.Chip) - gameTable := account.Player.GameTable - // table player remove - for i := range gameTable.Players { - if gameTable.Players[i] == account.Player { - gameTable.Players[i] = nil - } - } - account.Player = nil - // TODO notice 牌桌其他玩家 gameTable.notice(ResGameStatus) - return &api.ResSuccess{}, nil - default: - return &api.ResFail{Msg: "游戏进行中,不能退出"}, nil - } -} - // HandleReqKickOutTable 踢人 func HandleReqKickOutTable(player *game.Player, msg *api.ReqKickOutTable) (proto.Message, error) { player.GameTable.PlayersLock.Lock() @@ -212,6 +191,7 @@ func HandleReqKickOutTable(player *game.Player, msg *api.ReqKickOutTable) (proto func HandleReqLeaveTable(player *game.Player, msg *api.ReqLeaveTable) (proto.Message, error) { player.GameTable.PlayersLock.Lock() defer player.GameTable.PlayersLock.Unlock() + if player.GameTable.Stage != 1 { return &api.ResFail{Msg: "牌局进行中不能退出"}, nil } @@ -245,12 +225,149 @@ func HandleReqGameFullStatus(player *game.Player, msg *api.ReqGameFullStatus) (p } resGame := player.GameTable.BuildResGameFullStatus() resGame.PlayerId = player.Id - // TODO 其他玩家手牌不返回,计算自己的5张推荐牌 + // 其他玩家手牌不返回,TODO 计算自己的5张推荐牌 + for _, p := range resGame.Players { + if p != nil && p.Id != player.Id { + p.HandCard[0] = nil + p.HandCard[1] = nil + } + } return resGame, nil } // HandleReqReadyStart 准备开始游戏 -func HandleReqReadyStart(player game.Player, msg *api.ReqReadyStart) (proto.Message, error) { +func HandleReqReadyStart(player *game.Player, msg *api.ReqReadyStart) (proto.Message, error) { + player.Lock.Lock() + defer player.Lock.Unlock() + if player.Id == player.GameTable.MasterId { + return &api.ResFail{Msg: "房主不用准备"}, nil + } + if player.Status != 1 { + msg := "" + switch player.Status { + case 2: + msg = "已准备" + default: + msg = fmt.Sprintf("异常状态#%d", player.Status) + } + return &api.ResFail{Msg: msg}, nil + } + + player.Status = 2 + player.GameTable.NoticeGameFullStatus() + + return &api.ResSuccess{}, nil +} + +func HandleReqCancelReady(player *game.Player, msg *api.ReqCancelReady) (proto.Message, error) { + player.Lock.Lock() + defer player.Lock.Unlock() + if player.Id == player.GameTable.MasterId { + return &api.ResFail{Msg: "房主不用准备"}, nil + } + if player.Status != 2 { + return &api.ResFail{Msg: "当前未准备"}, nil + } + player.Status = 1 + player.GameTable.NoticeGameFullStatus() + return &api.ResSuccess{}, nil +} - return nil, nil +func HandleReqDismissGameTable(player *game.Player, msg *api.ReqDismissGameTable) (proto.Message, error) { + player.GameTable.ChipLock.Lock() + defer player.GameTable.ChipLock.Unlock() + if player.GameTable.Stage != 1 { + return &api.ResFail{Msg: fmt.Sprintf("#%d,牌局进行中", player.GameTable.Stage)}, nil + } + player.GameTable.Stage = 9 + delete(store.LobbyTables, player.GameTable.TableNo) + // 通知所有玩家,解除账号绑定,结算玩家金额 + for i, p := range player.GameTable.Players { + if p == nil { + continue + } + account := store.NetAccounts[p.Id] + account.IncrementBalance(p.Chip) + account.Player = nil + player.GameTable.Players[i] = nil + if p.Id != player.Id { + p.ProtoWriter.Write(&api.ResDismissGameTable{}) + } + } + return &api.ResDismissGameTable{}, nil +} + +func HandleReqGameStart(player *game.Player, msg *api.ReqGameStart) (proto.Message, error) { + player.GameTable.ChipLock.Lock() + defer player.GameTable.ChipLock.Unlock() + // 锁定牌桌所有玩家 + for _, p := range player.GameTable.Players { + if p != nil { + p.Lock.Lock() + defer p.Lock.Unlock() + } + } + + table := player.GameTable + if player.Id != table.MasterId { + return &api.ResFail{Msg: "你不是房主"}, nil + } + if table.Stage != 1 { + return &api.ResFail{Msg: fmt.Sprintf("牌局状态有误%d", table.Stage)}, nil + } + // 检查所有玩家准备状态 + for _, p := range table.Players { + if p != nil && p.Id != table.MasterId && p.Status != 2 { + return &api.ResFail{Msg: "有玩家未准备"}, nil + } + } + + // 游戏状态开始 + table.Stage = 2 + // 大盲注位 + if table.RoundTimes == 0 { + table.BigBlindPos = 0 + } else { + table.BigBlindPos = table.NextPosPlayer(table.BigBlindPos) + } + // 小盲注位 + table.SmallBlindPos = table.NextPosPlayer(table.BigBlindPos) + // 回合数+1 + table.RoundTimes++ + + // 扣除大小盲注金额 + table.Players[table.BigBlindPos].Chip -= game.BigBlindChip + table.Players[table.SmallBlindPos].Chip -= game.SmallBlinds + table.Chip += game.BigBlindChip + game.SmallBlinds + + table.Players[table.BigBlindPos].ProtoWriter.Write(&api.ResBigBlindChip{Chip: game.BigBlindChip}) + table.Players[table.SmallBlindPos].ProtoWriter.Write(&api.ResSmallBlindChip{Chip: game.SmallBlinds}) + + // 开始发牌(手牌,公共牌) + table.Dealer.Init() // 初始化发牌员 + for _, p := range table.Players { + if p == nil { + continue + } + for i := range p.Cards { + p.Cards[i] = table.Dealer.Deal() + } + // 玩家状态置为等待 + p.Status = 3 + } + // 发3张公共牌 + for i := 0; i < 5; i++ { + if i < 3 { + table.PublicCards[i] = table.Dealer.Deal() + continue + } + // 第4,5张牌置空 + table.PublicCards[i] = nil + } + // 待小盲注位玩家下注 + table.Players[table.SmallBlindPos].Status = 4 + + // 广播牌桌状态 + table.NoticeGameFullStatus() + return &api.ResSuccess{}, nil } diff --git a/internal/session/net_client.go b/internal/session/net_client.go index 1b393ad..4837c90 100644 --- a/internal/session/net_client.go +++ b/internal/session/net_client.go @@ -5,15 +5,24 @@ import ( "github.com/golang/protobuf/proto" "github.com/gorilla/websocket" "log" + "sync" "texas-poker-bk/api" "time" ) // NetClient 长连接客户端 type NetClient struct { - Id int64 - Conn *websocket.Conn - Account *NetAccount + // Id int64 + Conn *websocket.Conn + Account *NetAccount + WriteLock *sync.Mutex +} + +func NewNetClient(conn *websocket.Conn) *NetClient { + return &NetClient{ + Conn: conn, + WriteLock: new(sync.Mutex), + } } func (c *NetClient) Close(reason string) { @@ -28,6 +37,7 @@ func (c *NetClient) Write(msg proto.Message) { } func (c *NetClient) WriteSeq(success bool, seq int32, msg proto.Message) { + // 序列化 protobuf 消息 op, err := api.GetProtoOp(msg) if err != nil { fmt.Println("write msg match op err:", err) @@ -36,8 +46,12 @@ func (c *NetClient) WriteSeq(success bool, seq int32, msg proto.Message) { bytes, err := proto.Marshal(msg) wrap := &api.ProtoWrap{Ver: 1, Op: op, Seq: seq, Success: success, Body: bytes} wrapBytes, err := proto.Marshal(wrap) + + // 向ws客户端写 + c.WriteLock.Lock() + defer c.WriteLock.Unlock() // TODO 看文档 SetWriteDeadline - err = c.Conn.SetWriteDeadline(time.Now().Add(time.Millisecond * 100)) + err = c.Conn.SetWriteDeadline(time.Now().Add(10 * time.Second)) if err != nil { fmt.Println("set dead line err:", err) return @@ -47,9 +61,3 @@ func (c *NetClient) WriteSeq(success bool, seq int32, msg proto.Message) { fmt.Println("write msg err:", err) } } - -func NewNetClient(conn *websocket.Conn) *NetClient { - return &NetClient{ - Conn: conn, - } -}