From 7c4a3be31cf001c34ed105db15f7a1f5c126d6f6 Mon Sep 17 00:00:00 2001 From: ChillerDragon Date: Fri, 21 Jun 2024 09:38:59 +0800 Subject: [PATCH] Automatically compute chunk header size on pack --- messages7/cl_start_info.go | 11 ++++++ messages7/ctrl_accept.go | 8 +++++ messages7/ctrl_connect.go | 8 +++++ messages7/ctrl_keep_alive.go | 8 +++++ messages7/ctrl_token.go | 8 +++++ messages7/enter_game.go | 10 ++++++ messages7/info.go | 10 ++++++ messages7/net_message.go | 4 +++ messages7/ready.go | 10 ++++++ messages7/ready_to_enter.go | 10 ++++++ messages7/sv_chat.go | 11 ++++++ messages7/sv_client_info.go | 11 ++++++ protocol7/packet.go | 19 +++++----- protocol7/packet_test.go | 68 ++++++++++++++++++++++++++++++++++++ 14 files changed, 188 insertions(+), 8 deletions(-) diff --git a/messages7/cl_start_info.go b/messages7/cl_start_info.go index e4b4956..9a8e0db 100644 --- a/messages7/cl_start_info.go +++ b/messages7/cl_start_info.go @@ -3,11 +3,14 @@ package messages7 import ( "slices" + "github.com/teeworlds-go/teeworlds/chunk7" "github.com/teeworlds-go/teeworlds/network7" "github.com/teeworlds-go/teeworlds/packer" ) type ClStartInfo struct { + header *chunk7.ChunkHeader + Name string Clan string Country int @@ -96,3 +99,11 @@ func (info *ClStartInfo) Unpack(u *packer.Unpacker) { info.ColorFeet = u.GetInt() info.ColorEyes = u.GetInt() } + +func (msg *ClStartInfo) Header() *chunk7.ChunkHeader { + return msg.header +} + +func (msg *ClStartInfo) SetHeader(header *chunk7.ChunkHeader) { + msg.header = header +} diff --git a/messages7/ctrl_accept.go b/messages7/ctrl_accept.go index 8ce8253..7945159 100644 --- a/messages7/ctrl_accept.go +++ b/messages7/ctrl_accept.go @@ -3,6 +3,7 @@ package messages7 import ( "slices" + "github.com/teeworlds-go/teeworlds/chunk7" "github.com/teeworlds-go/teeworlds/network7" "github.com/teeworlds-go/teeworlds/packer" ) @@ -37,3 +38,10 @@ func (msg CtrlAccept) Pack() []byte { func (msg *CtrlAccept) Unpack(u *packer.Unpacker) { } + +func (msg *CtrlAccept) Header() *chunk7.ChunkHeader { + return nil +} + +func (msg *CtrlAccept) SetHeader(header *chunk7.ChunkHeader) { +} diff --git a/messages7/ctrl_connect.go b/messages7/ctrl_connect.go index f72cfe1..5b6bb55 100644 --- a/messages7/ctrl_connect.go +++ b/messages7/ctrl_connect.go @@ -3,6 +3,7 @@ package messages7 import ( "slices" + "github.com/teeworlds-go/teeworlds/chunk7" "github.com/teeworlds-go/teeworlds/network7" "github.com/teeworlds-go/teeworlds/packer" ) @@ -39,3 +40,10 @@ func (msg CtrlConnect) Pack() []byte { func (msg *CtrlConnect) Unpack(u *packer.Unpacker) { msg.Token = [4]byte(u.Data()) } + +func (msg *CtrlConnect) Header() *chunk7.ChunkHeader { + return nil +} + +func (msg *CtrlConnect) SetHeader(header *chunk7.ChunkHeader) { +} diff --git a/messages7/ctrl_keep_alive.go b/messages7/ctrl_keep_alive.go index 200ab8f..c48b78d 100644 --- a/messages7/ctrl_keep_alive.go +++ b/messages7/ctrl_keep_alive.go @@ -1,6 +1,7 @@ package messages7 import ( + "github.com/teeworlds-go/teeworlds/chunk7" "github.com/teeworlds-go/teeworlds/network7" "github.com/teeworlds-go/teeworlds/packer" ) @@ -30,3 +31,10 @@ func (msg CtrlKeepAlive) Pack() []byte { func (msg *CtrlKeepAlive) Unpack(u *packer.Unpacker) { } + +func (msg *CtrlKeepAlive) Header() *chunk7.ChunkHeader { + return nil +} + +func (msg *CtrlKeepAlive) SetHeader(header *chunk7.ChunkHeader) { +} diff --git a/messages7/ctrl_token.go b/messages7/ctrl_token.go index 570916d..b93e99e 100644 --- a/messages7/ctrl_token.go +++ b/messages7/ctrl_token.go @@ -6,6 +6,7 @@ package messages7 import ( "slices" + "github.com/teeworlds-go/teeworlds/chunk7" "github.com/teeworlds-go/teeworlds/network7" "github.com/teeworlds-go/teeworlds/packer" ) @@ -42,3 +43,10 @@ func (msg CtrlToken) Pack() []byte { func (msg *CtrlToken) Unpack(u *packer.Unpacker) { msg.Token = [4]byte(u.Data()) } + +func (msg *CtrlToken) Header() *chunk7.ChunkHeader { + return nil +} + +func (msg *CtrlToken) SetHeader(header *chunk7.ChunkHeader) { +} diff --git a/messages7/enter_game.go b/messages7/enter_game.go index d9a3240..84b3fb8 100644 --- a/messages7/enter_game.go +++ b/messages7/enter_game.go @@ -1,11 +1,13 @@ package messages7 import ( + "github.com/teeworlds-go/teeworlds/chunk7" "github.com/teeworlds-go/teeworlds/network7" "github.com/teeworlds-go/teeworlds/packer" ) type EnterGame struct { + header *chunk7.ChunkHeader } func (msg EnterGame) MsgId() int { @@ -30,3 +32,11 @@ func (msg EnterGame) Pack() []byte { func (msg *EnterGame) Unpack(u *packer.Unpacker) { } + +func (msg *EnterGame) Header() *chunk7.ChunkHeader { + return msg.header +} + +func (msg *EnterGame) SetHeader(header *chunk7.ChunkHeader) { + msg.header = header +} diff --git a/messages7/info.go b/messages7/info.go index 9784eb5..db51233 100644 --- a/messages7/info.go +++ b/messages7/info.go @@ -1,11 +1,13 @@ package messages7 import ( + "github.com/teeworlds-go/teeworlds/chunk7" "github.com/teeworlds-go/teeworlds/network7" "github.com/teeworlds-go/teeworlds/packer" ) type Info struct { + header *chunk7.ChunkHeader } func (msg Info) MsgId() int { @@ -37,3 +39,11 @@ func (msg *Info) Unpack(u *packer.Unpacker) { // TODO: implement panic("not implemented") } + +func (msg *Info) Header() *chunk7.ChunkHeader { + return msg.header +} + +func (msg *Info) SetHeader(header *chunk7.ChunkHeader) { + msg.header = header +} diff --git a/messages7/net_message.go b/messages7/net_message.go index 578ab12..0d26307 100644 --- a/messages7/net_message.go +++ b/messages7/net_message.go @@ -1,6 +1,7 @@ package messages7 import ( + "github.com/teeworlds-go/teeworlds/chunk7" "github.com/teeworlds-go/teeworlds/network7" "github.com/teeworlds-go/teeworlds/packer" ) @@ -12,4 +13,7 @@ type NetMessage interface { Vital() bool Pack() []byte Unpack(u *packer.Unpacker) + + Header() *chunk7.ChunkHeader + SetHeader(chunkHeader *chunk7.ChunkHeader) } diff --git a/messages7/ready.go b/messages7/ready.go index 1b452aa..d0e6916 100644 --- a/messages7/ready.go +++ b/messages7/ready.go @@ -1,11 +1,13 @@ package messages7 import ( + "github.com/teeworlds-go/teeworlds/chunk7" "github.com/teeworlds-go/teeworlds/network7" "github.com/teeworlds-go/teeworlds/packer" ) type Ready struct { + header *chunk7.ChunkHeader } func (msg Ready) MsgId() int { @@ -30,3 +32,11 @@ func (msg Ready) Pack() []byte { func (msg *Ready) Unpack(u *packer.Unpacker) { } + +func (msg *Ready) Header() *chunk7.ChunkHeader { + return msg.header +} + +func (msg *Ready) SetHeader(header *chunk7.ChunkHeader) { + msg.header = header +} diff --git a/messages7/ready_to_enter.go b/messages7/ready_to_enter.go index 4286e45..b1a7ccb 100644 --- a/messages7/ready_to_enter.go +++ b/messages7/ready_to_enter.go @@ -1,11 +1,13 @@ package messages7 import ( + "github.com/teeworlds-go/teeworlds/chunk7" "github.com/teeworlds-go/teeworlds/network7" "github.com/teeworlds-go/teeworlds/packer" ) type ReadyToEnter struct { + header *chunk7.ChunkHeader } func (msg ReadyToEnter) MsgId() int { @@ -30,3 +32,11 @@ func (msg ReadyToEnter) Pack() []byte { func (msg *ReadyToEnter) Unpack(u *packer.Unpacker) { } + +func (msg *ReadyToEnter) Header() *chunk7.ChunkHeader { + return msg.header +} + +func (msg *ReadyToEnter) SetHeader(header *chunk7.ChunkHeader) { + msg.header = header +} diff --git a/messages7/sv_chat.go b/messages7/sv_chat.go index dd2e7f4..66a1bb7 100644 --- a/messages7/sv_chat.go +++ b/messages7/sv_chat.go @@ -3,11 +3,14 @@ package messages7 import ( "slices" + "github.com/teeworlds-go/teeworlds/chunk7" "github.com/teeworlds-go/teeworlds/network7" "github.com/teeworlds-go/teeworlds/packer" ) type SvChat struct { + header *chunk7.ChunkHeader + Mode int ClientId int TargetId int @@ -45,3 +48,11 @@ func (msg *SvChat) Unpack(u *packer.Unpacker) { msg.TargetId = u.GetInt() msg.Message = u.GetString() } + +func (msg *SvChat) Header() *chunk7.ChunkHeader { + return msg.header +} + +func (msg *SvChat) SetHeader(header *chunk7.ChunkHeader) { + msg.header = header +} diff --git a/messages7/sv_client_info.go b/messages7/sv_client_info.go index d99a919..4bc754c 100644 --- a/messages7/sv_client_info.go +++ b/messages7/sv_client_info.go @@ -1,11 +1,14 @@ package messages7 import ( + "github.com/teeworlds-go/teeworlds/chunk7" "github.com/teeworlds-go/teeworlds/network7" "github.com/teeworlds-go/teeworlds/packer" ) type SvClientInfo struct { + header *chunk7.ChunkHeader + ClientId int Local bool Team int @@ -74,3 +77,11 @@ func (info *SvClientInfo) Unpack(u *packer.Unpacker) { info.ColorEyes = u.GetInt() info.Silent = u.GetInt() != 0 } + +func (msg *SvClientInfo) Header() *chunk7.ChunkHeader { + return msg.header +} + +func (msg *SvClientInfo) SetHeader(header *chunk7.ChunkHeader) { + msg.header = header +} diff --git a/protocol7/packet.go b/protocol7/packet.go index a710370..b35cda1 100644 --- a/protocol7/packet.go +++ b/protocol7/packet.go @@ -55,17 +55,20 @@ func PackChunk(msg messages7.NetMessage, connection *Connection) []byte { msgAndSys := packer.PackInt(msgId) payload := msg.Pack() - // TODO: support resend - chunkHeader := chunk7.ChunkHeader{ - Flags: chunk7.ChunkFlags{ - Vital: msg.Vital(), - }, - Size: len(msgAndSys) + len(payload), - Seq: connection.Sequence, + if msg.Header() == nil { + header := &chunk7.ChunkHeader{ + Flags: chunk7.ChunkFlags{ + Vital: msg.Vital(), + }, + Seq: connection.Sequence, + } + msg.SetHeader(header) } + msg.Header().Size = len(msgAndSys) + len(payload) + data := slices.Concat( - chunkHeader.Pack(), + msg.Header().Pack(), msgAndSys, payload, ) diff --git a/protocol7/packet_test.go b/protocol7/packet_test.go index e6732e4..76979dc 100644 --- a/protocol7/packet_test.go +++ b/protocol7/packet_test.go @@ -4,8 +4,76 @@ import ( "reflect" "slices" "testing" + + "github.com/teeworlds-go/teeworlds/chunk7" + "github.com/teeworlds-go/teeworlds/messages7" ) +// update chunk headers + +func TestPackUpdateChunkHeaders(t *testing.T) { + // The chunk header is nil by default + packet := Packet{} + packet.Messages = append(packet.Messages, &messages7.SvChat{Message: "foo"}) + + { + got := packet.Messages[0].Header() + + if got != nil { + t.Errorf("got %v, wanted %v", got, nil) + } + } + + // When packing the chunk header will be set automatically + // Based on the current context + conn := &Connection{Sequence: 1} + packet.Pack(conn) + + { + got := packet.Messages[0].Header() + want := &chunk7.ChunkHeader{ + Flags: chunk7.ChunkFlags{ + Vital: true, + }, + Size: 8, + Seq: 2, + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("got %v, wanted %v", got, want) + } + } + + // When the chunk header is already set + // Packing will only update the size + + var chat *messages7.SvChat + var ok bool + if chat, ok = packet.Messages[0].(*messages7.SvChat); ok { + chat.Message = "hello world" + packet.Messages[0] = chat + } else { + t.Fatal("failed to cast chat message") + } + + packet.Pack(conn) + + { + got := packet.Messages[0].Header() + want := &chunk7.ChunkHeader{ + Flags: chunk7.ChunkFlags{ + Vital: true, + }, + Size: 16, + Seq: 2, + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("got %v, wanted %v", got, want) + } + } +} + // pack header func TestPackHeader(t *testing.T) {