Compare commits
No commits in common. "master" and "v1.1.1" have entirely different histories.
@ -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 {
|
||||||
@ -169,19 +168,18 @@ func (x *Action) GetPassword() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ActionBatch struct {
|
type ActionBatch 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"`
|
||||||
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
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
BIN
goonserver
BIN
goonserver
Binary file not shown.
217
main.go
217
main.go
@ -24,10 +24,9 @@ const (
|
|||||||
|
|
||||||
type Player struct {
|
type Player struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
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)
|
player := &Player{
|
||||||
|
ID: playerID,
|
||||||
// Check for existing session and force disconnect if needed
|
X: x,
|
||||||
mu.Lock()
|
Y: y,
|
||||||
existingPlayer, alreadyLoggedIn := players[playerID]
|
Username: username,
|
||||||
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))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure player state is saved on any kind of disconnect
|
// Prevent multiple logins
|
||||||
defer func() {
|
mu.Lock()
|
||||||
if p, exists := players[playerID]; exists {
|
for _, p := range players {
|
||||||
if err := db.SavePlayerState(playerID, p.X, p.Y); err != nil {
|
if p.Username == username {
|
||||||
log.Printf("Error saving state for player %d: %v", playerID, err)
|
mu.Unlock()
|
||||||
|
response := &pb.ServerMessage{
|
||||||
|
AuthSuccess: false,
|
||||||
|
ErrorMessage: "Account already logged in",
|
||||||
}
|
}
|
||||||
|
writeMessage(conn, response)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
addSystemMessage(fmt.Sprintf("%s disconnected", username))
|
}
|
||||||
mu.Lock()
|
players[playerID] = player
|
||||||
delete(players, playerID)
|
playerConns[playerID] = conn
|
||||||
delete(playerConns, playerID)
|
mu.Unlock()
|
||||||
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 {
|
chatMutex.RLock()
|
||||||
player, exists := activePlayers[playerID]
|
state.ChatMessages = chatHistory[max(0, len(chatHistory)-5):] // Only send last 5 messages
|
||||||
if !exists {
|
chatMutex.RUnlock()
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
state := &pb.ServerMessage{
|
// Send to each connected player
|
||||||
CurrentTick: currentTick,
|
for _, conn := range playerConns {
|
||||||
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 {
|
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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user