Add Packet.Unpack()

This commit is contained in:
ChillerDragon 2024-06-22 10:38:06 +08:00
parent 94b6c7787c
commit 915943ff16
5 changed files with 294 additions and 0 deletions

42
messages7/con_ready.go Normal file
View file

@ -0,0 +1,42 @@
package messages7
import (
"github.com/teeworlds-go/teeworlds/chunk7"
"github.com/teeworlds-go/teeworlds/network7"
"github.com/teeworlds-go/teeworlds/packer"
)
type ConReady struct {
ChunkHeader *chunk7.ChunkHeader
}
func (msg ConReady) MsgId() int {
return network7.MsgSysConReady
}
func (msg ConReady) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg ConReady) System() bool {
return true
}
func (msg ConReady) Vital() bool {
return true
}
func (msg ConReady) Pack() []byte {
return []byte{}
}
func (msg *ConReady) Unpack(u *packer.Unpacker) {
}
func (msg *ConReady) Header() *chunk7.ChunkHeader {
return msg.ChunkHeader
}
func (msg *ConReady) SetHeader(header *chunk7.ChunkHeader) {
msg.ChunkHeader = header
}

64
messages7/map_change.go Normal file
View file

@ -0,0 +1,64 @@
package messages7
import (
"slices"
"github.com/teeworlds-go/teeworlds/chunk7"
"github.com/teeworlds-go/teeworlds/network7"
"github.com/teeworlds-go/teeworlds/packer"
)
type MapChange struct {
ChunkHeader *chunk7.ChunkHeader
Name string
Crc int
Size int
NumResponseChunksPerRequest int
ChunkSize int
Sha256 [32]byte
}
func (msg MapChange) MsgId() int {
return network7.MsgSysMapChange
}
func (msg MapChange) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg MapChange) System() bool {
return true
}
func (msg MapChange) Vital() bool {
return true
}
func (msg MapChange) Pack() []byte {
return slices.Concat(
packer.PackStr(msg.Name),
packer.PackInt(msg.Crc),
packer.PackInt(msg.Size),
packer.PackInt(msg.NumResponseChunksPerRequest),
packer.PackInt(msg.ChunkSize),
msg.Sha256[:],
)
}
func (msg *MapChange) Unpack(u *packer.Unpacker) {
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())
}
func (msg *MapChange) Header() *chunk7.ChunkHeader {
return msg.ChunkHeader
}
func (msg *MapChange) SetHeader(header *chunk7.ChunkHeader) {
msg.ChunkHeader = header
}

View file

@ -1,6 +1,8 @@
package messages7
import (
"slices"
"github.com/teeworlds-go/teeworlds/chunk7"
"github.com/teeworlds-go/teeworlds/network7"
"github.com/teeworlds-go/teeworlds/packer"
@ -51,6 +53,35 @@ func (info *SvClientInfo) Vital() bool {
return true
}
func (msg SvClientInfo) Pack() []byte {
return slices.Concat(
packer.PackInt(msg.ClientId),
packer.PackBool(msg.Local),
packer.PackInt(msg.Team),
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.ColorHands),
packer.PackInt(msg.ColorFeet),
packer.PackInt(msg.ColorEyes),
packer.PackBool(msg.Silent),
)
}
func (info *SvClientInfo) Unpack(u *packer.Unpacker) {
info.ClientId = u.GetInt()
info.Local = u.GetInt() != 0

45
messages7/sv_motd.go Normal file
View file

@ -0,0 +1,45 @@
package messages7
import (
"github.com/teeworlds-go/teeworlds/chunk7"
"github.com/teeworlds-go/teeworlds/network7"
"github.com/teeworlds-go/teeworlds/packer"
)
type SvMotd struct {
ChunkHeader *chunk7.ChunkHeader
Message string
}
func (msg SvMotd) MsgId() int {
return network7.MsgGameSvMotd
}
func (msg SvMotd) MsgType() network7.MsgType {
return network7.TypeNet
}
func (msg SvMotd) System() bool {
return false
}
func (msg SvMotd) Vital() bool {
return true
}
func (msg SvMotd) Pack() []byte {
return packer.PackStr(msg.Message)
}
func (msg *SvMotd) Unpack(u *packer.Unpacker) {
msg.Message = u.GetString()
}
func (msg *SvMotd) Header() *chunk7.ChunkHeader {
return msg.ChunkHeader
}
func (msg *SvMotd) SetHeader(header *chunk7.ChunkHeader) {
msg.ChunkHeader = header
}

View file

@ -80,6 +80,118 @@ func PackChunk(msg messages7.NetMessage, connection *Connection) []byte {
return data
}
func (packet *Packet) unpackSystem(msgId int, chunk chunk7.Chunk, u *packer.Unpacker) bool {
if msgId == network7.MsgSysMapChange {
msg := &messages7.MapChange{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 {
return false
}
// packet.Messages[len(packet.Messages)-1].SetHeader(&chunk.Header)
return true
}
func (packet *Packet) unpackGame(msgId int, chunk chunk7.Chunk, u *packer.Unpacker) bool {
if msgId == network7.MsgGameReadyToEnter {
msg := &messages7.Ready{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
}
return true
}
func (packet *Packet) unpackChunk(chunk chunk7.Chunk) bool {
u := packer.Unpacker{}
u.Reset(chunk.Data)
msg := u.GetInt()
sys := msg&1 != 0
msg >>= 1
if sys {
return packet.unpackSystem(msg, chunk, &u)
}
return packet.unpackGame(msg, chunk, &u)
}
func (packet *Packet) unpackPayload(payload []byte) {
chunks := chunk7.UnpackChunks(payload)
for _, c := range chunks {
if packet.unpackChunk(c) == false {
unknown := &messages7.Unknown{
Data: slices.Concat(c.Header.Pack(), c.Data),
Type: network7.TypeNet,
}
packet.Messages = append(packet.Messages, unknown)
}
}
}
// 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:]
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,
Type: network7.TypeControl,
}
packet.Messages = append(packet.Messages, unknown)
}
return nil
}
if packet.Header.Flags.Compression {
huff := huffman.Huffman{}
var err error
payload, err = huff.Decompress(payload)
if err != nil {
return err
}
}
packet.unpackPayload(payload)
return nil
}
func (packet *Packet) Pack(connection *Connection) []byte {
payload := []byte{}
control := false