Browse Source

ws msg logic

master
tangmingyou 4 years ago
parent
commit
43235f1e84
  1. 8
      api/operation.go
  2. 207
      api/poker.pb.go
  3. 10
      api/poker.proto
  4. 482
      api/proto.js
  5. 5
      cmd/main.go
  6. 2
      internal/game/card.go
  7. 51
      internal/game/game.go
  8. 15
      internal/game/player.go
  9. 5
      internal/game/robot.go
  10. 38
      internal/game/table.go
  11. 10
      internal/model/vo/game.go
  12. 11
      internal/model/vo/lobby.go
  13. 4
      internal/server/route.go
  14. 12
      internal/server/ws.go
  15. 11
      internal/server/wsroute.go
  16. 68
      internal/service/store/store.go
  17. 93
      internal/service/table.go
  18. 1
      internal/session/net_account.go
  19. 7
      internal/session/subject.go

8
api/operation.go

@ -13,6 +13,7 @@ const OpOffset int32 = 13578
// 注册消息类型
var protoInstances = []proto.Message{
&ProtoWrap{},
&ResSuccess{},
&ResFail{},
&Ping{},
&Pong{},
@ -21,6 +22,7 @@ var protoInstances = []proto.Message{
&ReqLobbyView{},
&ResLobbyView{},
&ReqCreateTable{},
&ResCreateTable{},
&ReqJoinTable{},
&ResJoinTable{},
}
@ -72,11 +74,13 @@ func NewProtoInstance(op int32) (proto.Message, error) {
// GetOpNameMap 获取编号和消息
func GetOpNameMap() map[string]any {
failOp, _ := GetProtoOp(&ResFail{})
opSuccess, _ := GetProtoOp(&ResSuccess{})
oPFail, _ := GetProtoOp(&ResFail{})
front := make(map[string]any, 4)
front["offset"] = OpOffset
front["failOp"] = failOp
front["opSuccess"] = opSuccess
front["oPFail"] = oPFail
front["opPathMap"] = opProtoNameMap
front["nameOpMap"] = protoNameOpMap
return front

207
api/poker.pb.go

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc v3.21.12
// protoc v3.19.0
// source: poker.proto
package api
@ -177,6 +177,45 @@ func (*Pong) Descriptor() ([]byte, []int) {
return file_poker_proto_rawDescGZIP(), []int{2}
}
// 成功消息
type ResSuccess struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *ResSuccess) Reset() {
*x = ResSuccess{}
if protoimpl.UnsafeEnabled {
mi := &file_poker_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ResSuccess) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ResSuccess) ProtoMessage() {}
func (x *ResSuccess) ProtoReflect() protoreflect.Message {
mi := &file_poker_proto_msgTypes[3]
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 ResSuccess.ProtoReflect.Descriptor instead.
func (*ResSuccess) Descriptor() ([]byte, []int) {
return file_poker_proto_rawDescGZIP(), []int{3}
}
// 失败响应
type ResFail struct {
state protoimpl.MessageState
@ -189,7 +228,7 @@ type ResFail struct {
func (x *ResFail) Reset() {
*x = ResFail{}
if protoimpl.UnsafeEnabled {
mi := &file_poker_proto_msgTypes[3]
mi := &file_poker_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -202,7 +241,7 @@ func (x *ResFail) String() string {
func (*ResFail) ProtoMessage() {}
func (x *ResFail) ProtoReflect() protoreflect.Message {
mi := &file_poker_proto_msgTypes[3]
mi := &file_poker_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -215,7 +254,7 @@ func (x *ResFail) ProtoReflect() protoreflect.Message {
// Deprecated: Use ResFail.ProtoReflect.Descriptor instead.
func (*ResFail) Descriptor() ([]byte, []int) {
return file_poker_proto_rawDescGZIP(), []int{3}
return file_poker_proto_rawDescGZIP(), []int{4}
}
func (x *ResFail) GetMsg() string {
@ -236,7 +275,7 @@ type ReqIdentity struct {
func (x *ReqIdentity) Reset() {
*x = ReqIdentity{}
if protoimpl.UnsafeEnabled {
mi := &file_poker_proto_msgTypes[4]
mi := &file_poker_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -249,7 +288,7 @@ func (x *ReqIdentity) String() string {
func (*ReqIdentity) ProtoMessage() {}
func (x *ReqIdentity) ProtoReflect() protoreflect.Message {
mi := &file_poker_proto_msgTypes[4]
mi := &file_poker_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -262,7 +301,7 @@ func (x *ReqIdentity) ProtoReflect() protoreflect.Message {
// Deprecated: Use ReqIdentity.ProtoReflect.Descriptor instead.
func (*ReqIdentity) Descriptor() ([]byte, []int) {
return file_poker_proto_rawDescGZIP(), []int{4}
return file_poker_proto_rawDescGZIP(), []int{5}
}
func (x *ReqIdentity) GetToken() string {
@ -284,7 +323,7 @@ type ResIdentity struct {
func (x *ResIdentity) Reset() {
*x = ResIdentity{}
if protoimpl.UnsafeEnabled {
mi := &file_poker_proto_msgTypes[5]
mi := &file_poker_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -297,7 +336,7 @@ func (x *ResIdentity) String() string {
func (*ResIdentity) ProtoMessage() {}
func (x *ResIdentity) ProtoReflect() protoreflect.Message {
mi := &file_poker_proto_msgTypes[5]
mi := &file_poker_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -310,7 +349,7 @@ func (x *ResIdentity) ProtoReflect() protoreflect.Message {
// Deprecated: Use ResIdentity.ProtoReflect.Descriptor instead.
func (*ResIdentity) Descriptor() ([]byte, []int) {
return file_poker_proto_rawDescGZIP(), []int{5}
return file_poker_proto_rawDescGZIP(), []int{6}
}
func (x *ResIdentity) GetStatus() int32 {
@ -336,7 +375,7 @@ type ReqLobbyView struct {
func (x *ReqLobbyView) Reset() {
*x = ReqLobbyView{}
if protoimpl.UnsafeEnabled {
mi := &file_poker_proto_msgTypes[6]
mi := &file_poker_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -349,7 +388,7 @@ func (x *ReqLobbyView) String() string {
func (*ReqLobbyView) ProtoMessage() {}
func (x *ReqLobbyView) ProtoReflect() protoreflect.Message {
mi := &file_poker_proto_msgTypes[6]
mi := &file_poker_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -362,7 +401,7 @@ func (x *ReqLobbyView) ProtoReflect() protoreflect.Message {
// Deprecated: Use ReqLobbyView.ProtoReflect.Descriptor instead.
func (*ReqLobbyView) Descriptor() ([]byte, []int) {
return file_poker_proto_rawDescGZIP(), []int{6}
return file_poker_proto_rawDescGZIP(), []int{7}
}
type ResLobbyView struct {
@ -374,7 +413,7 @@ type ResLobbyView struct {
func (x *ResLobbyView) Reset() {
*x = ResLobbyView{}
if protoimpl.UnsafeEnabled {
mi := &file_poker_proto_msgTypes[7]
mi := &file_poker_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -387,7 +426,7 @@ func (x *ResLobbyView) String() string {
func (*ResLobbyView) ProtoMessage() {}
func (x *ResLobbyView) ProtoReflect() protoreflect.Message {
mi := &file_poker_proto_msgTypes[7]
mi := &file_poker_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -400,19 +439,22 @@ func (x *ResLobbyView) ProtoReflect() protoreflect.Message {
// Deprecated: Use ResLobbyView.ProtoReflect.Descriptor instead.
func (*ResLobbyView) Descriptor() ([]byte, []int) {
return file_poker_proto_rawDescGZIP(), []int{7}
return file_poker_proto_rawDescGZIP(), []int{8}
}
type ReqCreateTable struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Players int32 `protobuf:"varint,1,opt,name=players,proto3" json:"players,omitempty"`
Robots int32 `protobuf:"varint,2,opt,name=robots,proto3" json:"robots,omitempty"`
}
func (x *ReqCreateTable) Reset() {
*x = ReqCreateTable{}
if protoimpl.UnsafeEnabled {
mi := &file_poker_proto_msgTypes[8]
mi := &file_poker_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -425,7 +467,7 @@ func (x *ReqCreateTable) String() string {
func (*ReqCreateTable) ProtoMessage() {}
func (x *ReqCreateTable) ProtoReflect() protoreflect.Message {
mi := &file_poker_proto_msgTypes[8]
mi := &file_poker_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -438,19 +480,35 @@ func (x *ReqCreateTable) ProtoReflect() protoreflect.Message {
// Deprecated: Use ReqCreateTable.ProtoReflect.Descriptor instead.
func (*ReqCreateTable) Descriptor() ([]byte, []int) {
return file_poker_proto_rawDescGZIP(), []int{8}
return file_poker_proto_rawDescGZIP(), []int{9}
}
func (x *ReqCreateTable) GetPlayers() int32 {
if x != nil {
return x.Players
}
return 0
}
func (x *ReqCreateTable) GetRobots() int32 {
if x != nil {
return x.Robots
}
return 0
}
type ResCreateTable struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
TableNo int32 `protobuf:"varint,1,opt,name=tableNo,proto3" json:"tableNo,omitempty"`
}
func (x *ResCreateTable) Reset() {
*x = ResCreateTable{}
if protoimpl.UnsafeEnabled {
mi := &file_poker_proto_msgTypes[9]
mi := &file_poker_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -463,7 +521,7 @@ func (x *ResCreateTable) String() string {
func (*ResCreateTable) ProtoMessage() {}
func (x *ResCreateTable) ProtoReflect() protoreflect.Message {
mi := &file_poker_proto_msgTypes[9]
mi := &file_poker_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -476,7 +534,14 @@ func (x *ResCreateTable) ProtoReflect() protoreflect.Message {
// Deprecated: Use ResCreateTable.ProtoReflect.Descriptor instead.
func (*ResCreateTable) Descriptor() ([]byte, []int) {
return file_poker_proto_rawDescGZIP(), []int{9}
return file_poker_proto_rawDescGZIP(), []int{10}
}
func (x *ResCreateTable) GetTableNo() int32 {
if x != nil {
return x.TableNo
}
return 0
}
type ReqJoinTable struct {
@ -488,7 +553,7 @@ type ReqJoinTable struct {
func (x *ReqJoinTable) Reset() {
*x = ReqJoinTable{}
if protoimpl.UnsafeEnabled {
mi := &file_poker_proto_msgTypes[10]
mi := &file_poker_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -501,7 +566,7 @@ func (x *ReqJoinTable) String() string {
func (*ReqJoinTable) ProtoMessage() {}
func (x *ReqJoinTable) ProtoReflect() protoreflect.Message {
mi := &file_poker_proto_msgTypes[10]
mi := &file_poker_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -514,7 +579,7 @@ func (x *ReqJoinTable) ProtoReflect() protoreflect.Message {
// Deprecated: Use ReqJoinTable.ProtoReflect.Descriptor instead.
func (*ReqJoinTable) Descriptor() ([]byte, []int) {
return file_poker_proto_rawDescGZIP(), []int{10}
return file_poker_proto_rawDescGZIP(), []int{11}
}
type ResJoinTable struct {
@ -526,7 +591,7 @@ type ResJoinTable struct {
func (x *ResJoinTable) Reset() {
*x = ResJoinTable{}
if protoimpl.UnsafeEnabled {
mi := &file_poker_proto_msgTypes[11]
mi := &file_poker_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -539,7 +604,7 @@ func (x *ResJoinTable) String() string {
func (*ResJoinTable) ProtoMessage() {}
func (x *ResJoinTable) ProtoReflect() protoreflect.Message {
mi := &file_poker_proto_msgTypes[11]
mi := &file_poker_proto_msgTypes[12]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -552,7 +617,7 @@ func (x *ResJoinTable) ProtoReflect() protoreflect.Message {
// Deprecated: Use ResJoinTable.ProtoReflect.Descriptor instead.
func (*ResJoinTable) Descriptor() ([]byte, []int) {
return file_poker_proto_rawDescGZIP(), []int{11}
return file_poker_proto_rawDescGZIP(), []int{12}
}
var File_poker_proto protoreflect.FileDescriptor
@ -567,22 +632,27 @@ var file_poker_proto_rawDesc = []byte{
0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a,
0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64,
0x79, 0x22, 0x06, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x22, 0x06, 0x0a, 0x04, 0x50, 0x6f, 0x6e,
0x67, 0x22, 0x1b, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x46, 0x61, 0x69, 0x6c, 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, 0x0e, 0x0a, 0x0c,
0x52, 0x65, 0x73, 0x4c, 0x6f, 0x62, 0x62, 0x79, 0x56, 0x69, 0x65, 0x77, 0x22, 0x10, 0x0a, 0x0e,
0x52, 0x65, 0x71, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x10,
0x67, 0x22, 0x0c, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22,
0x1b, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x46, 0x61, 0x69, 0x6c, 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, 0x0e, 0x0a, 0x0c, 0x52, 0x65,
0x73, 0x4c, 0x6f, 0x62, 0x62, 0x79, 0x56, 0x69, 0x65, 0x77, 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,
0x22, 0x0e, 0x0a, 0x0c, 0x52, 0x65, 0x71, 0x4a, 0x6f, 0x69, 0x6e, 0x54, 0x61, 0x62, 0x6c, 0x65,
0x22, 0x0e, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 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,
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, 0x0e, 0x0a, 0x0c, 0x52, 0x65,
0x71, 0x4a, 0x6f, 0x69, 0x6e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x0e, 0x0a, 0x0c, 0x52, 0x65,
0x73, 0x4a, 0x6f, 0x69, 0x6e, 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 (
@ -597,20 +667,21 @@ func file_poker_proto_rawDescGZIP() []byte {
return file_poker_proto_rawDescData
}
var file_poker_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
var file_poker_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
var file_poker_proto_goTypes = []interface{}{
(*ProtoWrap)(nil), // 0: api.ProtoWrap
(*Ping)(nil), // 1: api.Ping
(*Pong)(nil), // 2: api.Pong
(*ResFail)(nil), // 3: api.ResFail
(*ReqIdentity)(nil), // 4: api.ReqIdentity
(*ResIdentity)(nil), // 5: api.ResIdentity
(*ReqLobbyView)(nil), // 6: api.ReqLobbyView
(*ResLobbyView)(nil), // 7: api.ResLobbyView
(*ReqCreateTable)(nil), // 8: api.ReqCreateTable
(*ResCreateTable)(nil), // 9: api.ResCreateTable
(*ReqJoinTable)(nil), // 10: api.ReqJoinTable
(*ResJoinTable)(nil), // 11: api.ResJoinTable
(*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
(*ReqCreateTable)(nil), // 9: api.ReqCreateTable
(*ResCreateTable)(nil), // 10: api.ResCreateTable
(*ReqJoinTable)(nil), // 11: api.ReqJoinTable
(*ResJoinTable)(nil), // 12: api.ResJoinTable
}
var file_poker_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
@ -663,7 +734,7 @@ func file_poker_proto_init() {
}
}
file_poker_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ResFail); i {
switch v := v.(*ResSuccess); i {
case 0:
return &v.state
case 1:
@ -675,7 +746,7 @@ func file_poker_proto_init() {
}
}
file_poker_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReqIdentity); i {
switch v := v.(*ResFail); i {
case 0:
return &v.state
case 1:
@ -687,7 +758,7 @@ func file_poker_proto_init() {
}
}
file_poker_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ResIdentity); i {
switch v := v.(*ReqIdentity); i {
case 0:
return &v.state
case 1:
@ -699,7 +770,7 @@ func file_poker_proto_init() {
}
}
file_poker_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReqLobbyView); i {
switch v := v.(*ResIdentity); i {
case 0:
return &v.state
case 1:
@ -711,7 +782,7 @@ func file_poker_proto_init() {
}
}
file_poker_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ResLobbyView); i {
switch v := v.(*ReqLobbyView); i {
case 0:
return &v.state
case 1:
@ -723,7 +794,7 @@ func file_poker_proto_init() {
}
}
file_poker_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReqCreateTable); i {
switch v := v.(*ResLobbyView); i {
case 0:
return &v.state
case 1:
@ -735,7 +806,7 @@ func file_poker_proto_init() {
}
}
file_poker_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ResCreateTable); i {
switch v := v.(*ReqCreateTable); i {
case 0:
return &v.state
case 1:
@ -747,7 +818,7 @@ func file_poker_proto_init() {
}
}
file_poker_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReqJoinTable); i {
switch v := v.(*ResCreateTable); i {
case 0:
return &v.state
case 1:
@ -759,6 +830,18 @@ func file_poker_proto_init() {
}
}
file_poker_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReqJoinTable); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_poker_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ResJoinTable); i {
case 0:
return &v.state
@ -777,7 +860,7 @@ func file_poker_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_poker_proto_rawDesc,
NumEnums: 0,
NumMessages: 12,
NumMessages: 13,
NumExtensions: 0,
NumServices: 0,
},

10
api/poker.proto

@ -24,6 +24,11 @@ message Pong {
}
//
message ResSuccess {
}
//
message ResFail {
string msg = 3; //
@ -47,11 +52,12 @@ message ResLobbyView {
}
message ReqCreateTable {
int32 players = 1;
int32 robots = 2;
}
message ResCreateTable {
int32 tableNo = 1;
}
message ReqJoinTable {

482
api/proto.js

@ -671,6 +671,181 @@ export const api = $root.api = (() => {
return Pong;
})();
api.ResSuccess = (function() {
/**
* Properties of a ResSuccess.
* @memberof api
* @interface IResSuccess
*/
/**
* Constructs a new ResSuccess.
* @memberof api
* @classdesc Represents a ResSuccess.
* @implements IResSuccess
* @constructor
* @param {api.IResSuccess=} [properties] Properties to set
*/
function ResSuccess(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 ResSuccess instance using the specified properties.
* @function create
* @memberof api.ResSuccess
* @static
* @param {api.IResSuccess=} [properties] Properties to set
* @returns {api.ResSuccess} ResSuccess instance
*/
ResSuccess.create = function create(properties) {
return new ResSuccess(properties);
};
/**
* Encodes the specified ResSuccess message. Does not implicitly {@link api.ResSuccess.verify|verify} messages.
* @function encode
* @memberof api.ResSuccess
* @static
* @param {api.IResSuccess} message ResSuccess message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
ResSuccess.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
return writer;
};
/**
* Encodes the specified ResSuccess message, length delimited. Does not implicitly {@link api.ResSuccess.verify|verify} messages.
* @function encodeDelimited
* @memberof api.ResSuccess
* @static
* @param {api.IResSuccess} message ResSuccess message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
ResSuccess.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a ResSuccess message from the specified reader or buffer.
* @function decode
* @memberof api.ResSuccess
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {api.ResSuccess} ResSuccess
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
ResSuccess.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.ResSuccess();
while (reader.pos < end) {
let tag = reader.uint32();
switch (tag >>> 3) {
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes a ResSuccess message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof api.ResSuccess
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {api.ResSuccess} ResSuccess
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
ResSuccess.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a ResSuccess message.
* @function verify
* @memberof api.ResSuccess
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
ResSuccess.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
return null;
};
/**
* Creates a ResSuccess message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof api.ResSuccess
* @static
* @param {Object.<string,*>} object Plain object
* @returns {api.ResSuccess} ResSuccess
*/
ResSuccess.fromObject = function fromObject(object) {
if (object instanceof $root.api.ResSuccess)
return object;
return new $root.api.ResSuccess();
};
/**
* Creates a plain object from a ResSuccess message. Also converts values to other types if specified.
* @function toObject
* @memberof api.ResSuccess
* @static
* @param {api.ResSuccess} message ResSuccess
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
ResSuccess.toObject = function toObject() {
return {};
};
/**
* Converts this ResSuccess to JSON.
* @function toJSON
* @memberof api.ResSuccess
* @instance
* @returns {Object.<string,*>} JSON object
*/
ResSuccess.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
/**
* Gets the default type url for ResSuccess
* @function getTypeUrl
* @memberof api.ResSuccess
* @static
* @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
* @returns {string} The default type url
*/
ResSuccess.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
if (typeUrlPrefix === undefined) {
typeUrlPrefix = "type.googleapis.com";
}
return typeUrlPrefix + "/api.ResSuccess";
};
return ResSuccess;
})();
api.ResFail = (function() {
/**
@ -1660,6 +1835,8 @@ export const api = $root.api = (() => {
* Properties of a ReqCreateTable.
* @memberof api
* @interface IReqCreateTable
* @property {number|null} [players] ReqCreateTable players
* @property {number|null} [robots] ReqCreateTable robots
*/
/**
@ -1677,6 +1854,22 @@ export const api = $root.api = (() => {
this[keys[i]] = properties[keys[i]];
}
/**
* ReqCreateTable players.
* @member {number} players
* @memberof api.ReqCreateTable
* @instance
*/
ReqCreateTable.prototype.players = 0;
/**
* ReqCreateTable robots.
* @member {number} robots
* @memberof api.ReqCreateTable
* @instance
*/
ReqCreateTable.prototype.robots = 0;
/**
* Creates a new ReqCreateTable instance using the specified properties.
* @function create
@ -1701,6 +1894,10 @@ export const api = $root.api = (() => {
ReqCreateTable.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.players != null && Object.hasOwnProperty.call(message, "players"))
writer.uint32(/* id 1, wireType 0 =*/8).int32(message.players);
if (message.robots != null && Object.hasOwnProperty.call(message, "robots"))
writer.uint32(/* id 2, wireType 0 =*/16).int32(message.robots);
return writer;
};
@ -1735,6 +1932,14 @@ export const api = $root.api = (() => {
while (reader.pos < end) {
let tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
message.players = reader.int32();
break;
}
case 2: {
message.robots = reader.int32();
break;
}
default:
reader.skipType(tag & 7);
break;
@ -1770,6 +1975,12 @@ export const api = $root.api = (() => {
ReqCreateTable.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.players != null && message.hasOwnProperty("players"))
if (!$util.isInteger(message.players))
return "players: integer expected";
if (message.robots != null && message.hasOwnProperty("robots"))
if (!$util.isInteger(message.robots))
return "robots: integer expected";
return null;
};
@ -1784,7 +1995,12 @@ export const api = $root.api = (() => {
ReqCreateTable.fromObject = function fromObject(object) {
if (object instanceof $root.api.ReqCreateTable)
return object;
return new $root.api.ReqCreateTable();
let message = new $root.api.ReqCreateTable();
if (object.players != null)
message.players = object.players | 0;
if (object.robots != null)
message.robots = object.robots | 0;
return message;
};
/**
@ -1796,8 +2012,19 @@ export const api = $root.api = (() => {
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
ReqCreateTable.toObject = function toObject() {
return {};
ReqCreateTable.toObject = function toObject(message, options) {
if (!options)
options = {};
let object = {};
if (options.defaults) {
object.players = 0;
object.robots = 0;
}
if (message.players != null && message.hasOwnProperty("players"))
object.players = message.players;
if (message.robots != null && message.hasOwnProperty("robots"))
object.robots = message.robots;
return object;
};
/**
@ -1835,6 +2062,7 @@ export const api = $root.api = (() => {
* Properties of a ResCreateTable.
* @memberof api
* @interface IResCreateTable
* @property {number|null} [tableNo] ResCreateTable tableNo
*/
/**
@ -1852,6 +2080,14 @@ export const api = $root.api = (() => {
this[keys[i]] = properties[keys[i]];
}
/**
* ResCreateTable tableNo.
* @member {number} tableNo
* @memberof api.ResCreateTable
* @instance
*/
ResCreateTable.prototype.tableNo = 0;
/**
* Creates a new ResCreateTable instance using the specified properties.
* @function create
@ -1876,6 +2112,8 @@ export const api = $root.api = (() => {
ResCreateTable.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.tableNo != null && Object.hasOwnProperty.call(message, "tableNo"))
writer.uint32(/* id 1, wireType 0 =*/8).int32(message.tableNo);
return writer;
};
@ -1910,6 +2148,10 @@ export const api = $root.api = (() => {
while (reader.pos < end) {
let tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
message.tableNo = reader.int32();
break;
}
default:
reader.skipType(tag & 7);
break;
@ -1945,6 +2187,9 @@ export const api = $root.api = (() => {
ResCreateTable.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.tableNo != null && message.hasOwnProperty("tableNo"))
if (!$util.isInteger(message.tableNo))
return "tableNo: integer expected";
return null;
};
@ -1959,7 +2204,10 @@ export const api = $root.api = (() => {
ResCreateTable.fromObject = function fromObject(object) {
if (object instanceof $root.api.ResCreateTable)
return object;
return new $root.api.ResCreateTable();
let message = new $root.api.ResCreateTable();
if (object.tableNo != null)
message.tableNo = object.tableNo | 0;
return message;
};
/**
@ -1971,8 +2219,15 @@ export const api = $root.api = (() => {
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
ResCreateTable.toObject = function toObject() {
return {};
ResCreateTable.toObject = function toObject(message, options) {
if (!options)
options = {};
let object = {};
if (options.defaults)
object.tableNo = 0;
if (message.tableNo != null && message.hasOwnProperty("tableNo"))
object.tableNo = message.tableNo;
return object;
};
/**
@ -2357,219 +2612,4 @@ export const api = $root.api = (() => {
return api;
})();
export const test = $root.test = (() => {
/**
* Namespace test.
* @exports test
* @namespace
*/
const test = {};
test.Test = (function() {
/**
* Properties of a Test.
* @memberof test
* @interface ITest
* @property {string|null} [msg] Test msg
*/
/**
* Constructs a new Test.
* @memberof test
* @classdesc Represents a Test.
* @implements ITest
* @constructor
* @param {test.ITest=} [properties] Properties to set
*/
function Test(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]];
}
/**
* Test msg.
* @member {string} msg
* @memberof test.Test
* @instance
*/
Test.prototype.msg = "";
/**
* Creates a new Test instance using the specified properties.
* @function create
* @memberof test.Test
* @static
* @param {test.ITest=} [properties] Properties to set
* @returns {test.Test} Test instance
*/
Test.create = function create(properties) {
return new Test(properties);
};
/**
* Encodes the specified Test message. Does not implicitly {@link test.Test.verify|verify} messages.
* @function encode
* @memberof test.Test
* @static
* @param {test.ITest} message Test message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
Test.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.msg != null && Object.hasOwnProperty.call(message, "msg"))
writer.uint32(/* id 3, wireType 2 =*/26).string(message.msg);
return writer;
};
/**
* Encodes the specified Test message, length delimited. Does not implicitly {@link test.Test.verify|verify} messages.
* @function encodeDelimited
* @memberof test.Test
* @static
* @param {test.ITest} message Test message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
Test.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a Test message from the specified reader or buffer.
* @function decode
* @memberof test.Test
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {test.Test} Test
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
Test.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.test.Test();
while (reader.pos < end) {
let tag = reader.uint32();
switch (tag >>> 3) {
case 3: {
message.msg = reader.string();
break;
}
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes a Test message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof test.Test
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {test.Test} Test
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
Test.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a Test message.
* @function verify
* @memberof test.Test
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
Test.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.msg != null && message.hasOwnProperty("msg"))
if (!$util.isString(message.msg))
return "msg: string expected";
return null;
};
/**
* Creates a Test message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof test.Test
* @static
* @param {Object.<string,*>} object Plain object
* @returns {test.Test} Test
*/
Test.fromObject = function fromObject(object) {
if (object instanceof $root.test.Test)
return object;
let message = new $root.test.Test();
if (object.msg != null)
message.msg = String(object.msg);
return message;
};
/**
* Creates a plain object from a Test message. Also converts values to other types if specified.
* @function toObject
* @memberof test.Test
* @static
* @param {test.Test} message Test
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
Test.toObject = function toObject(message, options) {
if (!options)
options = {};
let object = {};
if (options.defaults)
object.msg = "";
if (message.msg != null && message.hasOwnProperty("msg"))
object.msg = message.msg;
return object;
};
/**
* Converts this Test to JSON.
* @function toJSON
* @memberof test.Test
* @instance
* @returns {Object.<string,*>} JSON object
*/
Test.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
/**
* Gets the default type url for Test
* @function getTypeUrl
* @memberof test.Test
* @static
* @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com")
* @returns {string} The default type url
*/
Test.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
if (typeUrlPrefix === undefined) {
typeUrlPrefix = "type.googleapis.com";
}
return typeUrlPrefix + "/test.Test";
};
return Test;
})();
return test;
})();
export { $root as default };

5
cmd/main.go

@ -1,11 +1,16 @@
package main
import (
"math/rand"
"texas-poker-bk/internal/conf"
"texas-poker-bk/internal/server"
"time"
)
func startServer() {
// TODO 真随机数 crypto/rand
rand.Seed(time.Now().UnixNano())
httpServer := server.NewServer()
err := httpServer.Run(conf.Conf.Http.Addr)
if err != nil {

2
internal/game/card.go

@ -1,4 +1,4 @@
package card
package game
type Card struct {
Dot PokerDot // 点数

51
internal/game/game.go

@ -0,0 +1,51 @@
package game
import (
"math/rand"
)
// Dealer 发牌员, 有打乱的一副牌
type Dealer struct {
// 一副牌
// cardList *collect.LinkedList[Card]
cards []*Card
index int
}
func (d *Dealer) Init() *Dealer {
d.index = 0
d.cards = make([]*Card, 52)
// 初始化一副牌,13张牌
for i := 0; i < 13; i++ {
// 4 种花色
for j := 0; j < 4; j++ {
d.cards[i*4+j] = &Card{PokerDot(i), PokerSuit(j)}
}
}
// 洗牌
disorder(d.cards)
return d
}
// Deal 发牌堆第一张牌
func (d *Dealer) Deal() *Card {
card := d.cards[d.index]
d.index++
return card
}
// disorder 洗牌
func disorder(cards []*Card) {
length := len(cards)
// 洗13次
for i := 0; i < 13; i++ {
for j := 0; j < length; j++ {
repIdx := rand.Intn(length)
cards[i], cards[repIdx] = cards[repIdx], cards[i]
}
}
}
func NewDealer() *Dealer {
return new(Dealer).Init()
}

15
internal/game/player.go

@ -0,0 +1,15 @@
package game
// Player 游戏玩家
type Player struct {
Id int64
Username string
Avatar string
cards [2]*Card // 手牌
chip int // 玩家筹码
}
func NewPlayer() *Player {
return &Player{}
}

5
internal/game/robot.go

@ -0,0 +1,5 @@
package game
// Robot 机器人
type Robot struct {
}

38
internal/game/table.go

@ -0,0 +1,38 @@
package game
type Table struct {
TableNo int32 // 牌桌编号
roundTimes int // 回合次数
stage Stage // 游戏阶段
chip int // 牌桌当前筹码
robotChip int // 牌桌当前机器人下注筹码
dealer *Dealer // 发牌员
publicCards [5]*Dealer // 公共牌
PlayerNum int32 // 玩家数
RobotNum int32 // 机器人数
Players []*Player // 玩家
Robots []*Robot
bigBlindsPos int // 大盲注位
// TODO game logs
}
type Stage int
func (s *Stage) String() string {
return stageNames[*s]
}
// 游戏阶段名称
var stageNames = []string{"Stage00WaitBegin", "Stage10Perflop", "Stage20Flop", "Stage30Turn", "Stage40River"}
// 游戏阶段
const (
Stage00WaitBegin Stage = iota // 等待游戏开始
Stage10Perflop Stage = iota // 下大小盲注,然后没人发2张底牌,大盲注后面第一个玩家跟注、加注或放弃,依次顺时针表态
Stage20Flop Stage = iota // 发三张公牌,由小盲注开始顺时针表态
Stage30Turn Stage = iota // 发第四张公共牌,由小盲注开始顺时针表态
Stage40River Stage = iota // 发第五张牌,由小盲注开始顺时针表态,然后亮牌比大小
)

10
internal/model/vo/game.go

@ -0,0 +1,10 @@
package vo
type PlayerVO struct {
Id int64 `json:"id"`
Username string `json:"username"`
Avatar string `json:"avatar"`
}
type RobotVO struct {
}

11
internal/model/vo/lobby.go

@ -0,0 +1,11 @@
package vo
import "texas-poker-bk/internal/game"
type TableVO struct {
TableNo int32 // 牌桌编号
RoundTimes int32 // 回合次数
Stage game.Stage // 游戏阶段
Players []*PlayerVO // 玩家
Robots []*RobotVO // 机器人
}

4
internal/server/server.go → internal/server/route.go

@ -31,5 +31,9 @@ func NewServer() *gin.Engine {
user := base.Group("/user")
user.GET("/findByName", service.FindUserByName)
game := base.Group("/game")
game.GET("/createTable", service.CreateTable) // 新建牌桌
game.GET("/lobby", service.GetLobbyView) // 游戏大厅
return server
}

12
internal/server/ws.go

@ -81,7 +81,10 @@ func handleNetClient(client *session.NetClient) {
err = proto.Unmarshal(wrap.Body, msg)
if err != nil {
client.Close("api body unmarshal fail! " + err.Error())
return
}
log.Println(fmt.Sprintf("ws msg: %v", msg))
// TODO queue channel -> msg -> handler
var called bool
var res proto.Message
@ -95,7 +98,7 @@ func handleNetClient(client *session.NetClient) {
handlerNetAccount := NetAccountHandlers[wrap.Op]
if called = handlerNetAccount != nil; called {
// TODO account check
res, resErr = handlerNetAccount(client.Account, msg)
res, resErr = handlerNetAccount(*client.Account, msg)
// continue
} else {
// player process
@ -116,10 +119,11 @@ func handleNetClient(client *session.NetClient) {
if res != nil {
// 响应消息
client.WriteSeq(true, wrap.Seq, res)
return
}
// log not found handler wrap.Op
fmt.Printf("not found handler for op %d, msg: %v", wrap.Op, msg)
if !called {
// log not found handler wrap.Op
fmt.Printf("not found handler for op %d, msg: %v", wrap.Op, msg)
}
}
}

11
internal/server/wsroute.go

@ -9,17 +9,18 @@ import (
)
var NetClientHandlers = make(map[int32]func(*session.NetClient, proto.Message) (proto.Message, error))
var NetAccountHandlers = make(map[int32]func(*session.NetAccount, proto.Message) (proto.Message, error))
var NetAccountHandlers = make(map[int32]func(session.NetAccount, proto.Message) (proto.Message, error))
var PlayerHandlers = make(map[int32]func(*session.Player, proto.Message) (proto.Message, error))
func init() {
// 连接token认证
HandleNetClientMsg(&api.ReqIdentity{}, func(client *session.NetClient, msg *api.ReqIdentity) (proto.Message, error) {
subject, err := service.DecodeSubject(msg.Token)
if err != nil {
// client.Close("authorize failed!")
return nil, err
}
account := &session.NetAccount{Id: subject.Id, UserName: subject.Name, Client: client}
account := &session.NetAccount{Id: subject.Id, UserName: subject.Name, Avatar: subject.Avatar, Client: client}
client.Account = account
// response
@ -27,6 +28,8 @@ func init() {
// client.Write(res)
return res, nil
})
// 创建桌面
HandleNetAccountMsg(&api.ReqCreateTable{}, service.CreateNewTable)
}
func checkExistsTypeHandler(op int32, err error) {
@ -47,10 +50,10 @@ func HandleNetClientMsg[T proto.Message](msg T, f func(*session.NetClient, T) (p
}
}
func HandleNetAccountMsg[T proto.Message](msg T, f func(*session.NetAccount, T) (proto.Message, error)) {
func HandleNetAccountMsg[T proto.Message](msg T, f func(session.NetAccount, T) (proto.Message, error)) {
op, err := api.GetProtoOp(msg)
checkExistsTypeHandler(op, err)
NetAccountHandlers[op] = func(account *session.NetAccount, msg proto.Message) (proto.Message, error) {
NetAccountHandlers[op] = func(account session.NetAccount, msg proto.Message) (proto.Message, error) {
return f(account, msg.(T))
}
}

68
internal/service/store/store.go

@ -0,0 +1,68 @@
package store
import (
"errors"
"fmt"
"sort"
"sync"
"sync/atomic"
"texas-poker-bk/internal/game"
"texas-poker-bk/internal/model/vo"
"texas-poker-bk/tool/collect"
)
var (
TableNo *atomic.Int32
LobbyTables map[int32]*game.Table
LobbyLock *sync.Mutex
)
func init() {
TableNo = &atomic.Int32{}
LobbyTables = make(map[int32]*game.Table, 16)
LobbyLock = &sync.Mutex{}
}
func SaveNewTable(table *game.Table) error {
LobbyLock.Lock()
defer LobbyLock.Unlock()
if LobbyTables[table.TableNo] != nil {
return errors.New(fmt.Sprintf("table no %d exists!", table.TableNo))
}
LobbyTables[table.TableNo] = table
return nil
}
func GetLobbyTablesView() []*vo.TableVO {
if LobbyTables == nil || len(LobbyTables) == 0 {
return make([]*vo.TableVO, 0)
}
tables := make([]*vo.TableVO, len(LobbyTables))
idx := 0
for _, t := range LobbyTables {
tVO := &vo.TableVO{}
tVO.TableNo = t.TableNo
if collect.IsNotEmptySlice(t.Players) {
tVO.Players = make([]*vo.PlayerVO, len(t.Players))
for i, player := range t.Players {
pVO := &vo.PlayerVO{Id: player.Id, Username: player.Username, Avatar: player.Avatar}
tVO.Players[i] = pVO
}
}
if collect.IsNotEmptySlice(t.Robots) {
tVO.Robots = make([]*vo.RobotVO, len(t.Robots))
for i, _ := range t.Robots {
rVO := &vo.RobotVO{}
tVO.Robots[i] = rVO
}
}
tables[idx] = tVO
idx++
}
// 牌桌号降序
sort.Slice(tables, func(i, j int) bool {
return tables[i].TableNo > tables[j].TableNo
})
return tables
}

93
internal/service/table.go

@ -1,11 +1,100 @@
package service
import (
"github.com/gin-gonic/gin"
"github.com/golang/protobuf/proto"
"net/http"
"strconv"
"texas-poker-bk/api"
"texas-poker-bk/internal/game"
"texas-poker-bk/internal/service/store"
"texas-poker-bk/internal/session"
)
// CreateTable 创建桌面
func CreateTable(client session.NetAccount, msg *api.ReqIdentity) {
// CreateNewTable 创建桌面 TODO 当前在房间则不可创建房间了
func CreateNewTable(account session.NetAccount, msg *api.ReqCreateTable) (proto.Message, error) {
// 人数,机器人数
playerNum := msg.Players
robotNum := msg.Robots
if playerNum+robotNum <= 0 {
return &api.ResFail{Msg: "至少添加一个玩家或机器人"}, nil
}
// 初始化一个牌桌
table := &game.Table{}
table.TableNo = store.TableNo.Add(1)
table.PlayerNum = int32(playerNum) + 1
table.RobotNum = int32(playerNum)
table.Players = make([]*game.Player, playerNum)
table.Robots = make([]*game.Robot, robotNum)
// 房主 [0]
owner := &game.Player{
Id: account.Id,
Username: account.UserName,
Avatar: account.Avatar,
}
table.Players[0] = owner
for i := 0; i < int(robotNum); i++ {
table.Robots[i] = &game.Robot{}
}
err := store.SaveNewTable(table)
if err != nil {
return &api.ResFail{Msg: err.Error()}, nil
}
return &api.ResCreateTable{TableNo: table.TableNo}, nil
}
// CreateTable 创建新桌面
func CreateTable(ctx *gin.Context) {
user := GetSubject(ctx)
// 人数,机器人数
players := ctx.PostForm("players")
robots := ctx.PostForm("robots")
playerNum, err := strconv.Atoi(players)
if err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"msg": "人数格式有误"})
return
}
robotNum, err := strconv.Atoi(robots)
if err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"msg": "机器人数格式有误"})
return
}
if playerNum+robotNum <= 0 {
ctx.JSON(http.StatusBadRequest, gin.H{"msg": "至少添加一个玩家或机器人"})
return
}
// 初始化一个牌桌
table := &game.Table{}
table.TableNo = store.TableNo.Add(1)
table.PlayerNum = int32(playerNum) + 1
table.RobotNum = int32(playerNum)
table.Players = make([]*game.Player, playerNum)
table.Robots = make([]*game.Robot, robotNum)
// 房主 [0]
owner := &game.Player{
Id: user.Id,
Username: user.Name,
Avatar: user.Avatar,
}
table.Players[0] = owner
for i := 0; i < robotNum; i++ {
table.Robots[i] = &game.Robot{}
}
err = store.SaveNewTable(table)
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()})
return
}
ctx.JSON(http.StatusOK, gin.H{"data": gin.H{"tableNo": table.TableNo}})
}
func GetLobbyView(ctx *gin.Context) {
lobby := store.GetLobbyTablesView()
ctx.JSON(http.StatusOK, gin.H{"data": lobby})
}
// JoinTable 加入牌桌
func JoinTable(ctx *gin.Context) {
}

1
internal/session/net_account.go

@ -4,6 +4,7 @@ package session
type NetAccount struct {
Id int64
UserName string
Avatar string
Client *NetClient
}

7
internal/session/subject.go

@ -2,7 +2,8 @@ package session
// Subject 认证对象
type Subject struct {
Id int64 `json:"id,omitempty"` // 用户id
Name string `json:"name,omitempty"` // 用户名
Time int64 `json:"time,omitempty"` // 生成时间戳
Id int64 `json:"id,omitempty"` // 用户id
Name string `json:"name,omitempty"` // 用户名
Avatar string `json:"avatar,omitempty"` // 头像 TODO 缓存,不加到token
Time int64 `json:"time,omitempty"` // 生成时间戳
}

Loading…
Cancel
Save