Compare commits

..

No commits in common. "master" and "v1.1.1" have entirely different histories.

4 changed files with 184 additions and 265 deletions

View File

@ -1,8 +1,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.36.6 // protoc-gen-go v1.36.3
// protoc v6.30.1 // protoc v5.29.2
// source: actions/actions.proto // source: actions.proto
package actions package actions
@ -11,7 +11,6 @@ import (
protoimpl "google.golang.org/protobuf/runtime/protoimpl" protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect" reflect "reflect"
sync "sync" sync "sync"
unsafe "unsafe"
) )
const ( const (
@ -60,11 +59,11 @@ func (x Action_ActionType) String() string {
} }
func (Action_ActionType) Descriptor() protoreflect.EnumDescriptor { func (Action_ActionType) Descriptor() protoreflect.EnumDescriptor {
return file_actions_actions_proto_enumTypes[0].Descriptor() return file_actions_proto_enumTypes[0].Descriptor()
} }
func (Action_ActionType) Type() protoreflect.EnumType { func (Action_ActionType) Type() protoreflect.EnumType {
return &file_actions_actions_proto_enumTypes[0] return &file_actions_proto_enumTypes[0]
} }
func (x Action_ActionType) Number() protoreflect.EnumNumber { func (x Action_ActionType) Number() protoreflect.EnumNumber {
@ -73,7 +72,7 @@ func (x Action_ActionType) Number() protoreflect.EnumNumber {
// Deprecated: Use Action_ActionType.Descriptor instead. // Deprecated: Use Action_ActionType.Descriptor instead.
func (Action_ActionType) EnumDescriptor() ([]byte, []int) { func (Action_ActionType) EnumDescriptor() ([]byte, []int) {
return file_actions_actions_proto_rawDescGZIP(), []int{0, 0} return file_actions_proto_rawDescGZIP(), []int{0, 0}
} }
type Action struct { type Action struct {
@ -91,7 +90,7 @@ type Action struct {
func (x *Action) Reset() { func (x *Action) Reset() {
*x = Action{} *x = Action{}
mi := &file_actions_actions_proto_msgTypes[0] mi := &file_actions_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -103,7 +102,7 @@ func (x *Action) String() string {
func (*Action) ProtoMessage() {} func (*Action) ProtoMessage() {}
func (x *Action) ProtoReflect() protoreflect.Message { func (x *Action) ProtoReflect() protoreflect.Message {
mi := &file_actions_actions_proto_msgTypes[0] mi := &file_actions_proto_msgTypes[0]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -116,7 +115,7 @@ func (x *Action) ProtoReflect() protoreflect.Message {
// Deprecated: Use Action.ProtoReflect.Descriptor instead. // Deprecated: Use Action.ProtoReflect.Descriptor instead.
func (*Action) Descriptor() ([]byte, []int) { func (*Action) Descriptor() ([]byte, []int) {
return file_actions_actions_proto_rawDescGZIP(), []int{0} return file_actions_proto_rawDescGZIP(), []int{0}
} }
func (x *Action) GetType() Action_ActionType { func (x *Action) GetType() Action_ActionType {
@ -174,14 +173,13 @@ type ActionBatch struct {
Actions []*Action `protobuf:"bytes,2,rep,name=actions,proto3" json:"actions,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"` 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"` 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 unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
} }
func (x *ActionBatch) Reset() { func (x *ActionBatch) Reset() {
*x = ActionBatch{} *x = ActionBatch{}
mi := &file_actions_actions_proto_msgTypes[1] mi := &file_actions_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -193,7 +191,7 @@ func (x *ActionBatch) String() string {
func (*ActionBatch) ProtoMessage() {} func (*ActionBatch) ProtoMessage() {}
func (x *ActionBatch) ProtoReflect() protoreflect.Message { func (x *ActionBatch) ProtoReflect() protoreflect.Message {
mi := &file_actions_actions_proto_msgTypes[1] mi := &file_actions_proto_msgTypes[1]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -206,7 +204,7 @@ func (x *ActionBatch) ProtoReflect() protoreflect.Message {
// Deprecated: Use ActionBatch.ProtoReflect.Descriptor instead. // Deprecated: Use ActionBatch.ProtoReflect.Descriptor instead.
func (*ActionBatch) Descriptor() ([]byte, []int) { func (*ActionBatch) Descriptor() ([]byte, []int) {
return file_actions_actions_proto_rawDescGZIP(), []int{1} return file_actions_proto_rawDescGZIP(), []int{1}
} }
func (x *ActionBatch) GetPlayerId() int32 { func (x *ActionBatch) GetPlayerId() int32 {
@ -237,13 +235,6 @@ func (x *ActionBatch) GetProtocolVersion() int32 {
return 0 return 0
} }
func (x *ActionBatch) GetLastSeenMessageTimestamp() int64 {
if x != nil {
return x.LastSeenMessageTimestamp
}
return 0
}
type PlayerState struct { type PlayerState struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
PlayerId int32 `protobuf:"varint,1,opt,name=player_id,json=playerId,proto3" json:"player_id,omitempty"` PlayerId int32 `protobuf:"varint,1,opt,name=player_id,json=playerId,proto3" json:"player_id,omitempty"`
@ -256,7 +247,7 @@ type PlayerState struct {
func (x *PlayerState) Reset() { func (x *PlayerState) Reset() {
*x = PlayerState{} *x = PlayerState{}
mi := &file_actions_actions_proto_msgTypes[2] mi := &file_actions_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -268,7 +259,7 @@ func (x *PlayerState) String() string {
func (*PlayerState) ProtoMessage() {} func (*PlayerState) ProtoMessage() {}
func (x *PlayerState) ProtoReflect() protoreflect.Message { func (x *PlayerState) ProtoReflect() protoreflect.Message {
mi := &file_actions_actions_proto_msgTypes[2] mi := &file_actions_proto_msgTypes[2]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -281,7 +272,7 @@ func (x *PlayerState) ProtoReflect() protoreflect.Message {
// Deprecated: Use PlayerState.ProtoReflect.Descriptor instead. // Deprecated: Use PlayerState.ProtoReflect.Descriptor instead.
func (*PlayerState) Descriptor() ([]byte, []int) { func (*PlayerState) Descriptor() ([]byte, []int) {
return file_actions_actions_proto_rawDescGZIP(), []int{2} return file_actions_proto_rawDescGZIP(), []int{2}
} }
func (x *PlayerState) GetPlayerId() int32 { func (x *PlayerState) GetPlayerId() int32 {
@ -324,7 +315,7 @@ type ChatMessage struct {
func (x *ChatMessage) Reset() { func (x *ChatMessage) Reset() {
*x = ChatMessage{} *x = ChatMessage{}
mi := &file_actions_actions_proto_msgTypes[3] mi := &file_actions_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -336,7 +327,7 @@ func (x *ChatMessage) String() string {
func (*ChatMessage) ProtoMessage() {} func (*ChatMessage) ProtoMessage() {}
func (x *ChatMessage) ProtoReflect() protoreflect.Message { func (x *ChatMessage) ProtoReflect() protoreflect.Message {
mi := &file_actions_actions_proto_msgTypes[3] mi := &file_actions_proto_msgTypes[3]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -349,7 +340,7 @@ func (x *ChatMessage) ProtoReflect() protoreflect.Message {
// Deprecated: Use ChatMessage.ProtoReflect.Descriptor instead. // Deprecated: Use ChatMessage.ProtoReflect.Descriptor instead.
func (*ChatMessage) Descriptor() ([]byte, []int) { func (*ChatMessage) Descriptor() ([]byte, []int) {
return file_actions_actions_proto_rawDescGZIP(), []int{3} return file_actions_proto_rawDescGZIP(), []int{3}
} }
func (x *ChatMessage) GetPlayerId() int32 { func (x *ChatMessage) GetPlayerId() int32 {
@ -395,7 +386,7 @@ type ServerMessage struct {
func (x *ServerMessage) Reset() { func (x *ServerMessage) Reset() {
*x = ServerMessage{} *x = ServerMessage{}
mi := &file_actions_actions_proto_msgTypes[4] mi := &file_actions_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -407,7 +398,7 @@ func (x *ServerMessage) String() string {
func (*ServerMessage) ProtoMessage() {} func (*ServerMessage) ProtoMessage() {}
func (x *ServerMessage) ProtoReflect() protoreflect.Message { func (x *ServerMessage) ProtoReflect() protoreflect.Message {
mi := &file_actions_actions_proto_msgTypes[4] mi := &file_actions_proto_msgTypes[4]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -420,7 +411,7 @@ func (x *ServerMessage) ProtoReflect() protoreflect.Message {
// Deprecated: Use ServerMessage.ProtoReflect.Descriptor instead. // Deprecated: Use ServerMessage.ProtoReflect.Descriptor instead.
func (*ServerMessage) Descriptor() ([]byte, []int) { func (*ServerMessage) Descriptor() ([]byte, []int) {
return file_actions_actions_proto_rawDescGZIP(), []int{4} return file_actions_proto_rawDescGZIP(), []int{4}
} }
func (x *ServerMessage) GetPlayerId() int32 { func (x *ServerMessage) GetPlayerId() int32 {
@ -472,67 +463,92 @@ func (x *ServerMessage) GetProtocolVersion() int32 {
return 0 return 0
} }
var File_actions_actions_proto protoreflect.FileDescriptor var File_actions_proto protoreflect.FileDescriptor
const file_actions_actions_proto_rawDesc = "" + var file_actions_proto_rawDesc = []byte{
"\n" + 0x0a, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
"\x15actions/actions.proto\x12\aactions\"\x97\x02\n" + 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x97, 0x02, 0x0a, 0x06, 0x41, 0x63, 0x74,
"\x06Action\x12.\n" + 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
"\x04type\x18\x01 \x01(\x0e2\x1a.actions.Action.ActionTypeR\x04type\x12\f\n" + 0x0e, 0x32, 0x1a, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x41, 0x63, 0x74, 0x69,
"\x01x\x18\x02 \x01(\x05R\x01x\x12\f\n" + 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74,
"\x01y\x18\x03 \x01(\x05R\x01y\x12\x1b\n" + 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x01, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01,
"\tplayer_id\x18\x04 \x01(\x05R\bplayerId\x12!\n" + 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x79, 0x12,
"\fchat_message\x18\x05 \x01(\tR\vchatMessage\x12\x1a\n" + 0x1b, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01,
"\busername\x18\x06 \x01(\tR\busername\x12\x1a\n" + 0x28, 0x05, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c,
"\bpassword\x18\a \x01(\tR\bpassword\"I\n" + 0x63, 0x68, 0x61, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01,
"\n" + 0x28, 0x09, 0x52, 0x0b, 0x63, 0x68, 0x61, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
"ActionType\x12\b\n" + 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28,
"\x04MOVE\x10\x00\x12\b\n" + 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70,
"\x04CHAT\x10\x01\x12\x0e\n" + 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70,
"\n" + 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x49, 0x0a, 0x0a, 0x41, 0x63, 0x74, 0x69, 0x6f,
"DISCONNECT\x10\x02\x12\t\n" + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x4f, 0x56, 0x45, 0x10, 0x00, 0x12,
"\x05LOGIN\x10\x03\x12\f\n" + 0x08, 0x0a, 0x04, 0x43, 0x48, 0x41, 0x54, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x49, 0x53,
"\bREGISTER\x10\x04\"\xd3\x01\n" + 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x4c, 0x4f, 0x47,
"\vActionBatch\x12\x1b\n" + 0x49, 0x4e, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52,
"\tplayer_id\x18\x01 \x01(\x05R\bplayerId\x12)\n" + 0x10, 0x04, 0x22, 0x94, 0x01, 0x0a, 0x0b, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, 0x74,
"\aactions\x18\x02 \x03(\v2\x0f.actions.ActionR\aactions\x12\x12\n" + 0x63, 0x68, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18,
"\x04tick\x18\x03 \x01(\x03R\x04tick\x12)\n" + 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12,
"\x10protocol_version\x18\x04 \x01(\x05R\x0fprotocolVersion\x12=\n" + 0x29, 0x0a, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
"\x1blast_seen_message_timestamp\x18\x05 \x01(\x03R\x18lastSeenMessageTimestamp\"b\n" + 0x32, 0x0f, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f,
"\vPlayerState\x12\x1b\n" + 0x6e, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69,
"\tplayer_id\x18\x01 \x01(\x05R\bplayerId\x12\f\n" + 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x63, 0x6b, 0x12, 0x29,
"\x01x\x18\x02 \x01(\x05R\x01x\x12\f\n" + 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69,
"\x01y\x18\x03 \x01(\x05R\x01y\x12\x1a\n" + 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63,
"\busername\x18\x04 \x01(\tR\busername\"~\n" + 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x62, 0x0a, 0x0b, 0x50, 0x6c, 0x61,
"\vChatMessage\x12\x1b\n" + 0x79, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79,
"\tplayer_id\x18\x01 \x01(\x05R\bplayerId\x12\x1a\n" + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x6c, 0x61,
"\busername\x18\x02 \x01(\tR\busername\x12\x18\n" + 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x0c, 0x0a, 0x01, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
"\acontent\x18\x03 \x01(\tR\acontent\x12\x1c\n" + 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01,
"\ttimestamp\x18\x04 \x01(\x03R\ttimestamp\"\xad\x02\n" + 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20,
"\rServerMessage\x12\x1b\n" + 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x7e, 0x0a,
"\tplayer_id\x18\x01 \x01(\x05R\bplayerId\x12.\n" + 0x0b, 0x43, 0x68, 0x61, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09,
"\aplayers\x18\x02 \x03(\v2\x14.actions.PlayerStateR\aplayers\x12!\n" + 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
"\fcurrent_tick\x18\x03 \x01(\x03R\vcurrentTick\x129\n" + 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65,
"\rchat_messages\x18\x04 \x03(\v2\x14.actions.ChatMessageR\fchatMessages\x12!\n" + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65,
"\fauth_success\x18\x05 \x01(\bR\vauthSuccess\x12#\n" + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
"\rerror_message\x18\x06 \x01(\tR\ferrorMessage\x12)\n" + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12,
"\x10protocol_version\x18\a \x01(\x05R\x0fprotocolVersionB,Z*gitea.boner.be/bdnugget/goonserver/actionsb\x06proto3" 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,
var ( 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
file_actions_actions_proto_rawDescOnce sync.Once 0x1b, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
file_actions_actions_proto_rawDescData []byte 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,
func file_actions_actions_proto_rawDescGZIP() []byte { 0x61, 0x74, 0x65, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x12, 0x21, 0x0a, 0x0c,
file_actions_actions_proto_rawDescOnce.Do(func() { 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01,
file_actions_actions_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_actions_actions_proto_rawDesc), len(file_actions_actions_proto_rawDesc))) 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,
return file_actions_actions_proto_rawDescData 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,
} }
var file_actions_actions_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var (
var file_actions_actions_proto_msgTypes = make([]protoimpl.MessageInfo, 5) file_actions_proto_rawDescOnce sync.Once
var file_actions_actions_proto_goTypes = []any{ file_actions_proto_rawDescData = file_actions_proto_rawDesc
)
func file_actions_proto_rawDescGZIP() []byte {
file_actions_proto_rawDescOnce.Do(func() {
file_actions_proto_rawDescData = protoimpl.X.CompressGZIP(file_actions_proto_rawDescData)
})
return file_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{
(Action_ActionType)(0), // 0: actions.Action.ActionType (Action_ActionType)(0), // 0: actions.Action.ActionType
(*Action)(nil), // 1: actions.Action (*Action)(nil), // 1: actions.Action
(*ActionBatch)(nil), // 2: actions.ActionBatch (*ActionBatch)(nil), // 2: actions.ActionBatch
@ -540,7 +556,7 @@ var file_actions_actions_proto_goTypes = []any{
(*ChatMessage)(nil), // 4: actions.ChatMessage (*ChatMessage)(nil), // 4: actions.ChatMessage
(*ServerMessage)(nil), // 5: actions.ServerMessage (*ServerMessage)(nil), // 5: actions.ServerMessage
} }
var file_actions_actions_proto_depIdxs = []int32{ var file_actions_proto_depIdxs = []int32{
0, // 0: actions.Action.type:type_name -> actions.Action.ActionType 0, // 0: actions.Action.type:type_name -> actions.Action.ActionType
1, // 1: actions.ActionBatch.actions:type_name -> actions.Action 1, // 1: actions.ActionBatch.actions:type_name -> actions.Action
3, // 2: actions.ServerMessage.players:type_name -> actions.PlayerState 3, // 2: actions.ServerMessage.players:type_name -> actions.PlayerState
@ -552,27 +568,28 @@ var file_actions_actions_proto_depIdxs = []int32{
0, // [0:4] is the sub-list for field type_name 0, // [0:4] is the sub-list for field type_name
} }
func init() { file_actions_actions_proto_init() } func init() { file_actions_proto_init() }
func file_actions_actions_proto_init() { func file_actions_proto_init() {
if File_actions_actions_proto != nil { if File_actions_proto != nil {
return return
} }
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_actions_actions_proto_rawDesc), len(file_actions_actions_proto_rawDesc)), RawDescriptor: file_actions_proto_rawDesc,
NumEnums: 1, NumEnums: 1,
NumMessages: 5, NumMessages: 5,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },
GoTypes: file_actions_actions_proto_goTypes, GoTypes: file_actions_proto_goTypes,
DependencyIndexes: file_actions_actions_proto_depIdxs, DependencyIndexes: file_actions_proto_depIdxs,
EnumInfos: file_actions_actions_proto_enumTypes, EnumInfos: file_actions_proto_enumTypes,
MessageInfos: file_actions_actions_proto_msgTypes, MessageInfos: file_actions_proto_msgTypes,
}.Build() }.Build()
File_actions_actions_proto = out.File File_actions_proto = out.File
file_actions_actions_proto_goTypes = nil file_actions_proto_rawDesc = nil
file_actions_actions_proto_depIdxs = nil file_actions_proto_goTypes = nil
file_actions_proto_depIdxs = nil
} }

View File

@ -27,7 +27,6 @@ message ActionBatch {
repeated Action actions = 2; repeated Action actions = 2;
int64 tick = 3; int64 tick = 3;
int32 protocol_version = 4; int32 protocol_version = 4;
int64 last_seen_message_timestamp = 5;
} }
message PlayerState { message PlayerState {

Binary file not shown.

197
main.go
View File

@ -27,7 +27,6 @@ type Player struct {
ID int ID int
X, Y int X, Y int
Username string Username string
LastSeenMsgTimestamp int64 // Track the last message timestamp this player has seen
} }
var ( var (
@ -83,10 +82,7 @@ func main() {
} }
func handleConnection(conn net.Conn) { func handleConnection(conn net.Conn) {
defer func() { defer conn.Close()
conn.Close()
log.Printf("Connection closed and cleanup complete")
}()
// Get client IP // Get client IP
remoteAddr := conn.RemoteAddr().String() remoteAddr := conn.RemoteAddr().String()
@ -192,57 +188,29 @@ func handleConnection(conn net.Conn) {
return return
} }
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{ player := &Player{
ID: playerID, ID: playerID,
X: x, X: x,
Y: y, Y: y,
Username: username, Username: username,
LastSeenMsgTimestamp: 0, // Initialize to 0 to receive all messages initially }
// 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",
}
writeMessage(conn, response)
return
}
} }
players[playerID] = player players[playerID] = player
playerConns[playerID] = conn playerConns[playerID] = conn
mu.Unlock() mu.Unlock()
existingPlayer = player
// Announce connection
addSystemMessage(fmt.Sprintf("%s connected", username))
}
// 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)
}
}
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 // Send initial state with correct position
response = &pb.ServerMessage{ response = &pb.ServerMessage{
@ -257,13 +225,29 @@ func handleConnection(conn net.Conn) {
ProtocolVersion: protoVersion, 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 // Send player ID to client
if err := writeMessage(conn, response); err != nil { if err := writeMessage(conn, response); err != nil {
log.Printf("Failed to send player ID: %v", err) log.Printf("Failed to send player ID: %v", err)
return return
} }
log.Printf("Player %d (%s) connected successfully", playerID, username) fmt.Printf("Player %d connected\n", playerID)
// Listen for incoming actions from this player // Listen for incoming actions from this player
for { for {
@ -292,11 +276,6 @@ func handleConnection(conn net.Conn) {
continue continue
} }
// Update the last seen message timestamp
if batch.LastSeenMessageTimestamp > 0 {
existingPlayer.LastSeenMsgTimestamp = batch.LastSeenMessageTimestamp
}
// Queue the actions for processing // Queue the actions for processing
if batch.PlayerId == int32(playerID) { if batch.PlayerId == int32(playerID) {
for _, action := range batch.Actions { for _, action := range batch.Actions {
@ -305,9 +284,7 @@ func handleConnection(conn net.Conn) {
return return
} }
} }
mu.Lock()
actionQueue[playerID] = append(actionQueue[playerID], batch.Actions...) actionQueue[playerID] = append(actionQueue[playerID], batch.Actions...)
mu.Unlock()
} }
} }
} }
@ -353,30 +330,11 @@ func addSystemMessage(content string) {
func processActions() { func processActions() {
mu.Lock() mu.Lock()
// Make a list of players to process first, to avoid lock contention defer mu.Unlock()
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()
// Process actions without holding the global lock // Update players based on queued actions
for playerID, actions := range activeQueues { for playerID, actions := range actionQueue {
player, exists := activePlayers[playerID] player := players[playerID]
if !exists {
continue
}
player.Lock() player.Lock()
for _, action := range actions { for _, action := range actions {
switch action.Type { switch action.Type {
@ -390,21 +348,20 @@ func processActions() {
} }
} }
player.Unlock() player.Unlock()
actionQueue[playerID] = nil // Clear the action queue after processing
} }
// Prepare current game state // Prepare and broadcast the current game state
currentTick := time.Now().UnixNano() / int64(tickRate) currentTick := time.Now().UnixNano() / int64(tickRate)
state := &pb.ServerMessage{
CurrentTick: currentTick,
Players: make([]*pb.PlayerState, 0, len(players)),
}
// Get recent messages for new connections // Convert players to PlayerState
chatMutex.RLock() for id, p := range players {
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() p.Lock()
playerStates = append(playerStates, &pb.PlayerState{ state.Players = append(state.Players, &pb.PlayerState{
PlayerId: int32(id), PlayerId: int32(id),
X: int32(p.X), X: int32(p.X),
Y: int32(p.Y), Y: int32(p.Y),
@ -413,69 +370,15 @@ func processActions() {
p.Unlock() p.Unlock()
} }
// Now send updates to each player // Add chat messages to the state
for playerID, conn := range activeConns {
player, exists := activePlayers[playerID]
if !exists {
continue
}
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() chatMutex.RLock()
var newMessages []*pb.ChatMessage state.ChatMessages = chatHistory[max(0, len(chatHistory)-5):] // Only send last 5 messages
// 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() chatMutex.RUnlock()
// Log the number of messages we're sending // Send to each connected player
if len(newMessages) > 0 { for _, conn := range playerConns {
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 { if err := writeMessage(conn, state); err != nil {
log.Printf("Failed to send update to player %d: %v", playerID, err) log.Printf("Failed to send update: %v", err)
// Handle connection errors by removing the player
mu.Lock()
delete(players, playerID)
delete(playerConns, playerID)
delete(actionQueue, playerID)
mu.Unlock()
} }
} }
} }