diff options
| author | Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> | 2023-09-12 20:53:09 +0300 |
|---|---|---|
| committer | Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> | 2023-09-16 21:39:42 +0300 |
| commit | 82871ba1bac1d62f69e1933b66659e62d2e5e063 (patch) | |
| tree | a906310fba89b670bcfda9625a6d776553d482f6 | |
| parent | net/svc messages finally getting parsed correctly (diff) | |
| download | sdp.go-82871ba1bac1d62f69e1933b66659e62d2e5e063.tar.gz sdp.go-82871ba1bac1d62f69e1933b66659e62d2e5e063.tar.bz2 sdp.go-82871ba1bac1d62f69e1933b66659e62d2e5e063.zip | |
another rewrite, v1.0.0
74 files changed, 1147 insertions, 997 deletions
diff --git a/cmd/parser.go b/cmd/parser.go new file mode 100644 index 0000000..d03fa9c --- /dev/null +++ b/cmd/parser.go | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | package main | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | "os" | ||
| 6 | "reflect" | ||
| 7 | |||
| 8 | "github.com/pektezol/bitreader" | ||
| 9 | "github.com/pektezol/demoparser/pkg/packets" | ||
| 10 | ) | ||
| 11 | |||
| 12 | func main() { | ||
| 13 | if len(os.Args) != 2 { | ||
| 14 | panic("specify file in command line arguments") | ||
| 15 | } | ||
| 16 | files, err := os.ReadDir(os.Args[1]) | ||
| 17 | if err != nil { // If it's not a directory | ||
| 18 | file, err := os.Open(os.Args[1]) | ||
| 19 | if err != nil { | ||
| 20 | panic(err) | ||
| 21 | } | ||
| 22 | reader := bitreader.Reader(file, true) | ||
| 23 | demoParserHandler(reader) | ||
| 24 | defer file.Close() | ||
| 25 | } | ||
| 26 | for _, fileinfo := range files { // If it is a directory | ||
| 27 | file, err := os.Open(os.Args[1] + fileinfo.Name()) | ||
| 28 | if err != nil { | ||
| 29 | panic(err) | ||
| 30 | } | ||
| 31 | reader := bitreader.Reader(file, true) | ||
| 32 | demoParserHandler(reader) | ||
| 33 | defer file.Close() | ||
| 34 | } | ||
| 35 | // fmt.Scanln() | ||
| 36 | } | ||
| 37 | |||
| 38 | func demoParserHandler(reader *bitreader.ReaderType) { | ||
| 39 | packets.ParseHeaders(reader) | ||
| 40 | for { | ||
| 41 | packet := packets.ParsePackets(reader) | ||
| 42 | if packet.PacketType == 7 { | ||
| 43 | break | ||
| 44 | } | ||
| 45 | // if packet.PacketType != 5 { | ||
| 46 | // continue | ||
| 47 | // } | ||
| 48 | fmt.Printf("[%d] %s (%d):\n\t%+v\n", packet.TickNumber, reflect.ValueOf(packet.Data).Type(), packet.PacketType, packet.Data) | ||
| 49 | } | ||
| 50 | } | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | module github.com/pektezol/demoparser | 1 | module github.com/pektezol/demoparser |
| 2 | 2 | ||
| 3 | go 1.19 | 3 | go 1.21.0 |
| 4 | 4 | ||
| 5 | require github.com/pektezol/bitreader v1.2.9 | 5 | require github.com/pektezol/bitreader v1.3.0 |
| @@ -1,2 +1,2 @@ | |||
| 1 | github.com/pektezol/bitreader v1.2.9 h1:DnCe5vDt6vC9zRVaeX47XjlcgK1i0jDPhYd8cimyPvo= | 1 | github.com/pektezol/bitreader v1.3.0 h1:VOj1M+vw0+xuBUlD4HPHdkjnVdUrHw2nwa5Ccxxm2ek= |
| 2 | github.com/pektezol/bitreader v1.2.9/go.mod h1:RKAUiA//jCPJzO10P+VSkBq4wfY38TaNjpCjQ+DmbcQ= | 2 | github.com/pektezol/bitreader v1.3.0/go.mod h1:RKAUiA//jCPJzO10P+VSkBq4wfY38TaNjpCjQ+DmbcQ= |
diff --git a/main.go b/main.go deleted file mode 100644 index 8f05c2b..0000000 --- a/main.go +++ /dev/null | |||
| @@ -1,49 +0,0 @@ | |||
| 1 | package main | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | "io/ioutil" | ||
| 6 | "log" | ||
| 7 | "os" | ||
| 8 | |||
| 9 | "github.com/pektezol/bitreader" | ||
| 10 | "github.com/pektezol/demoparser/packets" | ||
| 11 | ) | ||
| 12 | |||
| 13 | func main() { | ||
| 14 | if len(os.Args) != 2 { | ||
| 15 | log.Fatal("Specify file in command line arguments.") | ||
| 16 | } | ||
| 17 | files, err := ioutil.ReadDir(os.Args[1]) | ||
| 18 | if err != nil { // If it's not a directory | ||
| 19 | file, err := os.Open(os.Args[1]) | ||
| 20 | if err != nil { | ||
| 21 | panic(err) | ||
| 22 | } | ||
| 23 | reader := bitreader.Reader(file, true) | ||
| 24 | packets.ParseHeader(reader) | ||
| 25 | for { | ||
| 26 | code := packets.ParsePacket(reader) | ||
| 27 | if code == 7 { | ||
| 28 | break | ||
| 29 | } | ||
| 30 | } | ||
| 31 | defer file.Close() | ||
| 32 | } | ||
| 33 | for _, fileinfo := range files { // If it is a directory | ||
| 34 | file, err := os.Open(os.Args[1] + fileinfo.Name()) | ||
| 35 | if err != nil { | ||
| 36 | panic(err) | ||
| 37 | } | ||
| 38 | /*messages.ParseHeader(file) | ||
| 39 | for { | ||
| 40 | code := messages.ParseMessage(file) | ||
| 41 | if code == 7 { | ||
| 42 | messages.ParseMessage(file) | ||
| 43 | break | ||
| 44 | } | ||
| 45 | }*/ | ||
| 46 | defer file.Close() | ||
| 47 | } | ||
| 48 | fmt.Scanln() | ||
| 49 | } | ||
diff --git a/packets/classes/cmdinfo.go b/packets/classes/cmdinfo.go deleted file mode 100644 index d11bebc..0000000 --- a/packets/classes/cmdinfo.go +++ /dev/null | |||
| @@ -1,61 +0,0 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type CmdInfo struct { | ||
| 6 | Flags int32 | ||
| 7 | ViewOrigin []float32 | ||
| 8 | ViewAngles []float32 | ||
| 9 | LocalViewAngles []float32 | ||
| 10 | ViewOrigin2 []float32 | ||
| 11 | ViewAngles2 []float32 | ||
| 12 | LocalViewAngles2 []float32 | ||
| 13 | } | ||
| 14 | |||
| 15 | func ParseCmdInfo(reader *bitreader.ReaderType, MSSC int) []CmdInfo { | ||
| 16 | var out []CmdInfo | ||
| 17 | for i := 0; i < MSSC; i++ { | ||
| 18 | flags := int32(reader.TryReadInt32()) | ||
| 19 | viewOrigin := []float32{ | ||
| 20 | reader.TryReadFloat32(), | ||
| 21 | reader.TryReadFloat32(), | ||
| 22 | reader.TryReadFloat32(), | ||
| 23 | } | ||
| 24 | viewAngles := []float32{ | ||
| 25 | reader.TryReadFloat32(), | ||
| 26 | reader.TryReadFloat32(), | ||
| 27 | reader.TryReadFloat32(), | ||
| 28 | } | ||
| 29 | localViewAngles := []float32{ | ||
| 30 | reader.TryReadFloat32(), | ||
| 31 | reader.TryReadFloat32(), | ||
| 32 | reader.TryReadFloat32(), | ||
| 33 | } | ||
| 34 | viewOrigin2 := []float32{ | ||
| 35 | reader.TryReadFloat32(), | ||
| 36 | reader.TryReadFloat32(), | ||
| 37 | reader.TryReadFloat32(), | ||
| 38 | } | ||
| 39 | viewAngles2 := []float32{ | ||
| 40 | reader.TryReadFloat32(), | ||
| 41 | reader.TryReadFloat32(), | ||
| 42 | reader.TryReadFloat32(), | ||
| 43 | } | ||
| 44 | localViewAngles2 := []float32{ | ||
| 45 | reader.TryReadFloat32(), | ||
| 46 | reader.TryReadFloat32(), | ||
| 47 | reader.TryReadFloat32(), | ||
| 48 | } | ||
| 49 | cmdInfo := CmdInfo{ | ||
| 50 | Flags: flags, | ||
| 51 | ViewOrigin: viewOrigin, | ||
| 52 | ViewAngles: viewAngles, | ||
| 53 | LocalViewAngles: localViewAngles, | ||
| 54 | ViewOrigin2: viewOrigin2, | ||
| 55 | ViewAngles2: viewAngles2, | ||
| 56 | LocalViewAngles2: localViewAngles2, | ||
| 57 | } | ||
| 58 | out = append(out, cmdInfo) | ||
| 59 | } | ||
| 60 | return out | ||
| 61 | } | ||
diff --git a/packets/classes/datatable.go b/packets/classes/datatable.go deleted file mode 100644 index 405dae6..0000000 --- a/packets/classes/datatable.go +++ /dev/null | |||
| @@ -1,66 +0,0 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "bytes" | ||
| 5 | "fmt" | ||
| 6 | |||
| 7 | "github.com/pektezol/bitreader" | ||
| 8 | ) | ||
| 9 | |||
| 10 | type DataTable struct { | ||
| 11 | SendTable []SendTable | ||
| 12 | ServerClassInfo []ServerClassInfo | ||
| 13 | } | ||
| 14 | |||
| 15 | type SendTable struct { | ||
| 16 | NeedsDecoder bool | ||
| 17 | NetTableName string | ||
| 18 | NumOfProps uint16 | ||
| 19 | SendPropType int8 | ||
| 20 | SendPropName string | ||
| 21 | SendPropFlags int16 | ||
| 22 | } | ||
| 23 | |||
| 24 | type ServerClassInfo struct { | ||
| 25 | ClassId int16 | ||
| 26 | ClassName string | ||
| 27 | DataTableName string | ||
| 28 | } | ||
| 29 | |||
| 30 | func ParseDataTable(data []byte) DataTable { | ||
| 31 | reader := bitreader.Reader(bytes.NewReader(data), true) | ||
| 32 | sendtable := parseSendTable(reader) | ||
| 33 | serverclassinfo := parseServerClassInfo(reader) | ||
| 34 | return DataTable{ | ||
| 35 | SendTable: sendtable, | ||
| 36 | ServerClassInfo: serverclassinfo, | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | func parseSendTable(reader *bitreader.ReaderType) []SendTable { | ||
| 41 | var sendtables []SendTable | ||
| 42 | for reader.TryReadBool() { | ||
| 43 | sendtables = append(sendtables, SendTable{ | ||
| 44 | NeedsDecoder: reader.TryReadBool(), | ||
| 45 | NetTableName: reader.TryReadString(), | ||
| 46 | NumOfProps: uint16(reader.TryReadBits(10)), | ||
| 47 | SendPropType: int8(reader.TryReadBits(5)), | ||
| 48 | SendPropName: reader.TryReadString(), | ||
| 49 | SendPropFlags: int16(reader.TryReadInt16()), | ||
| 50 | }) | ||
| 51 | } | ||
| 52 | return sendtables | ||
| 53 | } | ||
| 54 | func parseServerClassInfo(reader *bitreader.ReaderType) []ServerClassInfo { | ||
| 55 | var serverclassinfo []ServerClassInfo | ||
| 56 | numofclasses := reader.TryReadInt16() | ||
| 57 | fmt.Println(numofclasses) | ||
| 58 | for i := 0; i < int(numofclasses); i++ { | ||
| 59 | serverclassinfo = append(serverclassinfo, ServerClassInfo{ | ||
| 60 | ClassId: int16(reader.TryReadInt16()), | ||
| 61 | ClassName: reader.TryReadString(), | ||
| 62 | DataTableName: reader.TryReadString(), | ||
| 63 | }) | ||
| 64 | } | ||
| 65 | return serverclassinfo | ||
| 66 | } | ||
diff --git a/packets/classes/stringtable.go b/packets/classes/stringtable.go deleted file mode 100644 index a1432f9..0000000 --- a/packets/classes/stringtable.go +++ /dev/null | |||
| @@ -1,51 +0,0 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "bytes" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | ) | ||
| 8 | |||
| 9 | type StringTable struct { | ||
| 10 | TableName string | ||
| 11 | NumOfEntries int16 | ||
| 12 | EntryName string | ||
| 13 | EntrySize int16 | ||
| 14 | EntryData []byte | ||
| 15 | NumOfClientEntries int16 | ||
| 16 | ClientEntryName string | ||
| 17 | ClientEntrySize int16 | ||
| 18 | ClientEntryData []byte | ||
| 19 | } | ||
| 20 | |||
| 21 | func ParseStringTable(data []byte) []StringTable { | ||
| 22 | reader := bitreader.Reader(bytes.NewReader(data), true) | ||
| 23 | var stringTables []StringTable | ||
| 24 | numOfTables := reader.TryReadInt8() | ||
| 25 | for i := 0; i < int(numOfTables); i++ { | ||
| 26 | var stringTable StringTable | ||
| 27 | stringTable.TableName = reader.TryReadString() | ||
| 28 | stringTable.NumOfEntries = int16(reader.TryReadInt16()) | ||
| 29 | stringTable.EntryName = reader.TryReadString() | ||
| 30 | if reader.TryReadBool() { | ||
| 31 | stringTable.EntrySize = int16(reader.TryReadInt16()) | ||
| 32 | } | ||
| 33 | if reader.TryReadBool() { | ||
| 34 | stringTable.EntryData = reader.TryReadBytesToSlice(int(stringTable.EntrySize)) | ||
| 35 | } | ||
| 36 | if reader.TryReadBool() { | ||
| 37 | stringTable.NumOfClientEntries = int16(reader.TryReadInt16()) | ||
| 38 | } | ||
| 39 | if reader.TryReadBool() { | ||
| 40 | stringTable.ClientEntryName = reader.TryReadString() | ||
| 41 | } | ||
| 42 | if reader.TryReadBool() { | ||
| 43 | stringTable.ClientEntrySize = int16(reader.TryReadInt16()) | ||
| 44 | } | ||
| 45 | if reader.TryReadBool() { | ||
| 46 | stringTable.ClientEntryData = reader.TryReadBytesToSlice(int(stringTable.ClientEntrySize)) | ||
| 47 | } | ||
| 48 | stringTables = append(stringTables, stringTable) | ||
| 49 | } | ||
| 50 | return stringTables | ||
| 51 | } | ||
diff --git a/packets/header.go b/packets/header.go deleted file mode 100644 index c4172d9..0000000 --- a/packets/header.go +++ /dev/null | |||
| @@ -1,33 +0,0 @@ | |||
| 1 | package packets | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | ) | ||
| 8 | |||
| 9 | func ParseHeader(reader *bitreader.ReaderType) { | ||
| 10 | header := Header{ | ||
| 11 | DemoFileStamp: reader.TryReadStringLen(8), | ||
| 12 | DemoProtocol: uint32(reader.TryReadInt32()), | ||
| 13 | NetworkProtocol: uint32(reader.TryReadInt32()), | ||
| 14 | ServerName: reader.TryReadStringLen(260), | ||
| 15 | ClientName: reader.TryReadStringLen(260), | ||
| 16 | MapName: reader.TryReadStringLen(260), | ||
| 17 | GameDirectory: reader.TryReadStringLen(260), | ||
| 18 | PlaybackTime: reader.TryReadFloat32(), | ||
| 19 | PlaybackTicks: int32(reader.TryReadInt32()), | ||
| 20 | PlaybackFrames: int32(reader.TryReadInt32()), | ||
| 21 | SignOnLength: uint32(reader.TryReadInt32()), | ||
| 22 | } | ||
| 23 | if header.DemoFileStamp != "HL2DEMO" { | ||
| 24 | panic("Invalid demo file stamp. Make sure a valid demo file is given.") | ||
| 25 | } | ||
| 26 | if header.DemoProtocol != 4 { | ||
| 27 | panic("Given demo is from old engine. This parser is only supported for new engine.") | ||
| 28 | } | ||
| 29 | if header.NetworkProtocol != 2001 { | ||
| 30 | panic("Given demo is not from Portal2. This parser currently only supports Portal 2.") | ||
| 31 | } | ||
| 32 | fmt.Println(header) | ||
| 33 | } | ||
diff --git a/packets/messages/message.go b/packets/messages/message.go deleted file mode 100644 index 4a00212..0000000 --- a/packets/messages/message.go +++ /dev/null | |||
| @@ -1,94 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "bytes" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | "github.com/pektezol/demoparser/packets/messages/types" | ||
| 8 | ) | ||
| 9 | |||
| 10 | func ParseMessage(data []byte) []Message { | ||
| 11 | reader := bitreader.Reader(bytes.NewReader(data), true) | ||
| 12 | var messages []Message | ||
| 13 | for { | ||
| 14 | messageType, err := reader.ReadBits(6) | ||
| 15 | if err != nil { | ||
| 16 | break | ||
| 17 | } | ||
| 18 | switch messageType { | ||
| 19 | case 0: | ||
| 20 | messages = append(messages, Message{Data: types.NetNop{}}) | ||
| 21 | case 1: | ||
| 22 | messages = append(messages, Message{Data: types.ParseNetDisconnect(reader)}) | ||
| 23 | case 2: | ||
| 24 | messages = append(messages, Message{Data: types.ParseNetFile(reader)}) | ||
| 25 | case 3: | ||
| 26 | messages = append(messages, Message{Data: types.ParseNetSplitScreenUser(reader)}) | ||
| 27 | case 4: | ||
| 28 | messages = append(messages, Message{Data: types.ParseNetTick(reader)}) | ||
| 29 | case 5: | ||
| 30 | messages = append(messages, Message{Data: types.ParseNetStringCmd(reader)}) | ||
| 31 | case 6: | ||
| 32 | messages = append(messages, Message{Data: types.ParseNetSetConVar(reader)}) | ||
| 33 | case 7: | ||
| 34 | messages = append(messages, Message{Data: types.ParseNetSignOnState(reader)}) | ||
| 35 | case 8: | ||
| 36 | messages = append(messages, Message{Data: types.ParseSvcServerInfo(reader)}) | ||
| 37 | case 9: | ||
| 38 | messages = append(messages, Message{Data: types.ParseSvcSendTable(reader)}) | ||
| 39 | case 10: | ||
| 40 | messages = append(messages, Message{Data: types.ParseSvcClassInfo(reader)}) | ||
| 41 | case 11: | ||
| 42 | messages = append(messages, Message{Data: types.ParseSvcSetPause(reader)}) | ||
| 43 | case 12: | ||
| 44 | messages = append(messages, Message{Data: types.ParseSvcCreateStringTable(reader)}) | ||
| 45 | case 13: | ||
| 46 | messages = append(messages, Message{Data: types.ParseSvcUpdateStringTable(reader)}) | ||
| 47 | case 14: | ||
| 48 | messages = append(messages, Message{Data: types.ParseSvcVoiceInit(reader)}) | ||
| 49 | case 15: | ||
| 50 | messages = append(messages, Message{Data: types.ParseSvcVoiceData(reader)}) | ||
| 51 | case 16: | ||
| 52 | messages = append(messages, Message{Data: types.ParseSvcPrint(reader)}) | ||
| 53 | case 17: | ||
| 54 | messages = append(messages, Message{Data: types.ParseSvcSounds(reader)}) | ||
| 55 | case 18: | ||
| 56 | messages = append(messages, Message{Data: types.ParseSvcSetView(reader)}) | ||
| 57 | case 19: | ||
| 58 | messages = append(messages, Message{Data: types.ParseSvcFixAngle(reader)}) | ||
| 59 | case 20: | ||
| 60 | messages = append(messages, Message{Data: types.ParseSvcCrosshairAngle(reader)}) | ||
| 61 | case 21: | ||
| 62 | // TODO: SvcBspDecal | ||
| 63 | case 22: | ||
| 64 | messages = append(messages, Message{Data: types.ParseSvcSplitScreen(reader)}) | ||
| 65 | case 23: | ||
| 66 | messages = append(messages, Message{Data: types.ParseSvcUserMessage(reader)}) | ||
| 67 | case 24: | ||
| 68 | messages = append(messages, Message{Data: types.ParseSvcEntityMessage(reader)}) | ||
| 69 | case 25: | ||
| 70 | messages = append(messages, Message{Data: types.ParseSvcGameEvent(reader)}) | ||
| 71 | case 26: | ||
| 72 | messages = append(messages, Message{Data: types.ParseSvcPacketEntities(reader)}) | ||
| 73 | case 27: | ||
| 74 | messages = append(messages, Message{Data: types.ParseSvcTempEntities(reader)}) | ||
| 75 | case 28: | ||
| 76 | messages = append(messages, Message{Data: types.ParseSvcPrefetch(reader)}) | ||
| 77 | case 29: | ||
| 78 | messages = append(messages, Message{Data: types.ParseSvcMenu(reader)}) | ||
| 79 | case 30: | ||
| 80 | messages = append(messages, Message{Data: types.ParseSvcGameEventList(reader)}) | ||
| 81 | case 31: | ||
| 82 | messages = append(messages, Message{Data: types.ParseSvcGetCvarValue(reader)}) | ||
| 83 | case 32: | ||
| 84 | messages = append(messages, Message{Data: types.ParseSvcCmdKeyValues(reader)}) | ||
| 85 | case 33: | ||
| 86 | messages = append(messages, Message{Data: types.ParseSvcPaintmapData(reader)}) | ||
| 87 | } | ||
| 88 | } | ||
| 89 | return messages | ||
| 90 | } | ||
| 91 | |||
| 92 | type Message struct { | ||
| 93 | Data any | ||
| 94 | } | ||
diff --git a/packets/messages/types/NetNop.go b/packets/messages/types/NetNop.go deleted file mode 100644 index d0a1f7a..0000000 --- a/packets/messages/types/NetNop.go +++ /dev/null | |||
| @@ -1,3 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | type NetNop struct{} | ||
diff --git a/packets/messages/types/NetSignOnState.go b/packets/messages/types/NetSignOnState.go deleted file mode 100644 index a8f3add..0000000 --- a/packets/messages/types/NetSignOnState.go +++ /dev/null | |||
| @@ -1,27 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type NetSignOnState struct { | ||
| 8 | SignonState int8 | ||
| 9 | SpawnCount uint32 | ||
| 10 | NumServerPlayers uint32 | ||
| 11 | PlayersNetworkIds []byte | ||
| 12 | MapNameLength uint32 | ||
| 13 | MapName string | ||
| 14 | } | ||
| 15 | |||
| 16 | func ParseNetSignOnState(reader *bitreader.ReaderType) NetSignOnState { | ||
| 17 | netsignonstate := NetSignOnState{ | ||
| 18 | SignonState: int8(reader.TryReadInt8()), | ||
| 19 | SpawnCount: reader.TryReadInt32(), | ||
| 20 | NumServerPlayers: reader.TryReadInt32(), | ||
| 21 | } | ||
| 22 | length := reader.TryReadInt32() | ||
| 23 | netsignonstate.PlayersNetworkIds = reader.TryReadBytesToSlice(int(length)) | ||
| 24 | netsignonstate.MapNameLength = reader.TryReadInt32() | ||
| 25 | netsignonstate.MapName = reader.TryReadStringLen(int(netsignonstate.MapNameLength)) | ||
| 26 | return netsignonstate | ||
| 27 | } | ||
diff --git a/packets/messages/types/NetTick.go b/packets/messages/types/NetTick.go deleted file mode 100644 index 9dae14b..0000000 --- a/packets/messages/types/NetTick.go +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type NetTick struct { | ||
| 6 | Tick uint32 | ||
| 7 | HostFrameTime float32 | ||
| 8 | HostFrameTimeStdDeviation float32 | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseNetTick(reader *bitreader.ReaderType) NetTick { | ||
| 12 | return NetTick{ | ||
| 13 | Tick: reader.TryReadInt32(), | ||
| 14 | HostFrameTime: float32(reader.TryReadInt16()) / 1e5, | ||
| 15 | HostFrameTimeStdDeviation: float32(reader.TryReadInt16()) / 1e5, | ||
| 16 | } | ||
| 17 | } | ||
diff --git a/packets/messages/types/SvcClassInfo.go b/packets/messages/types/SvcClassInfo.go deleted file mode 100644 index df17bfc..0000000 --- a/packets/messages/types/SvcClassInfo.go +++ /dev/null | |||
| @@ -1,47 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcClassInfo struct { | ||
| 8 | CreateOnClient bool | ||
| 9 | ServerClasses []ServerClass | ||
| 10 | } | ||
| 11 | |||
| 12 | type ServerClass struct { | ||
| 13 | ClassId int32 | ||
| 14 | ClassName string | ||
| 15 | DataTableName string | ||
| 16 | } | ||
| 17 | |||
| 18 | func ParseSvcClassInfo(reader *bitreader.ReaderType) SvcClassInfo { | ||
| 19 | length := reader.TryReadInt16() | ||
| 20 | createonclient := reader.TryReadBool() | ||
| 21 | var serverclasses []ServerClass | ||
| 22 | if !createonclient { | ||
| 23 | serverclasses := make([]ServerClass, length) | ||
| 24 | for i := 0; i < int(length); i++ { | ||
| 25 | id, err := reader.ReadBits(HighestBitIndex(uint(length)) + 1) | ||
| 26 | if err != nil { | ||
| 27 | panic(err) | ||
| 28 | } | ||
| 29 | serverclasses[i] = ServerClass{ | ||
| 30 | ClassId: int32(id), | ||
| 31 | ClassName: reader.TryReadString(), | ||
| 32 | DataTableName: reader.TryReadString(), | ||
| 33 | } | ||
| 34 | } | ||
| 35 | } | ||
| 36 | return SvcClassInfo{ | ||
| 37 | CreateOnClient: createonclient, | ||
| 38 | ServerClasses: serverclasses, | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | func HighestBitIndex(i uint) int { | ||
| 43 | var j int | ||
| 44 | for j = 31; j >= 0 && (i&(1<<j)) == 0; j-- { | ||
| 45 | } | ||
| 46 | return j | ||
| 47 | } | ||
diff --git a/packets/messages/types/SvcCmdKeyValues.go b/packets/messages/types/SvcCmdKeyValues.go deleted file mode 100644 index 06504a2..0000000 --- a/packets/messages/types/SvcCmdKeyValues.go +++ /dev/null | |||
| @@ -1,14 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcCmdKeyValues struct { | ||
| 6 | Data []byte | ||
| 7 | } | ||
| 8 | |||
| 9 | func ParseSvcCmdKeyValues(reader *bitreader.ReaderType) SvcCmdKeyValues { | ||
| 10 | length := reader.TryReadInt32() | ||
| 11 | return SvcCmdKeyValues{ | ||
| 12 | Data: reader.TryReadBytesToSlice(int(length)), | ||
| 13 | } | ||
| 14 | } | ||
diff --git a/packets/messages/types/SvcCreateStringTable.go b/packets/messages/types/SvcCreateStringTable.go deleted file mode 100644 index 72ab1a7..0000000 --- a/packets/messages/types/SvcCreateStringTable.go +++ /dev/null | |||
| @@ -1,34 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcCreateStringTable struct { | ||
| 8 | Name string | ||
| 9 | MaxEntries uint16 | ||
| 10 | NumEntries uint8 | ||
| 11 | UserDataFixedSize bool | ||
| 12 | UserDataSize uint16 | ||
| 13 | UserDataSizeBits uint8 | ||
| 14 | Flags uint8 | ||
| 15 | StringData []byte | ||
| 16 | } | ||
| 17 | |||
| 18 | func ParseSvcCreateStringTable(reader *bitreader.ReaderType) SvcCreateStringTable { | ||
| 19 | svccreatestringtable := SvcCreateStringTable{ | ||
| 20 | Name: reader.TryReadString(), | ||
| 21 | MaxEntries: reader.TryReadInt16(), | ||
| 22 | } | ||
| 23 | svccreatestringtable.NumEntries = uint8(reader.TryReadBits(HighestBitIndex(uint(svccreatestringtable.MaxEntries)) + 1)) | ||
| 24 | length := reader.TryReadBits(20) | ||
| 25 | svccreatestringtable.UserDataFixedSize = reader.TryReadBool() | ||
| 26 | if svccreatestringtable.UserDataFixedSize { | ||
| 27 | svccreatestringtable.UserDataSize = uint16(reader.TryReadBits(12)) | ||
| 28 | svccreatestringtable.UserDataSizeBits = uint8(reader.TryReadBits(4)) | ||
| 29 | } | ||
| 30 | svccreatestringtable.Flags = uint8(reader.TryReadBits(2)) | ||
| 31 | svccreatestringtable.StringData = reader.TryReadBitsToSlice(int(length)) | ||
| 32 | return svccreatestringtable | ||
| 33 | |||
| 34 | } | ||
diff --git a/packets/messages/types/SvcEntityMessage.go b/packets/messages/types/SvcEntityMessage.go deleted file mode 100644 index f4fb518..0000000 --- a/packets/messages/types/SvcEntityMessage.go +++ /dev/null | |||
| @@ -1,20 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcEntityMessage struct { | ||
| 6 | EntityIndex int16 | ||
| 7 | ClassId int16 | ||
| 8 | Data []byte | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseSvcEntityMessage(reader *bitreader.ReaderType) SvcEntityMessage { | ||
| 12 | entityindex := reader.TryReadBits(11) | ||
| 13 | classid := reader.TryReadBits(9) | ||
| 14 | length := reader.TryReadBits(11) | ||
| 15 | return SvcEntityMessage{ | ||
| 16 | EntityIndex: int16(entityindex), | ||
| 17 | ClassId: int16(classid), | ||
| 18 | Data: reader.TryReadBytesToSlice(int(length / 8)), | ||
| 19 | } | ||
| 20 | } | ||
diff --git a/packets/messages/types/SvcFixAngle.go b/packets/messages/types/SvcFixAngle.go deleted file mode 100644 index d98dedd..0000000 --- a/packets/messages/types/SvcFixAngle.go +++ /dev/null | |||
| @@ -1,21 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcFixAngle struct { | ||
| 6 | Relative bool | ||
| 7 | Angle []int16 | ||
| 8 | } | ||
| 9 | |||
| 10 | func ParseSvcFixAngle(reader *bitreader.ReaderType) SvcFixAngle { | ||
| 11 | relative := reader.TryReadBool() | ||
| 12 | angles := []int16{ | ||
| 13 | int16(reader.TryReadInt16()), | ||
| 14 | int16(reader.TryReadInt16()), | ||
| 15 | int16(reader.TryReadInt16()), | ||
| 16 | } | ||
| 17 | return SvcFixAngle{ | ||
| 18 | Relative: relative, | ||
| 19 | Angle: angles, | ||
| 20 | } | ||
| 21 | } | ||
diff --git a/packets/messages/types/SvcGameEvent.go b/packets/messages/types/SvcGameEvent.go deleted file mode 100644 index 1d6b0ea..0000000 --- a/packets/messages/types/SvcGameEvent.go +++ /dev/null | |||
| @@ -1,15 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcGameEvent struct { | ||
| 8 | Data []byte | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseSvcGameEvent(reader *bitreader.ReaderType) SvcGameEvent { | ||
| 12 | length := reader.TryReadBits(11) | ||
| 13 | reader.SkipBits(int(length)) | ||
| 14 | return SvcGameEvent{} // TODO: Parse SvcGameEvent | ||
| 15 | } | ||
diff --git a/packets/messages/types/SvcGameEventList.go b/packets/messages/types/SvcGameEventList.go deleted file mode 100644 index fea0be4..0000000 --- a/packets/messages/types/SvcGameEventList.go +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcGameEventList struct { | ||
| 6 | Events int16 | ||
| 7 | Data []byte | ||
| 8 | } | ||
| 9 | |||
| 10 | func ParseSvcGameEventList(reader *bitreader.ReaderType) SvcGameEventList { | ||
| 11 | events := reader.TryReadBits(9) | ||
| 12 | length := reader.TryReadBits(20) | ||
| 13 | return SvcGameEventList{ | ||
| 14 | Events: int16(events), | ||
| 15 | Data: reader.TryReadBitsToSlice(int(length)), | ||
| 16 | } | ||
| 17 | } | ||
diff --git a/packets/messages/types/SvcMenu.go b/packets/messages/types/SvcMenu.go deleted file mode 100644 index 312115a..0000000 --- a/packets/messages/types/SvcMenu.go +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcMenu struct { | ||
| 6 | MenuType int16 | ||
| 7 | Data []byte | ||
| 8 | } | ||
| 9 | |||
| 10 | func ParseSvcMenu(reader *bitreader.ReaderType) SvcMenu { | ||
| 11 | menutype := reader.TryReadInt16() | ||
| 12 | length := reader.TryReadInt32() | ||
| 13 | return SvcMenu{ | ||
| 14 | MenuType: int16(menutype), | ||
| 15 | Data: reader.TryReadBytesToSlice(int(length / 8)), | ||
| 16 | } | ||
| 17 | } | ||
diff --git a/packets/messages/types/SvcPacketEntities.go b/packets/messages/types/SvcPacketEntities.go deleted file mode 100644 index 9d8a8b0..0000000 --- a/packets/messages/types/SvcPacketEntities.go +++ /dev/null | |||
| @@ -1,39 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcPacketEntities struct { | ||
| 8 | MaxEntries uint16 | ||
| 9 | IsDelta bool | ||
| 10 | DeltaFrom int32 | ||
| 11 | BaseLine bool | ||
| 12 | UpdatedEntries uint16 | ||
| 13 | UpdateBaseline bool | ||
| 14 | Data []byte | ||
| 15 | } | ||
| 16 | |||
| 17 | func ParseSvcPacketEntities(reader *bitreader.ReaderType) SvcPacketEntities { | ||
| 18 | maxentries := reader.TryReadBits(11) | ||
| 19 | isdelta := reader.TryReadBool() | ||
| 20 | var deltafrom int32 | ||
| 21 | if isdelta { | ||
| 22 | deltafrom = int32(reader.TryReadInt32()) | ||
| 23 | } else { | ||
| 24 | deltafrom = -1 | ||
| 25 | } | ||
| 26 | baseline := reader.TryReadBool() | ||
| 27 | updatedentries := reader.TryReadBits(11) | ||
| 28 | length := reader.TryReadBits(20) | ||
| 29 | updatebaseline := reader.TryReadBool() | ||
| 30 | return SvcPacketEntities{ | ||
| 31 | MaxEntries: uint16(maxentries), | ||
| 32 | IsDelta: isdelta, | ||
| 33 | DeltaFrom: deltafrom, | ||
| 34 | BaseLine: baseline, | ||
| 35 | UpdatedEntries: uint16(updatedentries), | ||
| 36 | UpdateBaseline: updatebaseline, | ||
| 37 | Data: reader.TryReadBitsToSlice(int(length)), | ||
| 38 | } | ||
| 39 | } | ||
diff --git a/packets/messages/types/SvcPaintmapData.go b/packets/messages/types/SvcPaintmapData.go deleted file mode 100644 index f3bd1a3..0000000 --- a/packets/messages/types/SvcPaintmapData.go +++ /dev/null | |||
| @@ -1,14 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcPaintmapData struct { | ||
| 6 | Data []byte | ||
| 7 | } | ||
| 8 | |||
| 9 | func ParseSvcPaintmapData(reader *bitreader.ReaderType) SvcPaintmapData { | ||
| 10 | length := reader.TryReadInt32() | ||
| 11 | return SvcPaintmapData{ | ||
| 12 | Data: reader.TryReadBytesToSlice(int(length / 8)), | ||
| 13 | } | ||
| 14 | } | ||
diff --git a/packets/messages/types/SvcSendTable.go b/packets/messages/types/SvcSendTable.go deleted file mode 100644 index f76aadb..0000000 --- a/packets/messages/types/SvcSendTable.go +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcSendTable struct { | ||
| 6 | NeedsDecoder bool | ||
| 7 | Length uint8 | ||
| 8 | Props int32 | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseSvcSendTable(reader *bitreader.ReaderType) SvcSendTable { | ||
| 12 | return SvcSendTable{ | ||
| 13 | NeedsDecoder: reader.TryReadBool(), | ||
| 14 | Length: reader.TryReadInt8(), | ||
| 15 | } | ||
| 16 | // No one cares about SvcSendTable | ||
| 17 | } | ||
diff --git a/packets/messages/types/SvcServerInfo.go b/packets/messages/types/SvcServerInfo.go deleted file mode 100644 index 9d2648b..0000000 --- a/packets/messages/types/SvcServerInfo.go +++ /dev/null | |||
| @@ -1,43 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcServerInfo struct { | ||
| 6 | Protocol uint16 | ||
| 7 | ServerCount uint32 | ||
| 8 | IsHltv bool | ||
| 9 | IsDedicated bool | ||
| 10 | ClientCrc int32 | ||
| 11 | MaxClasses uint16 | ||
| 12 | MapCrc uint32 | ||
| 13 | PlayerSlot uint8 | ||
| 14 | MaxClients uint8 | ||
| 15 | Unk uint32 | ||
| 16 | TickInterval float32 | ||
| 17 | COs byte | ||
| 18 | GameDir string | ||
| 19 | MapName string | ||
| 20 | SkyName string | ||
| 21 | HostName string | ||
| 22 | } | ||
| 23 | |||
| 24 | func ParseSvcServerInfo(reader *bitreader.ReaderType) SvcServerInfo { | ||
| 25 | return SvcServerInfo{ | ||
| 26 | Protocol: reader.TryReadInt16(), | ||
| 27 | ServerCount: reader.TryReadInt32(), | ||
| 28 | IsHltv: reader.TryReadBool(), | ||
| 29 | IsDedicated: reader.TryReadBool(), | ||
| 30 | ClientCrc: int32(reader.TryReadInt32()), | ||
| 31 | MaxClasses: reader.TryReadInt16(), | ||
| 32 | MapCrc: reader.TryReadInt32(), | ||
| 33 | PlayerSlot: reader.TryReadInt8(), | ||
| 34 | MaxClients: reader.TryReadInt8(), | ||
| 35 | Unk: reader.TryReadInt32(), | ||
| 36 | TickInterval: reader.TryReadFloat32(), | ||
| 37 | COs: reader.TryReadInt8(), | ||
| 38 | GameDir: reader.TryReadString(), | ||
| 39 | MapName: reader.TryReadString(), | ||
| 40 | SkyName: reader.TryReadString(), | ||
| 41 | HostName: reader.TryReadString(), | ||
| 42 | } | ||
| 43 | } | ||
diff --git a/packets/messages/types/SvcSounds.go b/packets/messages/types/SvcSounds.go deleted file mode 100644 index 2dc7974..0000000 --- a/packets/messages/types/SvcSounds.go +++ /dev/null | |||
| @@ -1,30 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcSounds struct { | ||
| 6 | ReliableSound bool | ||
| 7 | Size int8 | ||
| 8 | Data []byte | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseSvcSounds(reader *bitreader.ReaderType) SvcSounds { | ||
| 12 | reliablesound := reader.TryReadBool() | ||
| 13 | var size int8 | ||
| 14 | var length int16 | ||
| 15 | if reliablesound { | ||
| 16 | size = 1 | ||
| 17 | } else { | ||
| 18 | size = int8(reader.TryReadInt8()) | ||
| 19 | } | ||
| 20 | if reliablesound { | ||
| 21 | length = int16(reader.TryReadInt8()) | ||
| 22 | } else { | ||
| 23 | length = int16(reader.TryReadInt16()) | ||
| 24 | } | ||
| 25 | return SvcSounds{ | ||
| 26 | ReliableSound: reliablesound, | ||
| 27 | Size: size, | ||
| 28 | Data: reader.TryReadBitsToSlice(int(length)), | ||
| 29 | } | ||
| 30 | } | ||
diff --git a/packets/messages/types/SvcSplitScreen.go b/packets/messages/types/SvcSplitScreen.go deleted file mode 100644 index 6727558..0000000 --- a/packets/messages/types/SvcSplitScreen.go +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcSplitScreen struct { | ||
| 6 | Unk bool | ||
| 7 | Data []byte | ||
| 8 | } | ||
| 9 | |||
| 10 | func ParseSvcSplitScreen(reader *bitreader.ReaderType) SvcSplitScreen { | ||
| 11 | unk := reader.TryReadBool() | ||
| 12 | length := reader.TryReadBits(11) | ||
| 13 | return SvcSplitScreen{ | ||
| 14 | Unk: unk, | ||
| 15 | Data: reader.TryReadBytesToSlice(int(length / 8)), | ||
| 16 | } | ||
| 17 | } | ||
diff --git a/packets/messages/types/SvcTempEntities.go b/packets/messages/types/SvcTempEntities.go deleted file mode 100644 index 3bfae0c..0000000 --- a/packets/messages/types/SvcTempEntities.go +++ /dev/null | |||
| @@ -1,20 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcTempEntities struct { | ||
| 8 | NumEntries uint8 | ||
| 9 | Data []byte | ||
| 10 | } | ||
| 11 | |||
| 12 | func ParseSvcTempEntities(reader *bitreader.ReaderType) SvcTempEntities { | ||
| 13 | numentries := reader.TryReadInt8() | ||
| 14 | length := reader.TryReadBits(17) | ||
| 15 | //reader.SkipBits(int(length)) // TODO: Read data properly | ||
| 16 | return SvcTempEntities{ | ||
| 17 | NumEntries: numentries, | ||
| 18 | Data: reader.TryReadBitsToSlice(int(length)), | ||
| 19 | } | ||
| 20 | } | ||
diff --git a/packets/messages/types/SvcUpdateStringTable.go b/packets/messages/types/SvcUpdateStringTable.go deleted file mode 100644 index 9f178a5..0000000 --- a/packets/messages/types/SvcUpdateStringTable.go +++ /dev/null | |||
| @@ -1,21 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcUpdateStringTable struct { | ||
| 6 | TableId int8 | ||
| 7 | NumChangedEntries int16 | ||
| 8 | Data []byte | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseSvcUpdateStringTable(reader *bitreader.ReaderType) SvcUpdateStringTable { | ||
| 12 | svcupdatestringtable := SvcUpdateStringTable{ | ||
| 13 | TableId: int8(reader.TryReadBits(5)), | ||
| 14 | } | ||
| 15 | if reader.TryReadBool() { | ||
| 16 | svcupdatestringtable.NumChangedEntries = int16(reader.TryReadInt16()) | ||
| 17 | } | ||
| 18 | length := reader.TryReadBits(20) | ||
| 19 | svcupdatestringtable.Data = reader.TryReadBitsToSlice(int(length)) | ||
| 20 | return svcupdatestringtable | ||
| 21 | } | ||
diff --git a/packets/messages/types/SvcUserMessage.go b/packets/messages/types/SvcUserMessage.go deleted file mode 100644 index c7b0566..0000000 --- a/packets/messages/types/SvcUserMessage.go +++ /dev/null | |||
| @@ -1,19 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcUserMessage struct { | ||
| 8 | MsgType uint8 | ||
| 9 | Data []byte | ||
| 10 | } | ||
| 11 | |||
| 12 | func ParseSvcUserMessage(reader *bitreader.ReaderType) SvcUserMessage { | ||
| 13 | msgtype := reader.TryReadInt8() | ||
| 14 | length := reader.TryReadBits(12) | ||
| 15 | return SvcUserMessage{ | ||
| 16 | MsgType: msgtype, | ||
| 17 | Data: reader.TryReadBitsToSlice(int(length)), | ||
| 18 | } | ||
| 19 | } | ||
diff --git a/packets/messages/types/SvcVoiceData.go b/packets/messages/types/SvcVoiceData.go deleted file mode 100644 index f99db38..0000000 --- a/packets/messages/types/SvcVoiceData.go +++ /dev/null | |||
| @@ -1,19 +0,0 @@ | |||
| 1 | package types | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcVoiceData struct { | ||
| 6 | Client int8 | ||
| 7 | Proximity int8 | ||
| 8 | Data []byte | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseSvcVoiceData(reader *bitreader.ReaderType) SvcVoiceData { | ||
| 12 | svcvoicedata := SvcVoiceData{ | ||
| 13 | Client: int8(reader.TryReadInt8()), | ||
| 14 | Proximity: int8(reader.TryReadInt8()), | ||
| 15 | } | ||
| 16 | length := reader.TryReadInt16() | ||
| 17 | svcvoicedata.Data = reader.TryReadBytesToSlice(int(length / 8)) | ||
| 18 | return svcvoicedata | ||
| 19 | } | ||
diff --git a/packets/packet.go b/packets/packet.go deleted file mode 100644 index 8f4a262..0000000 --- a/packets/packet.go +++ /dev/null | |||
| @@ -1,87 +0,0 @@ | |||
| 1 | package packets | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | "github.com/pektezol/demoparser/packets/classes" | ||
| 8 | "github.com/pektezol/demoparser/packets/messages" | ||
| 9 | ) | ||
| 10 | |||
| 11 | const MSSC = 2 | ||
| 12 | |||
| 13 | func ParsePacket(reader *bitreader.ReaderType) (status int) { | ||
| 14 | messageType := reader.TryReadInt8() | ||
| 15 | messageTick := reader.TryReadInt32() | ||
| 16 | messageSlot := reader.TryReadInt8() | ||
| 17 | _ = messageSlot | ||
| 18 | switch messageType { | ||
| 19 | case 1: | ||
| 20 | signOn := SignOn{ | ||
| 21 | PacketInfo: classes.ParseCmdInfo(reader, MSSC), | ||
| 22 | InSequence: int32(reader.TryReadInt32()), | ||
| 23 | OutSequence: int32(reader.TryReadInt32()), | ||
| 24 | } | ||
| 25 | size := int(reader.TryReadInt32()) | ||
| 26 | signOn.Data = messages.ParseMessage(reader.TryReadBytesToSlice(size)) | ||
| 27 | // fmt.Printf("[%d] (%d) {%d} SignOn: %v\n", messageTick, messageType, messageSlot, signOn) | ||
| 28 | return 1 | ||
| 29 | case 2: | ||
| 30 | packet := Packet{ | ||
| 31 | PacketInfo: classes.ParseCmdInfo(reader, MSSC), | ||
| 32 | InSequence: int32(reader.TryReadInt32()), | ||
| 33 | OutSequence: int32(reader.TryReadInt32()), | ||
| 34 | } | ||
| 35 | size := int(reader.TryReadInt32()) | ||
| 36 | packet.Data = messages.ParseMessage(reader.TryReadBytesToSlice(size)) | ||
| 37 | // fmt.Printf("[%d] (%d) Packet: %v\n", messageTick, messageType, packet) | ||
| 38 | return 2 | ||
| 39 | case 3: | ||
| 40 | syncTick := SyncTick{} | ||
| 41 | fmt.Printf("[%d] (%d) SyncTick: %v\n", messageTick, messageType, syncTick) | ||
| 42 | return 3 | ||
| 43 | case 4: | ||
| 44 | size := int(reader.TryReadInt32()) | ||
| 45 | var consoleCmd ConsoleCmd | ||
| 46 | consoleCmd.Data = reader.TryReadStringLen(size) | ||
| 47 | // fmt.Printf("[%d] (%d) ConsoleCmd: %s\n", messageTick, messageType, consoleCmd.Data) | ||
| 48 | return 4 | ||
| 49 | case 5: // TODO: UserCmd - Buttons | ||
| 50 | userCmd := UserCmd{ | ||
| 51 | Cmd: int32(reader.TryReadInt32()), | ||
| 52 | } | ||
| 53 | size := int(reader.TryReadInt32()) | ||
| 54 | userCmd.Data = classes.ParseUserCmdInfo(reader.TryReadBytesToSlice(size)) | ||
| 55 | // fmt.Printf("[%d] (%d) UserCmd: %v\n", messageTick, messageType, userCmd) | ||
| 56 | return 5 | ||
| 57 | case 6: // TODO: DataTables | ||
| 58 | // datatables := DataTables{ | ||
| 59 | // Size: int32(reader.TryReadInt32()), | ||
| 60 | // } | ||
| 61 | size := int(reader.TryReadInt32()) | ||
| 62 | reader.SkipBytes(size) | ||
| 63 | // datatables.Data = classes.ParseDataTable(reader.TryReadBytesToSlice(int(datatables.Size))) | ||
| 64 | // fmt.Printf("[%d] (%d) DataTables: %v\n", messageTick, messageType, datatables) | ||
| 65 | return 6 | ||
| 66 | case 7: | ||
| 67 | stop := Stop{ | ||
| 68 | RemainingData: nil, | ||
| 69 | } | ||
| 70 | fmt.Printf("[%d] (%d) Stop: %v\n", messageTick, messageType, stop) | ||
| 71 | return 7 | ||
| 72 | case 8: // TODO: CustomData | ||
| 73 | reader.SkipBytes(4) | ||
| 74 | size := int(reader.TryReadInt32()) | ||
| 75 | reader.SkipBytes(size) | ||
| 76 | // fmt.Printf("[%d] (%d) CustomData: \n", messageTick, messageType) | ||
| 77 | return 8 | ||
| 78 | case 9: // TODO: StringTables - Data | ||
| 79 | var stringTables StringTables | ||
| 80 | size := int(reader.TryReadInt32()) | ||
| 81 | stringTables.Data = classes.ParseStringTable(reader.TryReadBytesToSlice(size)) | ||
| 82 | // fmt.Printf("[%d] (%d) StringTables: %v\n", messageTick, messageType, stringTables) | ||
| 83 | return 9 | ||
| 84 | default: | ||
| 85 | return 0 | ||
| 86 | } | ||
| 87 | } | ||
diff --git a/pkg/classes/cmdInfo.go b/pkg/classes/cmdInfo.go new file mode 100644 index 0000000..6e56c41 --- /dev/null +++ b/pkg/classes/cmdInfo.go | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type CmdInfo struct { | ||
| 8 | Flags int32 | ||
| 9 | ViewOrigin []float32 | ||
| 10 | ViewAngles []float32 | ||
| 11 | LocalViewAngles []float32 | ||
| 12 | ViewOrigin2 []float32 | ||
| 13 | ViewAngles2 []float32 | ||
| 14 | LocalViewAngles2 []float32 | ||
| 15 | } | ||
| 16 | |||
| 17 | func ParseCmdInfo(reader *bitreader.ReaderType) CmdInfo { | ||
| 18 | return CmdInfo{ | ||
| 19 | Flags: int32(reader.TryReadBits(32)), | ||
| 20 | ViewOrigin: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 21 | ViewAngles: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 22 | LocalViewAngles: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 23 | ViewOrigin2: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 24 | ViewAngles2: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 25 | LocalViewAngles2: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 26 | } | ||
| 27 | } | ||
diff --git a/pkg/classes/sendTable.go b/pkg/classes/sendTable.go new file mode 100644 index 0000000..4521464 --- /dev/null +++ b/pkg/classes/sendTable.go | |||
| @@ -0,0 +1,106 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SendTable struct { | ||
| 8 | NeedsDecoder bool | ||
| 9 | NetTableName string | ||
| 10 | NumOfProps int16 | ||
| 11 | Props []prop | ||
| 12 | } | ||
| 13 | |||
| 14 | type prop struct { | ||
| 15 | SendPropType int8 | ||
| 16 | SendPropName string | ||
| 17 | SendPropFlags int32 | ||
| 18 | Priority int8 | ||
| 19 | ExcludeDtName string | ||
| 20 | LowValue float32 | ||
| 21 | HighValue float32 | ||
| 22 | NumBits int32 | ||
| 23 | NumElements int32 | ||
| 24 | } | ||
| 25 | |||
| 26 | type sendPropFlag int | ||
| 27 | |||
| 28 | const ( | ||
| 29 | Unsigned sendPropFlag = iota | ||
| 30 | Coord | ||
| 31 | NoScale | ||
| 32 | RoundDown | ||
| 33 | RoundUp | ||
| 34 | Normal | ||
| 35 | Exclude | ||
| 36 | Xyze | ||
| 37 | InsideArray | ||
| 38 | ProxyAlwaysYes | ||
| 39 | IsVectorElem | ||
| 40 | Collapsible | ||
| 41 | CoordMp | ||
| 42 | CoordMpLp // low precision | ||
| 43 | CoordMpInt | ||
| 44 | CellCoord | ||
| 45 | CellCoordLp | ||
| 46 | CellCoordInt | ||
| 47 | ChangesOften | ||
| 48 | ) | ||
| 49 | |||
| 50 | type sendPropType int | ||
| 51 | |||
| 52 | const ( | ||
| 53 | Int sendPropType = iota | ||
| 54 | Float | ||
| 55 | Vector3 | ||
| 56 | Vector2 | ||
| 57 | String | ||
| 58 | Array | ||
| 59 | DataTable | ||
| 60 | ) | ||
| 61 | |||
| 62 | func ParseSendTable(reader *bitreader.ReaderType) SendTable { | ||
| 63 | sendTable := SendTable{ | ||
| 64 | NeedsDecoder: reader.TryReadBool(), | ||
| 65 | NetTableName: reader.TryReadString(), | ||
| 66 | NumOfProps: int16(reader.TryReadBits(10)), | ||
| 67 | // SendPropType: int8(reader.TryReadBits(5)), | ||
| 68 | // SendPropName: reader.TryReadString(), | ||
| 69 | // SendPropFlags: int16(reader.TryReadBits(16)), | ||
| 70 | } | ||
| 71 | if sendTable.NumOfProps < 0 { | ||
| 72 | return sendTable | ||
| 73 | } | ||
| 74 | for count := 0; count < int(sendTable.NumOfProps); count++ { | ||
| 75 | propType := int8(reader.TryReadBits(5)) | ||
| 76 | if propType >= int8(7) { | ||
| 77 | return sendTable | ||
| 78 | } | ||
| 79 | prop := prop{ | ||
| 80 | SendPropType: propType, | ||
| 81 | SendPropName: reader.TryReadString(), | ||
| 82 | SendPropFlags: int32(reader.TryReadBits(19)), | ||
| 83 | Priority: int8(reader.TryReadBits(8)), | ||
| 84 | } | ||
| 85 | if propType == int8(DataTable) || CheckBit(int64(prop.SendPropFlags), int(Exclude)) { | ||
| 86 | prop.ExcludeDtName = reader.TryReadString() | ||
| 87 | } else { | ||
| 88 | switch propType { | ||
| 89 | case int8(String), int8(Int), int8(Float), int8(Vector3), int8(Vector2): | ||
| 90 | prop.LowValue = reader.TryReadFloat32() | ||
| 91 | prop.HighValue = reader.TryReadFloat32() | ||
| 92 | prop.NumBits = int32(reader.TryReadBits(7)) | ||
| 93 | case int8(Array): | ||
| 94 | prop.NumElements = int32(reader.TryReadBits(10)) | ||
| 95 | default: | ||
| 96 | return sendTable | ||
| 97 | } | ||
| 98 | } | ||
| 99 | sendTable.Props = append(sendTable.Props, prop) | ||
| 100 | } | ||
| 101 | return sendTable | ||
| 102 | } | ||
| 103 | |||
| 104 | func CheckBit(val int64, bit int) bool { | ||
| 105 | return (val & (int64(1) << bit)) != 0 | ||
| 106 | } | ||
diff --git a/pkg/classes/serverClassInfo.go b/pkg/classes/serverClassInfo.go new file mode 100644 index 0000000..c60dad1 --- /dev/null +++ b/pkg/classes/serverClassInfo.go | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type ServerClassInfo struct { | ||
| 8 | ClassId int16 | ||
| 9 | ClassName string | ||
| 10 | DataTableName string | ||
| 11 | } | ||
| 12 | |||
| 13 | func ParseServerClassInfo(reader *bitreader.ReaderType, count int, numOfClasses int) ServerClassInfo { | ||
| 14 | return ServerClassInfo{ | ||
| 15 | ClassId: int16(reader.TryReadBits(16)), | ||
| 16 | ClassName: reader.TryReadString(), | ||
| 17 | DataTableName: reader.TryReadString(), | ||
| 18 | } | ||
| 19 | } | ||
| 20 | |||
| 21 | // func serverClassBits(numOfClasses int) int { | ||
| 22 | // return highestBitIndex(uint(numOfClasses)) + 1 | ||
| 23 | // } | ||
| 24 | |||
| 25 | // func highestBitIndex(i uint) int { | ||
| 26 | // var j int | ||
| 27 | // for j = 31; j >= 0 && (i&(1<<j)) == 0; j-- { | ||
| 28 | // } | ||
| 29 | // return j | ||
| 30 | // } | ||
diff --git a/pkg/classes/stringTable.go b/pkg/classes/stringTable.go new file mode 100644 index 0000000..c6709f5 --- /dev/null +++ b/pkg/classes/stringTable.go | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "bytes" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | ) | ||
| 8 | |||
| 9 | type StringTable struct { | ||
| 10 | Name string | ||
| 11 | TableEntries []StringTableEntry | ||
| 12 | Classes []StringTableClass | ||
| 13 | } | ||
| 14 | |||
| 15 | type StringTableEntry struct { | ||
| 16 | Name string | ||
| 17 | EntryData StringTableEntryData | ||
| 18 | } | ||
| 19 | |||
| 20 | type StringTableEntryData struct { | ||
| 21 | // TODO: Parse StringTableEntry | ||
| 22 | } | ||
| 23 | |||
| 24 | type StringTableClass struct { | ||
| 25 | Name string | ||
| 26 | Data string | ||
| 27 | } | ||
| 28 | |||
| 29 | func ParseStringTables(reader *bitreader.ReaderType) []StringTable { | ||
| 30 | tableCount := reader.TryReadBits(8) | ||
| 31 | stringTables := make([]StringTable, tableCount) | ||
| 32 | for i := 0; i < int(tableCount); i++ { | ||
| 33 | var table StringTable | ||
| 34 | table.ParseStream(reader) | ||
| 35 | stringTables[i] = table | ||
| 36 | } | ||
| 37 | return stringTables | ||
| 38 | } | ||
| 39 | |||
| 40 | func (stringTable *StringTable) ParseStream(reader *bitreader.ReaderType) { | ||
| 41 | stringTable.Name = reader.TryReadString() | ||
| 42 | entryCount := reader.TryReadBits(16) | ||
| 43 | stringTable.TableEntries = make([]StringTableEntry, entryCount) | ||
| 44 | |||
| 45 | for i := 0; i < int(entryCount); i++ { | ||
| 46 | var entry StringTableEntry | ||
| 47 | entry.Parse(reader) | ||
| 48 | stringTable.TableEntries[i] = entry | ||
| 49 | } | ||
| 50 | |||
| 51 | if reader.TryReadBool() { | ||
| 52 | classCount := reader.TryReadBits(16) | ||
| 53 | stringTable.Classes = make([]StringTableClass, classCount) | ||
| 54 | |||
| 55 | for i := 0; i < int(classCount); i++ { | ||
| 56 | var class StringTableClass | ||
| 57 | class.Parse(reader) | ||
| 58 | stringTable.Classes[i] = class | ||
| 59 | } | ||
| 60 | } | ||
| 61 | } | ||
| 62 | |||
| 63 | func (stringTableEntry *StringTableEntry) Parse(reader *bitreader.ReaderType) { | ||
| 64 | stringTableEntry.Name = reader.TryReadString() | ||
| 65 | if reader.TryReadBool() { | ||
| 66 | byteLen, err := reader.ReadBits(16) | ||
| 67 | if err != nil { | ||
| 68 | return | ||
| 69 | } | ||
| 70 | dataBsr := reader.TryReadBytesToSlice(int(byteLen)) | ||
| 71 | _ = bitreader.Reader(bytes.NewReader(dataBsr), true) // TODO: Parse StringTableEntry | ||
| 72 | // stringTableEntry.EntryData.ParseStream(entryReader) | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | func (stringTableClass *StringTableClass) Parse(reader *bitreader.ReaderType) { | ||
| 77 | stringTableClass.Name = reader.TryReadString() | ||
| 78 | if reader.TryReadBool() { | ||
| 79 | dataLen := reader.TryReadBits(16) | ||
| 80 | stringTableClass.Data = reader.TryReadStringLen(int(dataLen)) | ||
| 81 | } | ||
| 82 | } | ||
diff --git a/packets/classes/usercmd.go b/pkg/classes/userCmdInfo.go index d3328fd..a6d9091 100644 --- a/packets/classes/usercmd.go +++ b/pkg/classes/userCmdInfo.go | |||
| @@ -16,21 +16,21 @@ type UserCmdInfo struct { | |||
| 16 | SideMove float32 | 16 | SideMove float32 |
| 17 | UpMove float32 | 17 | UpMove float32 |
| 18 | Buttons int32 | 18 | Buttons int32 |
| 19 | Impulse byte | 19 | Impulse int8 |
| 20 | WeaponSelect int | 20 | WeaponSelect int16 |
| 21 | WeaponSubtype int | 21 | WeaponSubType int8 |
| 22 | MouseDx int16 | 22 | MouseDx int16 |
| 23 | MouseDy int16 | 23 | MouseDy int16 |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | func ParseUserCmdInfo(data []byte) UserCmdInfo { | 26 | func ParseUserCmdInfo(data []byte) UserCmdInfo { |
| 27 | reader := bitreader.Reader(bytes.NewReader(data), true) | 27 | reader := bitreader.Reader(bytes.NewReader(data), true) |
| 28 | var userCmdInfo UserCmdInfo | 28 | userCmdInfo := UserCmdInfo{} |
| 29 | if reader.TryReadBool() { | 29 | if reader.TryReadBool() { |
| 30 | userCmdInfo.CommandNumber = int32(reader.TryReadInt32()) | 30 | userCmdInfo.CommandNumber = int32(reader.TryReadBits(32)) |
| 31 | } | 31 | } |
| 32 | if reader.TryReadBool() { | 32 | if reader.TryReadBool() { |
| 33 | userCmdInfo.TickCount = int32(reader.TryReadInt32()) | 33 | userCmdInfo.TickCount = int32(reader.TryReadBits(32)) |
| 34 | } | 34 | } |
| 35 | if reader.TryReadBool() { | 35 | if reader.TryReadBool() { |
| 36 | userCmdInfo.ViewAnglesX = reader.TryReadFloat32() | 36 | userCmdInfo.ViewAnglesX = reader.TryReadFloat32() |
| @@ -51,30 +51,22 @@ func ParseUserCmdInfo(data []byte) UserCmdInfo { | |||
| 51 | userCmdInfo.UpMove = reader.TryReadFloat32() | 51 | userCmdInfo.UpMove = reader.TryReadFloat32() |
| 52 | } | 52 | } |
| 53 | if reader.TryReadBool() { | 53 | if reader.TryReadBool() { |
| 54 | userCmdInfo.Buttons = int32(reader.TryReadInt32()) | 54 | userCmdInfo.Buttons = int32(reader.TryReadBits(32)) |
| 55 | } | 55 | } |
| 56 | if reader.TryReadBool() { | 56 | if reader.TryReadBool() { |
| 57 | userCmdInfo.Impulse = reader.TryReadInt8() | 57 | userCmdInfo.Impulse = int8(reader.TryReadBits(8)) |
| 58 | } | 58 | } |
| 59 | if reader.TryReadBool() { | 59 | if reader.TryReadBool() { |
| 60 | value, err := reader.ReadBits(11) | 60 | userCmdInfo.WeaponSelect = int16(reader.TryReadBits(11)) |
| 61 | if err != nil { | ||
| 62 | panic(err) | ||
| 63 | } | ||
| 64 | userCmdInfo.WeaponSelect = int(value) | ||
| 65 | if reader.TryReadBool() { | 61 | if reader.TryReadBool() { |
| 66 | value, err := reader.ReadBits(6) | 62 | userCmdInfo.WeaponSubType = int8(reader.TryReadBits(6)) |
| 67 | if err != nil { | ||
| 68 | panic(err) | ||
| 69 | } | ||
| 70 | userCmdInfo.WeaponSubtype = int(value) | ||
| 71 | } | 63 | } |
| 72 | } | 64 | } |
| 73 | if reader.TryReadBool() { | 65 | if reader.TryReadBool() { |
| 74 | userCmdInfo.MouseDx = int16(reader.TryReadInt16()) | 66 | userCmdInfo.MouseDx = int16(reader.TryReadBits(16)) |
| 75 | } | 67 | } |
| 76 | if reader.TryReadBool() { | 68 | if reader.TryReadBool() { |
| 77 | userCmdInfo.MouseDy = int16(reader.TryReadInt16()) | 69 | userCmdInfo.MouseDy = int16(reader.TryReadBits(16)) |
| 78 | } | 70 | } |
| 79 | return userCmdInfo | 71 | return userCmdInfo |
| 80 | } | 72 | } |
diff --git a/pkg/messages/messages.go b/pkg/messages/messages.go new file mode 100644 index 0000000..39f89e9 --- /dev/null +++ b/pkg/messages/messages.go | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | "reflect" | ||
| 6 | |||
| 7 | "github.com/pektezol/bitreader" | ||
| 8 | messages "github.com/pektezol/demoparser/pkg/messages/types" | ||
| 9 | ) | ||
| 10 | |||
| 11 | func ParseMessages(messageType int, reader *bitreader.ReaderType) any { | ||
| 12 | var messageData any | ||
| 13 | switch messageType { | ||
| 14 | case 0: | ||
| 15 | messageData = messages.ParseNetNop(reader) | ||
| 16 | case 1: | ||
| 17 | messageData = messages.ParseNetDisconnect(reader) | ||
| 18 | case 2: | ||
| 19 | messageData = messages.ParseNetFile(reader) | ||
| 20 | case 3: | ||
| 21 | messageData = messages.ParseNetSplitScreenUser(reader) | ||
| 22 | case 4: | ||
| 23 | messageData = messages.ParseNetTick(reader) | ||
| 24 | case 5: | ||
| 25 | messageData = messages.ParseNetStringCmd(reader) | ||
| 26 | case 6: | ||
| 27 | messageData = messages.ParseNetSetConVar(reader) | ||
| 28 | case 7: | ||
| 29 | messageData = messages.ParseNetSignOnState(reader) | ||
| 30 | case 8: | ||
| 31 | messageData = messages.ParseSvcServerInfo(reader) | ||
| 32 | case 9: | ||
| 33 | messageData = messages.ParseSvcSendTable(reader) | ||
| 34 | case 10: | ||
| 35 | messageData = messages.ParseSvcClassInfo(reader) | ||
| 36 | case 11: | ||
| 37 | messageData = messages.ParseSvcSetPause(reader) | ||
| 38 | case 12: | ||
| 39 | messageData = messages.ParseSvcCreateStringTable(reader) | ||
| 40 | case 13: | ||
| 41 | messageData = messages.ParseSvcUpdateStringTable(reader) | ||
| 42 | case 14: | ||
| 43 | messageData = messages.ParseSvcVoiceInit(reader) | ||
| 44 | case 15: | ||
| 45 | messageData = messages.ParseSvcVoiceData(reader) | ||
| 46 | case 16: | ||
| 47 | messageData = messages.ParseSvcPrint(reader) | ||
| 48 | case 17: | ||
| 49 | messageData = messages.ParseSvcSounds(reader) | ||
| 50 | case 18: | ||
| 51 | messageData = messages.ParseSvcSetView(reader) | ||
| 52 | case 19: | ||
| 53 | messageData = messages.ParseSvcFixAngle(reader) | ||
| 54 | case 20: | ||
| 55 | messageData = messages.ParseSvcCrosshairAngle(reader) | ||
| 56 | case 21: | ||
| 57 | messageData = messages.ParseSvcBspDecal(reader) | ||
| 58 | case 22: | ||
| 59 | messageData = messages.ParseSvcSplitScreen(reader) | ||
| 60 | case 23: | ||
| 61 | messageData = messages.ParseSvcUserMessage(reader) | ||
| 62 | case 24: | ||
| 63 | messageData = messages.ParseSvcEntityMessage(reader) | ||
| 64 | case 25: | ||
| 65 | messageData = messages.ParseSvcGameEvent(reader) | ||
| 66 | case 26: | ||
| 67 | messageData = messages.ParseSvcPacketEntities(reader) | ||
| 68 | case 27: | ||
| 69 | messageData = messages.ParseSvcTempEntities(reader) | ||
| 70 | case 28: | ||
| 71 | messageData = messages.ParseSvcPrefetch(reader) | ||
| 72 | case 29: | ||
| 73 | messageData = messages.ParseSvcMenu(reader) | ||
| 74 | case 30: | ||
| 75 | messageData = messages.ParseSvcGameEventList(reader) | ||
| 76 | case 31: | ||
| 77 | messageData = messages.ParseSvcGetCvarValue(reader) | ||
| 78 | case 32: | ||
| 79 | messageData = messages.ParseSvcCmdKeyValues(reader) | ||
| 80 | case 33: | ||
| 81 | messageData = messages.ParseSvcPaintmapData(reader) | ||
| 82 | default: | ||
| 83 | return nil | ||
| 84 | } | ||
| 85 | fmt.Printf("\t\t(%d) %s:\n\t\t\t%+v\n", messageType, reflect.ValueOf(messageData).Type(), messageData) | ||
| 86 | return messageData | ||
| 87 | } | ||
diff --git a/packets/messages/types/NetDisconnect.go b/pkg/messages/types/netDisconnect.go index 8b65568..69d4a67 100644 --- a/packets/messages/types/NetDisconnect.go +++ b/pkg/messages/types/netDisconnect.go | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | package types | 1 | package messages |
| 2 | 2 | ||
| 3 | import "github.com/pektezol/bitreader" | 3 | import "github.com/pektezol/bitreader" |
| 4 | 4 | ||
| @@ -7,5 +7,7 @@ type NetDisconnect struct { | |||
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | func ParseNetDisconnect(reader *bitreader.ReaderType) NetDisconnect { | 9 | func ParseNetDisconnect(reader *bitreader.ReaderType) NetDisconnect { |
| 10 | return NetDisconnect{Text: reader.TryReadString()} | 10 | return NetDisconnect{ |
| 11 | Text: reader.TryReadString(), | ||
| 12 | } | ||
| 11 | } | 13 | } |
diff --git a/packets/messages/types/NetFile.go b/pkg/messages/types/netFile.go index c65873d..a41a0cf 100644 --- a/packets/messages/types/NetFile.go +++ b/pkg/messages/types/netFile.go | |||
| @@ -1,16 +1,16 @@ | |||
| 1 | package types | 1 | package messages |
| 2 | 2 | ||
| 3 | import "github.com/pektezol/bitreader" | 3 | import "github.com/pektezol/bitreader" |
| 4 | 4 | ||
| 5 | type NetFile struct { | 5 | type NetFile struct { |
| 6 | TransferId uint32 | 6 | TransferId int32 |
| 7 | FileName string | 7 | FileName string |
| 8 | FileRequested bool | 8 | FileRequested bool |
| 9 | } | 9 | } |
| 10 | 10 | ||
| 11 | func ParseNetFile(reader *bitreader.ReaderType) NetFile { | 11 | func ParseNetFile(reader *bitreader.ReaderType) NetFile { |
| 12 | return NetFile{ | 12 | return NetFile{ |
| 13 | TransferId: reader.TryReadInt32(), | 13 | TransferId: int32(reader.TryReadBits(32)), |
| 14 | FileName: reader.TryReadString(), | 14 | FileName: reader.TryReadString(), |
| 15 | FileRequested: reader.TryReadBool(), | 15 | FileRequested: reader.TryReadBool(), |
| 16 | } | 16 | } |
diff --git a/pkg/messages/types/netNop.go b/pkg/messages/types/netNop.go new file mode 100644 index 0000000..33f8e25 --- /dev/null +++ b/pkg/messages/types/netNop.go | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type NetNop struct{} | ||
| 6 | |||
| 7 | func ParseNetNop(reader *bitreader.ReaderType) NetNop { | ||
| 8 | return NetNop{} | ||
| 9 | } | ||
diff --git a/packets/messages/types/NetSetConVar.go b/pkg/messages/types/netSetConVar.go index eca05e0..08042ae 100644 --- a/packets/messages/types/NetSetConVar.go +++ b/pkg/messages/types/netSetConVar.go | |||
| @@ -1,26 +1,29 @@ | |||
| 1 | package types | 1 | package messages |
| 2 | 2 | ||
| 3 | import "github.com/pektezol/bitreader" | 3 | import "github.com/pektezol/bitreader" |
| 4 | 4 | ||
| 5 | type NetSetConVar struct { | 5 | type NetSetConVar struct { |
| 6 | ConVars []ConVar | 6 | Length int8 |
| 7 | ConVars []conVar | ||
| 7 | } | 8 | } |
| 8 | 9 | ||
| 9 | type ConVar struct { | 10 | type conVar struct { |
| 10 | Name string | 11 | Name string |
| 11 | Value string | 12 | Value string |
| 12 | } | 13 | } |
| 13 | 14 | ||
| 14 | func ParseNetSetConVar(reader *bitreader.ReaderType) NetSetConVar { | 15 | func ParseNetSetConVar(reader *bitreader.ReaderType) NetSetConVar { |
| 15 | length := reader.TryReadInt8() | 16 | length := reader.TryReadBits(8) |
| 16 | convars := make([]ConVar, length) | 17 | convars := []conVar{} |
| 17 | for i := 0; i < int(length); i++ { | 18 | for count := 0; count < int(length); count++ { |
| 18 | convars[i] = ConVar{ | 19 | convar := conVar{ |
| 19 | Name: reader.TryReadString(), | 20 | Name: reader.TryReadString(), |
| 20 | Value: reader.TryReadString(), | 21 | Value: reader.TryReadString(), |
| 21 | } | 22 | } |
| 23 | convars = append(convars, convar) | ||
| 22 | } | 24 | } |
| 23 | return NetSetConVar{ | 25 | return NetSetConVar{ |
| 26 | Length: int8(length), | ||
| 24 | ConVars: convars, | 27 | ConVars: convars, |
| 25 | } | 28 | } |
| 26 | } | 29 | } |
diff --git a/pkg/messages/types/netSignOnState.go b/pkg/messages/types/netSignOnState.go new file mode 100644 index 0000000..4609ff2 --- /dev/null +++ b/pkg/messages/types/netSignOnState.go | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type NetSignOnState struct { | ||
| 6 | SignOnState int8 | ||
| 7 | SpawnCount int32 | ||
| 8 | NumServerPlayers int32 | ||
| 9 | IdsLength int32 | ||
| 10 | PlayersNetworksIds []byte | ||
| 11 | MapNameLength int32 | ||
| 12 | MapName string | ||
| 13 | } | ||
| 14 | |||
| 15 | func ParseNetSignOnState(reader *bitreader.ReaderType) NetSignOnState { | ||
| 16 | netSignOnState := NetSignOnState{ | ||
| 17 | SignOnState: int8(reader.TryReadBits(8)), | ||
| 18 | SpawnCount: int32(reader.TryReadBits(32)), | ||
| 19 | NumServerPlayers: int32(reader.TryReadBits(32)), | ||
| 20 | IdsLength: int32(reader.TryReadBits(32)), | ||
| 21 | } | ||
| 22 | netSignOnState.PlayersNetworksIds = reader.TryReadBytesToSlice(int(netSignOnState.IdsLength)) | ||
| 23 | netSignOnState.MapNameLength = int32(reader.TryReadBits(32)) | ||
| 24 | netSignOnState.MapName = reader.TryReadStringLen(int(netSignOnState.MapNameLength)) | ||
| 25 | return netSignOnState | ||
| 26 | } | ||
diff --git a/packets/messages/types/NetSplitScreenUser.go b/pkg/messages/types/netSplitScreenUser.go index d4d04b5..65e85f3 100644 --- a/packets/messages/types/NetSplitScreenUser.go +++ b/pkg/messages/types/netSplitScreenUser.go | |||
| @@ -1,13 +1,13 @@ | |||
| 1 | package types | 1 | package messages |
| 2 | 2 | ||
| 3 | import "github.com/pektezol/bitreader" | 3 | import "github.com/pektezol/bitreader" |
| 4 | 4 | ||
| 5 | type NetSplitScreenUser struct { | 5 | type NetSplitScreenUser struct { |
| 6 | PlayerSlot bool | 6 | Unknown bool |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | func ParseNetSplitScreenUser(reader *bitreader.ReaderType) NetSplitScreenUser { | 9 | func ParseNetSplitScreenUser(reader *bitreader.ReaderType) NetSplitScreenUser { |
| 10 | return NetSplitScreenUser{ | 10 | return NetSplitScreenUser{ |
| 11 | PlayerSlot: reader.TryReadBool(), | 11 | Unknown: reader.TryReadBool(), |
| 12 | } | 12 | } |
| 13 | } | 13 | } |
diff --git a/packets/messages/types/NetStringCmd.go b/pkg/messages/types/netStringCmd.go index 1ee9f67..158658e 100644 --- a/packets/messages/types/NetStringCmd.go +++ b/pkg/messages/types/netStringCmd.go | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | package types | 1 | package messages |
| 2 | 2 | ||
| 3 | import "github.com/pektezol/bitreader" | 3 | import "github.com/pektezol/bitreader" |
| 4 | 4 | ||
diff --git a/pkg/messages/types/netTick.go b/pkg/messages/types/netTick.go new file mode 100644 index 0000000..e14f259 --- /dev/null +++ b/pkg/messages/types/netTick.go | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type NetTick struct { | ||
| 6 | Tick int32 | ||
| 7 | HostFrameTime int16 | ||
| 8 | HostFrameTimeStdDeviation int16 | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseNetTick(reader *bitreader.ReaderType) NetTick { | ||
| 12 | return NetTick{ | ||
| 13 | Tick: int32(reader.TryReadBits(32)), | ||
| 14 | HostFrameTime: int16(reader.TryReadBits(16) / 10e5), | ||
| 15 | HostFrameTimeStdDeviation: int16(reader.TryReadBits(16) / 10e5), | ||
| 16 | } | ||
| 17 | } | ||
diff --git a/pkg/messages/types/svcBspDecal.go b/pkg/messages/types/svcBspDecal.go new file mode 100644 index 0000000..484497f --- /dev/null +++ b/pkg/messages/types/svcBspDecal.go | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcBspDecal struct { | ||
| 8 | Pos []vectorCoord | ||
| 9 | DecalTextureIndex int16 | ||
| 10 | EntityIndex int16 | ||
| 11 | ModelIndex int16 | ||
| 12 | LowPriority int8 | ||
| 13 | } | ||
| 14 | |||
| 15 | type vectorCoord struct { | ||
| 16 | Value float32 | ||
| 17 | Valid bool | ||
| 18 | } | ||
| 19 | |||
| 20 | func ParseSvcBspDecal(reader *bitreader.ReaderType) SvcBspDecal { | ||
| 21 | svcBspDecal := SvcBspDecal{ | ||
| 22 | Pos: readVectorCoords(reader), | ||
| 23 | DecalTextureIndex: int16(reader.TryReadBits(9)), | ||
| 24 | } | ||
| 25 | if reader.TryReadBool() { | ||
| 26 | svcBspDecal.EntityIndex = int16(reader.TryReadBits(11)) | ||
| 27 | svcBspDecal.ModelIndex = int16(reader.TryReadBits(11)) | ||
| 28 | } | ||
| 29 | svcBspDecal.LowPriority = int8(reader.TryReadBits(1)) | ||
| 30 | return svcBspDecal | ||
| 31 | } | ||
| 32 | |||
| 33 | func readVectorCoords(reader *bitreader.ReaderType) []vectorCoord { | ||
| 34 | const COORD_INTEGER_BITS uint8 = 14 | ||
| 35 | const COORD_FRACTIONAL_BITS uint8 = 5 | ||
| 36 | const COORD_DENOMINATOR uint8 = 1 << COORD_FRACTIONAL_BITS | ||
| 37 | const COORD_RESOLUTION float32 = 1.0 / float32(COORD_DENOMINATOR) | ||
| 38 | readVectorCoord := func() float32 { | ||
| 39 | value := float32(0) | ||
| 40 | integer := reader.TryReadBits(1) | ||
| 41 | fraction := reader.TryReadBits(1) | ||
| 42 | if integer != 0 || fraction != 0 { | ||
| 43 | sign := reader.TryReadBits(1) | ||
| 44 | if integer != 0 { | ||
| 45 | integer = reader.TryReadBits(int(COORD_INTEGER_BITS)) + 1 | ||
| 46 | } | ||
| 47 | if fraction != 0 { | ||
| 48 | fraction = reader.TryReadBits(int(COORD_FRACTIONAL_BITS)) | ||
| 49 | } | ||
| 50 | value = float32(integer) + float32(fraction)*COORD_RESOLUTION | ||
| 51 | if sign != 0 { | ||
| 52 | value = -value | ||
| 53 | } | ||
| 54 | } | ||
| 55 | return value | ||
| 56 | } | ||
| 57 | x := reader.TryReadBits(1) | ||
| 58 | y := reader.TryReadBits(1) | ||
| 59 | z := reader.TryReadBits(1) | ||
| 60 | return []vectorCoord{{Value: readVectorCoord(), Valid: x != 0}, {Value: readVectorCoord(), Valid: y != 0}, {Value: readVectorCoord(), Valid: z != 0}} | ||
| 61 | } | ||
diff --git a/pkg/messages/types/svcClassInfo.go b/pkg/messages/types/svcClassInfo.go new file mode 100644 index 0000000..9f367d3 --- /dev/null +++ b/pkg/messages/types/svcClassInfo.go | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | "math" | ||
| 6 | |||
| 7 | "github.com/pektezol/bitreader" | ||
| 8 | ) | ||
| 9 | |||
| 10 | type SvcClassInfo struct { | ||
| 11 | Length int16 | ||
| 12 | CreateOnClient bool | ||
| 13 | ServerClasses []serverClass | ||
| 14 | } | ||
| 15 | |||
| 16 | type serverClass struct { | ||
| 17 | ClassId int16 | ||
| 18 | ClassName string | ||
| 19 | DataTableName string | ||
| 20 | } | ||
| 21 | |||
| 22 | func ParseSvcClassInfo(reader *bitreader.ReaderType) SvcClassInfo { | ||
| 23 | svcClassInfo := SvcClassInfo{ | ||
| 24 | Length: int16(reader.TryReadBits(16)), | ||
| 25 | CreateOnClient: reader.TryReadBool(), | ||
| 26 | } | ||
| 27 | classes := []serverClass{} | ||
| 28 | if !svcClassInfo.CreateOnClient { | ||
| 29 | for count := 0; count < int(svcClassInfo.Length); count++ { | ||
| 30 | fmt.Println(classes) | ||
| 31 | classes = append(classes, serverClass{ | ||
| 32 | ClassId: int16(reader.TryReadBits(int(math.Log2(float64(svcClassInfo.Length)) + 1))), | ||
| 33 | ClassName: reader.TryReadString(), | ||
| 34 | DataTableName: reader.TryReadString(), | ||
| 35 | }) | ||
| 36 | } | ||
| 37 | } | ||
| 38 | svcClassInfo.ServerClasses = classes | ||
| 39 | return svcClassInfo | ||
| 40 | } | ||
diff --git a/pkg/messages/types/svcCmdKeyValues.go b/pkg/messages/types/svcCmdKeyValues.go new file mode 100644 index 0000000..1c4d819 --- /dev/null +++ b/pkg/messages/types/svcCmdKeyValues.go | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcCmdKeyValues struct { | ||
| 6 | Length int32 | ||
| 7 | Data []byte | ||
| 8 | } | ||
| 9 | |||
| 10 | func ParseSvcCmdKeyValues(reader *bitreader.ReaderType) SvcCmdKeyValues { | ||
| 11 | svcCmdKeyValues := SvcCmdKeyValues{ | ||
| 12 | Length: int32(reader.TryReadBits(32)), | ||
| 13 | } | ||
| 14 | svcCmdKeyValues.Data = reader.TryReadBytesToSlice(int(svcCmdKeyValues.Length)) | ||
| 15 | return svcCmdKeyValues | ||
| 16 | } | ||
diff --git a/pkg/messages/types/svcCreateStringTable.go b/pkg/messages/types/svcCreateStringTable.go new file mode 100644 index 0000000..ed9e477 --- /dev/null +++ b/pkg/messages/types/svcCreateStringTable.go | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "math" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | ) | ||
| 8 | |||
| 9 | type SvcCreateStringTable struct { | ||
| 10 | Name string | ||
| 11 | MaxEntries int16 | ||
| 12 | NumEntries int8 | ||
| 13 | Length int32 | ||
| 14 | UserDataFixedSize bool | ||
| 15 | UserDataSize int16 | ||
| 16 | UserDataSizeBits int8 | ||
| 17 | Flags int8 | ||
| 18 | StringData int | ||
| 19 | } | ||
| 20 | |||
| 21 | func ParseSvcCreateStringTable(reader *bitreader.ReaderType) SvcCreateStringTable { | ||
| 22 | svcCreateStringTable := SvcCreateStringTable{ | ||
| 23 | Name: reader.TryReadString(), | ||
| 24 | MaxEntries: int16(reader.TryReadBits(16)), | ||
| 25 | } | ||
| 26 | svcCreateStringTable.NumEntries = int8(reader.TryReadBits(int(math.Log2(float64(svcCreateStringTable.MaxEntries))) + 1)) | ||
| 27 | svcCreateStringTable.Length = int32(reader.TryReadBits(20)) | ||
| 28 | svcCreateStringTable.UserDataFixedSize = reader.TryReadBool() | ||
| 29 | if svcCreateStringTable.UserDataFixedSize { | ||
| 30 | svcCreateStringTable.UserDataSize = int16(reader.TryReadBits(12)) | ||
| 31 | svcCreateStringTable.UserDataSizeBits = int8(reader.TryReadBits(4)) | ||
| 32 | } | ||
| 33 | svcCreateStringTable.Flags = int8(reader.TryReadBits(2)) | ||
| 34 | reader.SkipBits(int(svcCreateStringTable.Length)) // TODO: StringTable parsing | ||
| 35 | return svcCreateStringTable | ||
| 36 | } | ||
diff --git a/packets/messages/types/SvcCrosshairAngle.go b/pkg/messages/types/svcCrosshairAngle.go index 6584426..cf18212 100644 --- a/packets/messages/types/SvcCrosshairAngle.go +++ b/pkg/messages/types/svcCrosshairAngle.go | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | package types | 1 | package messages |
| 2 | 2 | ||
| 3 | import "github.com/pektezol/bitreader" | 3 | import "github.com/pektezol/bitreader" |
| 4 | 4 | ||
| @@ -8,10 +8,6 @@ type SvcCrosshairAngle struct { | |||
| 8 | 8 | ||
| 9 | func ParseSvcCrosshairAngle(reader *bitreader.ReaderType) SvcCrosshairAngle { | 9 | func ParseSvcCrosshairAngle(reader *bitreader.ReaderType) SvcCrosshairAngle { |
| 10 | return SvcCrosshairAngle{ | 10 | return SvcCrosshairAngle{ |
| 11 | Angle: []int16{ | 11 | Angle: []int16{int16(reader.TryReadBits(16)), int16(reader.TryReadBits(16)), int16(reader.TryReadBits(16))}, |
| 12 | int16(reader.TryReadInt16()), | ||
| 13 | int16(reader.TryReadInt16()), | ||
| 14 | int16(reader.TryReadInt16()), | ||
| 15 | }, | ||
| 16 | } | 12 | } |
| 17 | } | 13 | } |
diff --git a/pkg/messages/types/svcEntityMessage.go b/pkg/messages/types/svcEntityMessage.go new file mode 100644 index 0000000..9726ced --- /dev/null +++ b/pkg/messages/types/svcEntityMessage.go | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcEntityMessage struct { | ||
| 6 | EntityIndex int16 | ||
| 7 | ClassId int16 | ||
| 8 | Length int16 | ||
| 9 | Data []byte | ||
| 10 | } | ||
| 11 | |||
| 12 | func ParseSvcEntityMessage(reader *bitreader.ReaderType) SvcEntityMessage { | ||
| 13 | svcEntityMessage := SvcEntityMessage{ | ||
| 14 | EntityIndex: int16(reader.TryReadBits(11)), | ||
| 15 | ClassId: int16(reader.TryReadBits(9)), | ||
| 16 | Length: int16(reader.TryReadBits(11)), | ||
| 17 | } | ||
| 18 | svcEntityMessage.Data = reader.TryReadBitsToSlice(int(svcEntityMessage.Length)) | ||
| 19 | return svcEntityMessage | ||
| 20 | } | ||
diff --git a/pkg/messages/types/svcFixAngle.go b/pkg/messages/types/svcFixAngle.go new file mode 100644 index 0000000..56acf04 --- /dev/null +++ b/pkg/messages/types/svcFixAngle.go | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcFixAngle struct { | ||
| 6 | Relative bool | ||
| 7 | Angle []int16 | ||
| 8 | } | ||
| 9 | |||
| 10 | func ParseSvcFixAngle(reader *bitreader.ReaderType) SvcFixAngle { | ||
| 11 | return SvcFixAngle{ | ||
| 12 | Relative: reader.TryReadBool(), | ||
| 13 | Angle: []int16{int16(reader.TryReadBits(16)), int16(reader.TryReadBits(16)), int16(reader.TryReadBits(16))}, | ||
| 14 | } | ||
| 15 | } | ||
diff --git a/pkg/messages/types/svcGameEvent.go b/pkg/messages/types/svcGameEvent.go new file mode 100644 index 0000000..6ee4d01 --- /dev/null +++ b/pkg/messages/types/svcGameEvent.go | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcGameEvent struct { | ||
| 6 | Length int16 | ||
| 7 | Data []byte // TODO: GameEvent[] | ||
| 8 | } | ||
| 9 | |||
| 10 | func ParseSvcGameEvent(reader *bitreader.ReaderType) SvcGameEvent { | ||
| 11 | svcGameEvent := SvcGameEvent{ | ||
| 12 | Length: int16(reader.TryReadBits(11)), | ||
| 13 | } | ||
| 14 | svcGameEvent.Data = reader.TryReadBitsToSlice(int(svcGameEvent.Length)) | ||
| 15 | return svcGameEvent | ||
| 16 | } | ||
diff --git a/pkg/messages/types/svcGameEventList.go b/pkg/messages/types/svcGameEventList.go new file mode 100644 index 0000000..b99ce28 --- /dev/null +++ b/pkg/messages/types/svcGameEventList.go | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcGameEventList struct { | ||
| 6 | Events int16 | ||
| 7 | Length int32 | ||
| 8 | GameEventDescriptor []gameEventDescriptor | ||
| 9 | } | ||
| 10 | |||
| 11 | type gameEventDescriptor struct { | ||
| 12 | } | ||
| 13 | |||
| 14 | func ParseSvcGameEventList(reader *bitreader.ReaderType) SvcGameEventList { | ||
| 15 | svcGameEventList := SvcGameEventList{ | ||
| 16 | Events: int16(reader.TryReadBits(9)), | ||
| 17 | Length: int32(reader.TryReadBits(20)), | ||
| 18 | } | ||
| 19 | reader.TryReadBitsToSlice(int(svcGameEventList.Length)) | ||
| 20 | return svcGameEventList | ||
| 21 | } | ||
diff --git a/packets/messages/types/SvcGetCvarValue.go b/pkg/messages/types/svcGetCvarValue.go index 2925da5..aef5c8e 100644 --- a/packets/messages/types/SvcGetCvarValue.go +++ b/pkg/messages/types/svcGetCvarValue.go | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | package types | 1 | package messages |
| 2 | 2 | ||
| 3 | import "github.com/pektezol/bitreader" | 3 | import "github.com/pektezol/bitreader" |
| 4 | 4 | ||
| @@ -8,8 +8,9 @@ type SvcGetCvarValue struct { | |||
| 8 | } | 8 | } |
| 9 | 9 | ||
| 10 | func ParseSvcGetCvarValue(reader *bitreader.ReaderType) SvcGetCvarValue { | 10 | func ParseSvcGetCvarValue(reader *bitreader.ReaderType) SvcGetCvarValue { |
| 11 | return SvcGetCvarValue{ | 11 | svcGetCvarValue := SvcGetCvarValue{ |
| 12 | Cookie: reader.TryReadStringLen(32), | 12 | Cookie: reader.TryReadStringLen(4), |
| 13 | CvarName: reader.TryReadString(), | 13 | CvarName: reader.TryReadString(), |
| 14 | } | 14 | } |
| 15 | return svcGetCvarValue | ||
| 15 | } | 16 | } |
diff --git a/pkg/messages/types/svcMenu.go b/pkg/messages/types/svcMenu.go new file mode 100644 index 0000000..d89f52c --- /dev/null +++ b/pkg/messages/types/svcMenu.go | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcMenu struct { | ||
| 6 | MenuType int16 | ||
| 7 | Length int32 | ||
| 8 | Data []byte | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseSvcMenu(reader *bitreader.ReaderType) SvcMenu { | ||
| 12 | svcMenu := SvcMenu{ | ||
| 13 | MenuType: int16(reader.TryReadBits(16)), | ||
| 14 | Length: int32(reader.TryReadBits(32)), | ||
| 15 | } | ||
| 16 | svcMenu.Data = reader.TryReadBitsToSlice(int(svcMenu.Length)) | ||
| 17 | return svcMenu | ||
| 18 | } | ||
diff --git a/pkg/messages/types/svcPacketEntities.go b/pkg/messages/types/svcPacketEntities.go new file mode 100644 index 0000000..b1c23e5 --- /dev/null +++ b/pkg/messages/types/svcPacketEntities.go | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcPacketEntities struct { | ||
| 6 | MaxEntries int16 | ||
| 7 | IsDelta bool | ||
| 8 | DeltaFrom int32 | ||
| 9 | BaseLine bool | ||
| 10 | UpdatedEntries int16 | ||
| 11 | Length int32 | ||
| 12 | UpdatedBaseline bool | ||
| 13 | Data []byte | ||
| 14 | } | ||
| 15 | |||
| 16 | func ParseSvcPacketEntities(reader *bitreader.ReaderType) SvcPacketEntities { | ||
| 17 | svcPacketEntities := SvcPacketEntities{ | ||
| 18 | MaxEntries: int16(reader.TryReadBits(11)), | ||
| 19 | IsDelta: reader.TryReadBool(), | ||
| 20 | } | ||
| 21 | if svcPacketEntities.IsDelta { | ||
| 22 | svcPacketEntities.DeltaFrom = int32(reader.TryReadBits(32)) | ||
| 23 | } | ||
| 24 | svcPacketEntities.BaseLine = reader.TryReadBool() | ||
| 25 | svcPacketEntities.UpdatedEntries = int16(reader.TryReadBits(11)) | ||
| 26 | svcPacketEntities.Length = int32(reader.TryReadBits(20)) | ||
| 27 | svcPacketEntities.UpdatedBaseline = reader.TryReadBool() | ||
| 28 | svcPacketEntities.Data = reader.TryReadBitsToSlice(int(svcPacketEntities.Length)) | ||
| 29 | return svcPacketEntities | ||
| 30 | } | ||
diff --git a/pkg/messages/types/svcPaintmapData.go b/pkg/messages/types/svcPaintmapData.go new file mode 100644 index 0000000..6b041da --- /dev/null +++ b/pkg/messages/types/svcPaintmapData.go | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcPaintmapData struct { | ||
| 6 | Length int32 | ||
| 7 | Data []byte | ||
| 8 | } | ||
| 9 | |||
| 10 | func ParseSvcPaintmapData(reader *bitreader.ReaderType) SvcPaintmapData { | ||
| 11 | svcPaintmapData := SvcPaintmapData{ | ||
| 12 | Length: int32(reader.TryReadBits(32)), | ||
| 13 | } | ||
| 14 | svcPaintmapData.Data = reader.TryReadBitsToSlice(int(svcPaintmapData.Length)) | ||
| 15 | return svcPaintmapData | ||
| 16 | } | ||
diff --git a/packets/messages/types/SvcPrefetch.go b/pkg/messages/types/svcPrefetch.go index b277252..549f926 100644 --- a/packets/messages/types/SvcPrefetch.go +++ b/pkg/messages/types/svcPrefetch.go | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | package types | 1 | package messages |
| 2 | 2 | ||
| 3 | import "github.com/pektezol/bitreader" | 3 | import "github.com/pektezol/bitreader" |
| 4 | 4 | ||
diff --git a/packets/messages/types/SvcPrint.go b/pkg/messages/types/svcPrint.go index c6d91ac..8aff927 100644 --- a/packets/messages/types/SvcPrint.go +++ b/pkg/messages/types/svcPrint.go | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | package types | 1 | package messages |
| 2 | 2 | ||
| 3 | import "github.com/pektezol/bitreader" | 3 | import "github.com/pektezol/bitreader" |
| 4 | 4 | ||
diff --git a/pkg/messages/types/svcSendTable.go b/pkg/messages/types/svcSendTable.go new file mode 100644 index 0000000..ae8960b --- /dev/null +++ b/pkg/messages/types/svcSendTable.go | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcSendTable struct { | ||
| 6 | NeedsDecoder int8 | ||
| 7 | Length int8 | ||
| 8 | Props int32 | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseSvcSendTable(reader *bitreader.ReaderType) SvcSendTable { | ||
| 12 | return SvcSendTable{ | ||
| 13 | NeedsDecoder: int8(reader.TryReadBits(8)), | ||
| 14 | Length: int8(reader.TryReadBits(8)), | ||
| 15 | Props: int32(reader.TryReadBits(32)), | ||
| 16 | } | ||
| 17 | } | ||
diff --git a/pkg/messages/types/svcServerInfo.go b/pkg/messages/types/svcServerInfo.go new file mode 100644 index 0000000..b8bb308 --- /dev/null +++ b/pkg/messages/types/svcServerInfo.go | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcServerInfo struct { | ||
| 6 | Protocol int16 | ||
| 7 | ServerCount int32 | ||
| 8 | IsHltv bool | ||
| 9 | IsDedicated bool | ||
| 10 | ClientCrc int32 | ||
| 11 | MaxClasses int16 | ||
| 12 | MapCrc int32 | ||
| 13 | PlayerSlot int8 | ||
| 14 | MaxClients int8 | ||
| 15 | Unk int32 | ||
| 16 | TickInterval int32 | ||
| 17 | COs int8 | ||
| 18 | GameDir string | ||
| 19 | MapName string | ||
| 20 | SkyName string | ||
| 21 | HostName string | ||
| 22 | } | ||
| 23 | |||
| 24 | func ParseSvcServerInfo(reader *bitreader.ReaderType) SvcServerInfo { | ||
| 25 | return SvcServerInfo{ | ||
| 26 | Protocol: int16(reader.TryReadBits(16)), | ||
| 27 | ServerCount: int32(reader.TryReadBits(32)), | ||
| 28 | IsHltv: reader.TryReadBool(), | ||
| 29 | IsDedicated: reader.TryReadBool(), | ||
| 30 | ClientCrc: int32(reader.TryReadBits(32)), | ||
| 31 | MaxClasses: int16(reader.TryReadBits(16)), | ||
| 32 | MapCrc: int32(reader.TryReadBits(32)), | ||
| 33 | PlayerSlot: int8(reader.TryReadBits(8)), | ||
| 34 | MaxClients: int8(reader.TryReadBits(8)), | ||
| 35 | Unk: int32(reader.TryReadBits(32)), | ||
| 36 | TickInterval: int32(reader.TryReadBits(32)), | ||
| 37 | COs: int8(reader.TryReadBits(8)), | ||
| 38 | GameDir: reader.TryReadString(), | ||
| 39 | MapName: reader.TryReadString(), | ||
| 40 | SkyName: reader.TryReadString(), | ||
| 41 | HostName: reader.TryReadString(), | ||
| 42 | } | ||
| 43 | } | ||
diff --git a/packets/messages/types/SvcSetPause.go b/pkg/messages/types/svcSetPause.go index c71485c..94303b7 100644 --- a/packets/messages/types/SvcSetPause.go +++ b/pkg/messages/types/svcSetPause.go | |||
| @@ -1,13 +1,13 @@ | |||
| 1 | package types | 1 | package messages |
| 2 | 2 | ||
| 3 | import ( | 3 | import "github.com/pektezol/bitreader" |
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | 4 | ||
| 7 | type SvcSetPause struct { | 5 | type SvcSetPause struct { |
| 8 | Paused bool | 6 | Paused bool |
| 9 | } | 7 | } |
| 10 | 8 | ||
| 11 | func ParseSvcSetPause(reader *bitreader.ReaderType) SvcSetPause { | 9 | func ParseSvcSetPause(reader *bitreader.ReaderType) SvcSetPause { |
| 12 | return SvcSetPause{Paused: reader.TryReadBool()} | 10 | return SvcSetPause{ |
| 11 | Paused: reader.TryReadBool(), | ||
| 12 | } | ||
| 13 | } | 13 | } |
diff --git a/packets/messages/types/SvcSetView.go b/pkg/messages/types/svcSetView.go index 5507eae..70d1e2b 100644 --- a/packets/messages/types/SvcSetView.go +++ b/pkg/messages/types/svcSetView.go | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | package types | 1 | package messages |
| 2 | 2 | ||
| 3 | import "github.com/pektezol/bitreader" | 3 | import "github.com/pektezol/bitreader" |
| 4 | 4 | ||
diff --git a/pkg/messages/types/svcSounds.go b/pkg/messages/types/svcSounds.go new file mode 100644 index 0000000..e87d584 --- /dev/null +++ b/pkg/messages/types/svcSounds.go | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcSounds struct { | ||
| 6 | ReliableSound bool | ||
| 7 | Size int8 | ||
| 8 | Length int16 | ||
| 9 | Data []byte | ||
| 10 | } | ||
| 11 | |||
| 12 | func ParseSvcSounds(reader *bitreader.ReaderType) SvcSounds { | ||
| 13 | svcSounds := SvcSounds{ | ||
| 14 | ReliableSound: reader.TryReadBool(), | ||
| 15 | } | ||
| 16 | if svcSounds.ReliableSound { | ||
| 17 | svcSounds.Size = 1 | ||
| 18 | svcSounds.Length = int16(reader.TryReadBits(8)) | ||
| 19 | } else { | ||
| 20 | svcSounds.Size = int8(reader.TryReadBits(8)) | ||
| 21 | svcSounds.Length = int16(reader.TryReadBits(16)) | ||
| 22 | } | ||
| 23 | svcSounds.Data = reader.TryReadBitsToSlice(int(svcSounds.Length)) | ||
| 24 | return svcSounds | ||
| 25 | } | ||
diff --git a/pkg/messages/types/svcSplitScreen.go b/pkg/messages/types/svcSplitScreen.go new file mode 100644 index 0000000..9c808bc --- /dev/null +++ b/pkg/messages/types/svcSplitScreen.go | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcSplitScreen struct { | ||
| 6 | Unk bool | ||
| 7 | Length int16 | ||
| 8 | Data []byte | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseSvcSplitScreen(reader *bitreader.ReaderType) SvcSplitScreen { | ||
| 12 | svcSplitScreen := SvcSplitScreen{ | ||
| 13 | Unk: reader.TryReadBool(), | ||
| 14 | Length: int16(reader.TryReadBits(11)), | ||
| 15 | } | ||
| 16 | svcSplitScreen.Data = reader.TryReadBitsToSlice(int(svcSplitScreen.Length)) | ||
| 17 | return svcSplitScreen | ||
| 18 | } | ||
diff --git a/pkg/messages/types/svcTempEntities.go b/pkg/messages/types/svcTempEntities.go new file mode 100644 index 0000000..d22423d --- /dev/null +++ b/pkg/messages/types/svcTempEntities.go | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcTempEntities struct { | ||
| 6 | NumEntries int8 | ||
| 7 | Length int32 | ||
| 8 | Data []byte | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseSvcTempEntities(reader *bitreader.ReaderType) SvcTempEntities { | ||
| 12 | svcTempEntities := SvcTempEntities{ | ||
| 13 | NumEntries: int8(reader.TryReadBits(8)), | ||
| 14 | Length: int32(reader.TryReadBits(17)), | ||
| 15 | } | ||
| 16 | svcTempEntities.Data = reader.TryReadBitsToSlice(int(svcTempEntities.Length)) | ||
| 17 | return svcTempEntities | ||
| 18 | } | ||
diff --git a/pkg/messages/types/svcUpdateStringTable.go b/pkg/messages/types/svcUpdateStringTable.go new file mode 100644 index 0000000..2840482 --- /dev/null +++ b/pkg/messages/types/svcUpdateStringTable.go | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcUpdateStringTable struct { | ||
| 6 | TableId int8 | ||
| 7 | NumChangedEntries int16 | ||
| 8 | Length int32 | ||
| 9 | Data []byte | ||
| 10 | } | ||
| 11 | |||
| 12 | func ParseSvcUpdateStringTable(reader *bitreader.ReaderType) SvcUpdateStringTable { | ||
| 13 | svcUpdateStringTable := SvcUpdateStringTable{ | ||
| 14 | TableId: int8(reader.TryReadBits(5)), | ||
| 15 | } | ||
| 16 | if reader.TryReadBool() { | ||
| 17 | svcUpdateStringTable.NumChangedEntries = int16(reader.TryReadBits(16)) | ||
| 18 | } | ||
| 19 | svcUpdateStringTable.Length = int32(reader.TryReadBits(20)) | ||
| 20 | svcUpdateStringTable.Data = reader.TryReadBitsToSlice(int(svcUpdateStringTable.Length)) | ||
| 21 | return svcUpdateStringTable | ||
| 22 | } | ||
diff --git a/pkg/messages/types/svcUserMessage.go b/pkg/messages/types/svcUserMessage.go new file mode 100644 index 0000000..b53c7c0 --- /dev/null +++ b/pkg/messages/types/svcUserMessage.go | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcUserMessage struct { | ||
| 6 | MsgType int8 | ||
| 7 | Length int16 | ||
| 8 | Data []byte | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseSvcUserMessage(reader *bitreader.ReaderType) SvcUserMessage { | ||
| 12 | svcUserMessage := SvcUserMessage{ | ||
| 13 | MsgType: int8(reader.TryReadBits(8)), | ||
| 14 | Length: int16(reader.TryReadBits(12)), | ||
| 15 | } | ||
| 16 | svcUserMessage.Data = reader.TryReadBitsToSlice(int(svcUserMessage.Length)) | ||
| 17 | return svcUserMessage | ||
| 18 | } | ||
diff --git a/pkg/messages/types/svcVoiceData.go b/pkg/messages/types/svcVoiceData.go new file mode 100644 index 0000000..b6c81d4 --- /dev/null +++ b/pkg/messages/types/svcVoiceData.go | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import "github.com/pektezol/bitreader" | ||
| 4 | |||
| 5 | type SvcVoiceData struct { | ||
| 6 | Client int8 | ||
| 7 | Proximity int8 | ||
| 8 | Length int16 | ||
| 9 | Data []byte | ||
| 10 | } | ||
| 11 | |||
| 12 | func ParseSvcVoiceData(reader *bitreader.ReaderType) SvcVoiceData { | ||
| 13 | svcVoiceData := SvcVoiceData{ | ||
| 14 | Client: int8(reader.TryReadBits(8)), | ||
| 15 | Proximity: int8(reader.TryReadBits(8)), | ||
| 16 | Length: int16(reader.TryReadBits(16)), | ||
| 17 | } | ||
| 18 | svcVoiceData.Data = reader.TryReadBitsToSlice(int(svcVoiceData.Length)) | ||
| 19 | return svcVoiceData | ||
| 20 | } | ||
diff --git a/packets/messages/types/SvcVoiceInit.go b/pkg/messages/types/svcVoiceInit.go index 3e18a7b..4c95aab 100644 --- a/packets/messages/types/SvcVoiceInit.go +++ b/pkg/messages/types/svcVoiceInit.go | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | package types | 1 | package messages |
| 2 | 2 | ||
| 3 | import "github.com/pektezol/bitreader" | 3 | import "github.com/pektezol/bitreader" |
| 4 | 4 | ||
| @@ -9,12 +9,12 @@ type SvcVoiceInit struct { | |||
| 9 | } | 9 | } |
| 10 | 10 | ||
| 11 | func ParseSvcVoiceInit(reader *bitreader.ReaderType) SvcVoiceInit { | 11 | func ParseSvcVoiceInit(reader *bitreader.ReaderType) SvcVoiceInit { |
| 12 | svcvoiceinit := SvcVoiceInit{ | 12 | svcVoiceInit := SvcVoiceInit{ |
| 13 | Codec: reader.TryReadString(), | 13 | Codec: reader.TryReadString(), |
| 14 | Quality: reader.TryReadInt8(), | 14 | Quality: uint8(reader.TryReadBits(8)), |
| 15 | } | 15 | } |
| 16 | if svcvoiceinit.Quality == 255 { | 16 | if svcVoiceInit.Quality == 0b11111111 { |
| 17 | svcvoiceinit.Unk = reader.TryReadFloat32() | 17 | svcVoiceInit.Unk = reader.TryReadFloat32() |
| 18 | } | 18 | } |
| 19 | return svcvoiceinit | 19 | return svcVoiceInit |
| 20 | } | 20 | } |
diff --git a/pkg/packets/headers.go b/pkg/packets/headers.go new file mode 100644 index 0000000..543476b --- /dev/null +++ b/pkg/packets/headers.go | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | package packets | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | ) | ||
| 8 | |||
| 9 | type Headers struct { | ||
| 10 | DemoFileStamp string | ||
| 11 | DemoProtocol int32 | ||
| 12 | NetworkProtocol int32 | ||
| 13 | ServerName string | ||
| 14 | ClientName string | ||
| 15 | MapName string | ||
| 16 | GameDirectory string | ||
| 17 | PlaybackTime float32 | ||
| 18 | PlaybackTicks int32 | ||
| 19 | PlaybackFrames int32 | ||
| 20 | SignOnLength int32 | ||
| 21 | } | ||
| 22 | |||
| 23 | func ParseHeaders(reader *bitreader.ReaderType) Headers { | ||
| 24 | headers := Headers{ | ||
| 25 | DemoFileStamp: reader.TryReadString(), | ||
| 26 | DemoProtocol: int32(reader.TryReadInt32()), | ||
| 27 | NetworkProtocol: int32(reader.TryReadInt32()), | ||
| 28 | ServerName: reader.TryReadStringLen(260), | ||
| 29 | ClientName: reader.TryReadStringLen(260), | ||
| 30 | MapName: reader.TryReadStringLen(260), | ||
| 31 | GameDirectory: reader.TryReadStringLen(260), | ||
| 32 | PlaybackTime: reader.TryReadFloat32(), | ||
| 33 | PlaybackTicks: int32(reader.TryReadInt32()), | ||
| 34 | PlaybackFrames: int32(reader.TryReadInt32()), | ||
| 35 | SignOnLength: int32(reader.TryReadInt32()), | ||
| 36 | } | ||
| 37 | if headers.DemoFileStamp != "HL2DEMO" { | ||
| 38 | panic("invalid demo file stamp") | ||
| 39 | } | ||
| 40 | if headers.DemoProtocol != 4 { | ||
| 41 | panic("this parser only supports demos from new engine") | ||
| 42 | } | ||
| 43 | if headers.NetworkProtocol != 2001 { | ||
| 44 | panic("this parser only supports demos from portal 2") | ||
| 45 | } | ||
| 46 | fmt.Printf("Headers: %+v\n", headers) | ||
| 47 | return headers | ||
| 48 | } | ||
diff --git a/pkg/packets/packets.go b/pkg/packets/packets.go new file mode 100644 index 0000000..a84da21 --- /dev/null +++ b/pkg/packets/packets.go | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | package packets | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "bytes" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | "github.com/pektezol/demoparser/pkg/classes" | ||
| 8 | "github.com/pektezol/demoparser/pkg/messages" | ||
| 9 | ) | ||
| 10 | |||
| 11 | type PacketMessageInfo struct { | ||
| 12 | PacketType int8 | ||
| 13 | TickNumber int32 | ||
| 14 | SlotNumber int8 | ||
| 15 | Data any | ||
| 16 | } | ||
| 17 | |||
| 18 | const MSSC = 2 | ||
| 19 | |||
| 20 | func ParsePackets(reader *bitreader.ReaderType) PacketMessageInfo { | ||
| 21 | packetType := reader.TryReadBits(8) | ||
| 22 | tickNumber := reader.TryReadBits(32) | ||
| 23 | slotNumber := reader.TryReadBits(8) | ||
| 24 | var packetData any | ||
| 25 | switch packetType { | ||
| 26 | case 1: // SignOn | ||
| 27 | signOn := SignOn{} | ||
| 28 | for count := 0; count < MSSC; count++ { | ||
| 29 | signOn.PacketInfo = append(signOn.PacketInfo, classes.ParseCmdInfo(reader)) | ||
| 30 | } | ||
| 31 | signOn.InSequence = int32(reader.TryReadBits(32)) | ||
| 32 | signOn.OutSequence = int32(reader.TryReadBits(32)) | ||
| 33 | signOn.Size = int32(reader.TryReadInt32()) | ||
| 34 | data := reader.TryReadBytesToSlice(int(signOn.Size)) | ||
| 35 | packetReader := bitreader.Reader(bytes.NewReader(data), true) | ||
| 36 | for { | ||
| 37 | messageType, err := packetReader.ReadBits(6) | ||
| 38 | if err != nil { | ||
| 39 | break | ||
| 40 | } | ||
| 41 | signOn.Data = append(signOn.Data, messages.ParseMessages(int(messageType), packetReader)) | ||
| 42 | } | ||
| 43 | packetData = signOn | ||
| 44 | case 2: // Packet | ||
| 45 | packet := Packet{} | ||
| 46 | for count := 0; count < MSSC; count++ { | ||
| 47 | packet.PacketInfo = append(packet.PacketInfo, classes.ParseCmdInfo(reader)) | ||
| 48 | } | ||
| 49 | packet.InSequence = int32(reader.TryReadBits(32)) | ||
| 50 | packet.OutSequence = int32(reader.TryReadBits(32)) | ||
| 51 | packet.Size = int32(reader.TryReadInt32()) | ||
| 52 | data := reader.TryReadBytesToSlice(int(packet.Size)) | ||
| 53 | packetReader := bitreader.Reader(bytes.NewReader(data), true) | ||
| 54 | for { | ||
| 55 | messageType, err := packetReader.ReadBits(6) | ||
| 56 | if err != nil { | ||
| 57 | break | ||
| 58 | } | ||
| 59 | packet.Data = append(packet.Data, messages.ParseMessages(int(messageType), packetReader)) | ||
| 60 | } | ||
| 61 | packetData = packet | ||
| 62 | case 3: // SyncTick | ||
| 63 | syncTick := SyncTick{} | ||
| 64 | packetData = syncTick | ||
| 65 | case 4: // ConsoleCmd | ||
| 66 | size := reader.TryReadInt32() | ||
| 67 | consoleCmd := ConsoleCmd{ | ||
| 68 | Size: int32(size), | ||
| 69 | Data: reader.TryReadStringLen(int(size)), | ||
| 70 | } | ||
| 71 | packetData = consoleCmd | ||
| 72 | case 5: // UserCmd | ||
| 73 | userCmd := UserCmd{} | ||
| 74 | userCmd.Cmd = int32(reader.TryReadInt32()) | ||
| 75 | userCmd.Size = int32(reader.TryReadInt32()) | ||
| 76 | data := reader.TryReadBytesToSlice(int(userCmd.Size)) | ||
| 77 | userCmd.Data = classes.ParseUserCmdInfo(data) | ||
| 78 | packetData = userCmd | ||
| 79 | case 6: // DataTables | ||
| 80 | dataTables := DataTables{} | ||
| 81 | dataTables.Size = int32(reader.TryReadInt32()) | ||
| 82 | data := reader.TryReadBytesToSlice(int(dataTables.Size)) | ||
| 83 | dataTableReader := bitreader.Reader(bytes.NewReader(data), true) | ||
| 84 | count := 0 | ||
| 85 | for dataTableReader.TryReadBool() { | ||
| 86 | count++ | ||
| 87 | dataTables.SendTable = append(dataTables.SendTable, classes.ParseSendTable(dataTableReader)) | ||
| 88 | } | ||
| 89 | numOfClasses := dataTableReader.TryReadBits(16) | ||
| 90 | for count = 0; count < int(numOfClasses); count++ { | ||
| 91 | dataTables.ServerClassInfo = append(dataTables.ServerClassInfo, classes.ParseServerClassInfo(dataTableReader, count, int(numOfClasses))) | ||
| 92 | } | ||
| 93 | packetData = dataTables | ||
| 94 | case 7: // Stop | ||
| 95 | stop := Stop{} | ||
| 96 | if reader.TryReadBool() { | ||
| 97 | // read remaining data | ||
| 98 | stop.RemainingData = []byte{} | ||
| 99 | } | ||
| 100 | packetData = stop | ||
| 101 | case 8: // CustomData | ||
| 102 | customData := CustomData{ | ||
| 103 | Unknown: int32(reader.TryReadBits(32)), | ||
| 104 | Size: int32(reader.TryReadBits(32)), | ||
| 105 | } | ||
| 106 | customData.Data = string(reader.TryReadBytesToSlice(int(customData.Size))) | ||
| 107 | packetData = customData | ||
| 108 | case 9: // StringTables | ||
| 109 | stringTables := StringTables{ | ||
| 110 | Size: int32(reader.TryReadInt32()), | ||
| 111 | } | ||
| 112 | data := reader.TryReadBytesToSlice(int(stringTables.Size)) | ||
| 113 | stringTableReader := bitreader.Reader(bytes.NewReader(data), true) | ||
| 114 | stringTables.Data = classes.ParseStringTables(stringTableReader) | ||
| 115 | packetData = stringTables | ||
| 116 | default: // invalid | ||
| 117 | panic("invalid packet type") | ||
| 118 | } | ||
| 119 | return PacketMessageInfo{ | ||
| 120 | PacketType: int8(packetType), | ||
| 121 | TickNumber: int32(tickNumber), | ||
| 122 | SlotNumber: int8(slotNumber), | ||
| 123 | Data: packetData, | ||
| 124 | } | ||
| 125 | } | ||
diff --git a/packets/types.go b/pkg/packets/types.go index 41d633a..6297b01 100644 --- a/packets/types.go +++ b/pkg/packets/types.go | |||
| @@ -1,51 +1,40 @@ | |||
| 1 | package packets | 1 | package packets |
| 2 | 2 | ||
| 3 | import ( | 3 | import "github.com/pektezol/demoparser/pkg/classes" |
| 4 | "github.com/pektezol/demoparser/packets/classes" | ||
| 5 | "github.com/pektezol/demoparser/packets/messages" | ||
| 6 | ) | ||
| 7 | |||
| 8 | type Header struct { | ||
| 9 | DemoFileStamp string | ||
| 10 | DemoProtocol uint32 | ||
| 11 | NetworkProtocol uint32 | ||
| 12 | ServerName string | ||
| 13 | ClientName string | ||
| 14 | MapName string | ||
| 15 | GameDirectory string | ||
| 16 | PlaybackTime float32 | ||
| 17 | PlaybackTicks int32 | ||
| 18 | PlaybackFrames int32 | ||
| 19 | SignOnLength uint32 | ||
| 20 | } | ||
| 21 | 4 | ||
| 22 | type SignOn struct { | 5 | type SignOn struct { |
| 23 | PacketInfo []classes.CmdInfo | 6 | PacketInfo []classes.CmdInfo |
| 24 | InSequence int32 | 7 | InSequence int32 |
| 25 | OutSequence int32 | 8 | OutSequence int32 |
| 26 | Data []messages.Message | 9 | Size int32 |
| 10 | Data []any | ||
| 27 | } | 11 | } |
| 28 | 12 | ||
| 29 | type Packet struct { | 13 | type Packet struct { |
| 30 | PacketInfo []classes.CmdInfo | 14 | PacketInfo []classes.CmdInfo |
| 31 | InSequence int32 | 15 | InSequence int32 |
| 32 | OutSequence int32 | 16 | OutSequence int32 |
| 33 | Data []messages.Message | 17 | Size int32 |
| 18 | Data []any | ||
| 34 | } | 19 | } |
| 35 | 20 | ||
| 36 | type SyncTick struct{} | 21 | type SyncTick struct{} |
| 37 | 22 | ||
| 38 | type ConsoleCmd struct { | 23 | type ConsoleCmd struct { |
| 24 | Size int32 | ||
| 39 | Data string | 25 | Data string |
| 40 | } | 26 | } |
| 41 | 27 | ||
| 42 | type UserCmd struct { | 28 | type UserCmd struct { |
| 43 | Cmd int32 | 29 | Cmd int32 |
| 30 | Size int32 | ||
| 44 | Data classes.UserCmdInfo | 31 | Data classes.UserCmdInfo |
| 45 | } | 32 | } |
| 46 | 33 | ||
| 47 | type DataTables struct { | 34 | type DataTables struct { |
| 48 | Data classes.DataTable | 35 | Size int32 |
| 36 | SendTable []classes.SendTable | ||
| 37 | ServerClassInfo []classes.ServerClassInfo | ||
| 49 | } | 38 | } |
| 50 | 39 | ||
| 51 | type Stop struct { | 40 | type Stop struct { |
| @@ -54,9 +43,11 @@ type Stop struct { | |||
| 54 | 43 | ||
| 55 | type CustomData struct { | 44 | type CustomData struct { |
| 56 | Unknown int32 | 45 | Unknown int32 |
| 57 | Data []byte | 46 | Size int32 |
| 47 | Data string | ||
| 58 | } | 48 | } |
| 59 | 49 | ||
| 60 | type StringTables struct { | 50 | type StringTables struct { |
| 51 | Size int32 | ||
| 61 | Data []classes.StringTable | 52 | Data []classes.StringTable |
| 62 | } | 53 | } |