Merge pull request #3 from jxsl13/chore/cleanup-error-handling

cleanup code, add test utilities, add error return values
This commit is contained in:
Chiller Dragon 2024-06-24 08:12:44 +08:00 committed by GitHub
commit 98c01516e5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
55 changed files with 725 additions and 784 deletions

View file

@ -18,7 +18,7 @@ func UnpackChunks(data []byte) []Chunk {
}
end := i + chunk.Header.Size
chunk.Data = make([]byte, end-i)
copy(chunk.Data[:], data[i:end])
copy(chunk.Data, data[i:end])
i += chunk.Header.Size
chunks = append(chunks, chunk)
}

2
go.mod
View file

@ -2,4 +2,4 @@ module github.com/teeworlds-go/go-teeworlds-protocol
go 1.22.3
require github.com/teeworlds-go/huffman v1.0.0 // indirect
require github.com/teeworlds-go/huffman v1.0.0

View file

@ -0,0 +1,53 @@
package require
import (
"reflect"
"testing"
)
func New(t *testing.T) *Require {
return &Require{
t: t,
}
}
type Require struct {
t *testing.T
}
func (r *Require) Equal(expected any, actual any) {
r.t.Helper()
Equal(r.t, expected, actual)
}
func (r *Require) NoError(err error) {
r.t.Helper()
NoError(r.t, err)
}
func (r *Require) NotNil(a any) {
r.t.Helper()
NotNil(r.t, a)
}
func Equal(t *testing.T, expected any, actual any) {
t.Helper()
if !reflect.DeepEqual(expected, actual) {
t.Fatalf("expected: %v, got: %v", expected, actual)
}
}
func NoError(t *testing.T, err error) {
t.Helper()
if err != nil {
t.Fatalf("expected no error, got: %v", err)
}
}
func NotNil(t *testing.T, a any) {
t.Helper()
if a != nil {
return
}
t.Fatalf("expected not nil, got: %v", a)
}

View file

@ -0,0 +1 @@
package testutils

View file

