diff options
| author | Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> | 2023-11-06 18:37:11 +0300 |
|---|---|---|
| committer | Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> | 2023-11-06 18:37:11 +0300 |
| commit | 2f8c92f261586f68a976efce0cfcdd0401f402e0 (patch) | |
| tree | 33189cc48987789dff4e7fba0a74d2b2326f0a04 | |
| parent | convert cm ticks correctly (diff) | |
| download | sdp.go-2f8c92f261586f68a976efce0cfcdd0401f402e0.tar.gz sdp.go-2f8c92f261586f68a976efce0cfcdd0401f402e0.tar.bz2 sdp.go-2f8c92f261586f68a976efce0cfcdd0401f402e0.zip | |
dont try to understand it, feel itlp-parser
48 files changed, 221 insertions, 2276 deletions
diff --git a/cmd/parser.go b/cmd/parser.go index 5b84781..12a3562 100644 --- a/cmd/parser.go +++ b/cmd/parser.go | |||
| @@ -1,46 +1,237 @@ | |||
| 1 | package main | 1 | package main |
| 2 | 2 | ||
| 3 | import ( | 3 | import ( |
| 4 | "errors" | ||
| 5 | "math" | ||
| 4 | "os" | 6 | "os" |
| 5 | 7 | ||
| 6 | "github.com/pektezol/bitreader" | 8 | "github.com/pektezol/bitreader" |
| 7 | "github.com/pektezol/demoparser/pkg/packets" | ||
| 8 | ) | 9 | ) |
| 9 | 10 | ||
| 10 | const littleEndian bool = true | 11 | // Don't try to understand it, feel it. |
| 11 | 12 | func getScoreboard(filePath string) (portalCount int32, tickCount int64, err error) { | |
| 12 | func main() { | 13 | file, err := os.Open(filePath) |
| 13 | if len(os.Args) != 2 { | 14 | if err != nil { |
| 14 | panic("specify file in command line arguments") | 15 | return 0, 0, err |
| 15 | } | 16 | } |
| 16 | files, err := os.ReadDir(os.Args[1]) | 17 | reader := bitreader.NewReader(file, true) |
| 17 | if err != nil { // If it's not a directory | 18 | demoFileStamp := reader.TryReadString() |
| 18 | file, err := os.Open(os.Args[1]) | 19 | demoProtocol := reader.TryReadSInt32() |
| 19 | if err != nil { | 20 | networkProtocol := reader.TryReadSInt32() |
| 20 | panic(err) | 21 | reader.SkipBytes(1056) |
| 21 | } | 22 | if demoFileStamp != "HL2DEMO" { |
| 22 | reader := bitreader.NewReader(file, littleEndian) | 23 | return 0, 0, errors.New("invalid demo file stamp") |
| 23 | demoParserHandler(reader) | ||
| 24 | defer file.Close() | ||
| 25 | return | ||
| 26 | } | 24 | } |
| 27 | for _, fileinfo := range files { // If it is a directory | 25 | if demoProtocol != 4 { |
| 28 | file, err := os.Open(os.Args[1] + fileinfo.Name()) | 26 | return 0, 0, errors.New("this parser only supports demos from new engine") |
| 29 | if err != nil { | 27 | } |
| 30 | panic(err) | 28 | if networkProtocol != 2001 { |
| 31 | } | 29 | return 0, 0, errors.New("this parser only supports demos from portal 2") |
| 32 | reader := bitreader.NewReader(file, littleEndian) | ||
| 33 | demoParserHandler(reader) | ||
| 34 | defer file.Close() | ||
| 35 | } | 30 | } |
| 36 | } | ||
| 37 | |||
| 38 | func demoParserHandler(reader *bitreader.Reader) { | ||
| 39 | packets.ParseHeaders(reader) | ||
| 40 | for { | 31 | for { |
| 41 | packet := packets.ParsePackets(reader) | 32 | packetType := reader.TryReadUInt8() |
| 42 | if packet.PacketType == 7 { | 33 | reader.SkipBits(40) |
| 34 | switch packetType { | ||
| 35 | case 1: | ||
| 36 | reader.SkipBytes(160) | ||
| 37 | reader.SkipBytes(uint64(reader.TryReadSInt32())) | ||
| 38 | case 2: | ||
| 39 | reader.SkipBytes(160) | ||
| 40 | size := reader.TryReadUInt32() | ||
| 41 | packetReader := bitreader.NewReaderFromBytes(reader.TryReadBytesToSlice(uint64(size)), true) | ||
| 42 | for { | ||
| 43 | messageType, err := packetReader.ReadBits(6) | ||
| 44 | if err != nil { | ||
| 45 | break | ||
| 46 | } | ||
| 47 | switch messageType { | ||
| 48 | case 0: | ||
| 49 | case 1: | ||
| 50 | packetReader.TryReadString() | ||
| 51 | case 2: | ||
| 52 | packetReader.SkipBytes(4) | ||
| 53 | packetReader.TryReadString() | ||
| 54 | packetReader.SkipBits(2) | ||
| 55 | case 3: | ||
| 56 | packetReader.SkipBits(1) | ||
| 57 | case 4: | ||
| 58 | packetReader.SkipBytes(8) | ||
| 59 | case 5: | ||
| 60 | packetReader.TryReadString() | ||
| 61 | case 6: | ||
| 62 | for count := 0; count < int(packetReader.TryReadUInt8()); count++ { | ||
| 63 | packetReader.TryReadString() | ||
| 64 | packetReader.TryReadString() | ||
| 65 | } | ||
| 66 | case 7: | ||
| 67 | packetReader.SkipBytes(9) | ||
| 68 | idsLength := packetReader.TryReadUInt32() | ||
| 69 | if idsLength > 0 { | ||
| 70 | packetReader.SkipBytes(uint64(idsLength)) | ||
| 71 | } | ||
| 72 | mapLength := packetReader.TryReadUInt32() | ||
| 73 | if mapLength > 0 { | ||
| 74 | packetReader.TryReadStringLength(uint64(mapLength)) | ||
| 75 | } | ||
| 76 | case 8: | ||
| 77 | packetReader.SkipBits(210) | ||
| 78 | packetReader.TryReadStringLength(1) | ||
| 79 | packetReader.TryReadString() | ||
| 80 | packetReader.TryReadString() | ||
| 81 | packetReader.TryReadString() | ||
| 82 | packetReader.TryReadString() | ||
| 83 | case 9: | ||
| 84 | packetReader.SkipBits(1) | ||
| 85 | packetReader.SkipBits(uint64(packetReader.TryReadUInt8())) | ||
| 86 | case 10: | ||
| 87 | classCount := packetReader.TryReadUInt16() | ||
| 88 | if !packetReader.TryReadBool() { | ||
| 89 | for count := 0; count < int(classCount); count++ { | ||
| 90 | packetReader.SkipBits(uint64(math.Log2(float64(classCount)) + 1)) | ||
| 91 | packetReader.TryReadString() | ||
| 92 | packetReader.TryReadString() | ||
| 93 | } | ||
| 94 | } | ||
| 95 | case 11: | ||
| 96 | packetReader.SkipBits(1) | ||
| 97 | case 12: | ||
| 98 | packetReader.TryReadString() | ||
| 99 | maxEntries := packetReader.TryReadSInt16() | ||
| 100 | packetReader.SkipBits(uint64(math.Log2(float64(maxEntries))) + 1) | ||
| 101 | length := packetReader.TryReadBits(20) | ||
| 102 | if packetReader.TryReadBool() { | ||
| 103 | packetReader.SkipBytes(2) | ||
| 104 | } | ||
| 105 | packetReader.SkipBits(2) | ||
| 106 | packetReader.SkipBits(length) | ||
| 107 | case 13: | ||
| 108 | packetReader.SkipBits(5) | ||
| 109 | if packetReader.TryReadBool() { | ||
| 110 | packetReader.SkipBytes(2) | ||
| 111 | } | ||
| 112 | packetReader.SkipBits(packetReader.TryReadBits(20)) | ||
| 113 | case 14: | ||
| 114 | packetReader.TryReadString() | ||
| 115 | if packetReader.TryReadUInt8() == 255 { | ||
| 116 | packetReader.SkipBytes(4) | ||
| 117 | } | ||
| 118 | case 15: | ||
| 119 | packetReader.SkipBytes(2) | ||
| 120 | packetReader.SkipBits(uint64(packetReader.TryReadUInt16())) | ||
| 121 | case 16: | ||
| 122 | packetReader.TryReadString() | ||
| 123 | case 17: | ||
| 124 | var length uint16 | ||
| 125 | if packetReader.TryReadBool() { | ||
| 126 | length = uint16(packetReader.TryReadUInt8()) | ||
| 127 | } else { | ||
| 128 | packetReader.SkipBytes(1) | ||
| 129 | length = packetReader.TryReadUInt16() | ||
| 130 | } | ||
| 131 | packetReader.SkipBits(uint64(length)) | ||
| 132 | case 18: | ||
| 133 | packetReader.SkipBits(11) | ||
| 134 | case 19: | ||
| 135 | packetReader.SkipBits(49) | ||
| 136 | case 20: | ||
| 137 | packetReader.SkipBits(48) | ||
| 138 | case 21: | ||
| 139 | readVectorCoord := func() float32 { | ||
| 140 | value := float32(0) | ||
| 141 | integer := packetReader.TryReadBits(1) | ||
| 142 | fraction := packetReader.TryReadBits(1) | ||
| 143 | if integer != 0 || fraction != 0 { | ||
| 144 | sign := packetReader.TryReadBits(1) | ||
| 145 | if integer != 0 { | ||
| 146 | integer = packetReader.TryReadBits(uint64(14)) + 1 | ||
| 147 | } | ||
| 148 | if fraction != 0 { | ||
| 149 | fraction = packetReader.TryReadBits(uint64(5)) | ||
| 150 | } | ||
| 151 | value = float32(integer) + float32(fraction)*(1.0/float32(1<<5)) | ||
| 152 | if sign != 0 { | ||
| 153 | value = -value | ||
| 154 | } | ||
| 155 | } | ||
| 156 | return value | ||
| 157 | } | ||
| 158 | packetReader.SkipBits(3) | ||
| 159 | readVectorCoord() | ||
| 160 | readVectorCoord() | ||
| 161 | readVectorCoord() | ||
| 162 | packetReader.SkipBits(9) | ||
| 163 | if packetReader.TryReadBool() { | ||
| 164 | packetReader.SkipBits(22) | ||
| 165 | } | ||
| 166 | packetReader.SkipBits(1) | ||
| 167 | case 22: | ||
| 168 | packetReader.SkipBits(1) | ||
| 169 | packetReader.SkipBits(packetReader.TryReadBits(11)) | ||
| 170 | case 23: | ||
| 171 | msgType := int8(packetReader.TryReadBits(8)) | ||
| 172 | msgLength := packetReader.TryReadBits(12) | ||
| 173 | userMessageReader := bitreader.NewReaderFromBytes(packetReader.TryReadBitsToSlice(msgLength), true) | ||
| 174 | switch msgType { | ||
| 175 | case 60: | ||
| 176 | scoreboardTempUpdate := struct { | ||
| 177 | NumPortals int32 | ||
| 178 | TimeTaken int32 | ||
| 179 | }{ | ||
| 180 | NumPortals: userMessageReader.TryReadSInt32(), | ||
| 181 | TimeTaken: userMessageReader.TryReadSInt32(), | ||
| 182 | } | ||
| 183 | portalCount = scoreboardTempUpdate.NumPortals | ||
| 184 | tickCount = int64(math.Round(float64((float32(scoreboardTempUpdate.TimeTaken) / 100.0) / float32(1.0/60.0)))) | ||
| 185 | } | ||
| 186 | case 24: | ||
| 187 | packetReader.SkipBits(20) | ||
| 188 | packetReader.SkipBits(packetReader.TryReadBits(11)) | ||
| 189 | case 25: | ||
| 190 | packetReader.SkipBits(packetReader.TryReadBits(11)) | ||
| 191 | case 26: | ||
| 192 | packetReader.SkipBits(11) | ||
| 193 | if packetReader.TryReadBool() { | ||
| 194 | packetReader.SkipBytes(4) | ||
| 195 | } | ||
| 196 | packetReader.SkipBits(12) | ||
| 197 | length := packetReader.TryReadBits(20) | ||
| 198 | packetReader.SkipBits(1) | ||
| 199 | packetReader.SkipBits(length) | ||
| 200 | |||
| 201 | case 27: | ||
| 202 | packetReader.SkipBits(8) | ||
| 203 | packetReader.SkipBits(packetReader.TryReadBits(17)) | ||
| 204 | case 28: | ||
| 205 | packetReader.SkipBits(13) | ||
| 206 | case 29: | ||
| 207 | packetReader.SkipBits(16) | ||
| 208 | packetReader.SkipBits(packetReader.TryReadBits(32)) | ||
| 209 | case 30: | ||
| 210 | packetReader.SkipBits(9) | ||
| 211 | packetReader.SkipBits(packetReader.TryReadBits(20)) | ||
| 212 | case 31: | ||
| 213 | packetReader.SkipBits(32) | ||
| 214 | packetReader.TryReadString() | ||
| 215 | case 32: | ||
| 216 | packetReader.SkipBytes(packetReader.TryReadBits(32)) | ||
| 217 | case 33: | ||
| 218 | packetReader.SkipBits(packetReader.TryReadBits(32)) | ||
| 219 | default: | ||
| 220 | panic("unknown msg type") | ||
| 221 | } | ||
| 222 | } | ||
| 223 | case 3, 7: | ||
| 224 | case 4, 6, 9: | ||
| 225 | reader.SkipBytes(uint64(reader.TryReadSInt32())) | ||
| 226 | case 5, 8: | ||
| 227 | reader.SkipBits(32) | ||
| 228 | reader.SkipBytes(uint64(reader.TryReadSInt32())) | ||
| 229 | default: | ||
| 230 | return 0, 0, errors.New("invalid packet type") | ||
| 231 | } | ||
| 232 | if packetType == 7 { | ||
| 43 | break | 233 | break |
| 44 | } | 234 | } |
| 45 | } | 235 | } |
| 236 | return portalCount, tickCount, nil | ||
| 46 | } | 237 | } |
diff --git a/pkg/classes/consoleCmd.go b/pkg/classes/consoleCmd.go deleted file mode 100644 index fa9bbd0..0000000 --- a/pkg/classes/consoleCmd.go +++ /dev/null | |||
| @@ -1,15 +0,0 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type ConsoleCmd struct { | ||
| 8 | Size int32 | ||
| 9 | Data string | ||
| 10 | } | ||
| 11 | |||
| 12 | func (consoleCmd *ConsoleCmd) ParseConsoleCmd(reader *bitreader.Reader) { | ||
| 13 | consoleCmd.Size = reader.TryReadSInt32() | ||
| 14 | consoleCmd.Data = reader.TryReadStringLength(uint64(consoleCmd.Size)) | ||
| 15 | } | ||
diff --git a/pkg/classes/customData.go b/pkg/classes/customData.go deleted file mode 100644 index 59cb121..0000000 --- a/pkg/classes/customData.go +++ /dev/null | |||
| @@ -1,26 +0,0 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type CustomData struct { | ||
| 8 | Type int32 | ||
| 9 | Size int32 | ||
| 10 | Data string | ||
| 11 | } | ||
| 12 | |||
| 13 | func (customData *CustomData) ParseCustomData(reader *bitreader.Reader, tickNumber int32, packetType uint8) { | ||
| 14 | customData.Type = reader.TryReadSInt32() | ||
| 15 | customData.Size = reader.TryReadSInt32() | ||
| 16 | if customData.Type != 0 || customData.Size == 8 { | ||
| 17 | // Not SAR data | ||
| 18 | customData.Data = string(reader.TryReadBytesToSlice(uint64(customData.Size))) | ||
| 19 | return | ||
| 20 | } | ||
| 21 | // SAR data | ||
| 22 | sarData := SarData{} | ||
| 23 | data := reader.TryReadBytesToSlice(uint64(customData.Size)) | ||
| 24 | sarReader := bitreader.NewReaderFromBytes(data, true) | ||
| 25 | sarData.ParseSarData(sarReader) | ||
| 26 | } | ||
diff --git a/pkg/classes/dataTables.go b/pkg/classes/dataTables.go deleted file mode 100644 index c17e5f6..0000000 --- a/pkg/classes/dataTables.go +++ /dev/null | |||
| @@ -1,232 +0,0 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | ) | ||
| 8 | |||
| 9 | type DataTables struct { | ||
| 10 | Size int32 | ||
| 11 | SendTable []SendTable | ||
| 12 | ServerClassInfo []ServerClassInfo | ||
| 13 | } | ||
| 14 | |||
| 15 | type SendTable struct { | ||
| 16 | NeedsDecoder bool | ||
| 17 | NetTableName string | ||
| 18 | NumOfProps int16 | ||
| 19 | Props []prop | ||
| 20 | } | ||
| 21 | |||
| 22 | type ServerClassInfo struct { | ||
| 23 | ClassId uint16 | ||
| 24 | ClassName string | ||
| 25 | DataTableName string | ||
| 26 | } | ||
| 27 | |||
| 28 | type prop struct { | ||
| 29 | SendPropType sendPropType | ||
| 30 | SendPropName string | ||
| 31 | SendPropFlags uint32 | ||
| 32 | Priority uint8 | ||
| 33 | ExcludeDtName string | ||
| 34 | LowValue float32 | ||
| 35 | HighValue float32 | ||
| 36 | NumBits int32 | ||
| 37 | NumElements int32 | ||
| 38 | } | ||
| 39 | |||
| 40 | func (dataTables *DataTables) ParseDataTables(reader *bitreader.Reader) { | ||
| 41 | dataTables.Size = int32(reader.TryReadSInt32()) | ||
| 42 | dataTableReader := bitreader.NewReaderFromBytes(reader.TryReadBytesToSlice(uint64(dataTables.Size)), true) | ||
| 43 | count := 0 | ||
| 44 | for dataTableReader.TryReadBool() { | ||
| 45 | count++ | ||
| 46 | dataTables.SendTable = append(dataTables.SendTable, ParseSendTable(dataTableReader)) | ||
| 47 | } | ||
| 48 | numOfClasses := dataTableReader.TryReadBits(16) | ||
| 49 | for count = 0; count < int(numOfClasses); count++ { | ||
| 50 | dataTables.ServerClassInfo = append(dataTables.ServerClassInfo, ParseServerClassInfo(dataTableReader, count, int(numOfClasses))) | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | func ParseSendTable(reader *bitreader.Reader) SendTable { | ||
| 55 | sendTable := SendTable{ | ||
| 56 | NeedsDecoder: reader.TryReadBool(), | ||
| 57 | NetTableName: reader.TryReadString(), | ||
| 58 | NumOfProps: int16(reader.TryReadBits(10)), | ||
| 59 | } | ||
| 60 | if sendTable.NumOfProps < 0 { | ||
| 61 | return sendTable | ||
| 62 | } | ||
| 63 | for count := 0; count < int(sendTable.NumOfProps); count++ { | ||
| 64 | propType := int8(reader.TryReadBits(5)) | ||
| 65 | if propType >= int8(7) { | ||
| 66 | return sendTable | ||
| 67 | } | ||
| 68 | prop := prop{ | ||
| 69 | SendPropType: sendPropType(propType), | ||
| 70 | SendPropName: reader.TryReadString(), | ||
| 71 | SendPropFlags: uint32(reader.TryReadBits(19)), | ||
| 72 | Priority: reader.TryReadUInt8(), | ||
| 73 | } | ||
| 74 | if propType == int8(ESendPropTypeDataTable) || checkBit(prop.SendPropFlags, 6) { | ||
| 75 | prop.ExcludeDtName = reader.TryReadString() | ||
| 76 | } else { | ||
| 77 | switch propType { | ||
| 78 | case int8(ESendPropTypeString), int8(ESendPropTypeInt), int8(ESendPropTypeFloat), int8(ESendPropTypeVector3), int8(ESendPropTypeVector2): | ||
| 79 | prop.LowValue = reader.TryReadFloat32() | ||
| 80 | prop.HighValue = reader.TryReadFloat32() | ||
| 81 | prop.NumBits = int32(reader.TryReadBits(7)) | ||
| 82 | case int8(ESendPropTypeArray): | ||
| 83 | prop.NumElements = int32(reader.TryReadBits(10)) | ||
| 84 | default: | ||
| 85 | return sendTable | ||
| 86 | } | ||
| 87 | } | ||
| 88 | sendTable.Props = append(sendTable.Props, prop) | ||
| 89 | } | ||
| 90 | return sendTable | ||
| 91 | } | ||
| 92 | |||
| 93 | func ParseServerClassInfo(reader *bitreader.Reader, count int, numOfClasses int) ServerClassInfo { | ||
| 94 | serverClassInfo := ServerClassInfo{ | ||
| 95 | ClassId: reader.TryReadUInt16(), | ||
| 96 | ClassName: reader.TryReadString(), | ||
| 97 | DataTableName: reader.TryReadString(), | ||
| 98 | } | ||
| 99 | return serverClassInfo | ||
| 100 | } | ||
| 101 | |||
| 102 | // func serverClassBits(numOfClasses int) int { | ||
| 103 | // return highestBitIndex(uint(numOfClasses)) + 1 | ||
| 104 | // } | ||
| 105 | |||
| 106 | // func highestBitIndex(i uint) int { | ||
| 107 | // var j int | ||
| 108 | // for j = 31; j >= 0 && (i&(1<<j)) == 0; j-- { | ||
| 109 | // } | ||
| 110 | // return j | ||
| 111 | // } | ||
| 112 | |||
| 113 | func checkBit(val uint32, bit int) bool { | ||
| 114 | return (val & (uint32(1) << bit)) != 0 | ||
| 115 | } | ||
| 116 | |||
| 117 | type sendPropType int | ||
| 118 | |||
| 119 | const ( | ||
| 120 | ESendPropTypeInt sendPropType = iota | ||
| 121 | ESendPropTypeFloat | ||
| 122 | ESendPropTypeVector3 | ||
| 123 | ESendPropTypeVector2 | ||
| 124 | ESendPropTypeString | ||
| 125 | ESendPropTypeArray | ||
| 126 | ESendPropTypeDataTable | ||
| 127 | ) | ||
| 128 | |||
| 129 | const ( | ||
| 130 | ESendPropFlagUnsigned string = "Unsigned" | ||
| 131 | ESendPropFlagCoord string = "Coord" | ||
| 132 | ESendPropFlagNoScale string = "NoScale" | ||
| 133 | ESendPropFlagRoundDown string = "RoundDown" | ||
| 134 | ESendPropFlagRoundUp string = "RoundUp" | ||
| 135 | ESendPropFlagNormal string = "Normal" | ||
| 136 | ESendPropFlagExclude string = "Exclude" | ||
| 137 | ESendPropFlagXyze string = "Xyze" | ||
| 138 | ESendPropFlagInsideArray string = "InsideArray" | ||
| 139 | ESendPropFlagProxyAlwaysYes string = "ProxyAlwaysYes" | ||
| 140 | ESendPropFlagIsVectorElem string = "IsVectorElem" | ||
| 141 | ESendPropFlagCollapsible string = "Collapsible" | ||
| 142 | ESendPropFlagCoordMp string = "CoordMp" | ||
| 143 | ESendPropFlagCoordMpLp string = "CoordMpLp" | ||
| 144 | ESendPropFlagCoordMpInt string = "CoordMpInt" | ||
| 145 | ESendPropFlagCellCoord string = "CellCoord" | ||
| 146 | ESendPropFlagCellCoordLp string = "CellCoordLp" | ||
| 147 | ESendPropFlagCellCoordInt string = "CellCoordInt" | ||
| 148 | ESendPropFlagChangesOften string = "ChangesOften" | ||
| 149 | ) | ||
| 150 | |||
| 151 | func (prop prop) GetFlags() []string { | ||
| 152 | flags := []string{} | ||
| 153 | if checkBit(prop.SendPropFlags, 0) { | ||
| 154 | flags = append(flags, ESendPropFlagUnsigned) | ||
| 155 | } | ||
| 156 | if checkBit(prop.SendPropFlags, 1) { | ||
| 157 | flags = append(flags, ESendPropFlagCoord) | ||
| 158 | } | ||
| 159 | if checkBit(prop.SendPropFlags, 2) { | ||
| 160 | flags = append(flags, ESendPropFlagNoScale) | ||
| 161 | } | ||
| 162 | if checkBit(prop.SendPropFlags, 3) { | ||
| 163 | flags = append(flags, ESendPropFlagRoundDown) | ||
| 164 | } | ||
| 165 | if checkBit(prop.SendPropFlags, 4) { | ||
| 166 | flags = append(flags, ESendPropFlagRoundUp) | ||
| 167 | } | ||
| 168 | if checkBit(prop.SendPropFlags, 5) { | ||
| 169 | flags = append(flags, ESendPropFlagNormal) | ||
| 170 | } | ||
| 171 | if checkBit(prop.SendPropFlags, 6) { | ||
| 172 | flags = append(flags, ESendPropFlagExclude) | ||
| 173 | } | ||
| 174 | if checkBit(prop.SendPropFlags, 7) { | ||
| 175 | flags = append(flags, ESendPropFlagXyze) | ||
| 176 | } | ||
| 177 | if checkBit(prop.SendPropFlags, 8) { | ||
| 178 | flags = append(flags, ESendPropFlagInsideArray) | ||
| 179 | } | ||
| 180 | if checkBit(prop.SendPropFlags, 9) { | ||
| 181 | flags = append(flags, ESendPropFlagProxyAlwaysYes) | ||
| 182 | } | ||
| 183 | if checkBit(prop.SendPropFlags, 10) { | ||
| 184 | flags = append(flags, ESendPropFlagIsVectorElem) | ||
| 185 | } | ||
| 186 | if checkBit(prop.SendPropFlags, 11) { | ||
| 187 | flags = append(flags, ESendPropFlagCollapsible) | ||
| 188 | } | ||
| 189 | if checkBit(prop.SendPropFlags, 12) { | ||
| 190 | flags = append(flags, ESendPropFlagCoordMp) | ||
| 191 | } | ||
| 192 | if checkBit(prop.SendPropFlags, 13) { | ||
| 193 | flags = append(flags, ESendPropFlagCoordMpLp) | ||
| 194 | } | ||
| 195 | if checkBit(prop.SendPropFlags, 14) { | ||
| 196 | flags = append(flags, ESendPropFlagCoordMpInt) | ||
| 197 | } | ||
| 198 | if checkBit(prop.SendPropFlags, 15) { | ||
| 199 | flags = append(flags, ESendPropFlagCellCoord) | ||
| 200 | } | ||
| 201 | if checkBit(prop.SendPropFlags, 16) { | ||
| 202 | flags = append(flags, ESendPropFlagCellCoordLp) | ||
| 203 | } | ||
| 204 | if checkBit(prop.SendPropFlags, 17) { | ||
| 205 | flags = append(flags, ESendPropFlagCellCoordInt) | ||
| 206 | } | ||
| 207 | if checkBit(prop.SendPropFlags, 18) { | ||
| 208 | flags = append(flags, ESendPropFlagChangesOften) | ||
| 209 | } | ||
| 210 | return flags | ||
| 211 | } | ||
| 212 | |||
| 213 | func (sendPropType sendPropType) String() string { | ||
| 214 | switch sendPropType { | ||
| 215 | case ESendPropTypeInt: | ||
| 216 | return "Int" | ||
| 217 | case ESendPropTypeFloat: | ||
| 218 | return "Float" | ||
| 219 | case ESendPropTypeVector3: | ||
| 220 | return "Vector3" | ||
| 221 | case ESendPropTypeVector2: | ||
| 222 | return "Vector2" | ||
| 223 | case ESendPropTypeString: | ||
| 224 | return "String" | ||
| 225 | case ESendPropTypeArray: | ||
| 226 | return "Array" | ||
| 227 | case ESendPropTypeDataTable: | ||
| 228 | return "DataTable" | ||
| 229 | default: | ||
| 230 | return fmt.Sprintf("%d", int(sendPropType)) | ||
| 231 | } | ||
| 232 | } | ||
diff --git a/pkg/classes/packet.go b/pkg/classes/packet.go deleted file mode 100644 index c608244..0000000 --- a/pkg/classes/packet.go +++ /dev/null | |||
| @@ -1,81 +0,0 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | "github.com/pektezol/demoparser/pkg/messages" | ||
| 8 | ) | ||
| 9 | |||
| 10 | const MSSC int = 2 | ||
| 11 | |||
| 12 | type Packet struct { | ||
| 13 | PacketInfo []CmdInfo | ||
| 14 | InSequence uint32 | ||
| 15 | OutSequence uint32 | ||
| 16 | Size uint32 | ||
| 17 | Data []any | ||
| 18 | } | ||
| 19 | |||
| 20 | type CmdInfo struct { | ||
| 21 | Flags uint32 | ||
| 22 | ViewOrigin []float32 | ||
| 23 | ViewAngles []float32 | ||
| 24 | LocalViewAngles []float32 | ||
| 25 | ViewOrigin2 []float32 | ||
| 26 | ViewAngles2 []float32 | ||
| 27 | LocalViewAngles2 []float32 | ||
| 28 | } | ||
| 29 | |||
| 30 | func (packet *Packet) ParsePacket(reader *bitreader.Reader) { | ||
| 31 | for count := 0; count < MSSC; count++ { | ||
| 32 | packet.ParseCmdInfo(reader) | ||
| 33 | } | ||
| 34 | packet.InSequence = reader.TryReadUInt32() | ||
| 35 | packet.OutSequence = reader.TryReadUInt32() | ||
| 36 | packet.Size = reader.TryReadUInt32() | ||
| 37 | packetReader := bitreader.NewReaderFromBytes(reader.TryReadBytesToSlice(uint64(packet.Size)), true) | ||
| 38 | for { | ||
| 39 | messageType, err := packetReader.ReadBits(6) | ||
| 40 | if err != nil { | ||
| 41 | break | ||
| 42 | } | ||
| 43 | packet.Data = append(packet.Data, messages.ParseMessages(messageType, packetReader)) | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | func (packet *Packet) ParseCmdInfo(reader *bitreader.Reader) { | ||
| 48 | packet.PacketInfo = append(packet.PacketInfo, CmdInfo{ | ||
| 49 | Flags: reader.TryReadUInt32(), | ||
| 50 | ViewOrigin: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 51 | ViewAngles: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 52 | LocalViewAngles: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 53 | ViewOrigin2: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 54 | ViewAngles2: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 55 | LocalViewAngles2: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 56 | }) | ||
| 57 | } | ||
| 58 | |||
| 59 | type CmdInfoFlags int | ||
| 60 | |||
| 61 | const ( | ||
| 62 | ECmdInfoFlagsNone = 0 | ||
| 63 | ECmdInfoFlagsUseOrigin2 = 1 | ||
| 64 | ECmdInfoFlagsUserAngles2 = 1 << 1 | ||
| 65 | ECmdInfoFlagsNoInterp = 1 << 2 | ||
| 66 | ) | ||
| 67 | |||
| 68 | func (cmdInfoFlags CmdInfoFlags) String() string { | ||
| 69 | switch cmdInfoFlags { | ||
| 70 | case ECmdInfoFlagsNone: | ||
| 71 | return "None" | ||
| 72 | case ECmdInfoFlagsUseOrigin2: | ||
| 73 | return "UseOrigin2" | ||
| 74 | case ECmdInfoFlagsUserAngles2: | ||
| 75 | return "UserAngles2" | ||
| 76 | case ECmdInfoFlagsNoInterp: | ||
| 77 | return "NoInterp" | ||
| 78 | default: | ||
| 79 | return fmt.Sprintf("%d", int(cmdInfoFlags)) | ||
| 80 | } | ||
| 81 | } | ||
diff --git a/pkg/classes/sarData.go b/pkg/classes/sarData.go deleted file mode 100644 index 9c61304..0000000 --- a/pkg/classes/sarData.go +++ /dev/null | |||
| @@ -1,403 +0,0 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "errors" | ||
| 5 | "fmt" | ||
| 6 | |||
| 7 | "github.com/pektezol/bitreader" | ||
| 8 | ) | ||
| 9 | |||
| 10 | type SarDataType uint8 | ||
| 11 | |||
| 12 | const ( | ||
| 13 | ESarDataTimescaleCheat SarDataType = 0x01 | ||
| 14 | ESarDataInitialCVar SarDataType = 0x02 | ||
| 15 | ESarDataEntityInput SarDataType = 0x03 | ||
| 16 | ESarDataEntityInputSlot SarDataType = 0x04 | ||
| 17 | ESarDataPortalPlacement SarDataType = 0x05 | ||
| 18 | ESarDataChallengeFlags SarDataType = 0x06 | ||
| 19 | ESarDataCrouchFly SarDataType = 0x07 | ||
| 20 | ESarDataPause SarDataType = 0x08 | ||
| 21 | ESarDataWaitRun SarDataType = 0x09 | ||
| 22 | ESarDataSpeedrunTime SarDataType = 0x0A | ||
| 23 | ESarDataTimestamp SarDataType = 0x0B | ||
| 24 | ESarDataFileChecksum SarDataType = 0x0C | ||
| 25 | ESarDataHWaitRun SarDataType = 0x0D | ||
| 26 | ESarDataChecksum SarDataType = 0xFF | ||
| 27 | ESarDataChecksumV2 SarDataType = 0xFE | ||
| 28 | ESarDataInvalid SarDataType = iota | ||
| 29 | ) | ||
| 30 | |||
| 31 | func (sarDataType SarDataType) String() string { | ||
| 32 | switch sarDataType { | ||
| 33 | case ESarDataTimescaleCheat: | ||
| 34 | return "SarDataTimescaleCheat" | ||
| 35 | case ESarDataInitialCVar: | ||
| 36 | return "SarDataInitialCVar" | ||
| 37 | case ESarDataEntityInput: | ||
| 38 | return "SarDataEntityInput" | ||
| 39 | case ESarDataEntityInputSlot: | ||
| 40 | return "SarDataEntityInputSlot" | ||
| 41 | case ESarDataPortalPlacement: | ||
| 42 | return "SarDataPortalPlacement" | ||
| 43 | case ESarDataChallengeFlags: | ||
| 44 | return "SarDataChallengeFlags" | ||
| 45 | case ESarDataCrouchFly: | ||
| 46 | return "SarDataCrouchFly" | ||
| 47 | case ESarDataPause: | ||
| 48 | return "SarDataPause" | ||
| 49 | case ESarDataWaitRun: | ||
| 50 | return "SarDataWaitRun" | ||
| 51 | case ESarDataSpeedrunTime: | ||
| 52 | return "SarDataSpeedrunTime" | ||
| 53 | case ESarDataTimestamp: | ||
| 54 | return "SarDataTimestamp" | ||
| 55 | case ESarDataFileChecksum: | ||
| 56 | return "SarDataFileChecksum" | ||
| 57 | case ESarDataHWaitRun: | ||
| 58 | return "SarDataHWaitRun" | ||
| 59 | case ESarDataChecksum: | ||
| 60 | return "SarDataChecksum" | ||
| 61 | case ESarDataChecksumV2: | ||
| 62 | return "SarDataChecksumV2" | ||
| 63 | case ESarDataInvalid: | ||
| 64 | return "SarDataInvalid" | ||
| 65 | default: | ||
| 66 | return fmt.Sprintf("%d", int(sarDataType)) | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | type SarData struct { | ||
| 71 | Type SarDataType | ||
| 72 | Slot int | ||
| 73 | Data any | ||
| 74 | } | ||
| 75 | |||
| 76 | type SarDataTimescaleCheat struct { | ||
| 77 | Timescale float32 | ||
| 78 | } | ||
| 79 | |||
| 80 | type SarDataInitialCVar struct { | ||
| 81 | CVar string | ||
| 82 | Val string | ||
| 83 | } | ||
| 84 | |||
| 85 | type SarDataChecksum struct { | ||
| 86 | DemoSum uint32 | ||
| 87 | SarSum uint32 | ||
| 88 | } | ||
| 89 | |||
| 90 | type SarDataChecksumV2 struct { | ||
| 91 | SarSum uint32 | ||
| 92 | Signature [64]byte | ||
| 93 | } | ||
| 94 | |||
| 95 | type SarDataEntityInput struct { | ||
| 96 | TargetName string | ||
| 97 | ClassName string | ||
| 98 | InputName string | ||
| 99 | Parameter string | ||
| 100 | } | ||
| 101 | |||
| 102 | type SarDataPortalPlacement struct { | ||
| 103 | Orange bool | ||
| 104 | X float32 | ||
| 105 | Y float32 | ||
| 106 | Z float32 | ||
| 107 | } | ||
| 108 | |||
| 109 | type SarDataPause struct { | ||
| 110 | PauseTicks uint32 | ||
| 111 | } | ||
| 112 | |||
| 113 | type SarDataWaitRun struct { | ||
| 114 | Ticks int | ||
| 115 | Cmd string | ||
| 116 | } | ||
| 117 | |||
| 118 | type SarDataHWaitRun struct { | ||
| 119 | Ticks int | ||
| 120 | Cmd string | ||
| 121 | } | ||
| 122 | |||
| 123 | type SarDataSpeedrunTime struct { | ||
| 124 | NSplits uint32 | ||
| 125 | Splits []SarDataSpeedrunTimeSplits | ||
| 126 | } | ||
| 127 | |||
| 128 | type SarDataSpeedrunTimeSegs struct { | ||
| 129 | Name string | ||
| 130 | Ticks uint32 | ||
| 131 | } | ||
| 132 | |||
| 133 | type SarDataSpeedrunTimeSplits struct { | ||
| 134 | Name string | ||
| 135 | NSegs uint32 | ||
| 136 | Segs []SarDataSpeedrunTimeSegs | ||
| 137 | } | ||
| 138 | |||
| 139 | type SarDataTimestamp struct { | ||
| 140 | Year uint16 | ||
| 141 | Month uint8 | ||
| 142 | Day uint8 | ||
| 143 | Hour uint8 | ||
| 144 | Minute uint8 | ||
| 145 | Second uint8 | ||
| 146 | } | ||
| 147 | |||
| 148 | type SarDataFileChecksum struct { | ||
| 149 | Sum uint32 | ||
| 150 | Path string | ||
| 151 | } | ||
| 152 | |||
| 153 | func (sarData *SarData) ParseSarData(reader *bitreader.Reader) (err error) { | ||
| 154 | reader.SkipBytes(8) | ||
| 155 | len := reader.TryReadRemainingBits() / 8 | ||
| 156 | if len == 0 { | ||
| 157 | sarData.Type = ESarDataInvalid | ||
| 158 | err = errors.New("sar data invalid") | ||
| 159 | return err | ||
| 160 | } | ||
| 161 | sarData.Type = SarDataType(reader.TryReadBytes(1)) | ||
| 162 | if sarData.Type == ESarDataChecksum && len == 5 { | ||
| 163 | len = 9 | ||
| 164 | } | ||
| 165 | dataReader := bitreader.NewReaderFromBytes(reader.TryReadBytesToSlice(len-1), true) | ||
| 166 | switch sarData.Type { | ||
| 167 | case ESarDataTimescaleCheat: | ||
| 168 | sarData.Data, err = parseTimescaleCheatData(dataReader, len) | ||
| 169 | if err != nil { | ||
| 170 | sarData.Data = nil | ||
| 171 | } | ||
| 172 | case ESarDataInitialCVar: | ||
| 173 | sarData.Data = parseInitialCVarData(dataReader) | ||
| 174 | case ESarDataEntityInputSlot: | ||
| 175 | sarData.Slot = int(dataReader.TryReadBytes(1)) | ||
| 176 | case ESarDataEntityInput: | ||
| 177 | sarData.Data = parseEntityInputData(dataReader) | ||
| 178 | case ESarDataChecksum: | ||
| 179 | sarData.Data, err = parseChecksumData(dataReader, len) | ||
| 180 | if err != nil { | ||
| 181 | sarData.Data = nil | ||
| 182 | } | ||
| 183 | case ESarDataChecksumV2: | ||
| 184 | sarData.Data, err = parseChecksumV2Data(dataReader, len) | ||
| 185 | if err != nil { | ||
| 186 | sarData.Data = nil | ||
| 187 | } | ||
| 188 | case ESarDataPortalPlacement: | ||
| 189 | data, slot, err := parsePortalPlacementData(dataReader, len) | ||
| 190 | if err != nil { | ||
| 191 | sarData.Data = nil | ||
| 192 | } else { | ||
| 193 | sarData.Data = data | ||
| 194 | sarData.Slot = slot | ||
| 195 | } | ||
| 196 | case ESarDataChallengeFlags, ESarDataCrouchFly: | ||
| 197 | sarData.Slot, err = parseChallengeFlagsCrouchFlyData(dataReader, len) | ||
| 198 | if err != nil { | ||
| 199 | sarData.Data = nil | ||
| 200 | } | ||
| 201 | |||
| 202 | case ESarDataPause: | ||
| 203 | sarData.Data, err = parsePauseData(dataReader, len) | ||
| 204 | if err != nil { | ||
| 205 | sarData.Data = nil | ||
| 206 | } | ||
| 207 | case ESarDataWaitRun: | ||
| 208 | sarData.Data, err = parseWaitRunData(dataReader, len) | ||
| 209 | if err != nil { | ||
| 210 | sarData.Data = nil | ||
| 211 | } | ||
| 212 | case ESarDataHWaitRun: | ||
| 213 | sarData.Data, err = parseHWaitRunData(dataReader, len) | ||
| 214 | if err != nil { | ||
| 215 | sarData.Data = nil | ||
| 216 | } | ||
| 217 | case ESarDataSpeedrunTime: | ||
| 218 | sarData.Data, err = parseSpeedrunTimeData(dataReader, len) | ||
| 219 | if err != nil { | ||
| 220 | sarData.Data = nil | ||
| 221 | } | ||
| 222 | case ESarDataTimestamp: | ||
| 223 | sarData.Data, err = parseTimestampData(dataReader, len) | ||
| 224 | if err != nil { | ||
| 225 | sarData.Data = nil | ||
| 226 | } | ||
| 227 | case ESarDataFileChecksum: | ||
| 228 | sarData.Data, err = parseFileChecksumData(dataReader, len) | ||
| 229 | if err != nil { | ||
| 230 | sarData.Data = nil | ||
| 231 | } | ||
| 232 | default: | ||
| 233 | err = errors.New("unsupported SAR data type") | ||
| 234 | return err | ||
| 235 | } | ||
| 236 | return nil | ||
| 237 | } | ||
| 238 | |||
| 239 | func parseTimescaleCheatData(reader *bitreader.Reader, length uint64) (SarDataTimescaleCheat, error) { | ||
| 240 | if length != 5 { | ||
| 241 | return SarDataTimescaleCheat{}, errors.New("sar data invalid") | ||
| 242 | } | ||
| 243 | sarDataTimescaleCheat := SarDataTimescaleCheat{ | ||
| 244 | Timescale: reader.TryReadFloat32(), | ||
| 245 | } | ||
| 246 | |||
| 247 | return sarDataTimescaleCheat, nil | ||
| 248 | } | ||
| 249 | |||
| 250 | func parseInitialCVarData(reader *bitreader.Reader) SarDataInitialCVar { | ||
| 251 | sarDataInitialCvar := SarDataInitialCVar{ | ||
| 252 | CVar: reader.TryReadString(), | ||
| 253 | Val: reader.TryReadString(), | ||
| 254 | } | ||
| 255 | |||
| 256 | return sarDataInitialCvar | ||
| 257 | } | ||
| 258 | |||
| 259 | func parseEntityInputData(reader *bitreader.Reader) SarDataEntityInput { | ||
| 260 | sarDataEntityInput := SarDataEntityInput{ | ||
| 261 | TargetName: reader.TryReadString(), | ||
| 262 | ClassName: reader.TryReadString(), | ||
| 263 | InputName: reader.TryReadString(), | ||
| 264 | Parameter: reader.TryReadString(), | ||
| 265 | } | ||
| 266 | |||
| 267 | return sarDataEntityInput | ||
| 268 | } | ||
| 269 | |||
| 270 | func parseChecksumData(reader *bitreader.Reader, length uint64) (SarDataChecksum, error) { | ||
| 271 | if length != 9 { | ||
| 272 | return SarDataChecksum{}, errors.New("sar data invalid") | ||
| 273 | } | ||
| 274 | sarDataChecksum := SarDataChecksum{ | ||
| 275 | DemoSum: reader.TryReadUInt32(), | ||
| 276 | SarSum: reader.TryReadUInt32(), | ||
| 277 | } | ||
| 278 | |||
| 279 | return sarDataChecksum, nil | ||
| 280 | } | ||
| 281 | |||
| 282 | func parseChecksumV2Data(reader *bitreader.Reader, length uint64) (SarDataChecksumV2, error) { | ||
| 283 | if length != 69 { | ||
| 284 | return SarDataChecksumV2{}, errors.New("sar data invalid") | ||
| 285 | } | ||
| 286 | sarDataChecksumV2 := SarDataChecksumV2{ | ||
| 287 | SarSum: reader.TryReadUInt32(), | ||
| 288 | Signature: [64]byte(reader.TryReadBytesToSlice(60)), | ||
| 289 | } | ||
| 290 | |||
| 291 | return sarDataChecksumV2, nil | ||
| 292 | } | ||
| 293 | |||
| 294 | func parsePortalPlacementData(reader *bitreader.Reader, length uint64) (SarDataPortalPlacement, int, error) { | ||
| 295 | if length != 15 { | ||
| 296 | return SarDataPortalPlacement{}, 0, errors.New("sar data invalid") | ||
| 297 | } | ||
| 298 | slot := int(reader.TryReadBytes(1)) | ||
| 299 | orange := reader.TryReadBool() | ||
| 300 | reader.SkipBits(7) | ||
| 301 | sarDataPortalPlacement := SarDataPortalPlacement{ | ||
| 302 | Orange: orange, | ||
| 303 | X: reader.TryReadFloat32(), | ||
| 304 | Y: reader.TryReadFloat32(), | ||
| 305 | Z: reader.TryReadFloat32(), | ||
| 306 | } | ||
| 307 | |||
| 308 | return sarDataPortalPlacement, slot, nil | ||
| 309 | } | ||
| 310 | |||
| 311 | func parseChallengeFlagsCrouchFlyData(reader *bitreader.Reader, length uint64) (int, error) { | ||
| 312 | if length != 2 { | ||
| 313 | return 0, errors.New("sar data invalid") | ||
| 314 | } | ||
| 315 | return int(reader.TryReadBytes(1)), nil | ||
| 316 | } | ||
| 317 | |||
| 318 | func parsePauseData(reader *bitreader.Reader, length uint64) (SarDataPause, error) { | ||
| 319 | if length != 5 { | ||
| 320 | return SarDataPause{}, errors.New("sar data invalid") | ||
| 321 | } | ||
| 322 | sarDataPause := SarDataPause{ | ||
| 323 | PauseTicks: reader.TryReadUInt32(), | ||
| 324 | } | ||
| 325 | |||
| 326 | return sarDataPause, nil | ||
| 327 | } | ||
| 328 | |||
| 329 | func parseWaitRunData(reader *bitreader.Reader, length uint64) (SarDataWaitRun, error) { | ||
| 330 | if length < 6 { | ||
| 331 | return SarDataWaitRun{}, errors.New("sar data invalid") | ||
| 332 | } | ||
| 333 | sarDataWaitRun := SarDataWaitRun{ | ||
| 334 | Ticks: int(reader.TryReadUInt32()), | ||
| 335 | Cmd: reader.TryReadString(), | ||
| 336 | } | ||
| 337 | |||
| 338 | return sarDataWaitRun, nil | ||
| 339 | } | ||
| 340 | |||
| 341 | func parseHWaitRunData(reader *bitreader.Reader, length uint64) (SarDataHWaitRun, error) { | ||
| 342 | if length < 6 { | ||
| 343 | return SarDataHWaitRun{}, errors.New("sar data invalid") | ||
| 344 | } | ||
| 345 | sarDataHWaitRun := SarDataHWaitRun{ | ||
| 346 | Ticks: int(reader.TryReadUInt32()), | ||
| 347 | Cmd: reader.TryReadString(), | ||
| 348 | } | ||
| 349 | |||
| 350 | return sarDataHWaitRun, nil | ||
| 351 | } | ||
| 352 | |||
| 353 | func parseSpeedrunTimeData(reader *bitreader.Reader, length uint64) (SarDataSpeedrunTime, error) { | ||
| 354 | if length < 5 { | ||
| 355 | return SarDataSpeedrunTime{}, errors.New("sar data invalid") | ||
| 356 | } | ||
| 357 | numberOfSplits := reader.TryReadUInt32() | ||
| 358 | splits := make([]SarDataSpeedrunTimeSplits, numberOfSplits) | ||
| 359 | for splitCount := 0; splitCount < int(numberOfSplits); splitCount++ { | ||
| 360 | splits[splitCount].Name = reader.TryReadString() | ||
| 361 | splits[splitCount].NSegs = reader.TryReadUInt32() | ||
| 362 | |||
| 363 | splits[splitCount].Segs = make([]SarDataSpeedrunTimeSegs, splits[splitCount].NSegs) | ||
| 364 | for segCount := 0; segCount < int(splits[splitCount].NSegs); segCount++ { | ||
| 365 | splits[splitCount].Segs[segCount].Name = reader.TryReadString() | ||
| 366 | splits[splitCount].Segs[segCount].Ticks = reader.TryReadUInt32() | ||
| 367 | |||
| 368 | } | ||
| 369 | } | ||
| 370 | return SarDataSpeedrunTime{ | ||
| 371 | NSplits: numberOfSplits, | ||
| 372 | Splits: splits, | ||
| 373 | }, nil | ||
| 374 | } | ||
| 375 | |||
| 376 | func parseTimestampData(reader *bitreader.Reader, length uint64) (SarDataTimestamp, error) { | ||
| 377 | if length != 8 { | ||
| 378 | return SarDataTimestamp{}, errors.New("sar data invalid") | ||
| 379 | } | ||
| 380 | timestamp := reader.TryReadBytesToSlice(7) | ||
| 381 | sarDataTimeStamp := SarDataTimestamp{ | ||
| 382 | Year: uint16(timestamp[0]) | uint16(timestamp[1])<<8, | ||
| 383 | Month: timestamp[2] + 1, | ||
| 384 | Day: timestamp[3], | ||
| 385 | Hour: timestamp[4], | ||
| 386 | Minute: timestamp[5], | ||
| 387 | Second: timestamp[6], | ||
| 388 | } | ||
| 389 | |||
| 390 | return sarDataTimeStamp, nil | ||
| 391 | } | ||
| 392 | |||
| 393 | func parseFileChecksumData(reader *bitreader.Reader, length uint64) (SarDataFileChecksum, error) { | ||
| 394 | if length < 6 { | ||
| 395 | return SarDataFileChecksum{}, errors.New("sar data invalid") | ||
| 396 | } | ||
| 397 | sarDataFileChecksum := SarDataFileChecksum{ | ||
| 398 | Sum: reader.TryReadUInt32(), | ||
| 399 | Path: reader.TryReadString(), | ||
| 400 | } | ||
| 401 | |||
| 402 | return sarDataFileChecksum, nil | ||
| 403 | } | ||
diff --git a/pkg/classes/signOn.go b/pkg/classes/signOn.go deleted file mode 100644 index 5f004c0..0000000 --- a/pkg/classes/signOn.go +++ /dev/null | |||
| @@ -1,43 +0,0 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | "github.com/pektezol/demoparser/pkg/messages" | ||
| 6 | ) | ||
| 7 | |||
| 8 | type SignOn struct { | ||
| 9 | PacketInfo []CmdInfo | ||
| 10 | InSequence uint32 | ||
| 11 | OutSequence uint32 | ||
| 12 | Size uint32 | ||
| 13 | Data []any | ||
| 14 | } | ||
| 15 | |||
| 16 | func (signOn *SignOn) ParseSignOn(reader *bitreader.Reader) { | ||
| 17 | for count := 0; count < MSSC; count++ { | ||
| 18 | signOn.ParseCmdInfo(reader) | ||
| 19 | } | ||
| 20 | signOn.InSequence = reader.TryReadUInt32() | ||
| 21 | signOn.OutSequence = reader.TryReadUInt32() | ||
| 22 | signOn.Size = reader.TryReadUInt32() | ||
| 23 | packetReader := bitreader.NewReaderFromBytes(reader.TryReadBytesToSlice(uint64(signOn.Size)), true) | ||
| 24 | for { | ||
| 25 | messageType, err := packetReader.ReadBits(6) | ||
| 26 | if err != nil { | ||
| 27 | break | ||
| 28 | } | ||
| 29 | signOn.Data = append(signOn.Data, messages.ParseMessages(messageType, packetReader)) | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 33 | func (signOn *SignOn) ParseCmdInfo(reader *bitreader.Reader) { | ||
| 34 | signOn.PacketInfo = append(signOn.PacketInfo, CmdInfo{ | ||
| 35 | Flags: reader.TryReadUInt32(), | ||
| 36 | ViewOrigin: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 37 | ViewAngles: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 38 | LocalViewAngles: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 39 | ViewOrigin2: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 40 | ViewAngles2: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 41 | LocalViewAngles2: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, | ||
| 42 | }) | ||
| 43 | } | ||
diff --git a/pkg/classes/stop.go b/pkg/classes/stop.go deleted file mode 100644 index 96bc1e4..0000000 --- a/pkg/classes/stop.go +++ /dev/null | |||
| @@ -1,15 +0,0 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type Stop struct { | ||
| 8 | RemainingData []byte | ||
| 9 | } | ||
| 10 | |||
| 11 | func (stop *Stop) ParseStop(reader *bitreader.Reader) { | ||
| 12 | if reader.TryReadBool() { | ||
| 13 | stop.RemainingData = reader.TryReadBitsToSlice(uint64(reader.TryReadRemainingBits())) | ||
| 14 | } | ||
| 15 | } | ||
diff --git a/pkg/classes/stringTables.go b/pkg/classes/stringTables.go deleted file mode 100644 index 45954be..0000000 --- a/pkg/classes/stringTables.go +++ /dev/null | |||
| @@ -1,86 +0,0 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type StringTables struct { | ||
| 8 | Size int32 | ||
| 9 | Data []StringTable | ||
| 10 | } | ||
| 11 | |||
| 12 | type StringTable struct { | ||
| 13 | Name string | ||
| 14 | TableEntries []StringTableEntry | ||
| 15 | Classes []StringTableClass | ||
| 16 | } | ||
| 17 | |||
| 18 | type StringTableEntry struct { | ||
| 19 | Name string | ||
| 20 | EntryData StringTableEntryData | ||
| 21 | } | ||
| 22 | |||
| 23 | type StringTableEntryData struct { | ||
| 24 | // TODO: Parse StringTableEntry | ||
| 25 | } | ||
| 26 | |||
| 27 | type StringTableClass struct { | ||
| 28 | Name string | ||
| 29 | Data string | ||
| 30 | } | ||
| 31 | |||
| 32 | func (stringTables *StringTables) ParseStringTables(reader *bitreader.Reader) { | ||
| 33 | stringTables.Size = reader.TryReadSInt32() | ||
| 34 | stringTableReader := bitreader.NewReaderFromBytes(reader.TryReadBytesToSlice(uint64(stringTables.Size)), true) | ||
| 35 | tableCount := stringTableReader.TryReadBits(8) | ||
| 36 | tables := make([]StringTable, tableCount) | ||
| 37 | for i := 0; i < int(tableCount); i++ { | ||
| 38 | var table StringTable | ||
| 39 | table.ParseStream(stringTableReader) | ||
| 40 | tables[i] = table | ||
| 41 | } | ||
| 42 | stringTables.Data = tables | ||
| 43 | } | ||
| 44 | |||
| 45 | func (stringTable *StringTable) ParseStream(reader *bitreader.Reader) { | ||
| 46 | stringTable.Name = reader.TryReadString() | ||
| 47 | entryCount := reader.TryReadBits(16) | ||
| 48 | stringTable.TableEntries = make([]StringTableEntry, entryCount) | ||
| 49 | |||
| 50 | for i := 0; i < int(entryCount); i++ { | ||
| 51 | var entry StringTableEntry | ||
| 52 | entry.Parse(reader) | ||
| 53 | stringTable.TableEntries[i] = entry | ||
| 54 | } | ||
| 55 | if reader.TryReadBool() { | ||
| 56 | classCount := reader.TryReadBits(16) | ||
| 57 | stringTable.Classes = make([]StringTableClass, classCount) | ||
| 58 | |||
| 59 | for i := 0; i < int(classCount); i++ { | ||
| 60 | var class StringTableClass | ||
| 61 | class.Parse(reader) | ||
| 62 | stringTable.Classes[i] = class | ||
| 63 | } | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | func (stringTableEntry *StringTableEntry) Parse(reader *bitreader.Reader) { | ||
| 68 | stringTableEntry.Name = reader.TryReadString() | ||
| 69 | if reader.TryReadBool() { | ||
| 70 | byteLen, err := reader.ReadBits(16) | ||
| 71 | if err != nil { | ||
| 72 | return | ||
| 73 | } | ||
| 74 | dataBsr := reader.TryReadBytesToSlice(byteLen) | ||
| 75 | _ = bitreader.NewReaderFromBytes(dataBsr, true) // TODO: Parse StringTableEntry | ||
| 76 | // stringTableEntry.EntryData.ParseStream(entryReader) | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | func (stringTableClass *StringTableClass) Parse(reader *bitreader.Reader) { | ||
| 81 | stringTableClass.Name = reader.TryReadString() | ||
| 82 | if reader.TryReadBool() { | ||
| 83 | dataLen := reader.TryReadBits(16) | ||
| 84 | stringTableClass.Data = reader.TryReadStringLength(dataLen) | ||
| 85 | } | ||
| 86 | } | ||
diff --git a/pkg/classes/syncTick.go b/pkg/classes/syncTick.go deleted file mode 100644 index 2f9df3e..0000000 --- a/pkg/classes/syncTick.go +++ /dev/null | |||
| @@ -1,5 +0,0 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | type SyncTick struct{} | ||
| 4 | |||
| 5 | func (syncTick *SyncTick) ParseSyncTick() {} | ||
diff --git a/pkg/classes/userCmd.go b/pkg/classes/userCmd.go deleted file mode 100644 index a4bf3d4..0000000 --- a/pkg/classes/userCmd.go +++ /dev/null | |||
| @@ -1,222 +0,0 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type UserCmd struct { | ||
| 8 | Cmd uint32 | ||
| 9 | Size uint32 | ||
| 10 | Data UserCmdInfo | ||
| 11 | } | ||
| 12 | |||
| 13 | type UserCmdInfo struct { | ||
| 14 | CommandNumber uint32 | ||
| 15 | TickCount uint32 | ||
| 16 | ViewAnglesX float32 | ||
| 17 | ViewAnglesY float32 | ||
| 18 | ViewAnglesZ float32 | ||
| 19 | ForwardMove float32 | ||
| 20 | SideMove float32 | ||
| 21 | UpMove float32 | ||
| 22 | Buttons uint32 | ||
| 23 | Impulse uint8 | ||
| 24 | WeaponSelect uint16 | ||
| 25 | WeaponSubType uint8 | ||
| 26 | MouseDx uint16 | ||
| 27 | MouseDy uint16 | ||
| 28 | } | ||
| 29 | |||
| 30 | func (userCmd *UserCmd) ParseUserCmd(reader *bitreader.Reader) { | ||
| 31 | userCmd.Cmd = reader.TryReadUInt32() | ||
| 32 | userCmd.Size = reader.TryReadUInt32() | ||
| 33 | userCmdReader := bitreader.NewReaderFromBytes(reader.TryReadBytesToSlice(uint64(userCmd.Size)), true) | ||
| 34 | userCmd.ParseUserCmdInfo(userCmdReader) | ||
| 35 | } | ||
| 36 | |||
| 37 | func (userCmd *UserCmd) ParseUserCmdInfo(reader *bitreader.Reader) { | ||
| 38 | if reader.TryReadBool() { | ||
| 39 | userCmd.Data.CommandNumber = reader.TryReadUInt32() | ||
| 40 | } | ||
| 41 | if reader.TryReadBool() { | ||
| 42 | userCmd.Data.TickCount = reader.TryReadUInt32() | ||
| 43 | } | ||
| 44 | if reader.TryReadBool() { | ||
| 45 | userCmd.Data.ViewAnglesX = reader.TryReadFloat32() | ||
| 46 | } | ||
| 47 | if reader.TryReadBool() { | ||
| 48 | userCmd.Data.ViewAnglesY = reader.TryReadFloat32() | ||
| 49 | } | ||
| 50 | if reader.TryReadBool() { | ||
| 51 | userCmd.Data.ViewAnglesZ = reader.TryReadFloat32() | ||
| 52 | } | ||
| 53 | if reader.TryReadBool() { | ||
| 54 | userCmd.Data.ForwardMove = reader.TryReadFloat32() | ||
| 55 | } | ||
| 56 | if reader.TryReadBool() { | ||
| 57 | userCmd.Data.SideMove = reader.TryReadFloat32() | ||
| 58 | } | ||
| 59 | if reader.TryReadBool() { | ||
| 60 | userCmd.Data.UpMove = reader.TryReadFloat32() | ||
| 61 | } | ||
| 62 | if reader.TryReadBool() { | ||
| 63 | userCmd.Data.Buttons = reader.TryReadUInt32() | ||
| 64 | } | ||
| 65 | if reader.TryReadBool() { | ||
| 66 | userCmd.Data.Impulse = reader.TryReadUInt8() | ||
| 67 | } | ||
| 68 | if reader.TryReadBool() { | ||
| 69 | userCmd.Data.WeaponSelect = uint16(reader.TryReadBits(11)) | ||
| 70 | if reader.TryReadBool() { | ||
| 71 | userCmd.Data.WeaponSubType = uint8(reader.TryReadBits(6)) | ||
| 72 | } | ||
| 73 | } | ||
| 74 | if reader.TryReadBool() { | ||
| 75 | userCmd.Data.MouseDx = reader.TryReadUInt16() | ||
| 76 | } | ||
| 77 | if reader.TryReadBool() { | ||
| 78 | userCmd.Data.MouseDy = reader.TryReadUInt16() | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | func (button Buttons) GetButtons() []string { | ||
| 83 | flags := []string{} | ||
| 84 | if button == 0 { | ||
| 85 | flags = append(flags, EButtonsNone) | ||
| 86 | } | ||
| 87 | if checkBit(uint32(button), 0) { | ||
| 88 | flags = append(flags, EButtonsAttack) | ||
| 89 | } | ||
| 90 | if checkBit(uint32(button), 1) { | ||
| 91 | flags = append(flags, EButtonsJump) | ||
| 92 | } | ||
| 93 | if checkBit(uint32(button), 2) { | ||
| 94 | flags = append(flags, EButtonsDuck) | ||
| 95 | } | ||
| 96 | if checkBit(uint32(button), 3) { | ||
| 97 | flags = append(flags, EButtonsForward) | ||
| 98 | } | ||
| 99 | if checkBit(uint32(button), 4) { | ||
| 100 | flags = append(flags, EButtonsBack) | ||
| 101 | } | ||
| 102 | if checkBit(uint32(button), 5) { | ||
| 103 | flags = append(flags, EButtonsUse) | ||
| 104 | } | ||
| 105 | if checkBit(uint32(button), 6) { | ||
| 106 | flags = append(flags, EButtonsCancel) | ||
| 107 | } | ||
| 108 | if checkBit(uint32(button), 7) { | ||
| 109 | flags = append(flags, EButtonsLeft) | ||
| 110 | } | ||
| 111 | if checkBit(uint32(button), 8) { | ||
| 112 | flags = append(flags, EButtonsRight) | ||
| 113 | } | ||
| 114 | if checkBit(uint32(button), 9) { | ||
| 115 | flags = append(flags, EButtonsMoveLeft) | ||
| 116 | } | ||
| 117 | if checkBit(uint32(button), 10) { | ||
| 118 | flags = append(flags, EButtonsMoveRight) | ||
| 119 | } | ||
| 120 | if checkBit(uint32(button), 11) { | ||
| 121 | flags = append(flags, EButtonsAttack2) | ||
| 122 | } | ||
| 123 | if checkBit(uint32(button), 12) { | ||
| 124 | flags = append(flags, EButtonsRun) | ||
| 125 | } | ||
| 126 | if checkBit(uint32(button), 13) { | ||
| 127 | flags = append(flags, EButtonsReload) | ||
| 128 | } | ||
| 129 | if checkBit(uint32(button), 14) { | ||
| 130 | flags = append(flags, EButtonsAlt1) | ||
| 131 | } | ||
| 132 | if checkBit(uint32(button), 15) { | ||
| 133 | flags = append(flags, EButtonsAlt2) | ||
| 134 | } | ||
| 135 | if checkBit(uint32(button), 16) { | ||
| 136 | flags = append(flags, EButtonsScore) | ||
| 137 | } | ||
| 138 | if checkBit(uint32(button), 17) { | ||
| 139 | flags = append(flags, EButtonsSpeed) | ||
| 140 | } | ||
| 141 | if checkBit(uint32(button), 18) { | ||
| 142 | flags = append(flags, EButtonsWalk) | ||
| 143 | } | ||
| 144 | if checkBit(uint32(button), 19) { | ||
| 145 | flags = append(flags, EButtonsZoom) | ||
| 146 | } | ||
| 147 | if checkBit(uint32(button), 20) { | ||
| 148 | flags = append(flags, EButtonsWeapon1) | ||
| 149 | } | ||
| 150 | if checkBit(uint32(button), 21) { | ||
| 151 | flags = append(flags, EButtonsWeapon2) | ||
| 152 | } | ||
| 153 | if checkBit(uint32(button), 22) { | ||
| 154 | flags = append(flags, EButtonsBullRush) | ||
| 155 | } | ||
| 156 | if checkBit(uint32(button), 23) { | ||
| 157 | flags = append(flags, EButtonsGrenade1) | ||
| 158 | } | ||
| 159 | if checkBit(uint32(button), 24) { | ||
| 160 | flags = append(flags, EButtonsGrenade2) | ||
| 161 | } | ||
| 162 | if checkBit(uint32(button), 25) { | ||
| 163 | flags = append(flags, EButtonsLookSpin) | ||
| 164 | } | ||
| 165 | if checkBit(uint32(button), 26) { | ||
| 166 | flags = append(flags, EButtonsCurrentAbility) | ||
| 167 | } | ||
| 168 | if checkBit(uint32(button), 27) { | ||
| 169 | flags = append(flags, EButtonsPreviousAbility) | ||
| 170 | } | ||
| 171 | if checkBit(uint32(button), 28) { | ||
| 172 | flags = append(flags, EButtonsAbility1) | ||
| 173 | } | ||
| 174 | if checkBit(uint32(button), 29) { | ||
| 175 | flags = append(flags, EButtonsAbility2) | ||
| 176 | } | ||
| 177 | if checkBit(uint32(button), 30) { | ||
| 178 | flags = append(flags, EButtonsAbility3) | ||
| 179 | } | ||
| 180 | if checkBit(uint32(button), 31) { | ||
| 181 | flags = append(flags, EButtonsAbility4) | ||
| 182 | } | ||
| 183 | return flags | ||
| 184 | } | ||
| 185 | |||
| 186 | type Buttons int | ||
| 187 | |||
| 188 | const ( | ||
| 189 | EButtonsNone string = "None" | ||
| 190 | EButtonsAttack string = "Attack" | ||
| 191 | EButtonsJump string = "Jump" | ||
| 192 | EButtonsDuck string = "Duck" | ||
| 193 | EButtonsForward string = "Forward" | ||
| 194 | EButtonsBack string = "Back" | ||
| 195 | EButtonsUse string = "Use" | ||
| 196 | EButtonsCancel string = "Cancel" | ||
| 197 | EButtonsLeft string = "Left" | ||
| 198 | EButtonsRight string = "Right" | ||
| 199 | EButtonsMoveLeft string = "MoveLeft" | ||
| 200 | EButtonsMoveRight string = "MoveRight" | ||
| 201 | EButtonsAttack2 string = "Attack2" | ||
| 202 | EButtonsRun string = "Run" | ||
| 203 | EButtonsReload string = "Reload" | ||
| 204 | EButtonsAlt1 string = "Alt1" | ||
| 205 | EButtonsAlt2 string = "Alt2" | ||
| 206 | EButtonsScore string = "Score" | ||
| 207 | EButtonsSpeed string = "Speed" | ||
| 208 | EButtonsWalk string = "Walk" | ||
| 209 | EButtonsZoom string = "Zoom" | ||
| 210 | EButtonsWeapon1 string = "Weapon1" | ||
| 211 | EButtonsWeapon2 string = "Weapon2" | ||
| 212 | EButtonsBullRush string = "BullRush" | ||
| 213 | EButtonsGrenade1 string = "Grenade1" | ||
| 214 | EButtonsGrenade2 string = "Grenade2" | ||
| 215 | EButtonsLookSpin string = "LookSpin" | ||
| 216 | EButtonsCurrentAbility string = "CurrentAbility" | ||
| 217 | EButtonsPreviousAbility string = "PreviousAbility" | ||
| 218 | EButtonsAbility1 string = "Ability1" | ||
| 219 | EButtonsAbility2 string = "Ability2" | ||
| 220 | EButtonsAbility3 string = "Ability3" | ||
| 221 | EButtonsAbility4 string = "Ability4" | ||
| 222 | ) | ||
diff --git a/pkg/messages/messages.go b/pkg/messages/messages.go deleted file mode 100644 index 9b2422f..0000000 --- a/pkg/messages/messages.go +++ /dev/null | |||
| @@ -1,83 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | messages "github.com/pektezol/demoparser/pkg/messages/types" | ||
| 6 | ) | ||
| 7 | |||
| 8 | func ParseMessages(messageType uint64, reader *bitreader.Reader) any { | ||
| 9 | var messageData any | ||
| 10 | switch messageType { | ||
| 11 | case 0: | ||
| 12 | messageData = messages.ParseNetNop(reader) | ||
| 13 | case 1: | ||
| 14 | messageData = messages.ParseNetDisconnect(reader) | ||
| 15 | case 2: | ||
| 16 | messageData = messages.ParseNetFile(reader) | ||
| 17 | case 3: | ||
| 18 | messageData = messages.ParseNetSplitScreenUser(reader) | ||
| 19 | case 4: | ||
| 20 | messageData = messages.ParseNetTick(reader) | ||
| 21 | case 5: | ||
| 22 | messageData = messages.ParseNetStringCmd(reader) | ||
| 23 | case 6: | ||
| 24 | messageData = messages.ParseNetSetConVar(reader) | ||
| 25 | case 7: | ||
| 26 | messageData = messages.ParseNetSignOnState(reader) | ||
| 27 | case 8: | ||
| 28 | messageData = messages.ParseSvcServerInfo(reader) | ||
| 29 | case 9: | ||
| 30 | messageData = messages.ParseSvcSendTable(reader) | ||
| 31 | case 10: | ||
| 32 | messageData = messages.ParseSvcClassInfo(reader) | ||
| 33 | case 11: | ||
| 34 | messageData = messages.ParseSvcSetPause(reader) | ||
| 35 | case 12: | ||
| 36 | messageData = messages.ParseSvcCreateStringTable(reader) // TODO: | ||
| 37 | case 13: | ||
| 38 | messageData = messages.ParseSvcUpdateStringTable(reader) // TODO: | ||
| 39 | case 14: | ||
| 40 | messageData = messages.ParseSvcVoiceInit(reader) | ||
| 41 | case 15: | ||
| 42 | messageData = messages.ParseSvcVoiceData(reader) | ||
| 43 | case 16: | ||
| 44 | messageData = messages.ParseSvcPrint(reader) | ||
| 45 | case 17: | ||
| 46 | messageData = messages.ParseSvcSounds(reader) // TODO: | ||
| 47 | case 18: | ||
| 48 | messageData = messages.ParseSvcSetView(reader) | ||
| 49 | case 19: | ||
| 50 | messageData = messages.ParseSvcFixAngle(reader) | ||
| 51 | case 20: | ||
| 52 | messageData = messages.ParseSvcCrosshairAngle(reader) | ||
| 53 | case 21: | ||
| 54 | messageData = messages.ParseSvcBspDecal(reader) // untested | ||
| 55 | case 22: | ||
| 56 | messageData = messages.ParseSvcSplitScreen(reader) // skipped | ||
| 57 | case 23: | ||
| 58 | messageData = messages.ParseSvcUserMessage(reader) // TODO: | ||
| 59 | case 24: | ||
| 60 | messageData = messages.ParseSvcEntityMessage(reader) // skipped | ||
| 61 | case 25: | ||
| 62 | messageData = messages.ParseSvcGameEvent(reader) // TODO: | ||
| 63 | case 26: | ||
| 64 | messageData = messages.ParseSvcPacketEntities(reader) // TODO: | ||
| 65 | case 27: | ||
| 66 | messageData = messages.ParseSvcTempEntities(reader) // skipped | ||
| 67 | case 28: | ||
| 68 | messageData = messages.ParseSvcPrefetch(reader) | ||
| 69 | case 29: | ||
| 70 | messageData = messages.ParseSvcMenu(reader) // skipped | ||
| 71 | case 30: | ||
| 72 | messageData = messages.ParseSvcGameEventList(reader) // TODO: | ||
| 73 | case 31: | ||
| 74 | messageData = messages.ParseSvcGetCvarValue(reader) | ||
| 75 | case 32: | ||
| 76 | messageData = messages.ParseSvcCmdKeyValues(reader) | ||
| 77 | case 33: | ||
| 78 | messageData = messages.ParseSvcPaintmapData(reader) | ||
| 79 | default: | ||
| 80 | return nil | ||
| 81 | } | ||
| 82 | return messageData | ||
| 83 | } | ||
diff --git a/pkg/messages/types/netDisconnect.go b/pkg/messages/types/netDisconnect.go deleted file mode 100644 index 10a8b05..0000000 --- a/pkg/messages/types/netDisconnect.go +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type NetDisconnect struct { | ||
| 8 | Text string | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseNetDisconnect(reader *bitreader.Reader) NetDisconnect { | ||
| 12 | netDisconnect := NetDisconnect{ | ||
| 13 | Text: reader.TryReadString(), | ||
| 14 | } | ||
| 15 | |||
| 16 | return netDisconnect | ||
| 17 | } | ||
diff --git a/pkg/messages/types/netFile.go b/pkg/messages/types/netFile.go deleted file mode 100644 index fc65229..0000000 --- a/pkg/messages/types/netFile.go +++ /dev/null | |||
| @@ -1,44 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | ) | ||
| 8 | |||
| 9 | type NetFile struct { | ||
| 10 | TransferId uint32 | ||
| 11 | FileName string | ||
| 12 | FileFlags string | ||
| 13 | } | ||
| 14 | |||
| 15 | type NetFileFlags int | ||
| 16 | |||
| 17 | const ( | ||
| 18 | ENetFileFlagsNone NetFileFlags = 0 | ||
| 19 | ENetFileFlagsFileRequested NetFileFlags = 1 | ||
| 20 | ENetFileFlagsUnknown NetFileFlags = 1 << 1 | ||
| 21 | ) | ||
| 22 | |||
| 23 | func (netFileFlags NetFileFlags) String() string { | ||
| 24 | switch netFileFlags { | ||
| 25 | case ENetFileFlagsNone: | ||
| 26 | return "None" | ||
| 27 | case ENetFileFlagsFileRequested: | ||
| 28 | return "FileRequested" | ||
| 29 | case ENetFileFlagsUnknown: | ||
| 30 | return "Unknown" | ||
| 31 | default: | ||
| 32 | return fmt.Sprintf("%d", int(netFileFlags)) | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | func ParseNetFile(reader *bitreader.Reader) NetFile { | ||
| 37 | netFile := NetFile{ | ||
| 38 | TransferId: reader.TryReadUInt32(), | ||
| 39 | FileName: reader.TryReadString(), | ||
| 40 | FileFlags: NetFileFlags(reader.TryReadBits(2)).String(), | ||
| 41 | } | ||
| 42 | |||
| 43 | return netFile | ||
| 44 | } | ||
diff --git a/pkg/messages/types/netNop.go b/pkg/messages/types/netNop.go deleted file mode 100644 index 826da6b..0000000 --- a/pkg/messages/types/netNop.go +++ /dev/null | |||
| @@ -1,12 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type NetNop struct{} | ||
| 8 | |||
| 9 | func ParseNetNop(reader *bitreader.Reader) NetNop { | ||
| 10 | |||
| 11 | return NetNop{} | ||
| 12 | } | ||
diff --git a/pkg/messages/types/netSetConVar.go b/pkg/messages/types/netSetConVar.go deleted file mode 100644 index 03e9e0d..0000000 --- a/pkg/messages/types/netSetConVar.go +++ /dev/null | |||
| @@ -1,33 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type NetSetConVar struct { | ||
| 8 | Length uint8 | ||
| 9 | ConVars []conVar | ||
| 10 | } | ||
| 11 | |||
| 12 | type conVar struct { | ||
| 13 | Name string | ||
| 14 | Value string | ||
| 15 | } | ||
| 16 | |||
| 17 | func ParseNetSetConVar(reader *bitreader.Reader) NetSetConVar { | ||
| 18 | length := reader.TryReadUInt8() | ||
| 19 | convars := []conVar{} | ||
| 20 | |||
| 21 | for count := 0; count < int(length); count++ { | ||
| 22 | convar := conVar{ | ||
| 23 | Name: reader.TryReadString(), | ||
| 24 | Value: reader.TryReadString(), | ||
| 25 | } | ||
| 26 | |||
| 27 | convars = append(convars, convar) | ||
| 28 | } | ||
| 29 | return NetSetConVar{ | ||
| 30 | Length: length, | ||
| 31 | ConVars: convars, | ||
| 32 | } | ||
| 33 | } | ||
diff --git a/pkg/messages/types/netSignOnState.go b/pkg/messages/types/netSignOnState.go deleted file mode 100644 index 65e17a4..0000000 --- a/pkg/messages/types/netSignOnState.go +++ /dev/null | |||
| @@ -1,73 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | ) | ||
| 8 | |||
| 9 | type NetSignOnState struct { | ||
| 10 | SignOnState string | ||
| 11 | SpawnCount int32 | ||
| 12 | NumServerPlayers uint32 | ||
| 13 | IdsLength uint32 | ||
| 14 | PlayersNetworksIds []byte | ||
| 15 | MapNameLength uint32 | ||
| 16 | MapName string | ||
| 17 | } | ||
| 18 | |||
| 19 | type SignOnState int | ||
| 20 | |||
| 21 | const ( | ||
| 22 | ESignOnStateNone SignOnState = iota // no state yet, about to connect | ||
| 23 | ESignOnStateChallenge // client challenging server, all OOB packets | ||
| 24 | ESignOnStateConnected // client is connected to server, netchans ready | ||
| 25 | ESignOnStateNew // just got server info and string tables | ||
| 26 | ESignOnStatePreSpawn // received signon buggers | ||
| 27 | ESignOnStateSpawn // ready to receive entity packets | ||
| 28 | ESignOnStateFull // we are fully connected, first non-delta packet received | ||
| 29 | ESignOnStateChangeLevel // server is changing level, please wait | ||
| 30 | ) | ||
| 31 | |||
| 32 | func (signOnState SignOnState) String() string { | ||
| 33 | switch signOnState { | ||
| 34 | case ESignOnStateNone: | ||
| 35 | return "None" | ||
| 36 | case ESignOnStateChallenge: | ||
| 37 | return "Challenge" | ||
| 38 | case ESignOnStateConnected: | ||
| 39 | return "Connected" | ||
| 40 | case ESignOnStateNew: | ||
| 41 | return "New" | ||
| 42 | case ESignOnStatePreSpawn: | ||
| 43 | return "PreSpawn" | ||
| 44 | case ESignOnStateSpawn: | ||
| 45 | return "Spawn" | ||
| 46 | case ESignOnStateFull: | ||
| 47 | return "Full" | ||
| 48 | case ESignOnStateChangeLevel: | ||
| 49 | return "ChangeLevel" | ||
| 50 | default: | ||
| 51 | return fmt.Sprintf("%d", int(signOnState)) | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | func ParseNetSignOnState(reader *bitreader.Reader) NetSignOnState { | ||
| 56 | netSignOnState := NetSignOnState{ | ||
| 57 | SignOnState: SignOnState(reader.TryReadUInt8()).String(), | ||
| 58 | SpawnCount: reader.TryReadSInt32(), | ||
| 59 | NumServerPlayers: reader.TryReadUInt32(), | ||
| 60 | IdsLength: reader.TryReadUInt32(), | ||
| 61 | } | ||
| 62 | |||
| 63 | if netSignOnState.IdsLength > 0 { | ||
| 64 | netSignOnState.PlayersNetworksIds = reader.TryReadBytesToSlice(uint64(netSignOnState.IdsLength)) | ||
| 65 | |||
| 66 | } | ||
| 67 | netSignOnState.MapNameLength = reader.TryReadUInt32() | ||
| 68 | if netSignOnState.MapNameLength > 0 { | ||
| 69 | netSignOnState.MapName = reader.TryReadStringLength(uint64(netSignOnState.MapNameLength)) | ||
| 70 | |||
| 71 | } | ||
| 72 | return netSignOnState | ||
| 73 | } | ||
diff --git a/pkg/messages/types/netSplitScreenUser.go b/pkg/messages/types/netSplitScreenUser.go deleted file mode 100644 index 8b14f63..0000000 --- a/pkg/messages/types/netSplitScreenUser.go +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type NetSplitScreenUser struct { | ||
| 8 | Slot bool | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseNetSplitScreenUser(reader *bitreader.Reader) NetSplitScreenUser { | ||
| 12 | netSplitScreenUser := NetSplitScreenUser{ | ||
| 13 | Slot: reader.TryReadBool(), | ||
| 14 | } | ||
| 15 | |||
| 16 | return netSplitScreenUser | ||
| 17 | } | ||
diff --git a/pkg/messages/types/netStringCmd.go b/pkg/messages/types/netStringCmd.go deleted file mode 100644 index 2f7e830..0000000 --- a/pkg/messages/types/netStringCmd.go +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type NetStringCmd struct { | ||
| 8 | Command string | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseNetStringCmd(reader *bitreader.Reader) NetStringCmd { | ||
| 12 | netStringCmd := NetStringCmd{ | ||
| 13 | Command: reader.TryReadString(), | ||
| 14 | } | ||
| 15 | |||
| 16 | return netStringCmd | ||
| 17 | } | ||
diff --git a/pkg/messages/types/netTick.go b/pkg/messages/types/netTick.go deleted file mode 100644 index 49e997e..0000000 --- a/pkg/messages/types/netTick.go +++ /dev/null | |||
| @@ -1,21 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type NetTick struct { | ||
| 8 | Tick uint32 | ||
| 9 | HostFrameTime float32 | ||
| 10 | HostFrameTimeStdDeviation float32 | ||
| 11 | } | ||
| 12 | |||
| 13 | func ParseNetTick(reader *bitreader.Reader) NetTick { | ||
| 14 | netTick := NetTick{ | ||
| 15 | Tick: reader.TryReadUInt32(), | ||
| 16 | HostFrameTime: float32(reader.TryReadUInt16()) / 1e5, | ||
| 17 | HostFrameTimeStdDeviation: float32(reader.TryReadUInt16()) / 1e5, | ||
| 18 | } | ||
| 19 | |||
| 20 | return netTick | ||
| 21 | } | ||
diff --git a/pkg/messages/types/svcBspDecal.go b/pkg/messages/types/svcBspDecal.go deleted file mode 100644 index 6bf96a3..0000000 --- a/pkg/messages/types/svcBspDecal.go +++ /dev/null | |||
| @@ -1,62 +0,0 @@ | |||
| 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 uint16 | ||
| 11 | ModelIndex uint16 | ||
| 12 | LowPriority bool | ||
| 13 | } | ||
| 14 | |||
| 15 | type vectorCoord struct { | ||
| 16 | Value float32 | ||
| 17 | Valid bool | ||
| 18 | } | ||
| 19 | |||
| 20 | func ParseSvcBspDecal(reader *bitreader.Reader) SvcBspDecal { | ||
| 21 | svcBspDecal := SvcBspDecal{ | ||
| 22 | Pos: readVectorCoords(reader), | ||
| 23 | DecalTextureIndex: int16(reader.TryReadBits(9)), | ||
| 24 | } | ||
| 25 | if reader.TryReadBool() { | ||
| 26 | svcBspDecal.EntityIndex = uint16(reader.TryReadBits(11)) | ||
| 27 | svcBspDecal.ModelIndex = uint16(reader.TryReadBits(11)) | ||
| 28 | } | ||
| 29 | svcBspDecal.LowPriority = reader.TryReadBool() | ||
| 30 | |||
| 31 | return svcBspDecal | ||
| 32 | } | ||
| 33 | |||
| 34 | func readVectorCoords(reader *bitreader.Reader) []vectorCoord { | ||
| 35 | const COORD_INTEGER_BITS uint8 = 14 | ||
| 36 | const COORD_FRACTIONAL_BITS uint8 = 5 | ||
| 37 | const COORD_DENOMINATOR uint8 = 1 << COORD_FRACTIONAL_BITS | ||
| 38 | const COORD_RESOLUTION float32 = 1.0 / float32(COORD_DENOMINATOR) | ||
| 39 | readVectorCoord := func() float32 { | ||
| 40 | value := float32(0) | ||
| 41 | integer := reader.TryReadBits(1) | ||
| 42 | fraction := reader.TryReadBits(1) | ||
| 43 | if integer != 0 || fraction != 0 { | ||
| 44 | sign := reader.TryReadBits(1) | ||
| 45 | if integer != 0 { | ||
| 46 | integer = reader.TryReadBits(uint64(COORD_INTEGER_BITS)) + 1 | ||
| 47 | } | ||
| 48 | if fraction != 0 { | ||
| 49 | fraction = reader.TryReadBits(uint64(COORD_FRACTIONAL_BITS)) | ||
| 50 | } | ||
| 51 | value = float32(integer) + float32(fraction)*COORD_RESOLUTION | ||
| 52 | if sign != 0 { | ||
| 53 | value = -value | ||
| 54 | } | ||
| 55 | } | ||
| 56 | return value | ||
| 57 | } | ||
| 58 | x := reader.TryReadBits(1) | ||
| 59 | y := reader.TryReadBits(1) | ||
| 60 | z := reader.TryReadBits(1) | ||
| 61 | return []vectorCoord{{Value: readVectorCoord(), Valid: x != 0}, {Value: readVectorCoord(), Valid: y != 0}, {Value: readVectorCoord(), Valid: z != 0}} | ||
| 62 | } | ||
diff --git a/pkg/messages/types/svcClassInfo.go b/pkg/messages/types/svcClassInfo.go deleted file mode 100644 index a20bfa3..0000000 --- a/pkg/messages/types/svcClassInfo.go +++ /dev/null | |||
| @@ -1,41 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "math" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | ) | ||
| 8 | |||
| 9 | type SvcClassInfo struct { | ||
| 10 | ClassCount uint16 | ||
| 11 | CreateOnClient bool | ||
| 12 | ServerClasses []serverClass | ||
| 13 | } | ||
| 14 | |||
| 15 | type serverClass struct { | ||
| 16 | ClassId int16 | ||
| 17 | ClassName string | ||
| 18 | DataTableName string | ||
| 19 | } | ||
| 20 | |||
| 21 | func ParseSvcClassInfo(reader *bitreader.Reader) SvcClassInfo { | ||
| 22 | svcClassInfo := SvcClassInfo{ | ||
| 23 | ClassCount: reader.TryReadUInt16(), | ||
| 24 | CreateOnClient: reader.TryReadBool(), | ||
| 25 | } | ||
| 26 | classes := []serverClass{} | ||
| 27 | |||
| 28 | if !svcClassInfo.CreateOnClient { | ||
| 29 | |||
| 30 | for count := 0; count < int(svcClassInfo.ClassCount); count++ { | ||
| 31 | classes = append(classes, serverClass{ | ||
| 32 | ClassId: int16(reader.TryReadBits(uint64(math.Log2(float64(svcClassInfo.ClassCount)) + 1))), | ||
| 33 | ClassName: reader.TryReadString(), | ||
| 34 | DataTableName: reader.TryReadString(), | ||
| 35 | }) | ||
| 36 | |||
| 37 | } | ||
| 38 | } | ||
| 39 | svcClassInfo.ServerClasses = classes | ||
| 40 | return svcClassInfo | ||
| 41 | } | ||
diff --git a/pkg/messages/types/svcCmdKeyValues.go b/pkg/messages/types/svcCmdKeyValues.go deleted file mode 100644 index 61d6290..0000000 --- a/pkg/messages/types/svcCmdKeyValues.go +++ /dev/null | |||
| @@ -1,19 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcCmdKeyValues struct { | ||
| 8 | Length uint32 | ||
| 9 | Data []byte | ||
| 10 | } | ||
| 11 | |||
| 12 | func ParseSvcCmdKeyValues(reader *bitreader.Reader) SvcCmdKeyValues { | ||
| 13 | svcCmdKeyValues := SvcCmdKeyValues{ | ||
| 14 | Length: reader.TryReadUInt32(), | ||
| 15 | } | ||
| 16 | svcCmdKeyValues.Data = reader.TryReadBytesToSlice(uint64(svcCmdKeyValues.Length)) | ||
| 17 | |||
| 18 | return svcCmdKeyValues | ||
| 19 | } | ||
diff --git a/pkg/messages/types/svcCreateStringTable.go b/pkg/messages/types/svcCreateStringTable.go deleted file mode 100644 index 8d36fcf..0000000 --- a/pkg/messages/types/svcCreateStringTable.go +++ /dev/null | |||
| @@ -1,37 +0,0 @@ | |||
| 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.Reader) SvcCreateStringTable { | ||
| 22 | svcCreateStringTable := SvcCreateStringTable{ | ||
| 23 | Name: reader.TryReadString(), | ||
| 24 | MaxEntries: reader.TryReadSInt16(), | ||
| 25 | } | ||
| 26 | svcCreateStringTable.NumEntries = int8(reader.TryReadBits(uint64(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 | |||
| 35 | reader.SkipBits(uint64(svcCreateStringTable.Length)) // TODO: StringTable parsing | ||
| 36 | return svcCreateStringTable | ||
| 37 | } | ||
diff --git a/pkg/messages/types/svcCrosshairAngle.go b/pkg/messages/types/svcCrosshairAngle.go deleted file mode 100644 index f689876..0000000 --- a/pkg/messages/types/svcCrosshairAngle.go +++ /dev/null | |||
| @@ -1,27 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcCrosshairAngle struct { | ||
| 8 | Angle crosshairAngles | ||
| 9 | } | ||
| 10 | |||
| 11 | type crosshairAngles struct { | ||
| 12 | X float32 | ||
| 13 | Y float32 | ||
| 14 | Z float32 | ||
| 15 | } | ||
| 16 | |||
| 17 | func ParseSvcCrosshairAngle(reader *bitreader.Reader) SvcCrosshairAngle { | ||
| 18 | svcCrosshairAngle := SvcCrosshairAngle{ | ||
| 19 | Angle: crosshairAngles{ | ||
| 20 | X: float32(reader.TryReadBits(16)), | ||
| 21 | Y: float32(reader.TryReadBits(16)), | ||
| 22 | Z: float32(reader.TryReadBits(16)), | ||
| 23 | }, | ||
| 24 | } | ||
| 25 | |||
| 26 | return svcCrosshairAngle | ||
| 27 | } | ||
diff --git a/pkg/messages/types/svcEntityMessage.go b/pkg/messages/types/svcEntityMessage.go deleted file mode 100644 index c4676ec..0000000 --- a/pkg/messages/types/svcEntityMessage.go +++ /dev/null | |||
| @@ -1,23 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcEntityMessage struct { | ||
| 8 | EntityIndex uint16 | ||
| 9 | ClassId uint16 | ||
| 10 | Length uint16 | ||
| 11 | Data []byte | ||
| 12 | } | ||
| 13 | |||
| 14 | func ParseSvcEntityMessage(reader *bitreader.Reader) SvcEntityMessage { | ||
| 15 | svcEntityMessage := SvcEntityMessage{ | ||
| 16 | EntityIndex: uint16(reader.TryReadBits(11)), | ||
| 17 | ClassId: uint16(reader.TryReadBits(9)), | ||
| 18 | Length: uint16(reader.TryReadBits(11)), | ||
| 19 | } | ||
| 20 | svcEntityMessage.Data = reader.TryReadBitsToSlice(uint64(svcEntityMessage.Length)) | ||
| 21 | |||
| 22 | return svcEntityMessage | ||
| 23 | } | ||
diff --git a/pkg/messages/types/svcFixAngle.go b/pkg/messages/types/svcFixAngle.go deleted file mode 100644 index f00c239..0000000 --- a/pkg/messages/types/svcFixAngle.go +++ /dev/null | |||
| @@ -1,29 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcFixAngle struct { | ||
| 8 | Relative bool | ||
| 9 | Angle fixAngles | ||
| 10 | } | ||
| 11 | |||
| 12 | type fixAngles struct { | ||
| 13 | X float32 | ||
| 14 | Y float32 | ||
| 15 | Z float32 | ||
| 16 | } | ||
| 17 | |||
| 18 | func ParseSvcFixAngle(reader *bitreader.Reader) SvcFixAngle { | ||
| 19 | svcFixAngle := SvcFixAngle{ | ||
| 20 | Relative: reader.TryReadBool(), | ||
| 21 | Angle: fixAngles{ | ||
| 22 | X: float32(reader.TryReadBits(16)), | ||
| 23 | Y: float32(reader.TryReadBits(16)), | ||
| 24 | Z: float32(reader.TryReadBits(16)), | ||
| 25 | }, | ||
| 26 | } | ||
| 27 | |||
| 28 | return svcFixAngle | ||
| 29 | } | ||
diff --git a/pkg/messages/types/svcGameEvent.go b/pkg/messages/types/svcGameEvent.go deleted file mode 100644 index ec96653..0000000 --- a/pkg/messages/types/svcGameEvent.go +++ /dev/null | |||
| @@ -1,19 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcGameEvent struct { | ||
| 8 | Length uint16 | ||
| 9 | Data []byte // TODO: GameEvent[] | ||
| 10 | } | ||
| 11 | |||
| 12 | func ParseSvcGameEvent(reader *bitreader.Reader) SvcGameEvent { | ||
| 13 | svcGameEvent := SvcGameEvent{ | ||
| 14 | Length: uint16(reader.TryReadBits(11)), | ||
| 15 | } | ||
| 16 | svcGameEvent.Data = reader.TryReadBitsToSlice(uint64(svcGameEvent.Length)) | ||
| 17 | |||
| 18 | return svcGameEvent | ||
| 19 | } | ||
diff --git a/pkg/messages/types/svcGameEventList.go b/pkg/messages/types/svcGameEventList.go deleted file mode 100644 index ca2cf76..0000000 --- a/pkg/messages/types/svcGameEventList.go +++ /dev/null | |||
| @@ -1,24 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcGameEventList struct { | ||
| 8 | Events int16 | ||
| 9 | Length int32 | ||
| 10 | GameEventDescriptor []gameEventDescriptor | ||
| 11 | } | ||
| 12 | |||
| 13 | type gameEventDescriptor struct { | ||
| 14 | } | ||
| 15 | |||
| 16 | func ParseSvcGameEventList(reader *bitreader.Reader) SvcGameEventList { | ||
| 17 | svcGameEventList := SvcGameEventList{ | ||
| 18 | Events: int16(reader.TryReadBits(9)), | ||
| 19 | Length: int32(reader.TryReadBits(20)), | ||
| 20 | } | ||
| 21 | reader.TryReadBitsToSlice(uint64(svcGameEventList.Length)) | ||
| 22 | |||
| 23 | return svcGameEventList | ||
| 24 | } | ||
diff --git a/pkg/messages/types/svcGetCvarValue.go b/pkg/messages/types/svcGetCvarValue.go deleted file mode 100644 index b0513d0..0000000 --- a/pkg/messages/types/svcGetCvarValue.go +++ /dev/null | |||
| @@ -1,19 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcGetCvarValue struct { | ||
| 8 | Cookie int32 | ||
| 9 | CvarName string | ||
| 10 | } | ||
| 11 | |||
| 12 | func ParseSvcGetCvarValue(reader *bitreader.Reader) SvcGetCvarValue { | ||
| 13 | svcGetCvarValue := SvcGetCvarValue{ | ||
| 14 | Cookie: reader.TryReadSInt32(), | ||
| 15 | CvarName: reader.TryReadString(), | ||
| 16 | } | ||
| 17 | |||
| 18 | return svcGetCvarValue | ||
| 19 | } | ||
diff --git a/pkg/messages/types/svcMenu.go b/pkg/messages/types/svcMenu.go deleted file mode 100644 index df14048..0000000 --- a/pkg/messages/types/svcMenu.go +++ /dev/null | |||
| @@ -1,21 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcMenu struct { | ||
| 8 | Type uint16 | ||
| 9 | Length uint32 | ||
| 10 | Data []byte | ||
| 11 | } | ||
| 12 | |||
| 13 | func ParseSvcMenu(reader *bitreader.Reader) SvcMenu { | ||
| 14 | svcMenu := SvcMenu{ | ||
| 15 | Type: reader.TryReadUInt16(), | ||
| 16 | Length: reader.TryReadUInt32(), | ||
| 17 | } | ||
| 18 | svcMenu.Data = reader.TryReadBitsToSlice(uint64(svcMenu.Length)) | ||
| 19 | |||
| 20 | return svcMenu | ||
| 21 | } | ||
diff --git a/pkg/messages/types/svcPacketEntities.go b/pkg/messages/types/svcPacketEntities.go deleted file mode 100644 index 8000a55..0000000 --- a/pkg/messages/types/svcPacketEntities.go +++ /dev/null | |||
| @@ -1,35 +0,0 @@ | |||
| 1 | package messages | ||
| 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 | Length uint32 | ||
| 14 | UpdatedBaseline bool | ||
| 15 | Data []byte | ||
| 16 | } | ||
| 17 | |||
| 18 | func ParseSvcPacketEntities(reader *bitreader.Reader) SvcPacketEntities { | ||
| 19 | svcPacketEntities := SvcPacketEntities{ | ||
| 20 | MaxEntries: uint16(reader.TryReadBits(11)), | ||
| 21 | IsDelta: reader.TryReadBool(), | ||
| 22 | } | ||
| 23 | if svcPacketEntities.IsDelta { | ||
| 24 | svcPacketEntities.DeltaFrom = reader.TryReadSInt32() | ||
| 25 | } else { | ||
| 26 | svcPacketEntities.DeltaFrom = -1 | ||
| 27 | } | ||
| 28 | svcPacketEntities.BaseLine = reader.TryReadBool() | ||
| 29 | svcPacketEntities.UpdatedEntries = uint16(reader.TryReadBits(11)) | ||
| 30 | svcPacketEntities.Length = uint32(reader.TryReadBits(20)) | ||
| 31 | svcPacketEntities.UpdatedBaseline = reader.TryReadBool() | ||
| 32 | svcPacketEntities.Data = reader.TryReadBitsToSlice(uint64(svcPacketEntities.Length)) | ||
| 33 | |||
| 34 | return svcPacketEntities | ||
| 35 | } | ||
diff --git a/pkg/messages/types/svcPaintmapData.go b/pkg/messages/types/svcPaintmapData.go deleted file mode 100644 index 49aa433..0000000 --- a/pkg/messages/types/svcPaintmapData.go +++ /dev/null | |||
| @@ -1,19 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcPaintmapData struct { | ||
| 8 | Length uint32 | ||
| 9 | Data []byte | ||
| 10 | } | ||
| 11 | |||
| 12 | func ParseSvcPaintmapData(reader *bitreader.Reader) SvcPaintmapData { | ||
| 13 | svcPaintmapData := SvcPaintmapData{ | ||
| 14 | Length: reader.TryReadUInt32(), | ||
| 15 | } | ||
| 16 | svcPaintmapData.Data = reader.TryReadBitsToSlice(uint64(svcPaintmapData.Length)) | ||
| 17 | |||
| 18 | return svcPaintmapData | ||
| 19 | } | ||
diff --git a/pkg/messages/types/svcPrefetch.go b/pkg/messages/types/svcPrefetch.go deleted file mode 100644 index a9a88fe..0000000 --- a/pkg/messages/types/svcPrefetch.go +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcPrefetch struct { | ||
| 8 | SoundIndex int16 | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseSvcPrefetch(reader *bitreader.Reader) SvcPrefetch { | ||
| 12 | svcPrefetch := SvcPrefetch{ | ||
| 13 | SoundIndex: int16(reader.TryReadBits(13)), | ||
| 14 | } | ||
| 15 | |||
| 16 | return svcPrefetch | ||
| 17 | } | ||
diff --git a/pkg/messages/types/svcPrint.go b/pkg/messages/types/svcPrint.go deleted file mode 100644 index 5868ab2..0000000 --- a/pkg/messages/types/svcPrint.go +++ /dev/null | |||
| @@ -1,18 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcPrint struct { | ||
| 8 | Message string | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseSvcPrint(reader *bitreader.Reader) SvcPrint { | ||
| 12 | svcPrint := SvcPrint{ | ||
| 13 | Message: reader.TryReadString(), | ||
| 14 | } | ||
| 15 | // common psycopath behaviour | ||
| 16 | |||
| 17 | return svcPrint | ||
| 18 | } | ||
diff --git a/pkg/messages/types/svcSendTable.go b/pkg/messages/types/svcSendTable.go deleted file mode 100644 index 4397db0..0000000 --- a/pkg/messages/types/svcSendTable.go +++ /dev/null | |||
| @@ -1,21 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcSendTable struct { | ||
| 8 | NeedsDecoder bool | ||
| 9 | Length uint8 | ||
| 10 | Props uint32 | ||
| 11 | } | ||
| 12 | |||
| 13 | func ParseSvcSendTable(reader *bitreader.Reader) SvcSendTable { | ||
| 14 | svcSendTable := SvcSendTable{ | ||
| 15 | NeedsDecoder: reader.TryReadBool(), | ||
| 16 | Length: reader.TryReadUInt8(), | ||
| 17 | } | ||
| 18 | svcSendTable.Props = uint32(reader.TryReadBits(uint64(svcSendTable.Length))) | ||
| 19 | |||
| 20 | return svcSendTable | ||
| 21 | } | ||
diff --git a/pkg/messages/types/svcServerInfo.go b/pkg/messages/types/svcServerInfo.go deleted file mode 100644 index 507b7ca..0000000 --- a/pkg/messages/types/svcServerInfo.go +++ /dev/null | |||
| @@ -1,47 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcServerInfo struct { | ||
| 8 | Protocol uint16 | ||
| 9 | ServerCount uint32 | ||
| 10 | IsHltv bool | ||
| 11 | IsDedicated bool | ||
| 12 | ClientCrc int32 | ||
| 13 | StringTableCrc uint32 | ||
| 14 | MaxServerClasses uint16 | ||
| 15 | MapCrc uint32 | ||
| 16 | PlayerCount uint8 | ||
| 17 | MaxClients uint8 | ||
| 18 | TickInterval float32 | ||
| 19 | Platform string | ||
| 20 | GameDir string | ||
| 21 | MapName string | ||
| 22 | SkyName string | ||
| 23 | HostName string | ||
| 24 | } | ||
| 25 | |||
| 26 | func ParseSvcServerInfo(reader *bitreader.Reader) SvcServerInfo { | ||
| 27 | svcServerInfo := SvcServerInfo{ | ||
| 28 | Protocol: reader.TryReadUInt16(), | ||
| 29 | ServerCount: reader.TryReadUInt32(), | ||
| 30 | IsHltv: reader.TryReadBool(), | ||
| 31 | IsDedicated: reader.TryReadBool(), | ||
| 32 | ClientCrc: reader.TryReadSInt32(), | ||
| 33 | StringTableCrc: reader.TryReadUInt32(), | ||
| 34 | MaxServerClasses: reader.TryReadUInt16(), | ||
| 35 | MapCrc: reader.TryReadUInt32(), | ||
| 36 | PlayerCount: reader.TryReadUInt8(), | ||
| 37 | MaxClients: reader.TryReadUInt8(), | ||
| 38 | TickInterval: reader.TryReadFloat32(), | ||
| 39 | Platform: reader.TryReadStringLength(1), | ||
| 40 | GameDir: reader.TryReadString(), | ||
| 41 | MapName: reader.TryReadString(), | ||
| 42 | SkyName: reader.TryReadString(), | ||
| 43 | HostName: reader.TryReadString(), | ||
| 44 | } | ||
| 45 | |||
| 46 | return svcServerInfo | ||
| 47 | } | ||
diff --git a/pkg/messages/types/svcSetPause.go b/pkg/messages/types/svcSetPause.go deleted file mode 100644 index 1f6f25f..0000000 --- a/pkg/messages/types/svcSetPause.go +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcSetPause struct { | ||
| 8 | Paused bool | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseSvcSetPause(reader *bitreader.Reader) SvcSetPause { | ||
| 12 | svcSetPause := SvcSetPause{ | ||
| 13 | Paused: reader.TryReadBool(), | ||
| 14 | } | ||
| 15 | |||
| 16 | return svcSetPause | ||
| 17 | } | ||
diff --git a/pkg/messages/types/svcSetView.go b/pkg/messages/types/svcSetView.go deleted file mode 100644 index a60d547..0000000 --- a/pkg/messages/types/svcSetView.go +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcSetView struct { | ||
| 8 | EntityIndex uint16 | ||
| 9 | } | ||
| 10 | |||
| 11 | func ParseSvcSetView(reader *bitreader.Reader) SvcSetView { | ||
| 12 | svcSetView := SvcSetView{ | ||
| 13 | EntityIndex: uint16(reader.TryReadBits(11)), | ||
| 14 | } | ||
| 15 | |||
| 16 | return svcSetView | ||
| 17 | } | ||
diff --git a/pkg/messages/types/svcSounds.go b/pkg/messages/types/svcSounds.go deleted file mode 100644 index 34d99f6..0000000 --- a/pkg/messages/types/svcSounds.go +++ /dev/null | |||
| @@ -1,28 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcSounds struct { | ||
| 8 | ReliableSound bool | ||
| 9 | SoundCount uint8 | ||
| 10 | Length uint16 | ||
| 11 | Data []byte | ||
| 12 | } | ||
| 13 | |||
| 14 | func ParseSvcSounds(reader *bitreader.Reader) SvcSounds { | ||
| 15 | svcSounds := SvcSounds{ | ||
| 16 | ReliableSound: reader.TryReadBool(), | ||
| 17 | } | ||
| 18 | if svcSounds.ReliableSound { | ||
| 19 | svcSounds.SoundCount = 1 | ||
| 20 | svcSounds.Length = uint16(reader.TryReadUInt8()) | ||
| 21 | } else { | ||
| 22 | svcSounds.SoundCount = reader.TryReadUInt8() | ||
| 23 | svcSounds.Length = reader.TryReadUInt16() | ||
| 24 | } | ||
| 25 | svcSounds.Data = reader.TryReadBitsToSlice(uint64(svcSounds.Length)) | ||
| 26 | |||
| 27 | return svcSounds | ||
| 28 | } | ||
diff --git a/pkg/messages/types/svcSplitScreen.go b/pkg/messages/types/svcSplitScreen.go deleted file mode 100644 index fc6acb4..0000000 --- a/pkg/messages/types/svcSplitScreen.go +++ /dev/null | |||
| @@ -1,21 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcSplitScreen struct { | ||
| 8 | RemoveUser bool | ||
| 9 | Length uint16 | ||
| 10 | Data []byte | ||
| 11 | } | ||
| 12 | |||
| 13 | func ParseSvcSplitScreen(reader *bitreader.Reader) SvcSplitScreen { | ||
| 14 | svcSplitScreen := SvcSplitScreen{ | ||
| 15 | RemoveUser: reader.TryReadBool(), | ||
| 16 | Length: uint16(reader.TryReadBits(11)), | ||
| 17 | } | ||
| 18 | svcSplitScreen.Data = reader.TryReadBitsToSlice(uint64(svcSplitScreen.Length)) | ||
| 19 | |||
| 20 | return svcSplitScreen | ||
| 21 | } | ||
diff --git a/pkg/messages/types/svcTempEntities.go b/pkg/messages/types/svcTempEntities.go deleted file mode 100644 index 41b1afb..0000000 --- a/pkg/messages/types/svcTempEntities.go +++ /dev/null | |||
| @@ -1,21 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcTempEntities struct { | ||
| 8 | NumEntries uint8 | ||
| 9 | Length uint32 | ||
| 10 | Data []byte | ||
| 11 | } | ||
| 12 | |||
| 13 | func ParseSvcTempEntities(reader *bitreader.Reader) SvcTempEntities { | ||
| 14 | svcTempEntities := SvcTempEntities{ | ||
| 15 | NumEntries: reader.TryReadUInt8(), | ||
| 16 | Length: uint32(reader.TryReadBits(17)), | ||
| 17 | } | ||
| 18 | svcTempEntities.Data = reader.TryReadBitsToSlice(uint64(svcTempEntities.Length)) | ||
| 19 | |||
| 20 | return svcTempEntities | ||
| 21 | } | ||
diff --git a/pkg/messages/types/svcUpdateStringTable.go b/pkg/messages/types/svcUpdateStringTable.go deleted file mode 100644 index ca716eb..0000000 --- a/pkg/messages/types/svcUpdateStringTable.go +++ /dev/null | |||
| @@ -1,25 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcUpdateStringTable struct { | ||
| 8 | TableId uint8 | ||
| 9 | NumChangedEntries uint16 | ||
| 10 | Length int32 | ||
| 11 | Data []byte | ||
| 12 | } | ||
| 13 | |||
| 14 | func ParseSvcUpdateStringTable(reader *bitreader.Reader) SvcUpdateStringTable { | ||
| 15 | svcUpdateStringTable := SvcUpdateStringTable{ | ||
| 16 | TableId: uint8(reader.TryReadBits(5)), | ||
| 17 | } | ||
| 18 | if reader.TryReadBool() { | ||
| 19 | svcUpdateStringTable.NumChangedEntries = reader.TryReadUInt16() | ||
| 20 | } | ||
| 21 | svcUpdateStringTable.Length = int32(reader.TryReadBits(20)) | ||
| 22 | svcUpdateStringTable.Data = reader.TryReadBitsToSlice(uint64(svcUpdateStringTable.Length)) | ||
| 23 | |||
| 24 | return svcUpdateStringTable | ||
| 25 | } | ||
diff --git a/pkg/messages/types/svcUserMessage.go b/pkg/messages/types/svcUserMessage.go deleted file mode 100644 index a39e64b..0000000 --- a/pkg/messages/types/svcUserMessage.go +++ /dev/null | |||
| @@ -1,41 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | "math" | ||
| 6 | |||
| 7 | "github.com/pektezol/bitreader" | ||
| 8 | ) | ||
| 9 | |||
| 10 | type SvcUserMessage struct { | ||
| 11 | Type int8 | ||
| 12 | Length int16 | ||
| 13 | Data any | ||
| 14 | } | ||
| 15 | |||
| 16 | func ParseSvcUserMessage(reader *bitreader.Reader) SvcUserMessage { | ||
| 17 | svcUserMessage := SvcUserMessage{ | ||
| 18 | Type: int8(reader.TryReadBits(8)), | ||
| 19 | Length: int16(reader.TryReadBits(12)), | ||
| 20 | } | ||
| 21 | svcUserMessage.Data = reader.TryReadBitsToSlice(uint64(svcUserMessage.Length)) | ||
| 22 | userMessageReader := bitreader.NewReaderFromBytes(svcUserMessage.Data.([]byte), true) | ||
| 23 | switch svcUserMessage.Type { | ||
| 24 | case 60: | ||
| 25 | svcUserMessage.parseScoreboardTempUpdate(userMessageReader) | ||
| 26 | } | ||
| 27 | return svcUserMessage | ||
| 28 | } | ||
| 29 | |||
| 30 | func (svcUserMessage *SvcUserMessage) parseScoreboardTempUpdate(reader *bitreader.Reader) { | ||
| 31 | scoreboardTempUpdate := struct { | ||
| 32 | NumPortals int32 | ||
| 33 | TimeTaken int32 | ||
| 34 | }{ | ||
| 35 | NumPortals: reader.TryReadSInt32(), | ||
| 36 | TimeTaken: reader.TryReadSInt32(), | ||
| 37 | } | ||
| 38 | svcUserMessage.Data = scoreboardTempUpdate | ||
| 39 | fmt.Printf("Portal Count: %d\n", scoreboardTempUpdate.NumPortals) | ||
| 40 | fmt.Printf("CM Ticks: %d\n", int(math.Round(float64((float32(scoreboardTempUpdate.TimeTaken)/100.0)/float32(1.0/60.0))))) | ||
| 41 | } | ||
diff --git a/pkg/messages/types/svcVoiceData.go b/pkg/messages/types/svcVoiceData.go deleted file mode 100644 index 6ac8050..0000000 --- a/pkg/messages/types/svcVoiceData.go +++ /dev/null | |||
| @@ -1,25 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcVoiceData struct { | ||
| 8 | FromClient uint8 | ||
| 9 | Proximity bool | ||
| 10 | Length int16 | ||
| 11 | Data []byte | ||
| 12 | } | ||
| 13 | |||
| 14 | func ParseSvcVoiceData(reader *bitreader.Reader) SvcVoiceData { | ||
| 15 | svcVoiceData := SvcVoiceData{ | ||
| 16 | FromClient: reader.TryReadUInt8(), | ||
| 17 | } | ||
| 18 | proximity := reader.TryReadUInt8() | ||
| 19 | if proximity != 0 { | ||
| 20 | svcVoiceData.Proximity = true | ||
| 21 | } | ||
| 22 | svcVoiceData.Data = reader.TryReadBitsToSlice(uint64(svcVoiceData.Length)) | ||
| 23 | |||
| 24 | return svcVoiceData | ||
| 25 | } | ||
diff --git a/pkg/messages/types/svcVoiceInit.go b/pkg/messages/types/svcVoiceInit.go deleted file mode 100644 index eb6093f..0000000 --- a/pkg/messages/types/svcVoiceInit.go +++ /dev/null | |||
| @@ -1,29 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type SvcVoiceInit struct { | ||
| 8 | Codec string | ||
| 9 | Quality uint8 | ||
| 10 | SampleRate int32 | ||
| 11 | } | ||
| 12 | |||
| 13 | func ParseSvcVoiceInit(reader *bitreader.Reader) SvcVoiceInit { | ||
| 14 | svcVoiceInit := SvcVoiceInit{ | ||
| 15 | Codec: reader.TryReadString(), | ||
| 16 | Quality: reader.TryReadUInt8(), | ||
| 17 | } | ||
| 18 | if svcVoiceInit.Quality == 0b11111111 { | ||
| 19 | svcVoiceInit.SampleRate = reader.TryReadSInt32() | ||
| 20 | } else { | ||
| 21 | if svcVoiceInit.Codec == "vaudio_celt" { | ||
| 22 | svcVoiceInit.SampleRate = 22050 | ||
| 23 | } else { | ||
| 24 | svcVoiceInit.SampleRate = 11025 | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | return svcVoiceInit | ||
| 29 | } | ||
diff --git a/pkg/packets/headers.go b/pkg/packets/headers.go deleted file mode 100644 index ba5482b..0000000 --- a/pkg/packets/headers.go +++ /dev/null | |||
| @@ -1,45 +0,0 @@ | |||
| 1 | package packets | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type Headers struct { | ||
| 8 | DemoFileStamp string | ||
| 9 | DemoProtocol int32 | ||
| 10 | NetworkProtocol int32 | ||
| 11 | ServerName string | ||
| 12 | ClientName string | ||
| 13 | MapName string | ||
| 14 | GameDirectory string | ||
| 15 | PlaybackTime float32 | ||
| 16 | PlaybackTicks int32 | ||
| 17 | PlaybackFrames int32 | ||
| 18 | SignOnLength int32 | ||
| 19 | } | ||
| 20 | |||
| 21 | func ParseHeaders(reader *bitreader.Reader) Headers { | ||
| 22 | headers := Headers{ | ||
| 23 | DemoFileStamp: reader.TryReadString(), | ||
| 24 | DemoProtocol: int32(reader.TryReadSInt32()), | ||
| 25 | NetworkProtocol: int32(reader.TryReadSInt32()), | ||
| 26 | ServerName: reader.TryReadStringLength(260), | ||
| 27 | ClientName: reader.TryReadStringLength(260), | ||
| 28 | MapName: reader.TryReadStringLength(260), | ||
| 29 | GameDirectory: reader.TryReadStringLength(260), | ||
| 30 | PlaybackTime: reader.TryReadFloat32(), | ||
| 31 | PlaybackTicks: int32(reader.TryReadSInt32()), | ||
| 32 | PlaybackFrames: int32(reader.TryReadSInt32()), | ||
| 33 | SignOnLength: int32(reader.TryReadSInt32()), | ||
| 34 | } | ||
| 35 | if headers.DemoFileStamp != "HL2DEMO" { | ||
| 36 | panic("invalid demo file stamp") | ||
| 37 | } | ||
| 38 | if headers.DemoProtocol != 4 { | ||
| 39 | panic("this parser only supports demos from new engine") | ||
| 40 | } | ||
| 41 | if headers.NetworkProtocol != 2001 { | ||
| 42 | panic("this parser only supports demos from portal 2") | ||
| 43 | } | ||
| 44 | return headers | ||
| 45 | } | ||
diff --git a/pkg/packets/packets.go b/pkg/packets/packets.go deleted file mode 100644 index 02ad806..0000000 --- a/pkg/packets/packets.go +++ /dev/null | |||
| @@ -1,54 +0,0 @@ | |||
| 1 | package packets | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | "github.com/pektezol/demoparser/pkg/classes" | ||
| 6 | ) | ||
| 7 | |||
| 8 | type PacketMessageInfo struct { | ||
| 9 | PacketType uint8 | ||
| 10 | TickNumber int32 | ||
| 11 | SlotNumber uint8 | ||
| 12 | } | ||
| 13 | |||
| 14 | func ParsePackets(reader *bitreader.Reader) PacketMessageInfo { | ||
| 15 | packetType := reader.TryReadUInt8() | ||
| 16 | tickNumber := reader.TryReadSInt32() | ||
| 17 | slotNumber := reader.TryReadUInt8() | ||
| 18 | switch packetType { | ||
| 19 | case 1: // SignOn | ||
| 20 | signOn := classes.SignOn{} | ||
| 21 | signOn.ParseSignOn(reader) | ||
| 22 | case 2: // Packet | ||
| 23 | packet := classes.Packet{} | ||
| 24 | packet.ParsePacket(reader) | ||
| 25 | case 3: // SyncTick | ||
| 26 | syncTick := classes.SyncTick{} | ||
| 27 | syncTick.ParseSyncTick() | ||
| 28 | case 4: // ConsoleCmd | ||
| 29 | consoleCmd := classes.ConsoleCmd{} | ||
| 30 | consoleCmd.ParseConsoleCmd(reader) | ||
| 31 | case 5: // UserCmd | ||
| 32 | userCmd := classes.UserCmd{} | ||
| 33 | userCmd.ParseUserCmd(reader) | ||
| 34 | case 6: // DataTables | ||
| 35 | dataTables := classes.DataTables{} | ||
| 36 | dataTables.ParseDataTables(reader) | ||
| 37 | case 7: // Stop | ||
| 38 | stop := classes.Stop{} | ||
| 39 | stop.ParseStop(reader) | ||
| 40 | case 8: // CustomData TODO: not sar data | ||
| 41 | customData := classes.CustomData{} | ||
| 42 | customData.ParseCustomData(reader, tickNumber, packetType) | ||
| 43 | case 9: // StringTables TODO: parsing string table data | ||
| 44 | stringTables := classes.StringTables{} | ||
| 45 | stringTables.ParseStringTables(reader) | ||
| 46 | default: // Invalid | ||
| 47 | panic("invalid packet type") | ||
| 48 | } | ||
| 49 | return PacketMessageInfo{ | ||
| 50 | PacketType: packetType, | ||
| 51 | TickNumber: tickNumber, | ||
| 52 | SlotNumber: slotNumber, | ||
| 53 | } | ||
| 54 | } | ||