diff --git a/messages7/ctrl_accept.go b/messages7/ctrl_accept.go new file mode 100644 index 0000000..8ce8253 --- /dev/null +++ b/messages7/ctrl_accept.go @@ -0,0 +1,39 @@ +package messages7 + +import ( + "slices" + + "github.com/teeworlds-go/teeworlds/network7" + "github.com/teeworlds-go/teeworlds/packer" +) + +type CtrlAccept struct { + Token [4]byte +} + +func (msg CtrlAccept) MsgId() int { + return network7.MsgCtrlAccept +} + +func (msg CtrlAccept) MsgType() network7.MsgType { + return network7.TypeControl +} + +func (msg CtrlAccept) System() bool { + return false +} + +func (msg CtrlAccept) Vital() bool { + return false +} + +func (msg CtrlAccept) Pack() []byte { + return slices.Concat( + []byte{network7.MsgCtrlAccept}, + msg.Token[:], + []byte{512: 0}, + ) +} + +func (msg *CtrlAccept) Unpack(u *packer.Unpacker) { +} diff --git a/messages7/sv_chat.go b/messages7/sv_chat.go new file mode 100644 index 0000000..dd2e7f4 --- /dev/null +++ b/messages7/sv_chat.go @@ -0,0 +1,47 @@ +package messages7 + +import ( + "slices" + + "github.com/teeworlds-go/teeworlds/network7" + "github.com/teeworlds-go/teeworlds/packer" +) + +type SvChat struct { + Mode int + ClientId int + TargetId int + Message string +} + +func (msg SvChat) MsgId() int { + return network7.MsgGameSvChat +} + +func (msg SvChat) MsgType() network7.MsgType { + return network7.TypeNet +} + +func (msg SvChat) System() bool { + return false +} + +func (msg SvChat) Vital() bool { + return true +} + +func (msg SvChat) Pack() []byte { + return slices.Concat( + packer.PackInt(msg.Mode), + packer.PackInt(msg.ClientId), + packer.PackInt(msg.TargetId), + packer.PackStr(msg.Message), + ) +} + +func (msg *SvChat) Unpack(u *packer.Unpacker) { + msg.Mode = u.GetInt() + msg.ClientId = u.GetInt() + msg.TargetId = u.GetInt() + msg.Message = u.GetString() +} diff --git a/protocol7/connection.go b/protocol7/connection.go index afc3d1a..7f7132e 100644 --- a/protocol7/connection.go +++ b/protocol7/connection.go @@ -111,9 +111,9 @@ func (connection *Connection) OnSystemMsg(msg int, chunk chunk7.Chunk, u *packer } } -func (client *Connection) OnChatMessage(mode int, clientId int, targetId int, message string) { - name := client.Players[clientId].Info.Name - fmt.Printf("[chat] <%s> %s\n", name, message) +func (client *Connection) OnChatMessage(msg *messages7.SvChat) { + name := client.Players[msg.ClientId].Info.Name + fmt.Printf("[chat] <%s> %s\n", name, msg.Message) } func (client *Connection) OnMotd(motd string) { @@ -131,11 +131,10 @@ func (client *Connection) OnGameMsg(msg int, chunk chunk7.Chunk, u *packer.Unpac client.OnMotd(motd) } } else if msg == network7.MsgGameSvChat { - mode := u.GetInt() - clientId := u.GetInt() - targetId := u.GetInt() - message := u.GetString() - client.OnChatMessage(mode, clientId, targetId, message) + chat := &messages7.SvChat{} + chat.Unpack(u) + client.OnChatMessage(chat) + result.Packet.Messages = append(result.Packet.Messages, chat) } else if msg == network7.MsgGameSvClientInfo { clientId := packer.UnpackInt(chunk.Data[1:]) client.Players[clientId].Info.Unpack(u) @@ -202,6 +201,7 @@ func (connection *Connection) OnPacket(data []byte) (*PacketResult, error) { copy(connection.ServerToken[:], payload[1:5]) result.Response.Header.Token = connection.ServerToken fmt.Printf("got server token %x\n", connection.ServerToken) + result.Packet.Messages = append(result.Packet.Messages, &messages7.CtrlToken{Token: connection.ServerToken}) result.Response.Messages = append( result.Response.Messages, &messages7.CtrlConnect{ @@ -210,6 +210,7 @@ func (connection *Connection) OnPacket(data []byte) (*PacketResult, error) { ) } else if ctrlMsg == network7.MsgCtrlAccept { fmt.Println("got accept") + result.Packet.Messages = append(result.Packet.Messages, &messages7.CtrlAccept{}) // TODO: don't hardcode info result.Response.Messages = append(result.Response.Messages, &messages7.Info{}) } else if ctrlMsg == network7.MsgCtrlClose { diff --git a/teeworlds.go b/teeworlds.go index fbb53da..55e6558 100644 --- a/teeworlds.go +++ b/teeworlds.go @@ -73,12 +73,26 @@ func main() { } if result.Response != nil { + // example of inspecting incoming trafic + for i, msg := range result.Packet.Messages { + if msg.MsgId() == network7.MsgGameSvChat { + var chat *messages7.SvChat + var ok bool + if chat, ok = result.Packet.Messages[i].(*messages7.SvChat); ok { + fmt.Printf("got chat msg: %s\n", chat.Message) + + // modify chat if this was a proxy + result.Response.Messages[i] = chat + } + } + } + // example of modifying outgoing traffic for i, msg := range result.Response.Messages { if msg.MsgId() == network7.MsgCtrlConnect { var connect *messages7.CtrlConnect var ok bool - if connect, ok = result.Response.Messages[0].(*messages7.CtrlConnect); ok { + if connect, ok = result.Response.Messages[i].(*messages7.CtrlConnect); ok { connect.Token = [4]byte{0xaa, 0xaa, 0xaa, 0xaa} result.Response.Messages[i] = connect }