@ -11,27 +11,28 @@ type AuthChallenge struct {
ChunkHeader *chunk7.ChunkHeader
}
func (msg AuthChallenge) MsgId() int {
func (msg *AuthChallenge) MsgId() int {
return network7.MsgSysAuthChallenge
}
func (msg AuthChallenge) MsgType() network7.MsgType {
func (msg *AuthChallenge) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg AuthChallenge) System() bool {
func (msg *AuthChallenge) System() bool {
return true
}
func (msg AuthChallenge) Vital() bool {
func (msg *AuthChallenge) Vital() bool {
return true
}
func (msg AuthChallenge) Pack() []byte {
func (msg *AuthChallenge) Pack() []byte {
return []byte{}
}
func (msg *AuthChallenge) Unpack(u *packer.Unpacker) {
func (msg *AuthChallenge) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *AuthChallenge) Header() *chunk7.ChunkHeader {

View file

@ -11,27 +11,28 @@ type AuthResponse struct {
ChunkHeader *chunk7.ChunkHeader
}
func (msg AuthResponse) MsgId() int {
func (msg *AuthResponse) MsgId() int {
return network7.MsgSysAuthResponse
}
func (msg AuthResponse) MsgType() network7.MsgType {
func (msg *AuthResponse) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg AuthResponse) System() bool {
func (msg *AuthResponse) System() bool {
return true
}
func (msg AuthResponse) Vital() bool {
func (msg *AuthResponse) Vital() bool {
return true
}
func (msg AuthResponse) Pack() []byte {
func (msg *AuthResponse) Pack() []byte {
return []byte{}
}
func (msg *AuthResponse) Unpack(u *packer.Unpacker) {
func (msg *AuthResponse) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *AuthResponse) Header() *chunk7.ChunkHeader {

View file

@ -11,27 +11,28 @@ type AuthResult struct {
ChunkHeader *chunk7.ChunkHeader
}
func (msg AuthResult) MsgId() int {
func (msg *AuthResult) MsgId() int {
return network7.MsgSysAuthResult
}
func (msg AuthResult) MsgType() network7.MsgType {
func (msg *AuthResult) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg AuthResult) System() bool {
func (msg *AuthResult) System() bool {
return true
}
func (msg AuthResult) Vital() bool {
func (msg *AuthResult) Vital() bool {
return true
}
func (msg AuthResult) Pack() []byte {
func (msg *AuthResult) Pack() []byte {
return []byte{}
}
func (msg *AuthResult) Unpack(u *packer.Unpacker) {
func (msg *AuthResult) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *AuthResult) Header() *chunk7.ChunkHeader {

View file

@ -11,27 +11,28 @@ type AuthStart struct {
ChunkHeader *chunk7.ChunkHeader
}
func (msg AuthStart) MsgId() int {
func (msg *AuthStart) MsgId() int {
return network7.MsgSysAuthStart
}
func (msg AuthStart) MsgType() network7.MsgType {
func (msg *AuthStart) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg AuthStart) System() bool {
func (msg *AuthStart) System() bool {
return true
}
func (msg AuthStart) Vital() bool {
func (msg *AuthStart) Vital() bool {
return true
}
func (msg AuthStart) Pack() []byte {
func (msg *AuthStart) Pack() []byte {
return []byte{}
}
func (msg *AuthStart) Unpack(u *packer.Unpacker) {
func (msg *AuthStart) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *AuthStart) Header() *chunk7.ChunkHeader {

View file

@ -34,70 +34,71 @@ type ClStartInfo struct {
ColorEyes int
}
func (info ClStartInfo) MsgId() int {
func (msg *ClStartInfo) MsgId() int {
return network7.MsgGameClStartInfo
}
func (info ClStartInfo) MsgType() network7.MsgType {
func (msg *ClStartInfo) MsgType() network7.MsgType {
return network7.TypeNet
}
func (info ClStartInfo) System() bool {
func (msg *ClStartInfo) System() bool {
return false
}
func (info ClStartInfo) Vital() bool {
func (msg *ClStartInfo) Vital() bool {
return true
}
func (info ClStartInfo) Pack() []byte {
func (msg *ClStartInfo) Pack() []byte {
return slices.Concat(
packer.PackStr(info.Name),
packer.PackStr(info.Clan),
packer.PackInt(info.Country),
packer.PackStr(info.Body),
packer.PackStr(info.Marking),
packer.PackStr(info.Decoration),
packer.PackStr(info.Hands),
packer.PackStr(info.Feet),
packer.PackStr(info.Eyes),
packer.PackBool(info.CustomColorBody),
packer.PackBool(info.CustomColorMarking),
packer.PackBool(info.CustomColorDecoration),
packer.PackBool(info.CustomColorHands),
packer.PackBool(info.CustomColorFeet),
packer.PackBool(info.CustomColorEyes),
packer.PackInt(info.ColorBody),
packer.PackInt(info.ColorMarking),
packer.PackInt(info.ColorDecoration),
packer.PackInt(info.ColorHands),
packer.PackInt(info.ColorFeet),
packer.PackInt(info.ColorEyes),
packer.PackStr(msg.Name),
packer.PackStr(msg.Clan),
packer.PackInt(msg.Country),
packer.PackStr(msg.Body),
packer.PackStr(msg.Marking),
packer.PackStr(msg.Decoration),
packer.PackStr(msg.Hands),
packer.PackStr(msg.Feet),
packer.PackStr(msg.Eyes),
packer.PackBool(msg.CustomColorBody),
packer.PackBool(msg.CustomColorMarking),
packer.PackBool(msg.CustomColorDecoration),
packer.PackBool(msg.CustomColorHands),
packer.PackBool(msg.CustomColorFeet),
packer.PackBool(msg.CustomColorEyes),
packer.PackInt(msg.ColorBody),
packer.PackInt(msg.ColorMarking),
packer.PackInt(msg.ColorDecoration),
packer.PackInt(msg.ColorHands),
packer.PackInt(msg.ColorFeet),
packer.PackInt(msg.ColorEyes),
)
}
func (info *ClStartInfo) Unpack(u *packer.Unpacker) {
info.Name = u.GetString()
info.Clan = u.GetString()
info.Country = u.GetInt()
info.Body = u.GetString()
info.Marking = u.GetString()
info.Decoration = u.GetString()
info.Hands = u.GetString()
info.Feet = u.GetString()
info.Eyes = u.GetString()
info.CustomColorBody = u.GetInt() != 0
info.CustomColorMarking = u.GetInt() != 0
info.CustomColorDecoration = u.GetInt() != 0
info.CustomColorHands = u.GetInt() != 0
info.CustomColorFeet = u.GetInt() != 0
info.CustomColorEyes = u.GetInt() != 0
info.ColorBody = u.GetInt()
info.ColorMarking = u.GetInt()
info.ColorDecoration = u.GetInt()
info.ColorHands = u.GetInt()
info.ColorFeet = u.GetInt()
info.ColorEyes = u.GetInt()
func (msg *ClStartInfo) Unpack(u *packer.Unpacker) error {
msg.Name = u.GetString()
msg.Clan = u.GetString()
msg.Country = u.GetInt()
msg.Body = u.GetString()
msg.Marking = u.GetString()
msg.Decoration = u.GetString()
msg.Hands = u.GetString()
msg.Feet = u.GetString()
msg.Eyes = u.GetString()
msg.CustomColorBody = u.GetInt() != 0
msg.CustomColorMarking = u.GetInt() != 0
msg.CustomColorDecoration = u.GetInt() != 0
msg.CustomColorHands = u.GetInt() != 0
msg.CustomColorFeet = u.GetInt() != 0
msg.CustomColorEyes = u.GetInt() != 0
msg.ColorBody = u.GetInt()
msg.ColorMarking = u.GetInt()
msg.ColorDecoration = u.GetInt()
msg.ColorHands = u.GetInt()
msg.ColorFeet = u.GetInt()
msg.ColorEyes = u.GetInt()
return nil
}
func (msg *ClStartInfo) Header() *chunk7.ChunkHeader {

View file

@ -1,9 +1,9 @@
package messages7
import (
"reflect"
"testing"
"github.com/teeworlds-go/go-teeworlds-protocol/internal/testutils/require"
"github.com/teeworlds-go/go-teeworlds-protocol/packer"
)
@ -44,10 +44,7 @@ func TestPackStartInfo(t *testing.T) {
}
got := info.Pack()
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
require.Equal(t, want, got)
}
func TestUnpackStartInfo(t *testing.T) {
@ -64,34 +61,29 @@ func TestUnpackStartInfo(t *testing.T) {
})
info := ClStartInfo{}
info.Unpack(&u)
err := info.Unpack(&u)
require.NoError(t, err)
{
got := info.Eyes
want := "standard"
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
got := info.Eyes
require.Equal(t, want, got)
got = info.Decoration
want = ""
got = info.Decoration
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
got = info.Marking
want = "duodonny"
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
got = info.Marking
require.Equal(t, want, got)
}
{
got := info.ColorDecoration
want := 65408
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
got := info.ColorDecoration
require.Equal(t, want, got)
}
wantedInfo := ClStartInfo{
@ -118,7 +110,5 @@ func TestUnpackStartInfo(t *testing.T) {
ColorEyes: 65408,
}
if !reflect.DeepEqual(info, wantedInfo) {
t.Errorf("got %v, wanted %v", info, wantedInfo)
}
require.Equal(t, wantedInfo, info)
}

View file

@ -10,27 +10,28 @@ type ConReady struct {
ChunkHeader *chunk7.ChunkHeader
}
func (msg ConReady) MsgId() int {
func (msg *ConReady) MsgId() int {
return network7.MsgSysConReady
}
func (msg ConReady) MsgType() network7.MsgType {
func (msg *ConReady) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg ConReady) System() bool {
func (msg *ConReady) System() bool {
return true
}
func (msg ConReady) Vital() bool {
func (msg *ConReady) Vital() bool {
return true
}
func (msg ConReady) Pack() []byte {
func (msg *ConReady) Pack() []byte {
return []byte{}
}
func (msg *ConReady) Unpack(u *packer.Unpacker) {
func (msg *ConReady) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *ConReady) Header() *chunk7.ChunkHeader {

View file

@ -12,23 +12,23 @@ type CtrlAccept struct {
Token [4]byte
}
func (msg CtrlAccept) MsgId() int {
func (msg *CtrlAccept) MsgId() int {
return network7.MsgCtrlAccept
}
func (msg CtrlAccept) MsgType() network7.MsgType {
func (msg *CtrlAccept) MsgType() network7.MsgType {
return network7.TypeControl
}
func (msg CtrlAccept) System() bool {
func (msg *CtrlAccept) System() bool {
return false
}
func (msg CtrlAccept) Vital() bool {
func (msg *CtrlAccept) Vital() bool {
return false
}
func (msg CtrlAccept) Pack() []byte {
func (msg *CtrlAccept) Pack() []byte {
return slices.Concat(
[]byte{network7.MsgCtrlAccept},
msg.Token[:],
@ -36,7 +36,8 @@ func (msg CtrlAccept) Pack() []byte {
)
}
func (msg *CtrlAccept) Unpack(u *packer.Unpacker) {
func (msg *CtrlAccept) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *CtrlAccept) Header() *chunk7.ChunkHeader {

View file

@ -12,32 +12,33 @@ type CtrlClose struct {
Reason string
}
func (msg CtrlClose) MsgId() int {
func (msg *CtrlClose) MsgId() int {
return network7.MsgCtrlClose
}
func (msg CtrlClose) MsgType() network7.MsgType {
func (msg *CtrlClose) MsgType() network7.MsgType {
return network7.TypeControl
}
func (msg CtrlClose) System() bool {
func (msg *CtrlClose) System() bool {
return false
}
func (msg CtrlClose) Vital() bool {
func (msg *CtrlClose) Vital() bool {
return false
}
func (msg CtrlClose) Pack() []byte {
func (msg *CtrlClose) Pack() []byte {
return slices.Concat(
[]byte{network7.MsgCtrlClose},
packer.PackStr(msg.Reason),
)
}
func (msg *CtrlClose) Unpack(u *packer.Unpacker) {
func (msg *CtrlClose) Unpack(u *packer.Unpacker) error {
// TODO: sanitize
msg.Reason = u.GetString()
return nil
}
func (msg *CtrlClose) Header() *chunk7.ChunkHeader {

View file

@ -12,23 +12,23 @@ type CtrlConnect struct {
Token [4]byte
}
func (msg CtrlConnect) MsgId() int {
func (msg *CtrlConnect) MsgId() int {
return network7.MsgCtrlConnect
}
func (msg CtrlConnect) MsgType() network7.MsgType {
func (msg *CtrlConnect) MsgType() network7.MsgType {
return network7.TypeControl
}
func (msg CtrlConnect) System() bool {
func (msg *CtrlConnect) System() bool {
return false
}
func (msg CtrlConnect) Vital() bool {
func (msg *CtrlConnect) Vital() bool {
return false
}
func (msg CtrlConnect) Pack() []byte {
func (msg *CtrlConnect) Pack() []byte {
return slices.Concat(
[]byte{network7.MsgCtrlConnect},
msg.Token[:],
@ -36,8 +36,9 @@ func (msg CtrlConnect) Pack() []byte {
)
}
func (msg *CtrlConnect) Unpack(u *packer.Unpacker) {
func (msg *CtrlConnect) Unpack(u *packer.Unpacker) error {
msg.Token = [4]byte(u.Rest())
return nil
}
func (msg *CtrlConnect) Header() *chunk7.ChunkHeader {

View file

@ -9,27 +9,28 @@ import (
type CtrlKeepAlive struct {
}
func (msg CtrlKeepAlive) MsgId() int {
func (msg *CtrlKeepAlive) MsgId() int {
return network7.MsgCtrlKeepAlive
}
func (msg CtrlKeepAlive) MsgType() network7.MsgType {
func (msg *CtrlKeepAlive) MsgType() network7.MsgType {
return network7.TypeControl
}
func (msg CtrlKeepAlive) System() bool {
func (msg *CtrlKeepAlive) System() bool {
return false
}
func (msg CtrlKeepAlive) Vital() bool {
func (msg *CtrlKeepAlive) Vital() bool {
return false
}
func (msg CtrlKeepAlive) Pack() []byte {
func (msg *CtrlKeepAlive) Pack() []byte {
return []byte{network7.MsgCtrlKeepAlive}
}
func (msg *CtrlKeepAlive) Unpack(u *packer.Unpacker) {
func (msg *CtrlKeepAlive) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *CtrlKeepAlive) Header() *chunk7.ChunkHeader {

View file

@ -15,23 +15,23 @@ type CtrlToken struct {
Token [4]byte
}
func (msg CtrlToken) MsgId() int {
func (msg *CtrlToken) MsgId() int {
return network7.MsgCtrlToken
}
func (msg CtrlToken) MsgType() network7.MsgType {
func (msg *CtrlToken) MsgType() network7.MsgType {
return network7.TypeControl
}
func (msg CtrlToken) System() bool {
func (msg *CtrlToken) System() bool {
return false
}
func (msg CtrlToken) Vital() bool {
func (msg *CtrlToken) Vital() bool {
return false
}
func (msg CtrlToken) Pack() []byte {
func (msg *CtrlToken) Pack() []byte {
return slices.Concat(
[]byte{network7.MsgCtrlToken},
msg.Token[:],
@ -39,8 +39,9 @@ func (msg CtrlToken) Pack() []byte {
)
}
func (msg *CtrlToken) Unpack(u *packer.Unpacker) {
func (msg *CtrlToken) Unpack(u *packer.Unpacker) error {
msg.Token = [4]byte(u.Rest())
return nil
}
func (msg *CtrlToken) Header() *chunk7.ChunkHeader {

View file

@ -10,27 +10,28 @@ type EnterGame struct {
ChunkHeader *chunk7.ChunkHeader
}
func (msg EnterGame) MsgId() int {
func (msg *EnterGame) MsgId() int {
return network7.MsgSysEnterGame
}
func (msg EnterGame) MsgType() network7.MsgType {
func (msg *EnterGame) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg EnterGame) System() bool {
func (msg *EnterGame) System() bool {
return true
}
func (msg EnterGame) Vital() bool {
func (msg *EnterGame) Vital() bool {
return true
}
func (msg EnterGame) Pack() []byte {
func (msg *EnterGame) Pack() []byte {
return []byte{}
}
func (msg *EnterGame) Unpack(u *packer.Unpacker) {
func (msg *EnterGame) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *EnterGame) Header() *chunk7.ChunkHeader {

View file

@ -11,27 +11,28 @@ type Error struct {
ChunkHeader *chunk7.ChunkHeader
}
func (msg Error) MsgId() int {
func (msg *Error) MsgId() int {
return network7.MsgSysError
}
func (msg Error) MsgType() network7.MsgType {
func (msg *Error) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg Error) System() bool {
func (msg *Error) System() bool {
return true
}
func (msg Error) Vital() bool {
func (msg *Error) Vital() bool {
return true
}
func (msg Error) Pack() []byte {
func (msg *Error) Pack() []byte {
return []byte{}
}
func (msg *Error) Unpack(u *packer.Unpacker) {
func (msg *Error) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *Error) Header() *chunk7.ChunkHeader {

View file

@ -34,7 +34,7 @@ type Info struct {
ClientVersion int
}
func (msg Info) MsgId() int {
func (msg *Info) MsgId() int {
return network7.MsgSysInfo
}
@ -42,15 +42,15 @@ func (info Info) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg Info) System() bool {
func (msg *Info) System() bool {
return true
}
func (msg Info) Vital() bool {
func (msg *Info) Vital() bool {
return true
}
func (msg Info) Pack() []byte {
func (msg *Info) Pack() []byte {
return slices.Concat(
packer.PackStr(msg.Version),
packer.PackStr(msg.Password),
@ -58,10 +58,11 @@ func (msg Info) Pack() []byte {
)
}
func (msg *Info) Unpack(u *packer.Unpacker) {
func (msg *Info) Unpack(u *packer.Unpacker) error {
msg.Version = u.GetString()
msg.Password = u.GetString()
msg.ClientVersion = u.GetInt()
return nil
}
func (msg *Info) Header() *chunk7.ChunkHeader {

View file

@ -27,23 +27,23 @@ type Input struct {
PrevWeapon network7.Weapon
}
func (msg Input) MsgId() int {
func (msg *Input) MsgId() int {
return network7.MsgSysInput
}
func (msg Input) MsgType() network7.MsgType {
func (msg *Input) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg Input) System() bool {
func (msg *Input) System() bool {
return true
}
func (msg Input) Vital() bool {
func (msg *Input) Vital() bool {
return false
}
func (msg Input) Pack() []byte {
func (msg *Input) Pack() []byte {
return slices.Concat(
packer.PackInt(msg.Direction),
packer.PackInt(msg.TargetX),
@ -58,7 +58,7 @@ func (msg Input) Pack() []byte {
)
}
func (msg *Input) Unpack(u *packer.Unpacker) {
func (msg *Input) Unpack(u *packer.Unpacker) error {
msg.Direction = u.GetInt()
msg.TargetX = u.GetInt()
msg.TargetY = u.GetInt()
@ -69,6 +69,7 @@ func (msg *Input) Unpack(u *packer.Unpacker) {
msg.WantedWeapon = network7.Weapon(u.GetInt())
msg.NextWeapon = network7.Weapon(u.GetInt())
msg.PrevWeapon = network7.Weapon(u.GetInt())
return nil
}
func (msg *Input) Header() *chunk7.ChunkHeader {

View file

@ -15,32 +15,33 @@ type InputTiming struct {
TimeLeft int
}
func (msg InputTiming) MsgId() int {
func (msg *InputTiming) MsgId() int {
return network7.MsgSysInputTiming
}
func (msg InputTiming) MsgType() network7.MsgType {
func (msg *InputTiming) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg InputTiming) System() bool {
func (msg *InputTiming) System() bool {
return true
}
func (msg InputTiming) Vital() bool {
func (msg *InputTiming) Vital() bool {
return false
}
func (msg InputTiming) Pack() []byte {
func (msg *InputTiming) Pack() []byte {
return slices.Concat(
packer.PackInt(msg.IntendedPredTick),
packer.PackInt(msg.TimeLeft),
)
}
func (msg *InputTiming) Unpack(u *packer.Unpacker) {
func (msg *InputTiming) Unpack(u *packer.Unpacker) error {
msg.IntendedPredTick = u.GetInt()
msg.TimeLeft = u.GetInt()
return nil
}
func (msg *InputTiming) Header() *chunk7.ChunkHeader {

View file

@ -19,23 +19,23 @@ type MapChange struct {
Sha256 [32]byte
}
func (msg MapChange) MsgId() int {
func (msg *MapChange) MsgId() int {
return network7.MsgSysMapChange
}
func (msg MapChange) MsgType() network7.MsgType {
func (msg *MapChange) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg MapChange) System() bool {
func (msg *MapChange) System() bool {
return true
}
func (msg MapChange) Vital() bool {
func (msg *MapChange) Vital() bool {
return true
}
func (msg MapChange) Pack() []byte {
func (msg *MapChange) Pack() []byte {
return slices.Concat(
packer.PackStr(msg.Name),
packer.PackInt(msg.Crc),
@ -46,13 +46,14 @@ func (msg MapChange) Pack() []byte {
)
}
func (msg *MapChange) Unpack(u *packer.Unpacker) {
func (msg *MapChange) Unpack(u *packer.Unpacker) error {
msg.Name = u.GetString()
msg.Crc = u.GetInt()
msg.Size = u.GetInt()
msg.NumResponseChunksPerRequest = u.GetInt()
msg.ChunkSize = u.GetInt()
msg.Sha256 = [32]byte(u.Rest())
return nil
}
func (msg *MapChange) Header() *chunk7.ChunkHeader {

View file

@ -12,28 +12,29 @@ type MapData struct {
Data []byte
}
func (msg MapData) MsgId() int {
func (msg *MapData) MsgId() int {
return network7.MsgSysMapData
}
func (msg MapData) MsgType() network7.MsgType {
func (msg *MapData) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg MapData) System() bool {
func (msg *MapData) System() bool {
return true
}
func (msg MapData) Vital() bool {
func (msg *MapData) Vital() bool {
return true
}
func (msg MapData) Pack() []byte {
func (msg *MapData) Pack() []byte {
return msg.Data
}
func (msg *MapData) Unpack(u *packer.Unpacker) {
func (msg *MapData) Unpack(u *packer.Unpacker) error {
msg.Data = u.Rest()
return nil
}
func (msg *MapData) Header() *chunk7.ChunkHeader {

View file

@ -14,30 +14,31 @@ type MaplistEntryAdd struct {
MapName string
}
func (msg MaplistEntryAdd) MsgId() int {
func (msg *MaplistEntryAdd) MsgId() int {
return network7.MsgSysMaplistEntryAdd
}
func (msg MaplistEntryAdd) MsgType() network7.MsgType {
func (msg *MaplistEntryAdd) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg MaplistEntryAdd) System() bool {
func (msg *MaplistEntryAdd) System() bool {
return true
}
func (msg MaplistEntryAdd) Vital() bool {
func (msg *MaplistEntryAdd) Vital() bool {
return true
}
func (msg MaplistEntryAdd) Pack() []byte {
func (msg *MaplistEntryAdd) Pack() []byte {
return slices.Concat(
packer.PackStr(msg.MapName),
)
}
func (msg *MaplistEntryAdd) Unpack(u *packer.Unpacker) {
func (msg *MaplistEntryAdd) Unpack(u *packer.Unpacker) error {
msg.MapName = u.GetString()
return nil
}
func (msg *MaplistEntryAdd) Header() *chunk7.ChunkHeader {

View file

@ -14,30 +14,31 @@ type MaplistEntryRem struct {
MapName string
}
func (msg MaplistEntryRem) MsgId() int {
func (msg *MaplistEntryRem) MsgId() int {
return network7.MsgSysMaplistEntryRem
}
func (msg MaplistEntryRem) MsgType() network7.MsgType {
func (msg *MaplistEntryRem) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg MaplistEntryRem) System() bool {
func (msg *MaplistEntryRem) System() bool {
return true
}
func (msg MaplistEntryRem) Vital() bool {
func (msg *MaplistEntryRem) Vital() bool {
return true
}
func (msg MaplistEntryRem) Pack() []byte {
func (msg *MaplistEntryRem) Pack() []byte {
return slices.Concat(
packer.PackStr(msg.MapName),
)
}
func (msg *MaplistEntryRem) Unpack(u *packer.Unpacker) {
func (msg *MaplistEntryRem) Unpack(u *packer.Unpacker) error {
msg.MapName = u.GetString()
return nil
}
func (msg *MaplistEntryRem) Header() *chunk7.ChunkHeader {

View file

@ -12,7 +12,7 @@ type NetMessage interface {
System() bool
Vital() bool
Pack() []byte
Unpack(u *packer.Unpacker)
Unpack(u *packer.Unpacker) error
Header() *chunk7.ChunkHeader
SetHeader(header *chunk7.ChunkHeader)

View file

@ -10,27 +10,28 @@ type Ping struct {
ChunkHeader *chunk7.ChunkHeader
}
func (msg Ping) MsgId() int {
func (msg *Ping) MsgId() int {
return network7.MsgSysPing
}
func (msg Ping) MsgType() network7.MsgType {
func (msg *Ping) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg Ping) System() bool {
func (msg *Ping) System() bool {
return true
}
func (msg Ping) Vital() bool {
func (msg *Ping) Vital() bool {
return true
}
func (msg Ping) Pack() []byte {
func (msg *Ping) Pack() []byte {
return []byte{}
}
func (msg *Ping) Unpack(u *packer.Unpacker) {
func (msg *Ping) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *Ping) Header() *chunk7.ChunkHeader {

View file

@ -10,27 +10,28 @@ type PingReply struct {
ChunkHeader *chunk7.ChunkHeader
}
func (msg PingReply) MsgId() int {
func (msg *PingReply) MsgId() int {
return network7.MsgSysPingReply
}
func (msg PingReply) MsgType() network7.MsgType {
func (msg *PingReply) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg PingReply) System() bool {
func (msg *PingReply) System() bool {
return true
}
func (msg PingReply) Vital() bool {
func (msg *PingReply) Vital() bool {
return true
}
func (msg PingReply) Pack() []byte {
func (msg *PingReply) Pack() []byte {
return []byte{}
}
func (msg *PingReply) Unpack(u *packer.Unpacker) {
func (msg *PingReply) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *PingReply) Header() *chunk7.ChunkHeader {

View file

@ -14,30 +14,31 @@ type RconAuth struct {
Password string
}
func (msg RconAuth) MsgId() int {
func (msg *RconAuth) MsgId() int {
return network7.MsgSysRconAuth
}
func (msg RconAuth) MsgType() network7.MsgType {
func (msg *RconAuth) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg RconAuth) System() bool {
func (msg *RconAuth) System() bool {
return true
}
func (msg RconAuth) Vital() bool {
func (msg *RconAuth) Vital() bool {
return true
}
func (msg RconAuth) Pack() []byte {
func (msg *RconAuth) Pack() []byte {
return slices.Concat(
packer.PackStr(msg.Password),
)
}
func (msg *RconAuth) Unpack(u *packer.Unpacker) {
func (msg *RconAuth) Unpack(u *packer.Unpacker) error {
msg.Password = u.GetString()
return nil
}
func (msg *RconAuth) Header() *chunk7.ChunkHeader {

View file

@ -10,27 +10,28 @@ type RconAuthOff struct {
ChunkHeader *chunk7.ChunkHeader
}
func (msg RconAuthOff) MsgId() int {
func (msg *RconAuthOff) MsgId() int {
return network7.MsgSysRconAuthOff
}
func (msg RconAuthOff) MsgType() network7.MsgType {
func (msg *RconAuthOff) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg RconAuthOff) System() bool {
func (msg *RconAuthOff) System() bool {
return true
}
func (msg RconAuthOff) Vital() bool {
func (msg *RconAuthOff) Vital() bool {
return true
}
func (msg RconAuthOff) Pack() []byte {
func (msg *RconAuthOff) Pack() []byte {
return []byte{}
}
func (msg *RconAuthOff) Unpack(u *packer.Unpacker) {
func (msg *RconAuthOff) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *RconAuthOff) Header() *chunk7.ChunkHeader {

View file

@ -10,27 +10,28 @@ type RconAuthOn struct {
ChunkHeader *chunk7.ChunkHeader
}
func (msg RconAuthOn) MsgId() int {
func (msg *RconAuthOn) MsgId() int {
return network7.MsgSysRconAuthOn
}
func (msg RconAuthOn) MsgType() network7.MsgType {
func (msg *RconAuthOn) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg RconAuthOn) System() bool {
func (msg *RconAuthOn) System() bool {
return true
}
func (msg RconAuthOn) Vital() bool {
func (msg *RconAuthOn) Vital() bool {
return true
}
func (msg RconAuthOn) Pack() []byte {
func (msg *RconAuthOn) Pack() []byte {
return []byte{}
}
func (msg *RconAuthOn) Unpack(u *packer.Unpacker) {
func (msg *RconAuthOn) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *RconAuthOn) Header() *chunk7.ChunkHeader {

View file

@ -14,30 +14,31 @@ type RconCmd struct {
Command string
}
func (msg RconCmd) MsgId() int {
func (msg *RconCmd) MsgId() int {
return network7.MsgSysRconCmd
}
func (msg RconCmd) MsgType() network7.MsgType {
func (msg *RconCmd) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg RconCmd) System() bool {
func (msg *RconCmd) System() bool {
return true
}
func (msg RconCmd) Vital() bool {
func (msg *RconCmd) Vital() bool {
return true
}
func (msg RconCmd) Pack() []byte {
func (msg *RconCmd) Pack() []byte {
return slices.Concat(
packer.PackStr(msg.Command),
)
}
func (msg *RconCmd) Unpack(u *packer.Unpacker) {
func (msg *RconCmd) Unpack(u *packer.Unpacker) error {
msg.Command = u.GetString()
return nil
}
func (msg *RconCmd) Header() *chunk7.ChunkHeader {

View file

@ -16,23 +16,23 @@ type RconCmdAdd struct {
Params string
}
func (msg RconCmdAdd) MsgId() int {
func (msg *RconCmdAdd) MsgId() int {
return network7.MsgSysRconCmdAdd
}
func (msg RconCmdAdd) MsgType() network7.MsgType {
func (msg *RconCmdAdd) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg RconCmdAdd) System() bool {
func (msg *RconCmdAdd) System() bool {
return true
}
func (msg RconCmdAdd) Vital() bool {
func (msg *RconCmdAdd) Vital() bool {
return true
}
func (msg RconCmdAdd) Pack() []byte {
func (msg *RconCmdAdd) Pack() []byte {
return slices.Concat(
packer.PackStr(msg.Name),
packer.PackStr(msg.Help),
@ -40,10 +40,11 @@ func (msg RconCmdAdd) Pack() []byte {
)
}
func (msg *RconCmdAdd) Unpack(u *packer.Unpacker) {
func (msg *RconCmdAdd) Unpack(u *packer.Unpacker) error {
msg.Name = u.GetString()
msg.Help = u.GetString()
msg.Params = u.GetString()
return nil
}
func (msg *RconCmdAdd) Header() *chunk7.ChunkHeader {

View file

@ -14,30 +14,31 @@ type RconCmdRem struct {
Name string
}
func (msg RconCmdRem) MsgId() int {
func (msg *RconCmdRem) MsgId() int {
return network7.MsgSysRconCmdRem
}
func (msg RconCmdRem) MsgType() network7.MsgType {
func (msg *RconCmdRem) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg RconCmdRem) System() bool {
func (msg *RconCmdRem) System() bool {
return true
}
func (msg RconCmdRem) Vital() bool {
func (msg *RconCmdRem) Vital() bool {
return true
}
func (msg RconCmdRem) Pack() []byte {
func (msg *RconCmdRem) Pack() []byte {
return slices.Concat(
packer.PackStr(msg.Name),
)
}
func (msg *RconCmdRem) Unpack(u *packer.Unpacker) {
func (msg *RconCmdRem) Unpack(u *packer.Unpacker) error {
msg.Name = u.GetString()
return nil
}
func (msg *RconCmdRem) Header() *chunk7.ChunkHeader {

View file

@ -14,30 +14,31 @@ type RconLine struct {
Line string
}
func (msg RconLine) MsgId() int {
func (msg *RconLine) MsgId() int {
return network7.MsgSysRconLine
}
func (msg RconLine) MsgType() network7.MsgType {
func (msg *RconLine) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg RconLine) System() bool {
func (msg *RconLine) System() bool {
return true
}
func (msg RconLine) Vital() bool {
func (msg *RconLine) Vital() bool {
return true
}
func (msg RconLine) Pack() []byte {
func (msg *RconLine) Pack() []byte {
return slices.Concat(
packer.PackStr(msg.Line),
)
}
func (msg *RconLine) Unpack(u *packer.Unpacker) {
func (msg *RconLine) Unpack(u *packer.Unpacker) error {
msg.Line = u.GetString()
return nil
}
func (msg *RconLine) Header() *chunk7.ChunkHeader {

View file

@ -10,27 +10,28 @@ type Ready struct {
ChunkHeader *chunk7.ChunkHeader
}
func (msg Ready) MsgId() int {
func (msg *Ready) MsgId() int {
return network7.MsgSysReady
}
func (msg Ready) MsgType() network7.MsgType {
func (msg *Ready) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg Ready) System() bool {
func (msg *Ready) System() bool {
return true
}
func (msg Ready) Vital() bool {
func (msg *Ready) Vital() bool {
return true
}
func (msg Ready) Pack() []byte {
func (msg *Ready) Pack() []byte {
return []byte{}
}
func (msg *Ready) Unpack(u *packer.Unpacker) {
func (msg *Ready) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *Ready) Header() *chunk7.ChunkHeader {

View file

@ -10,27 +10,28 @@ type ReadyToEnter struct {
ChunkHeader *chunk7.ChunkHeader
}
func (msg ReadyToEnter) MsgId() int {
func (msg *ReadyToEnter) MsgId() int {
return network7.MsgGameReadyToEnter
}
func (msg ReadyToEnter) MsgType() network7.MsgType {
func (msg *ReadyToEnter) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg ReadyToEnter) System() bool {
func (msg *ReadyToEnter) System() bool {
return false
}
func (msg ReadyToEnter) Vital() bool {
func (msg *ReadyToEnter) Vital() bool {
return true
}
func (msg ReadyToEnter) Pack() []byte {
func (msg *ReadyToEnter) Pack() []byte {
return []byte{}
}
func (msg *ReadyToEnter) Unpack(u *packer.Unpacker) {
func (msg *ReadyToEnter) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *ReadyToEnter) Header() *chunk7.ChunkHeader {

View file

@ -10,27 +10,28 @@ type RequestMapData struct {
ChunkHeader *chunk7.ChunkHeader
}
func (msg RequestMapData) MsgId() int {
func (msg *RequestMapData) MsgId() int {
return network7.MsgSysRequestMapData
}
func (msg RequestMapData) MsgType() network7.MsgType {
func (msg *RequestMapData) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg RequestMapData) System() bool {
func (msg *RequestMapData) System() bool {
return true
}
func (msg RequestMapData) Vital() bool {
func (msg *RequestMapData) Vital() bool {
return true
}
func (msg RequestMapData) Pack() []byte {
func (msg *RequestMapData) Pack() []byte {
return []byte{}
}
func (msg *RequestMapData) Unpack(u *packer.Unpacker) {
func (msg *RequestMapData) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *RequestMapData) Header() *chunk7.ChunkHeader {

View file

@ -24,23 +24,23 @@ type ServerInfo struct {
MaxClients int
}
func (msg ServerInfo) MsgId() int {
func (msg *ServerInfo) MsgId() int {
return network7.MsgSysServerInfo
}
func (msg ServerInfo) MsgType() network7.MsgType {
func (msg *ServerInfo) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg ServerInfo) System() bool {
func (msg *ServerInfo) System() bool {
return true
}
func (msg ServerInfo) Vital() bool {
func (msg *ServerInfo) Vital() bool {
return true
}
func (msg ServerInfo) Pack() []byte {
func (msg *ServerInfo) Pack() []byte {
return slices.Concat(
packer.PackStr(msg.Version),
packer.PackStr(msg.Name),
@ -56,7 +56,7 @@ func (msg ServerInfo) Pack() []byte {
)
}
func (msg *ServerInfo) Unpack(u *packer.Unpacker) {
func (msg *ServerInfo) Unpack(u *packer.Unpacker) error {
msg.Version = u.GetString()
msg.Name = u.GetString()
msg.Hostname = u.GetString()
@ -68,6 +68,7 @@ func (msg *ServerInfo) Unpack(u *packer.Unpacker) {
msg.PlayerSlots = u.GetInt()
msg.ClientCount = u.GetInt()
msg.MaxClients = u.GetInt()
return nil
}
func (msg *ServerInfo) Header() *chunk7.ChunkHeader {

View file

@ -20,23 +20,23 @@ type Snap struct {
Data []byte
}
func (msg Snap) MsgId() int {
func (msg *Snap) MsgId() int {
return network7.MsgSysSnap
}
func (msg Snap) MsgType() network7.MsgType {
func (msg *Snap) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg Snap) System() bool {
func (msg *Snap) System() bool {
return true
}
func (msg Snap) Vital() bool {
func (msg *Snap) Vital() bool {
return false
}
func (msg Snap) Pack() []byte {
func (msg *Snap) Pack() []byte {
return slices.Concat(
packer.PackInt(msg.GameTick),
packer.PackInt(msg.DeltaTick),
@ -44,11 +44,11 @@ func (msg Snap) Pack() []byte {
packer.PackInt(msg.Part),
packer.PackInt(msg.Crc),
packer.PackInt(msg.PartSize),
msg.Data[:],
msg.Data,
)
}
func (msg *Snap) Unpack(u *packer.Unpacker) {
func (msg *Snap) Unpack(u *packer.Unpacker) error {
msg.GameTick = u.GetInt()
msg.DeltaTick = u.GetInt()
msg.NumParts = u.GetInt()
@ -56,6 +56,7 @@ func (msg *Snap) Unpack(u *packer.Unpacker) {
msg.Crc = u.GetInt()
msg.PartSize = u.GetInt()
msg.Data = u.Rest()
return nil
}
func (msg *Snap) Header() *chunk7.ChunkHeader {

View file

@ -15,32 +15,33 @@ type SnapEmpty struct {
DeltaTick int
}
func (msg SnapEmpty) MsgId() int {
func (msg *SnapEmpty) MsgId() int {
return network7.MsgSysSnapEmpty
}
func (msg SnapEmpty) MsgType() network7.MsgType {
func (msg *SnapEmpty) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg SnapEmpty) System() bool {
func (msg *SnapEmpty) System() bool {
return true
}
func (msg SnapEmpty) Vital() bool {
func (msg *SnapEmpty) Vital() bool {
return false
}
func (msg SnapEmpty) Pack() []byte {
func (msg *SnapEmpty) Pack() []byte {
return slices.Concat(
packer.PackInt(msg.GameTick),
packer.PackInt(msg.DeltaTick),
)
}
func (msg *SnapEmpty) Unpack(u *packer.Unpacker) {
func (msg *SnapEmpty) Unpack(u *packer.Unpacker) error {
msg.GameTick = u.GetInt()
msg.DeltaTick = u.GetInt()
return nil
}
func (msg *SnapEmpty) Header() *chunk7.ChunkHeader {

View file

@ -18,38 +18,39 @@ type SnapSingle struct {
Data []byte
}
func (msg SnapSingle) MsgId() int {
func (msg *SnapSingle) MsgId() int {
return network7.MsgSysSnapSingle
}
func (msg SnapSingle) MsgType() network7.MsgType {
func (msg *SnapSingle) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg SnapSingle) System() bool {
func (msg *SnapSingle) System() bool {
return true
}
func (msg SnapSingle) Vital() bool {
func (msg *SnapSingle) Vital() bool {
return false
}
func (msg SnapSingle) Pack() []byte {
func (msg *SnapSingle) Pack() []byte {
return slices.Concat(
packer.PackInt(msg.GameTick),
packer.PackInt(msg.DeltaTick),
packer.PackInt(msg.Crc),
packer.PackInt(msg.PartSize),
msg.Data[:],
msg.Data,
)
}
func (msg *SnapSingle) Unpack(u *packer.Unpacker) {
func (msg *SnapSingle) Unpack(u *packer.Unpacker) error {
msg.GameTick = u.GetInt()
msg.DeltaTick = u.GetInt()
msg.Crc = u.GetInt()
msg.PartSize = u.GetInt()
msg.Data = u.Rest()
return nil
}
func (msg *SnapSingle) Header() *chunk7.ChunkHeader {

View file

@ -11,27 +11,28 @@ type SnapSmall struct {
ChunkHeader *chunk7.ChunkHeader
}
func (msg SnapSmall) MsgId() int {
func (msg *SnapSmall) MsgId() int {
return network7.MsgSysSnapSmall
}
func (msg SnapSmall) MsgType() network7.MsgType {
func (msg *SnapSmall) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg SnapSmall) System() bool {
func (msg *SnapSmall) System() bool {
return true
}
func (msg SnapSmall) Vital() bool {
func (msg *SnapSmall) Vital() bool {
return false
}
func (msg SnapSmall) Pack() []byte {
func (msg *SnapSmall) Pack() []byte {
return []byte{}
}
func (msg *SnapSmall) Unpack(u *packer.Unpacker) {
func (msg *SnapSmall) Unpack(u *packer.Unpacker) error {
return nil
}
func (msg *SnapSmall) Header() *chunk7.ChunkHeader {

View file

@ -12,28 +12,29 @@ type SvBroadcast struct {
Message string
}
func (msg SvBroadcast) MsgId() int {
func (msg *SvBroadcast) MsgId() int {
return network7.MsgGameSvBroadcast
}
func (msg SvBroadcast) MsgType() network7.MsgType {
func (msg *SvBroadcast) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg SvBroadcast) System() bool {
func (msg *SvBroadcast) System() bool {
return false
}
func (msg SvBroadcast) Vital() bool {
func (msg *SvBroadcast) Vital() bool {
return true
}
func (msg SvBroadcast) Pack() []byte {
func (msg *SvBroadcast) Pack() []byte {
return packer.PackStr(msg.Message)
}
func (msg *SvBroadcast) Unpack(u *packer.Unpacker) {
func (msg *SvBroadcast) Unpack(u *packer.Unpacker) error {
msg.Message = u.GetString()
return nil
}
func (msg *SvBroadcast) Header() *chunk7.ChunkHeader {

View file

@ -17,23 +17,23 @@ type SvChat struct {
Message string
}
func (msg SvChat) MsgId() int {
func (msg *SvChat) MsgId() int {
return network7.MsgGameSvChat
}
func (msg SvChat) MsgType() network7.MsgType {
func (msg *SvChat) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg SvChat) System() bool {
func (msg *SvChat) System() bool {
return false
}
func (msg SvChat) Vital() bool {
func (msg *SvChat) Vital() bool {
return true
}
func (msg SvChat) Pack() []byte {
func (msg *SvChat) Pack() []byte {
return slices.Concat(
packer.PackInt(int(msg.Mode)),
packer.PackInt(msg.ClientId),
@ -42,11 +42,13 @@ func (msg SvChat) Pack() []byte {
)
}
func (msg *SvChat) Unpack(u *packer.Unpacker) {
func (msg *SvChat) Unpack(u *packer.Unpacker) error {
msg.Mode = network7.ChatMode(u.GetInt())
msg.ClientId = u.GetInt()
msg.TargetId = u.GetInt()
msg.Message = u.GetString()
return nil
}
func (msg *SvChat) Header() *chunk7.ChunkHeader {

View file

@ -53,7 +53,7 @@ func (info *SvClientInfo) Vital() bool {
return true
}
func (msg SvClientInfo) Pack() []byte {
func (msg *SvClientInfo) Pack() []byte {
return slices.Concat(
packer.PackInt(msg.ClientId),
packer.PackBool(msg.Local),
@ -82,7 +82,7 @@ func (msg SvClientInfo) Pack() []byte {
)
}
func (info *SvClientInfo) Unpack(u *packer.Unpacker) {
func (info *SvClientInfo) Unpack(u *packer.Unpacker) error {
info.ClientId = u.GetInt()
info.Local = u.GetInt() != 0
info.Team = u.GetInt()
@ -107,6 +107,8 @@ func (info *SvClientInfo) Unpack(u *packer.Unpacker) {
info.ColorFeet = u.GetInt()
info.ColorEyes = u.GetInt()
info.Silent = u.GetInt() != 0
return nil
}
func (msg *SvClientInfo) Header() *chunk7.ChunkHeader {

View file

@ -1,9 +1,9 @@
package messages7
import (
"reflect"
"testing"
"github.com/teeworlds-go/go-teeworlds-protocol/internal/testutils/require"
"github.com/teeworlds-go/go-teeworlds-protocol/packer"
)
@ -21,26 +21,21 @@ func TestUnpackClientInfo(t *testing.T) {
})
info := SvClientInfo{}
info.Unpack(&u)
err := info.Unpack(&u)
require.NoError(t, err)
{
got := info.Eyes
want := "standard"
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
got := info.Eyes
require.Equal(t, want, got)
got = info.Decoration
want = ""
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
got = info.Decoration
require.Equal(t, want, got)
got = info.Marking
want = "duodonny"
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
got = info.Marking
require.Equal(t, want, got)
}
wantedInfo := SvClientInfo{
@ -69,8 +64,5 @@ func TestUnpackClientInfo(t *testing.T) {
ColorEyes: 65408,
Silent: true,
}
if !reflect.DeepEqual(info, wantedInfo) {
t.Errorf("got %v, wanted %v", info, wantedInfo)
}
require.Equal(t, wantedInfo, info)
}

View file

@ -12,28 +12,29 @@ type SvMotd struct {
Message string
}
func (msg SvMotd) MsgId() int {
func (msg *SvMotd) MsgId() int {
return network7.MsgGameSvMotd
}
func (msg SvMotd) MsgType() network7.MsgType {
func (msg *SvMotd) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg SvMotd) System() bool {
func (msg *SvMotd) System() bool {
return false
}
func (msg SvMotd) Vital() bool {
func (msg *SvMotd) Vital() bool {
return true
}
func (msg SvMotd) Pack() []byte {
func (msg *SvMotd) Pack() []byte {
return packer.PackStr(msg.Message)
}
func (msg *SvMotd) Unpack(u *packer.Unpacker) {
func (msg *SvMotd) Unpack(u *packer.Unpacker) error {
msg.Message = u.GetString()
return nil
}
func (msg *SvMotd) Header() *chunk7.ChunkHeader {

View file

@ -16,23 +16,23 @@ type SvTeam struct {
CooldownTick int
}
func (msg SvTeam) MsgId() int {
func (msg *SvTeam) MsgId() int {
return network7.MsgGameSvTeam
}
func (msg SvTeam) MsgType() network7.MsgType {
func (msg *SvTeam) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg SvTeam) System() bool {
func (msg *SvTeam) System() bool {
return false
}
func (msg SvTeam) Vital() bool {
func (msg *SvTeam) Vital() bool {
return true
}
func (msg SvTeam) Pack() []byte {
func (msg *SvTeam) Pack() []byte {
return slices.Concat(
packer.PackInt(msg.ClientId),
packer.PackBool(msg.Silent),
@ -40,10 +40,11 @@ func (msg SvTeam) Pack() []byte {
)
}
func (msg *SvTeam) Unpack(u *packer.Unpacker) {
func (msg *SvTeam) Unpack(u *packer.Unpacker) error {
msg.ClientId = u.GetInt()
msg.Silent = u.GetInt() != 0
msg.CooldownTick = u.GetInt()
return nil
}
func (msg *SvTeam) Header() *chunk7.ChunkHeader {

View file

@ -14,40 +14,42 @@ type Unknown struct {
// can either be a control message or a game/system message
Data []byte
Type network7.MsgType
msgId int // TODO: is that supposed to be exported?
}
func (msg Unknown) MsgId() int {
msgId := packer.UnpackInt(msg.Data)
func (msg *Unknown) MsgId() int {
if msg.Type == network7.TypeControl {
return msgId
return msg.msgId
}
msgId >>= 1
return msgId
return msg.msgId >> 1
}
func (msg Unknown) MsgType() network7.MsgType {
func (msg *Unknown) MsgType() network7.MsgType {
return msg.Type
}
func (msg Unknown) System() bool {
msgId := packer.UnpackInt(msg.Data)
func (msg *Unknown) System() bool {
if msg.Type == network7.TypeControl {
return false
}
sys := msgId&1 != 0
sys := msg.msgId&1 != 0
return sys
}
func (msg Unknown) Vital() bool {
func (msg *Unknown) Vital() bool {
panic("You are not mean't to pack unknown messages. Use msg.Header().Vital instead.")
}
func (msg Unknown) Pack() []byte {
func (msg *Unknown) Pack() []byte {
return msg.Data
}
func (msg *Unknown) Unpack(u *packer.Unpacker) {
func (msg *Unknown) Unpack(u *packer.Unpacker) error {
msg.Data = u.Rest()
msgId := packer.UnpackInt(msg.Data)
msg.msgId = msgId
return nil
}
func (msg *Unknown) Header() *chunk7.ChunkHeader {

View file

@ -19,6 +19,9 @@ const (
MsgCtrlToken = 0x05
MsgCtrlClose = 0x04
// TODO: these should preferrably all be devide dinto different type dintegers
// same as ChatMode, etc. so that the user can easily see which integer to pass
// to which function as which parameter
MsgSysInfo = 1
MsgSysMapChange = 2
MsgSysMapData = 3

View file

@ -1,8 +1,9 @@
package packer
import (
"reflect"
"testing"
"github.com/teeworlds-go/go-teeworlds-protocol/internal/testutils/require"
)
// rest
@ -12,21 +13,15 @@ func TestUnpackRest(t *testing.T) {
u.Reset([]byte{0x01, 0xff, 0xaa})
{
got := u.GetInt()
want := 1
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
got := u.GetInt()
require.Equal(t, want, got)
}
{
got := u.Rest()
want := []byte{0xff, 0xaa}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got := u.Rest()
require.Equal(t, want, got)
}
}
@ -47,20 +42,14 @@ func TestUnpackClientInfo(t *testing.T) {
{
// message id
got := u.GetInt()
want := 36
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
got := u.GetInt()
require.Equal(t, want, got)
// client id
got = u.GetInt()
want = 0
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
got = u.GetInt()
require.Equal(t, want, got)
u.GetInt() // Local bool
u.GetInt() // Team int
@ -68,40 +57,28 @@ func TestUnpackClientInfo(t *testing.T) {
{
// name
got := u.GetString()
want := "gopher"
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
got := u.GetString()
require.Equal(t, want, got)
// clan
got = u.GetString()
want = ""
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
got = u.GetString()
require.Equal(t, want, got)
}
{
// country
got := u.GetInt()
want := -1
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
got := u.GetInt()
require.Equal(t, want, got)
}
{
// body
got := u.GetString()
want := "greensward"
if got != want {
t.Errorf("got %v, wanted %v", got, want)
}
got := u.GetString()
require.Equal(t, want, got)
}
}
@ -111,64 +88,44 @@ func TestUnpackSimpleInts(t *testing.T) {
u := Unpacker{}
u.Reset([]byte{0x01, 0x02, 0x03, 0x0f})
got := u.GetInt()
want := 1
got := u.GetInt()
require.Equal(t, want, got)
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = u.GetInt()
want = 2
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = u.GetInt()
require.Equal(t, want, got)
want = 3
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = u.GetInt()
want = 15
require.Equal(t, want, got)
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
want = 15
got = u.GetInt()
require.Equal(t, want, got)
}
func TestUnpackString(t *testing.T) {
u := Unpacker{}
u.Reset([]byte{'f', 'o', 'o', 0x00})
got := u.GetString()
want := "foo"
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got := u.GetString()
require.Equal(t, want, got)
}
func TestUnpackTwoStrings(t *testing.T) {
u := Unpacker{}
u.Reset([]byte{'f', 'o', 'o', 0x00, 'b', 'a', 'r', 0x00})
got := u.GetString()
want := "foo"
got := u.GetString()
require.Equal(t, want, got)
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = u.GetString()
want = "bar"
got = u.GetString()
require.Equal(t, want, got)
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
}
func TestUnpackMixed(t *testing.T) {
@ -177,45 +134,30 @@ func TestUnpackMixed(t *testing.T) {
// ints
{
got := u.GetInt()
want := 15
got := u.GetInt()
require.Equal(t, want, got)
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = u.GetInt()
want = 15
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = u.GetInt()
require.Equal(t, want, got)
}
// strings
{
got := u.GetString()
want := "foo"
got := u.GetString()
require.Equal(t, want, got)
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = u.GetString()
want = "bar"
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = u.GetString()
require.Equal(t, want, got)
}
// ints
{
got := u.GetInt()
want := 1
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got := u.GetInt()
require.Equal(t, want, got)
}
}

View file

@ -1,145 +1,95 @@
package packer
import (
"reflect"
"testing"
"github.com/teeworlds-go/go-teeworlds-protocol/internal/testutils/require"
)
// pack
func TestPackEmptyString(t *testing.T) {
got := PackStr("")
want := []byte{0x00}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got := PackStr("")
require.Equal(t, want, got)
}
func TestPackSimpleString(t *testing.T) {
got := PackStr("foo")
want := []byte{'f', 'o', 'o', 0x00}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got := PackStr("foo")
require.Equal(t, want, got)
}
func TestPackSmallPositiveInts(t *testing.T) {
got := PackInt(1)
want := []byte{0x01}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got := PackInt(1)
require.Equal(t, want, got)
}
func TestPackMultiBytePositiveInts(t *testing.T) {
got := PackInt(63)
want := []byte{0x3F}
got := PackInt(63)
require.Equal(t, want, got)
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = PackInt(64)
want = []byte{0x80, 0x01}
got = PackInt(64)
require.Equal(t, want, got)
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = PackInt(65)
want = []byte{0x81, 0x01}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = PackInt(65)
require.Equal(t, want, got)
}
func TestPackSmallNegativeInts(t *testing.T) {
got := PackInt(-1)
want := []byte{0x40}
got := PackInt(-1)
require.Equal(t, want, got)
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = PackInt(-2)
want = []byte{0x41}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = PackInt(-2)
require.Equal(t, want, got)
}
func TestPackMultiByteNegativeInts(t *testing.T) {
got := PackInt(-63)
want := []byte{0x7E}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got := PackInt(-63)
require.Equal(t, want, got)
got = PackInt(-64)
want = []byte{0x7F}
require.Equal(t, want, got)
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = PackInt(-65)
want = []byte{0xC0, 0x01}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = PackInt(-65)
require.Equal(t, want, got)
}
// unpack
func TestUnpackSmallPositiveInts(t *testing.T) {
got := UnpackInt([]byte{0x01})
want := 1
got := UnpackInt([]byte{0x01})
require.Equal(t, want, got)
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = UnpackInt([]byte{0x02})
want = 2
got = UnpackInt([]byte{0x02})
require.Equal(t, want, got)
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = UnpackInt([]byte{0x03})
want = 3
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = UnpackInt([]byte{0x03})
require.Equal(t, want, got)
}
func TestUnpackMultiBytePositiveInts(t *testing.T) {
got := UnpackInt([]byte{0x3f})
want := 63
got := UnpackInt([]byte{0x3f})
require.Equal(t, want, got)
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = UnpackInt([]byte{0x80, 0x01})
want = 64
got = UnpackInt([]byte{0x80, 0x01})
require.Equal(t, want, got)
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = UnpackInt([]byte{0x81, 0x01})
want = 65
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got = UnpackInt([]byte{0x81, 0x01})
require.Equal(t, want, got)
}

View file

@ -1,6 +1,7 @@
package protocol7
import (
"fmt"
"slices"
"github.com/teeworlds-go/go-teeworlds-protocol/chunk7"
@ -11,6 +12,7 @@ import (
)
const (
// TODO: these should preferrably be typed integers
packetFlagControl = 1
packetFlagResend = 2
packetFlagCompression = 4
@ -80,158 +82,122 @@ func PackChunk(msg messages7.NetMessage, connection *Session) []byte {
return data
}
func (packet *Packet) unpackSystem(msgId int, chunk chunk7.Chunk, u *packer.Unpacker) bool {
if msgId == network7.MsgSysInfo {
msg := &messages7.Info{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysMapChange {
msg := &messages7.MapChange{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysMapData {
msg := &messages7.MapData{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysServerInfo {
msg := &messages7.ServerInfo{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysConReady {
msg := &messages7.ConReady{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysSnap {
msg := &messages7.Snap{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysSnapEmpty {
msg := &messages7.SnapEmpty{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysSnapSingle {
msg := &messages7.SnapSingle{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysSnapSmall {
msg := &messages7.SnapSmall{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysInputTiming {
msg := &messages7.InputTiming{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysRconAuthOn {
msg := &messages7.RconAuthOn{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysRconAuthOff {
msg := &messages7.RconAuthOff{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysRconLine {
msg := &messages7.RconLine{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysRconCmdAdd {
msg := &messages7.RconCmdAdd{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysRconCmdRem {
msg := &messages7.RconCmdRem{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysAuthChallenge {
msg := &messages7.AuthChallenge{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysAuthResult {
msg := &messages7.AuthResult{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysReady {
msg := &messages7.Ready{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysEnterGame {
msg := &messages7.EnterGame{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysInput {
msg := &messages7.Input{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysRconCmd {
msg := &messages7.RconCmd{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysRconAuth {
msg := &messages7.RconAuth{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysRequestMapData {
msg := &messages7.RequestMapData{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysAuthStart {
msg := &messages7.AuthStart{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysAuthResponse {
msg := &messages7.AuthResponse{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysPing {
msg := &messages7.Ping{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysPingReply {
msg := &messages7.PingReply{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysError {
msg := &messages7.Error{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysMaplistEntryAdd {
msg := &messages7.MaplistEntryAdd{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgSysMaplistEntryRem {
msg := &messages7.MaplistEntryRem{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else {
return false
func (packet *Packet) unpackSystem(msgId int, chunk chunk7.Chunk, u *packer.Unpacker) (bool, error) {
var msg messages7.NetMessage
switch msgId {
case network7.MsgSysInfo:
msg = &messages7.Info{}
case network7.MsgSysMapChange:
msg = &messages7.MapChange{}
case network7.MsgSysMapData:
msg = &messages7.MapData{}
case network7.MsgSysServerInfo:
msg = &messages7.ServerInfo{}
case network7.MsgSysConReady:
msg = &messages7.ConReady{}
case network7.MsgSysSnap:
msg = &messages7.Snap{}
case network7.MsgSysSnapEmpty:
msg = &messages7.SnapEmpty{}
case network7.MsgSysSnapSingle:
msg = &messages7.SnapSingle{}
case network7.MsgSysSnapSmall:
msg = &messages7.SnapSmall{}
case network7.MsgSysInputTiming:
msg = &messages7.InputTiming{}
case network7.MsgSysRconAuthOn:
msg = &messages7.RconAuthOn{}
case network7.MsgSysRconAuthOff:
msg = &messages7.RconAuthOff{}
case network7.MsgSysRconLine:
msg = &messages7.RconLine{}
case network7.MsgSysRconCmdAdd:
msg = &messages7.RconCmdAdd{}
case network7.MsgSysRconCmdRem:
msg = &messages7.RconCmdRem{}
case network7.MsgSysAuthChallenge:
msg = &messages7.AuthChallenge{}
case network7.MsgSysAuthResult:
msg = &messages7.AuthResult{}
case network7.MsgSysReady:
msg = &messages7.Ready{}
case network7.MsgSysEnterGame:
msg = &messages7.EnterGame{}
case network7.MsgSysInput:
msg = &messages7.Input{}
case network7.MsgSysRconCmd:
msg = &messages7.RconCmd{}
case network7.MsgSysRconAuth:
msg = &messages7.RconAuth{}
case network7.MsgSysRequestMapData:
msg = &messages7.RequestMapData{}
case network7.MsgSysAuthStart:
msg = &messages7.AuthStart{}
case network7.MsgSysAuthResponse:
msg = &messages7.AuthResponse{}
case network7.MsgSysPing:
msg = &messages7.Ping{}
case network7.MsgSysPingReply:
msg = &messages7.PingReply{}
case network7.MsgSysError:
msg = &messages7.Error{}
case network7.MsgSysMaplistEntryAdd:
msg = &messages7.MaplistEntryAdd{}
case network7.MsgSysMaplistEntryRem:
msg = &messages7.MaplistEntryRem{}
default:
return false, nil
}
// packet.Messages[len(packet.Messages)-1].SetHeader(&chunk.Header)
return true
header := chunk.Header // decouple memory by copying only the needed value
msg.SetHeader(&header)
err := msg.Unpack(u)
if err != nil {
// in case of an error, the user is not supposed to continue
// working with the returned first value
return false, err
}
packet.Messages = append(packet.Messages, msg)
return true, nil
}
func (packet *Packet) unpackGame(msgId int, chunk chunk7.Chunk, u *packer.Unpacker) bool {
if msgId == network7.MsgGameReadyToEnter {
msg := &messages7.ReadyToEnter{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgGameSvMotd {
msg := &messages7.SvMotd{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgGameSvChat {
msg := &messages7.SvChat{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else if msgId == network7.MsgGameSvClientInfo {
msg := &messages7.SvClientInfo{ChunkHeader: &chunk.Header}
msg.Unpack(u)
packet.Messages = append(packet.Messages, msg)
} else {
return false
func (packet *Packet) unpackGame(msgId int, chunk chunk7.Chunk, u *packer.Unpacker) (bool, error) {
var msg messages7.NetMessage
switch msgId {
case network7.MsgGameReadyToEnter:
msg = &messages7.ReadyToEnter{}
case network7.MsgGameSvMotd:
msg = &messages7.SvMotd{}
case network7.MsgGameSvChat:
msg = &messages7.SvChat{}
case network7.MsgGameSvClientInfo:
msg = &messages7.SvClientInfo{}
default:
return false, nil
}
return true
header := chunk.Header // decouple memory by copying only the needed value
msg.SetHeader(&header)
err := msg.Unpack(u)
if err != nil {
// in case of an error, the user is not supposed to continue
// working with the returned first value
return false, err
}
packet.Messages = append(packet.Messages, msg)
return true, nil
}
func (packet *Packet) unpackChunk(chunk chunk7.Chunk) bool {
func (packet *Packet) unpackChunk(chunk chunk7.Chunk) (bool, error) {
u := packer.Unpacker{}
u.Reset(chunk.Data)
@ -249,13 +215,22 @@ func (packet *Packet) unpackChunk(chunk chunk7.Chunk) bool {
func (packet *Packet) unpackPayload(payload []byte) {
chunks := chunk7.UnpackChunks(payload)
var (
// reuse variables to avoid reallocation
ok bool
err error
)
for _, c := range chunks {
if packet.unpackChunk(c) == false {
ok, err = packet.unpackChunk(c)
if err != nil || !ok {
header := c.Header // decouple memory by copying only the needed value
unknown := &messages7.Unknown{
ChunkHeader: &c.Header,
Data: slices.Concat(c.Header.Pack(), c.Data),
Type: network7.TypeNet,
ChunkHeader: &header,
Data: slices.Concat(c.Header.Pack(), c.Data),
}
// INFO: no Unpack called here!
packet.Messages = append(packet.Messages, unknown)
}
}
@ -264,37 +239,42 @@ func (packet *Packet) unpackPayload(payload []byte) {
// Only returns an error if there is invalid huffman compression applied
// Unknown messages will be unpacked as messages7.Unknown
// There is no validation no messages will be dropped
func (packet *Packet) Unpack(data []byte) error {
packet.Header.Unpack(data[:7])
payload := data[7:]
func (packet *Packet) Unpack(data []byte) (err error) {
header, payload := data[:7], data[7:]
packet.Header.Unpack(header)
if packet.Header.Flags.Control {
unpacker := packer.Unpacker{}
unpacker.Reset(payload)
ctrlMsg := unpacker.GetInt()
if ctrlMsg == network7.MsgCtrlToken {
msg := &messages7.CtrlToken{}
msg.Unpack(&unpacker)
packet.Messages = append(packet.Messages, msg)
} else if ctrlMsg == network7.MsgCtrlAccept {
packet.Messages = append(packet.Messages, &messages7.CtrlAccept{})
} else if ctrlMsg == network7.MsgCtrlClose {
msg := &messages7.CtrlClose{}
msg.Unpack(&unpacker)
packet.Messages = append(packet.Messages, msg)
} else {
unknown := &messages7.Unknown{
Data: payload,
var msg messages7.NetMessage
switch ctrlMsg {
case network7.MsgCtrlToken:
msg = &messages7.CtrlToken{}
case network7.MsgCtrlAccept:
msg = &messages7.CtrlAccept{}
case network7.MsgCtrlClose:
msg = &messages7.CtrlClose{}
default:
msg = &messages7.Unknown{
Type: network7.TypeControl,
}
packet.Messages = append(packet.Messages, unknown)
}
err := msg.Unpack(&unpacker)
if err != nil {
return err
}
packet.Messages = append(packet.Messages, msg)
return nil
}
if packet.Header.Flags.Compression {
// TODO: try avoiding repeated initialization of the huffman tree structure
// move this into the Packet struct or even further up
huff := huffman.Huffman{}
var err error
payload, err = huff.Decompress(payload)
if err != nil {
return err
@ -319,10 +299,12 @@ func (packet *Packet) Pack(connection *Session) []byte {
packet.Header.NumChunks = len(packet.Messages)
if control {
packet.Header.Flags.Connless = false
packet.Header.Flags.Compression = false
packet.Header.Flags.Resend = false
packet.Header.Flags.Control = true
packet.Header.Flags = PacketFlags{
Connless: false,
Compression: false,
Resend: false,
Control: true,
}
}
if packet.Header.Flags.Compression {
@ -375,23 +357,36 @@ func (header *PacketHeader) Pack() []byte {
)
}
func (header *PacketHeader) Unpack(packet []byte) {
header.Flags.Unpack(packet)
func (header *PacketHeader) Unpack(packet []byte) (err error) {
if len(packet) < 7 {
return fmt.Errorf("failed to unpack packet header: packet too short: size %d", len(packet))
}
err = header.Flags.Unpack(packet)
if err != nil {
return fmt.Errorf("failed to unpack packet header: %w", err)
}
header.Ack = (int(packet[0]&0x3) << 8) | int(packet[1])
header.NumChunks = int(packet[2])
copy(header.Token[:], packet[3:7])
return nil
}
func (flags *PacketFlags) Unpack(packetHeaderRaw []byte) {
func (flags *PacketFlags) Unpack(packetHeaderRaw []byte) error {
if len(packetHeaderRaw) == 0 {
return fmt.Errorf("failed to unpack packet flags: packet header is empty")
}
flagBits := packetHeaderRaw[0] >> 2
flags.Control = (flagBits & packetFlagControl) != 0
flags.Resend = (flagBits & packetFlagResend) != 0
flags.Compression = (flagBits & packetFlagCompression) != 0
flags.Connless = (flagBits & packetFlagConnless) != 0
return nil
}
func (flags *PacketFlags) Pack() []byte {
data := 0
var data byte = 0
if flags.Control {
data |= packetFlagControl
@ -406,5 +401,5 @@ func (flags *PacketFlags) Pack() []byte {
data |= packetFlagConnless
}
return []byte{byte(data)}
return []byte{data}
}

View file

@ -1,11 +1,11 @@
package protocol7
import (
"reflect"
"slices"
"testing"
"github.com/teeworlds-go/go-teeworlds-protocol/chunk7"
"github.com/teeworlds-go/go-teeworlds-protocol/internal/testutils/require"
"github.com/teeworlds-go/go-teeworlds-protocol/messages7"
)
@ -137,12 +137,11 @@ func TestRepackUnknownMessages(t *testing.T) {
conn := Session{}
packet := Packet{}
packet.Unpack(dump)
repack := packet.Pack(&conn)
err := packet.Unpack(dump)
require.NoError(t, err)
if !reflect.DeepEqual(repack, dump) {
t.Errorf("got %v, wanted %v", repack, dump)
}
repack := packet.Pack(&conn)
require.Equal(t, dump, repack)
}
// update chunk headers
@ -154,16 +153,13 @@ func TestPackUpdateChunkHeaders(t *testing.T) {
{
got := packet.Messages[0].Header()
if got != nil {
t.Errorf("got %v, wanted %v", got, nil)
}
require.NotNil(t, got)
}
// When packing the chunk header will be set automatically
// Based on the current context
conn := &Session{Sequence: 1}
packet.Pack(conn)
_ = packet.Pack(conn)
{
got := packet.Messages[0].Header()
@ -174,10 +170,7 @@ func TestPackUpdateChunkHeaders(t *testing.T) {
Size: 8,
Seq: 2,
}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
require.Equal(t, want, got)
}
// When the chunk header is already set
@ -192,7 +185,7 @@ func TestPackUpdateChunkHeaders(t *testing.T) {
t.Fatal("failed to cast chat message")
}
packet.Pack(conn)
_ = packet.Pack(conn)
{
got := packet.Messages[0].Header()
@ -203,10 +196,7 @@ func TestPackUpdateChunkHeaders(t *testing.T) {
Size: 16,
Seq: 2,
}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
require.Equal(t, want, got)
}
}
@ -224,12 +214,9 @@ func TestPackHeader(t *testing.T) {
NumChunks: 0,
Token: [4]byte{0xcf, 0x2e, 0xde, 0x1d},
}
got := header.Pack()
want := []byte{0x04, 0x0a, 0x00, 0xcf, 0x2e, 0xde, 0x1d}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got := header.Pack()
require.Equal(t, want, got)
}
// pack flags
@ -242,12 +229,9 @@ func TestPackFlagsUnset(t *testing.T) {
Control: false,
}
got := flags.Pack()
want := []byte{0b0000}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got := flags.Pack()
require.Equal(t, want, got)
}
func TestPackFlagsCompressionSet(t *testing.T) {
@ -258,12 +242,9 @@ func TestPackFlagsCompressionSet(t *testing.T) {
Control: false,
}
got := flags.Pack()
want := []byte{0b0100}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got := flags.Pack()
require.Equal(t, want, got)
}
func TestPackFlagsAllSet(t *testing.T) {
@ -274,50 +255,41 @@ func TestPackFlagsAllSet(t *testing.T) {
Control: true,
}
got := flags.Pack()
want := []byte{0b1111}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got := flags.Pack()
require.Equal(t, want, got)
}
// unpack
func TestUnpackFlagsAllSet(t *testing.T) {
got := PacketFlags{}
want := PacketFlags{
Connless: true,
Compression: true,
Resend: true,
Control: true,
}
got.Unpack([]byte{0b00111100})
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got := PacketFlags{}
err := got.Unpack([]byte{0b00111100})
require.NoError(t, err)
require.Equal(t, want, got)
}
func TestUnpackFlagsControlSet(t *testing.T) {
got := PacketFlags{}
want := PacketFlags{
Connless: false,
Compression: false,
Resend: false,
Control: true,
}
got := PacketFlags{}
got.Unpack([]byte{0b00000100})
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
err := got.Unpack([]byte{0b00000100})
require.NoError(t, err)
require.Equal(t, want, got)
}
func TestUnpackFlagsUnset(t *testing.T) {
got := PacketFlags{}
want := PacketFlags{
Connless: false,
Compression: false,
@ -325,17 +297,15 @@ func TestUnpackFlagsUnset(t *testing.T) {
Control: false,
}
got.Unpack([]byte{0b00000000})
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got := PacketFlags{}
err := got.Unpack([]byte{0b00000000})
require.NoError(t, err)
require.Equal(t, want, got)
}
// packet header unpack
func TestUnpackCloseWithReason(t *testing.T) {
got := PacketHeader{}
want := PacketHeader{
Flags: PacketFlags{
Connless: false,
@ -348,15 +318,17 @@ func TestUnpackCloseWithReason(t *testing.T) {
Token: [4]byte{0xcf, 0x2e, 0xde, 0x1d},
}
got.Unpack(slices.Concat([]byte{0x04, 0x0a, 0x00, 0xcf, 0x2e, 0xde, 0x1d, 0x04}, []byte("shutdown"), []byte{0x00}))
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got := PacketHeader{}
err := got.Unpack(slices.Concat(
[]byte{0x04, 0x0a, 0x00, 0xcf, 0x2e, 0xde, 0x1d, 0x04},
[]byte("shutdown"),
[]byte{0x00},
))
require.NoError(t, err)
require.Equal(t, want, got)
}
func TestUnpackHeaderFlagsControlSet(t *testing.T) {
got := PacketHeader{}
want := PacketHeader{
Flags: PacketFlags{
Connless: false,
@ -369,15 +341,13 @@ func TestUnpackHeaderFlagsControlSet(t *testing.T) {
Token: [4]byte{0xff, 0xff, 0xff, 0xff},
}
got.Unpack([]byte{0b00000100, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff})
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got := PacketHeader{}
err := got.Unpack([]byte{0b00000100, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff})
require.NoError(t, err)
require.Equal(t, want, got)
}
func TestUnpackHeaderFlagsAllSet(t *testing.T) {
got := PacketHeader{}
want := PacketHeader{
Flags: PacketFlags{
Connless: true,
@ -390,9 +360,8 @@ func TestUnpackHeaderFlagsAllSet(t *testing.T) {
Token: [4]byte{0xff, 0xff, 0xff, 0xff},
}
got.Unpack([]byte{0b00111100, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff})
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, wanted %v", got, want)
}
got := PacketHeader{}
err := got.Unpack([]byte{0b00111100, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff})
require.NoError(t, err)
require.Equal(t, want, got)
}