diff --git a/.gitignore b/.gitignore index c665f0c..ef2dddc 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ protocol examples/client_echo/client_echo examples/client_verbose/client_verbose examples/client_trivia/client_trivia + +.idea/ \ No newline at end of file diff --git a/examples/client_trivia/bot/bot.go b/examples/client_trivia/bot/bot.go index c7fde2f..7101e43 100644 --- a/examples/client_trivia/bot/bot.go +++ b/examples/client_trivia/bot/bot.go @@ -4,6 +4,8 @@ import ( "context" "errors" "fmt" + "io" + "log" "log/slog" "strconv" "strings" @@ -66,6 +68,7 @@ func (b *Bot) start(ctx context.Context, ip string, port int) error { defer cancelCause(nil) client := teeworlds7.NewClient() + client.Logger = log.New(io.Discard, "", 0) // an example on how to discard protocol debugging logs client.OnUnknown(func(msg *messages7.Unknown, defaultAction teeworlds7.DefaultAction) error { return nil diff --git a/go.mod b/go.mod index 1b4104f..378c4a6 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,4 @@ module github.com/teeworlds-go/protocol go 1.22.3 -require github.com/teeworlds-go/huffman/v2 v2.0.0 +require github.com/teeworlds-go/huffman/v2 v2.0.0 \ No newline at end of file diff --git a/object7/snap_object.go b/object7/snap_object.go index b2f7b2d..b57e02c 100644 --- a/object7/snap_object.go +++ b/object7/snap_object.go @@ -1,7 +1,6 @@ package object7 import ( - "fmt" "log" "github.com/teeworlds-go/protocol/network7" @@ -85,7 +84,7 @@ func NewObject(typeId int, itemId int, u *packer.Unpacker) SnapObject { } else if typeId == network7.ObjGameDataRace { race := &GameDataRace{ItemId: itemId} size := u.GetInt() - fmt.Printf("got gamedata race red size=%d remaining unpacker data=%x\n", size, u.RemainingData()) + //fmt.Printf("got gamedata race red size=%d remaining unpacker data=%x\n", size, u.RemainingData()) if size != race.Size() { log.Panicf("got game data race with size %d but expected size %d\n", size, race.Size()) } diff --git a/snapshot7/ddnet_2part_snap_on_connect_test.go b/snapshot7/ddnet_2part_snap_on_connect_test.go index cfc1cdc..79b38d0 100644 --- a/snapshot7/ddnet_2part_snap_on_connect_test.go +++ b/snapshot7/ddnet_2part_snap_on_connect_test.go @@ -3,6 +3,7 @@ package snapshot7_test // ddnet rus production server import ( + "log" "testing" "github.com/teeworlds-go/protocol/internal/testutils/require" @@ -196,7 +197,7 @@ func TestDdnetCrash(t *testing.T) { u := &packer.Unpacker{} u.Reset(client.SnapshotStorage.IncomingData()) - newFullSnap, err := snapshot7.UnpackDelta(prevSnap, u) + newFullSnap, err := snapshot7.UnpackDelta(log.Default(), prevSnap, u) require.NoError(t, err) err = client.SnapshotStorage.Add(part1.GameTick, newFullSnap) diff --git a/snapshot7/multi_part_test.go b/snapshot7/multi_part_test.go index 2e93236..9acaed9 100644 --- a/snapshot7/multi_part_test.go +++ b/snapshot7/multi_part_test.go @@ -1,6 +1,7 @@ package snapshot7_test import ( + "log" "testing" "github.com/teeworlds-go/protocol/internal/testutils/require" @@ -367,7 +368,7 @@ func Test4PartSnap(t *testing.T) { u := &packer.Unpacker{} u.Reset(client.SnapshotStorage.IncomingData()) - newFullSnap, err := snapshot7.UnpackDelta(prevSnap, u) + newFullSnap, err := snapshot7.UnpackDelta(log.Default(), prevSnap, u) require.NoError(t, err) err = client.SnapshotStorage.Add(part2.GameTick, newFullSnap) diff --git a/snapshot7/snapshot7.go b/snapshot7/snapshot7.go index 99c53b3..f4b8e50 100644 --- a/snapshot7/snapshot7.go +++ b/snapshot7/snapshot7.go @@ -2,6 +2,7 @@ package snapshot7 import ( "fmt" + "log" "log/slog" "github.com/teeworlds-go/protocol/network7" @@ -143,7 +144,7 @@ func (snap *Snapshot) GetItemIndex(key int) (index int, found bool) { // it returns the new full snapshot with the delta applied to the from // // See also (Snapshot *)Unpack() -func UnpackDelta(from *Snapshot, u *packer.Unpacker) (*Snapshot, error) { +func UnpackDelta(l *log.Logger, from *Snapshot, u *packer.Unpacker) (*Snapshot, error) { // TODO: add all the error checking the C++ reference implementation has snap := &Snapshot{} @@ -152,12 +153,12 @@ func UnpackDelta(from *Snapshot, u *packer.Unpacker) (*Snapshot, error) { snap.NumItemDeltas = u.GetInt() u.GetInt() // _zero - slog.Debug("got new snapshot!", "num_deleted", snap.NumRemovedItems, "num_updates", snap.NumItemDeltas) + l.Println("got new snapshot!", "num_deleted", snap.NumRemovedItems, "num_updates", snap.NumItemDeltas) deletedKeys := make([]int, snap.NumRemovedItems) for d := 0; d < snap.NumRemovedItems; d++ { deletedKeys[d] = u.GetInt() - slog.Debug("delta unpack del key", "key", deletedKeys[d], "d_index", d, "num_deleted", snap.NumRemovedItems, "remaining_data", u.RemainingData()) + l.Println("delta unpack del key", "key", deletedKeys[d], "d_index", d, "num_deleted", snap.NumRemovedItems, "remaining_data", u.RemainingData()) } for i := 0; i < len(from.Items); i++ { @@ -166,7 +167,7 @@ func UnpackDelta(from *Snapshot, u *packer.Unpacker) (*Snapshot, error) { for _, deletedKey := range deletedKeys { if deletedKey == ItemKey(fromItem) { - slog.Debug("delta del item", "deleted_key", deletedKey, "item_type", fromItem.TypeId(), "item_id", fromItem.Id()) + l.Println("delta del item", "deleted_key", deletedKey, "item_type", fromItem.TypeId(), "item_id", fromItem.Id()) keep = false break } @@ -181,7 +182,7 @@ func UnpackDelta(from *Snapshot, u *packer.Unpacker) (*Snapshot, error) { itemType := u.GetInt() itemId := u.GetInt() - slog.Debug("unpack item snap item ", "num", i, "total", snap.NumItemDeltas, "type", itemType, "id", itemId) + l.Println("unpack item snap item ", "num", i, "total", snap.NumItemDeltas, "type", itemType, "id", itemId) item := object7.NewObject(itemType, itemId, u) err := item.Unpack(u) diff --git a/teeworlds7/client.go b/teeworlds7/client.go index c81fe39..80e0ad5 100644 --- a/teeworlds7/client.go +++ b/teeworlds7/client.go @@ -3,6 +3,7 @@ package teeworlds7 import ( "context" "fmt" + "log" "net" "time" @@ -66,6 +67,8 @@ type Client struct { // of the OnDisconnect callback Ctx context.Context CancelCause context.CancelCauseFunc + + Logger *log.Logger } // TODO: add this for all items and move it to a different file @@ -100,6 +103,7 @@ func NewClient() *Client { }, LocalClientId: UnknownClientId, LastSend: time.Now(), + Logger: log.Default(), } } diff --git a/teeworlds7/game.go b/teeworlds7/game.go index 9bb4c28..df35ac0 100644 --- a/teeworlds7/game.go +++ b/teeworlds7/game.go @@ -19,23 +19,23 @@ func (client *Client) processGame(netMsg messages7.NetMessage, response *protoco case *messages7.SvMotd: err = userMsgCallback(client.Callbacks.GameSvMotd, msg, func() error { if msg.Message != "" { - fmt.Printf("[motd] %s\n", msg.Message) + client.Logger.Printf("[motd] %s\n", msg.Message) } return nil }) case *messages7.SvBroadcast: err = userMsgCallback(client.Callbacks.GameSvBroadcast, msg, func() error { - fmt.Printf("[broadcast] %s\n", msg.Message) + client.Logger.Printf("[broadcast] %s\n", msg.Message) return nil }) case *messages7.SvChat: err = userMsgCallback(client.Callbacks.GameSvChat, msg, func() error { if msg.ClientId < 0 || msg.ClientId > network7.MaxClients { - fmt.Printf("[chat] *** %s\n", msg.Message) + client.Logger.Printf("[chat] *** %s\n", msg.Message) return nil } name := client.Game.Players[msg.ClientId].Info.Name - fmt.Printf("[chat] <%s> %s\n", name, msg.Message) + client.Logger.Printf("[chat] <%s> %s\n", name, msg.Message) return nil }) case *messages7.SvClientInfo: @@ -44,24 +44,24 @@ func (client *Client) processGame(netMsg messages7.NetMessage, response *protoco if msg.Local { client.LocalClientId = msg.ClientId } - fmt.Printf("got client info id=%d name=%s\n", msg.ClientId, msg.Name) + client.Logger.Printf("got client info id=%d name=%s\n", msg.ClientId, msg.Name) return nil }) case *messages7.SvReadyToEnter: err = userMsgCallback(client.Callbacks.GameSvReadyToEnter, msg, func() error { - fmt.Println("got ready to enter") + client.Logger.Println("got ready to enter") response.Messages = append(response.Messages, &messages7.EnterGame{}) return nil }) case *messages7.Unknown: err = userMsgCallback(client.Callbacks.MsgUnknown, msg, func() error { // TODO: msg id of unknown messages should not be -1 - fmt.Println("TODO: why is the msg id -1???") - printUnknownMessage(msg, "unknown game") + client.Logger.Println("TODO: why is the msg id -1???") + printUnknownMessage(client.Logger, msg, "unknown game") return nil }) default: - printUnknownMessage(netMsg, "unprocessed game") + printUnknownMessage(client.Logger, netMsg, "unprocessed game") return false, nil } if err != nil { diff --git a/teeworlds7/packet.go b/teeworlds7/packet.go index 9f4350a..dc4a8c4 100644 --- a/teeworlds7/packet.go +++ b/teeworlds7/packet.go @@ -2,6 +2,7 @@ package teeworlds7 import ( "fmt" + "log" "github.com/teeworlds-go/protocol/messages7" "github.com/teeworlds-go/protocol/network7" @@ -20,23 +21,23 @@ func (e DisconnectError) Error() string { return fmt.Sprintf("disconnected: %s", e.Reason) } -func printUnknownMessage(msg messages7.NetMessage, msgType string) { - fmt.Printf("%s message id=%d\n", msgType, msg.MsgId()) +func printUnknownMessage(l *log.Logger, msg messages7.NetMessage, msgType string) { + l.Printf("%s message id=%d\n", msgType, msg.MsgId()) if msg.Header() == nil { - fmt.Println(" header: nil") + l.Println(" header: nil") } else { - fmt.Printf(" header: %x\n", msg.Header().Pack()) + l.Printf(" header: %x\n", msg.Header().Pack()) } - fmt.Printf(" payload: %x\n", msg.Pack()) + l.Printf(" payload: %x\n", msg.Pack()) if msg.Header() != nil { - fmt.Printf(" full msg: %x%x\n", msg.Header().Pack(), msg.Pack()) + l.Printf(" full msg: %x%x\n", msg.Header().Pack(), msg.Pack()) } } -func (client *Client) processMessage(msg messages7.NetMessage, response *protocol7.Packet) (process bool, err error) { +func (client *Client) processMessage(l *log.Logger, msg messages7.NetMessage, response *protocol7.Packet) (process bool, err error) { if msg.Header() == nil { // this is probably an unknown message - fmt.Printf("warning ignoring msgId=%d because header is nil\n", msg.MsgId()) + l.Printf("warning ignoring msgId=%d because header is nil\n", msg.MsgId()) return false, nil } if msg.Header().Flags.Vital { @@ -75,18 +76,18 @@ func (client *Client) processPacket(packet *protocol7.Packet) (err error) { switch msg := msg.(type) { case *messages7.CtrlKeepAlive: err = userMsgCallback(client.Callbacks.CtrlKeepAlive, msg, func() error { - fmt.Println("got keep alive") + client.Logger.Println("got keep alive") return nil }) case *messages7.CtrlConnect: err = userMsgCallback(client.Callbacks.CtrlConnect, msg, func() error { - fmt.Println("we got connect as a client. this should never happen lol.") - fmt.Println("who is trying to connect to us? We are not a server!") + client.Logger.Println("we got connect as a client. this should never happen lol.") + client.Logger.Println("who is trying to connect to us? We are not a server!") return nil }) case *messages7.CtrlAccept: err = userMsgCallback(client.Callbacks.CtrlAccept, msg, func() error { - fmt.Println("got accept") + client.Logger.Println("got accept") response.Messages = append( response.Messages, &messages7.Info{ @@ -100,12 +101,12 @@ func (client *Client) processPacket(packet *protocol7.Packet) (err error) { case *messages7.CtrlClose: err = userMsgCallback(client.Callbacks.CtrlClose, msg, func() error { client.CancelCause(DisconnectError{Reason: msg.Reason}) - fmt.Printf("disconnected (%s)\n", msg.Reason) + client.Logger.Printf("disconnected (%s)\n", msg.Reason) return nil }) case *messages7.CtrlToken: err = userMsgCallback(client.Callbacks.CtrlToken, msg, func() error { - fmt.Printf("got server token %x\n", msg.Token) + client.Logger.Printf("got server token %x\n", msg.Token) client.Session.ServerToken = msg.Token response.Header.Token = msg.Token response.Messages = append( @@ -118,7 +119,7 @@ func (client *Client) processPacket(packet *protocol7.Packet) (err error) { }) case *messages7.Unknown: err = userMsgCallback(client.Callbacks.MsgUnknown, msg, func() error { - printUnknownMessage(msg, "unknown control") + printUnknownMessage(client.Logger, msg, "unknown control") return nil }) if err != nil { @@ -133,7 +134,7 @@ func (client *Client) processPacket(packet *protocol7.Packet) (err error) { } for _, msg := range packet.Messages { - _, err = client.processMessage(msg, response) + _, err = client.processMessage(client.Logger, msg, response) if err != nil { return err } diff --git a/teeworlds7/system.go b/teeworlds7/system.go index 184991a..72437ad 100644 --- a/teeworlds7/system.go +++ b/teeworlds7/system.go @@ -20,23 +20,23 @@ func (client *Client) processSystem(netMsg messages7.NetMessage, response *proto switch msg := netMsg.(type) { case *messages7.MapChange: err = userMsgCallback(client.Callbacks.SysMapChange, msg, func() error { - fmt.Println("got map change") + client.Logger.Println("got map change") response.Messages = append(response.Messages, &messages7.Ready{}) return nil }) case *messages7.MapData: err = userMsgCallback(client.Callbacks.SysMapData, msg, func() error { - fmt.Printf("got map chunk %x\n", msg.Data) + client.Logger.Printf("got map chunk %x\n", msg.Data) return nil }) case *messages7.ServerInfo: err = userMsgCallback(client.Callbacks.SysServerInfo, msg, func() error { - fmt.Printf("connected to server with name '%s'\n", msg.Name) + client.Logger.Printf("connected to server with name '%s'\n", msg.Name) return nil }) case *messages7.ConReady: err = userMsgCallback(client.Callbacks.SysConReady, msg, func() error { - fmt.Println("connected, sending info") + client.Logger.Println("connected, sending info") info := &messages7.ClStartInfo{ Name: client.Name, Clan: client.Clan, @@ -114,7 +114,7 @@ func (client *Client) processSystem(netMsg messages7.NetMessage, response *proto u := &packer.Unpacker{} u.Reset(client.SnapshotStorage.IncomingData()) - newFullSnap, err := snapshot7.UnpackDelta(prevSnap, u) + newFullSnap, err := snapshot7.UnpackDelta(client.Logger, prevSnap, u) if err != nil { return fmt.Errorf("delta unpack failed: %w", err) } @@ -171,7 +171,7 @@ func (client *Client) processSystem(netMsg messages7.NetMessage, response *proto u := &packer.Unpacker{} u.Reset(msg.Data) - newFullSnap, err := snapshot7.UnpackDelta(prevSnap, u) + newFullSnap, err := snapshot7.UnpackDelta(client.Logger, prevSnap, u) if err != nil { return fmt.Errorf("delta unpack failed: %w", err) } @@ -263,38 +263,38 @@ func (client *Client) processSystem(netMsg messages7.NetMessage, response *proto }) case *messages7.RconAuthOn: err = userMsgCallback(client.Callbacks.SysRconAuthOn, msg, func() error { - fmt.Println("you are now authenticated in rcon") + client.Logger.Println("you are now authenticated in rcon") return nil }) case *messages7.RconAuthOff: err = userMsgCallback(client.Callbacks.SysRconAuthOff, msg, func() error { - fmt.Println("you are no longer authenticated in rcon") + client.Logger.Println("you are no longer authenticated in rcon") return nil }) case *messages7.RconLine: err = userMsgCallback(client.Callbacks.SysRconLine, msg, func() error { - fmt.Printf("[rcon] %s\n", msg.Line) + client.Logger.Printf("[rcon] %s\n", msg.Line) return nil }) case *messages7.RconCmdAdd: err = userMsgCallback(client.Callbacks.SysRconCmdAdd, msg, func() error { - fmt.Printf("got rcon cmd=%s %s %s\n", msg.Name, msg.Params, msg.Help) + client.Logger.Printf("got rcon cmd=%s %s %s\n", msg.Name, msg.Params, msg.Help) return nil }) case *messages7.RconCmdRem: err = userMsgCallback(client.Callbacks.SysRconCmdRem, msg, func() error { - fmt.Printf("removed cmd=%s\n", msg.Name) + client.Logger.Printf("removed cmd=%s\n", msg.Name) return nil }) case *messages7.Unknown: err = userMsgCallback(client.Callbacks.MsgUnknown, msg, func() error { // TODO: msg id of unknown messages should not be -1 - fmt.Println("TODO: why is the msg id -1???") - printUnknownMessage(msg, "unknown system") + client.Logger.Println("TODO: why is the msg id -1???") + printUnknownMessage(client.Logger, msg, "unknown system") return nil }) default: - printUnknownMessage(netMsg, "unprocessed system") + printUnknownMessage(client.Logger, netMsg, "unprocessed system") return false, nil } if err != nil { diff --git a/teeworlds7/unpack_delta_test.go b/teeworlds7/unpack_delta_test.go index f54986c..3698bc7 100644 --- a/teeworlds7/unpack_delta_test.go +++ b/teeworlds7/unpack_delta_test.go @@ -1,6 +1,7 @@ package teeworlds7_test import ( + "log" "testing" "github.com/teeworlds-go/protocol/internal/testutils/require" @@ -216,7 +217,7 @@ func TestUnpackDelta(t *testing.T) { u := &packer.Unpacker{} u.Reset(snapSingle1.Data) - newFullSnap, err := snapshot7.UnpackDelta(prevSnap, u) + newFullSnap, err := snapshot7.UnpackDelta(log.Default(), prevSnap, u) require.NoError(t, err) err = client.SnapshotStorage.Add(snapSingle1.GameTick, newFullSnap) @@ -231,7 +232,7 @@ func TestUnpackDelta(t *testing.T) { u.Reset(snapSingle2.Data) - newFullSnap, err = snapshot7.UnpackDelta(prevSnap, u) + newFullSnap, err = snapshot7.UnpackDelta(log.Default(), prevSnap, u) require.NoError(t, err) err = client.SnapshotStorage.Add(snapSingle2.GameTick, newFullSnap)