diff --git a/actions/actions.pb.go b/actions/actions.pb.go index bcc75ab..f40e089 100644 --- a/actions/actions.pb.go +++ b/actions/actions.pb.go @@ -1,8 +1,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.3 -// protoc v5.29.2 -// source: actions.proto +// protoc-gen-go v1.36.6 +// protoc v6.30.1 +// source: actions/actions.proto package actions @@ -11,6 +11,7 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -59,11 +60,11 @@ func (x Action_ActionType) String() string { } func (Action_ActionType) Descriptor() protoreflect.EnumDescriptor { - return file_actions_proto_enumTypes[0].Descriptor() + return file_actions_actions_proto_enumTypes[0].Descriptor() } func (Action_ActionType) Type() protoreflect.EnumType { - return &file_actions_proto_enumTypes[0] + return &file_actions_actions_proto_enumTypes[0] } func (x Action_ActionType) Number() protoreflect.EnumNumber { @@ -72,7 +73,7 @@ func (x Action_ActionType) Number() protoreflect.EnumNumber { // Deprecated: Use Action_ActionType.Descriptor instead. func (Action_ActionType) EnumDescriptor() ([]byte, []int) { - return file_actions_proto_rawDescGZIP(), []int{0, 0} + return file_actions_actions_proto_rawDescGZIP(), []int{0, 0} } type Action struct { @@ -90,7 +91,7 @@ type Action struct { func (x *Action) Reset() { *x = Action{} - mi := &file_actions_proto_msgTypes[0] + mi := &file_actions_actions_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -102,7 +103,7 @@ func (x *Action) String() string { func (*Action) ProtoMessage() {} func (x *Action) ProtoReflect() protoreflect.Message { - mi := &file_actions_proto_msgTypes[0] + mi := &file_actions_actions_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -115,7 +116,7 @@ func (x *Action) ProtoReflect() protoreflect.Message { // Deprecated: Use Action.ProtoReflect.Descriptor instead. func (*Action) Descriptor() ([]byte, []int) { - return file_actions_proto_rawDescGZIP(), []int{0} + return file_actions_actions_proto_rawDescGZIP(), []int{0} } func (x *Action) GetType() Action_ActionType { @@ -168,18 +169,19 @@ func (x *Action) GetPassword() string { } type ActionBatch struct { - state protoimpl.MessageState `protogen:"open.v1"` - PlayerId int32 `protobuf:"varint,1,opt,name=player_id,json=playerId,proto3" json:"player_id,omitempty"` - Actions []*Action `protobuf:"bytes,2,rep,name=actions,proto3" json:"actions,omitempty"` - Tick int64 `protobuf:"varint,3,opt,name=tick,proto3" json:"tick,omitempty"` - ProtocolVersion int32 `protobuf:"varint,4,opt,name=protocol_version,json=protocolVersion,proto3" json:"protocol_version,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + PlayerId int32 `protobuf:"varint,1,opt,name=player_id,json=playerId,proto3" json:"player_id,omitempty"` + Actions []*Action `protobuf:"bytes,2,rep,name=actions,proto3" json:"actions,omitempty"` + Tick int64 `protobuf:"varint,3,opt,name=tick,proto3" json:"tick,omitempty"` + ProtocolVersion int32 `protobuf:"varint,4,opt,name=protocol_version,json=protocolVersion,proto3" json:"protocol_version,omitempty"` + LastSeenMessageTimestamp int64 `protobuf:"varint,5,opt,name=last_seen_message_timestamp,json=lastSeenMessageTimestamp,proto3" json:"last_seen_message_timestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ActionBatch) Reset() { *x = ActionBatch{} - mi := &file_actions_proto_msgTypes[1] + mi := &file_actions_actions_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -191,7 +193,7 @@ func (x *ActionBatch) String() string { func (*ActionBatch) ProtoMessage() {} func (x *ActionBatch) ProtoReflect() protoreflect.Message { - mi := &file_actions_proto_msgTypes[1] + mi := &file_actions_actions_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -204,7 +206,7 @@ func (x *ActionBatch) ProtoReflect() protoreflect.Message { // Deprecated: Use ActionBatch.ProtoReflect.Descriptor instead. func (*ActionBatch) Descriptor() ([]byte, []int) { - return file_actions_proto_rawDescGZIP(), []int{1} + return file_actions_actions_proto_rawDescGZIP(), []int{1} } func (x *ActionBatch) GetPlayerId() int32 { @@ -235,6 +237,13 @@ func (x *ActionBatch) GetProtocolVersion() int32 { return 0 } +func (x *ActionBatch) GetLastSeenMessageTimestamp() int64 { + if x != nil { + return x.LastSeenMessageTimestamp + } + return 0 +} + type PlayerState struct { state protoimpl.MessageState `protogen:"open.v1"` PlayerId int32 `protobuf:"varint,1,opt,name=player_id,json=playerId,proto3" json:"player_id,omitempty"` @@ -247,7 +256,7 @@ type PlayerState struct { func (x *PlayerState) Reset() { *x = PlayerState{} - mi := &file_actions_proto_msgTypes[2] + mi := &file_actions_actions_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -259,7 +268,7 @@ func (x *PlayerState) String() string { func (*PlayerState) ProtoMessage() {} func (x *PlayerState) ProtoReflect() protoreflect.Message { - mi := &file_actions_proto_msgTypes[2] + mi := &file_actions_actions_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -272,7 +281,7 @@ func (x *PlayerState) ProtoReflect() protoreflect.Message { // Deprecated: Use PlayerState.ProtoReflect.Descriptor instead. func (*PlayerState) Descriptor() ([]byte, []int) { - return file_actions_proto_rawDescGZIP(), []int{2} + return file_actions_actions_proto_rawDescGZIP(), []int{2} } func (x *PlayerState) GetPlayerId() int32 { @@ -315,7 +324,7 @@ type ChatMessage struct { func (x *ChatMessage) Reset() { *x = ChatMessage{} - mi := &file_actions_proto_msgTypes[3] + mi := &file_actions_actions_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -327,7 +336,7 @@ func (x *ChatMessage) String() string { func (*ChatMessage) ProtoMessage() {} func (x *ChatMessage) ProtoReflect() protoreflect.Message { - mi := &file_actions_proto_msgTypes[3] + mi := &file_actions_actions_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -340,7 +349,7 @@ func (x *ChatMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatMessage.ProtoReflect.Descriptor instead. func (*ChatMessage) Descriptor() ([]byte, []int) { - return file_actions_proto_rawDescGZIP(), []int{3} + return file_actions_actions_proto_rawDescGZIP(), []int{3} } func (x *ChatMessage) GetPlayerId() int32 { @@ -386,7 +395,7 @@ type ServerMessage struct { func (x *ServerMessage) Reset() { *x = ServerMessage{} - mi := &file_actions_proto_msgTypes[4] + mi := &file_actions_actions_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -398,7 +407,7 @@ func (x *ServerMessage) String() string { func (*ServerMessage) ProtoMessage() {} func (x *ServerMessage) ProtoReflect() protoreflect.Message { - mi := &file_actions_proto_msgTypes[4] + mi := &file_actions_actions_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -411,7 +420,7 @@ func (x *ServerMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use ServerMessage.ProtoReflect.Descriptor instead. func (*ServerMessage) Descriptor() ([]byte, []int) { - return file_actions_proto_rawDescGZIP(), []int{4} + return file_actions_actions_proto_rawDescGZIP(), []int{4} } func (x *ServerMessage) GetPlayerId() int32 { @@ -463,92 +472,67 @@ func (x *ServerMessage) GetProtocolVersion() int32 { return 0 } -var File_actions_proto protoreflect.FileDescriptor +var File_actions_actions_proto protoreflect.FileDescriptor -var file_actions_proto_rawDesc = []byte{ - 0x0a, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x97, 0x02, 0x0a, 0x06, 0x41, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x1a, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x01, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, - 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x79, 0x12, - 0x1b, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, - 0x63, 0x68, 0x61, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x63, 0x68, 0x61, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, - 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x49, 0x0a, 0x0a, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x4f, 0x56, 0x45, 0x10, 0x00, 0x12, - 0x08, 0x0a, 0x04, 0x43, 0x48, 0x41, 0x54, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x49, 0x53, - 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x4c, 0x4f, 0x47, - 0x49, 0x4e, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, - 0x10, 0x04, 0x22, 0x94, 0x01, 0x0a, 0x0b, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, - 0x29, 0x0a, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0f, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, - 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x63, 0x6b, 0x12, 0x29, - 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x62, 0x0a, 0x0b, 0x50, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x0c, 0x0a, 0x01, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, - 0x79, 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, 0x22, 0x7e, 0x0a, - 0x0b, 0x43, 0x68, 0x61, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, - 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, - 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xad, 0x02, - 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, - 0x1b, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x07, - 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x12, 0x21, 0x0a, 0x0c, - 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x12, - 0x39, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x43, 0x68, 0x61, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0c, 0x63, 0x68, - 0x61, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x75, - 0x74, 0x68, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, - 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5f, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x2c, 0x5a, - 0x2a, 0x67, 0x69, 0x74, 0x65, 0x61, 0x2e, 0x62, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x62, 0x65, 0x2f, - 0x62, 0x64, 0x6e, 0x75, 0x67, 0x67, 0x65, 0x74, 0x2f, 0x67, 0x6f, 0x6f, 0x6e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, -} +const file_actions_actions_proto_rawDesc = "" + + "\n" + + "\x15actions/actions.proto\x12\aactions\"\x97\x02\n" + + "\x06Action\x12.\n" + + "\x04type\x18\x01 \x01(\x0e2\x1a.actions.Action.ActionTypeR\x04type\x12\f\n" + + "\x01x\x18\x02 \x01(\x05R\x01x\x12\f\n" + + "\x01y\x18\x03 \x01(\x05R\x01y\x12\x1b\n" + + "\tplayer_id\x18\x04 \x01(\x05R\bplayerId\x12!\n" + + "\fchat_message\x18\x05 \x01(\tR\vchatMessage\x12\x1a\n" + + "\busername\x18\x06 \x01(\tR\busername\x12\x1a\n" + + "\bpassword\x18\a \x01(\tR\bpassword\"I\n" + + "\n" + + "ActionType\x12\b\n" + + "\x04MOVE\x10\x00\x12\b\n" + + "\x04CHAT\x10\x01\x12\x0e\n" + + "\n" + + "DISCONNECT\x10\x02\x12\t\n" + + "\x05LOGIN\x10\x03\x12\f\n" + + "\bREGISTER\x10\x04\"\xd3\x01\n" + + "\vActionBatch\x12\x1b\n" + + "\tplayer_id\x18\x01 \x01(\x05R\bplayerId\x12)\n" + + "\aactions\x18\x02 \x03(\v2\x0f.actions.ActionR\aactions\x12\x12\n" + + "\x04tick\x18\x03 \x01(\x03R\x04tick\x12)\n" + + "\x10protocol_version\x18\x04 \x01(\x05R\x0fprotocolVersion\x12=\n" + + "\x1blast_seen_message_timestamp\x18\x05 \x01(\x03R\x18lastSeenMessageTimestamp\"b\n" + + "\vPlayerState\x12\x1b\n" + + "\tplayer_id\x18\x01 \x01(\x05R\bplayerId\x12\f\n" + + "\x01x\x18\x02 \x01(\x05R\x01x\x12\f\n" + + "\x01y\x18\x03 \x01(\x05R\x01y\x12\x1a\n" + + "\busername\x18\x04 \x01(\tR\busername\"~\n" + + "\vChatMessage\x12\x1b\n" + + "\tplayer_id\x18\x01 \x01(\x05R\bplayerId\x12\x1a\n" + + "\busername\x18\x02 \x01(\tR\busername\x12\x18\n" + + "\acontent\x18\x03 \x01(\tR\acontent\x12\x1c\n" + + "\ttimestamp\x18\x04 \x01(\x03R\ttimestamp\"\xad\x02\n" + + "\rServerMessage\x12\x1b\n" + + "\tplayer_id\x18\x01 \x01(\x05R\bplayerId\x12.\n" + + "\aplayers\x18\x02 \x03(\v2\x14.actions.PlayerStateR\aplayers\x12!\n" + + "\fcurrent_tick\x18\x03 \x01(\x03R\vcurrentTick\x129\n" + + "\rchat_messages\x18\x04 \x03(\v2\x14.actions.ChatMessageR\fchatMessages\x12!\n" + + "\fauth_success\x18\x05 \x01(\bR\vauthSuccess\x12#\n" + + "\rerror_message\x18\x06 \x01(\tR\ferrorMessage\x12)\n" + + "\x10protocol_version\x18\a \x01(\x05R\x0fprotocolVersionB,Z*gitea.boner.be/bdnugget/goonserver/actionsb\x06proto3" var ( - file_actions_proto_rawDescOnce sync.Once - file_actions_proto_rawDescData = file_actions_proto_rawDesc + file_actions_actions_proto_rawDescOnce sync.Once + file_actions_actions_proto_rawDescData []byte ) -func file_actions_proto_rawDescGZIP() []byte { - file_actions_proto_rawDescOnce.Do(func() { - file_actions_proto_rawDescData = protoimpl.X.CompressGZIP(file_actions_proto_rawDescData) +func file_actions_actions_proto_rawDescGZIP() []byte { + file_actions_actions_proto_rawDescOnce.Do(func() { + file_actions_actions_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_actions_actions_proto_rawDesc), len(file_actions_actions_proto_rawDesc))) }) - return file_actions_proto_rawDescData + return file_actions_actions_proto_rawDescData } -var file_actions_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_actions_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_actions_proto_goTypes = []any{ +var file_actions_actions_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_actions_actions_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_actions_actions_proto_goTypes = []any{ (Action_ActionType)(0), // 0: actions.Action.ActionType (*Action)(nil), // 1: actions.Action (*ActionBatch)(nil), // 2: actions.ActionBatch @@ -556,7 +540,7 @@ var file_actions_proto_goTypes = []any{ (*ChatMessage)(nil), // 4: actions.ChatMessage (*ServerMessage)(nil), // 5: actions.ServerMessage } -var file_actions_proto_depIdxs = []int32{ +var file_actions_actions_proto_depIdxs = []int32{ 0, // 0: actions.Action.type:type_name -> actions.Action.ActionType 1, // 1: actions.ActionBatch.actions:type_name -> actions.Action 3, // 2: actions.ServerMessage.players:type_name -> actions.PlayerState @@ -568,28 +552,27 @@ var file_actions_proto_depIdxs = []int32{ 0, // [0:4] is the sub-list for field type_name } -func init() { file_actions_proto_init() } -func file_actions_proto_init() { - if File_actions_proto != nil { +func init() { file_actions_actions_proto_init() } +func file_actions_actions_proto_init() { + if File_actions_actions_proto != nil { return } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_actions_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_actions_actions_proto_rawDesc), len(file_actions_actions_proto_rawDesc)), NumEnums: 1, NumMessages: 5, NumExtensions: 0, NumServices: 0, }, - GoTypes: file_actions_proto_goTypes, - DependencyIndexes: file_actions_proto_depIdxs, - EnumInfos: file_actions_proto_enumTypes, - MessageInfos: file_actions_proto_msgTypes, + GoTypes: file_actions_actions_proto_goTypes, + DependencyIndexes: file_actions_actions_proto_depIdxs, + EnumInfos: file_actions_actions_proto_enumTypes, + MessageInfos: file_actions_actions_proto_msgTypes, }.Build() - File_actions_proto = out.File - file_actions_proto_rawDesc = nil - file_actions_proto_goTypes = nil - file_actions_proto_depIdxs = nil + File_actions_actions_proto = out.File + file_actions_actions_proto_goTypes = nil + file_actions_actions_proto_depIdxs = nil } diff --git a/actions/actions.proto b/actions/actions.proto index 4e27527..da870cd 100644 --- a/actions/actions.proto +++ b/actions/actions.proto @@ -27,6 +27,7 @@ message ActionBatch { repeated Action actions = 2; int64 tick = 3; int32 protocol_version = 4; + int64 last_seen_message_timestamp = 5; } message PlayerState { diff --git a/goonserver b/goonserver new file mode 100755 index 0000000..7aa6b06 Binary files /dev/null and b/goonserver differ diff --git a/main.go b/main.go index 73678ff..dcbb4e8 100644 --- a/main.go +++ b/main.go @@ -24,9 +24,10 @@ const ( type Player struct { sync.Mutex - ID int - X, Y int - Username string + ID int + X, Y int + Username string + LastSeenMsgTimestamp int64 // Track the last message timestamp this player has seen } var ( @@ -82,7 +83,10 @@ func main() { } func handleConnection(conn net.Conn) { - defer conn.Close() + defer func() { + conn.Close() + log.Printf("Connection closed and cleanup complete") + }() // Get client IP remoteAddr := conn.RemoteAddr().String() @@ -188,29 +192,57 @@ func handleConnection(conn net.Conn) { return } - player := &Player{ - ID: playerID, - X: x, - Y: y, - Username: username, + log.Printf("Player %d (%s) authenticated successfully, checking for existing session", playerID, username) + + // Check for existing session and force disconnect if needed + mu.Lock() + existingPlayer, alreadyLoggedIn := players[playerID] + if alreadyLoggedIn { + log.Printf("Player %d (%s) is already logged in, forcing disconnect of old session", playerID, username) + // An existing session is found - clean it up + if oldConn, exists := playerConns[playerID]; exists { + // Try to close the old connection + oldConn.Close() + delete(playerConns, playerID) + } + // Keep the player object but update its connection + existingPlayer.X = x + existingPlayer.Y = y + playerConns[playerID] = conn + mu.Unlock() + } else { + // Create a new player + player := &Player{ + ID: playerID, + X: x, + Y: y, + Username: username, + LastSeenMsgTimestamp: 0, // Initialize to 0 to receive all messages initially + } + players[playerID] = player + playerConns[playerID] = conn + mu.Unlock() + existingPlayer = player + + // Announce connection + addSystemMessage(fmt.Sprintf("%s connected", username)) } - // Prevent multiple logins - mu.Lock() - for _, p := range players { - if p.Username == username { - mu.Unlock() - response := &pb.ServerMessage{ - AuthSuccess: false, - ErrorMessage: "Account already logged in", + // Ensure player state is saved on any kind of disconnect + defer func() { + if p, exists := players[playerID]; exists { + if err := db.SavePlayerState(playerID, p.X, p.Y); err != nil { + log.Printf("Error saving state for player %d: %v", playerID, err) } - writeMessage(conn, response) - return } - } - players[playerID] = player - playerConns[playerID] = conn - mu.Unlock() + addSystemMessage(fmt.Sprintf("%s disconnected", username)) + mu.Lock() + delete(players, playerID) + delete(playerConns, playerID) + delete(actionQueue, playerID) + mu.Unlock() + log.Printf("Player %d (%s) disconnected", playerID, username) + }() // Send initial state with correct position response = &pb.ServerMessage{ @@ -225,29 +257,13 @@ func handleConnection(conn net.Conn) { ProtocolVersion: protoVersion, } - addSystemMessage(fmt.Sprintf("%s connected", username)) - - // Ensure player state is saved on any kind of disconnect - defer func() { - if err := db.SavePlayerState(playerID, player.X, player.Y); err != nil { - log.Printf("Error saving state for player %d: %v", playerID, err) - } - addSystemMessage(fmt.Sprintf("%s disconnected", player.Username)) - mu.Lock() - delete(players, playerID) - delete(playerConns, playerID) - delete(actionQueue, playerID) - mu.Unlock() - log.Printf("Player %d disconnected", playerID) - }() - // Send player ID to client if err := writeMessage(conn, response); err != nil { log.Printf("Failed to send player ID: %v", err) return } - fmt.Printf("Player %d connected\n", playerID) + log.Printf("Player %d (%s) connected successfully", playerID, username) // Listen for incoming actions from this player for { @@ -276,6 +292,11 @@ func handleConnection(conn net.Conn) { continue } + // Update the last seen message timestamp + if batch.LastSeenMessageTimestamp > 0 { + existingPlayer.LastSeenMsgTimestamp = batch.LastSeenMessageTimestamp + } + // Queue the actions for processing if batch.PlayerId == int32(playerID) { for _, action := range batch.Actions { @@ -284,7 +305,9 @@ func handleConnection(conn net.Conn) { return } } + mu.Lock() actionQueue[playerID] = append(actionQueue[playerID], batch.Actions...) + mu.Unlock() } } } @@ -330,11 +353,30 @@ func addSystemMessage(content string) { func processActions() { mu.Lock() - defer mu.Unlock() + // Make a list of players to process first, to avoid lock contention + activePlayers := make(map[int]*Player) + for id, p := range players { + activePlayers[id] = p + } + activeConns := make(map[int]net.Conn) + for id, conn := range playerConns { + activeConns[id] = conn + } + activeQueues := make(map[int][]*pb.Action) + for id, actions := range actionQueue { + if len(actions) > 0 { + activeQueues[id] = actions + actionQueue[id] = nil // Clear the queue early to avoid double processing + } + } + mu.Unlock() - // Update players based on queued actions - for playerID, actions := range actionQueue { - player := players[playerID] + // Process actions without holding the global lock + for playerID, actions := range activeQueues { + player, exists := activePlayers[playerID] + if !exists { + continue + } player.Lock() for _, action := range actions { switch action.Type { @@ -348,20 +390,21 @@ func processActions() { } } player.Unlock() - actionQueue[playerID] = nil // Clear the action queue after processing } - // Prepare and broadcast the current game state + // Prepare current game state currentTick := time.Now().UnixNano() / int64(tickRate) - state := &pb.ServerMessage{ - CurrentTick: currentTick, - Players: make([]*pb.PlayerState, 0, len(players)), - } - // Convert players to PlayerState - for id, p := range players { + // Get recent messages for new connections + chatMutex.RLock() + recentMessages := chatHistory[max(0, len(chatHistory)-5):] // Get last 5 for new connections + chatMutex.RUnlock() + + // To avoid holding locks too long, prepare player states first + playerStates := make([]*pb.PlayerState, 0, len(activePlayers)) + for id, p := range activePlayers { p.Lock() - state.Players = append(state.Players, &pb.PlayerState{ + playerStates = append(playerStates, &pb.PlayerState{ PlayerId: int32(id), X: int32(p.X), Y: int32(p.Y), @@ -370,15 +413,69 @@ func processActions() { p.Unlock() } - // Add chat messages to the state - chatMutex.RLock() - state.ChatMessages = chatHistory[max(0, len(chatHistory)-5):] // Only send last 5 messages - chatMutex.RUnlock() + // Now send updates to each player + for playerID, conn := range activeConns { + player, exists := activePlayers[playerID] + if !exists { + continue + } - // Send to each connected player - for _, conn := range playerConns { + state := &pb.ServerMessage{ + CurrentTick: currentTick, + Players: playerStates, + } + + // Add chat messages - only send those the player hasn't seen + player.Lock() + lastSeen := player.LastSeenMsgTimestamp + player.Unlock() + + chatMutex.RLock() + var newMessages []*pb.ChatMessage + + // For new connections, send the 5 most recent messages + if lastSeen == 0 && len(recentMessages) > 0 { + newMessages = recentMessages + if len(newMessages) > 0 { + // Update the player's timestamp to the latest message + player.Lock() + player.LastSeenMsgTimestamp = newMessages[len(newMessages)-1].Timestamp + player.Unlock() + } + } else { + // For existing connections, only send new messages + for _, msg := range chatHistory { + if msg.Timestamp > lastSeen { + newMessages = append(newMessages, msg) + } + } + + // Update the player's timestamp if we sent them new messages + if len(newMessages) > 0 { + player.Lock() + player.LastSeenMsgTimestamp = newMessages[len(newMessages)-1].Timestamp + player.Unlock() + } + } + + state.ChatMessages = newMessages + chatMutex.RUnlock() + + // Log the number of messages we're sending + if len(newMessages) > 0 { + log.Printf("Sending %d new messages to player %d", len(newMessages), playerID) + } + + // Send the state to the player - do this without holding any locks if err := writeMessage(conn, state); err != nil { - log.Printf("Failed to send update: %v", err) + log.Printf("Failed to send update to player %d: %v", playerID, err) + + // Handle connection errors by removing the player + mu.Lock() + delete(players, playerID) + delete(playerConns, playerID) + delete(actionQueue, playerID) + mu.Unlock() } } }