From 81f365e99636104ff81151370048a51e8ae8027a Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Sat, 16 Sep 2023 20:39:02 +0300 Subject: feat: parsing sar custom data (#4) --- .github/workflows/CI.yml | 40 --- cmd/parser.go | 15 +- go.mod | 2 +- go.sum | 4 +- pkg/classes/cmdInfo.go | 2 +- pkg/classes/sarData.go | 378 +++++++++++++++++++++++++++++ pkg/classes/sendTable.go | 2 +- pkg/classes/serverClassInfo.go | 2 +- pkg/classes/stringTable.go | 16 +- pkg/classes/userCmdInfo.go | 2 +- pkg/messages/messages.go | 2 +- pkg/messages/types/netDisconnect.go | 2 +- pkg/messages/types/netFile.go | 2 +- pkg/messages/types/netNop.go | 2 +- pkg/messages/types/netSetConVar.go | 2 +- pkg/messages/types/netSignOnState.go | 6 +- pkg/messages/types/netSplitScreenUser.go | 2 +- pkg/messages/types/netStringCmd.go | 2 +- pkg/messages/types/netTick.go | 2 +- pkg/messages/types/svcBspDecal.go | 8 +- pkg/messages/types/svcClassInfo.go | 4 +- pkg/messages/types/svcCmdKeyValues.go | 4 +- pkg/messages/types/svcCreateStringTable.go | 6 +- pkg/messages/types/svcCrosshairAngle.go | 2 +- pkg/messages/types/svcEntityMessage.go | 4 +- pkg/messages/types/svcFixAngle.go | 2 +- pkg/messages/types/svcGameEvent.go | 4 +- pkg/messages/types/svcGameEventList.go | 4 +- pkg/messages/types/svcGetCvarValue.go | 4 +- pkg/messages/types/svcMenu.go | 4 +- pkg/messages/types/svcPacketEntities.go | 13 +- pkg/messages/types/svcPaintmapData.go | 4 +- pkg/messages/types/svcPrefetch.go | 2 +- pkg/messages/types/svcPrint.go | 2 +- pkg/messages/types/svcSendTable.go | 2 +- pkg/messages/types/svcServerInfo.go | 2 +- pkg/messages/types/svcSetPause.go | 2 +- pkg/messages/types/svcSetView.go | 2 +- pkg/messages/types/svcSounds.go | 4 +- pkg/messages/types/svcSplitScreen.go | 4 +- pkg/messages/types/svcTempEntities.go | 4 +- pkg/messages/types/svcUpdateStringTable.go | 4 +- pkg/messages/types/svcUserMessage.go | 4 +- pkg/messages/types/svcVoiceData.go | 4 +- pkg/messages/types/svcVoiceInit.go | 2 +- pkg/packets/headers.go | 20 +- pkg/packets/packets.go | 57 +++-- 47 files changed, 506 insertions(+), 157 deletions(-) delete mode 100644 .github/workflows/CI.yml create mode 100644 pkg/classes/sarData.go diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml deleted file mode 100644 index f0e5e51..0000000 --- a/.github/workflows/CI.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: CI - -on: - push: - branches: [ "main" ] - paths-ignore: - - '.github/*' - - '.gitignore' - - '**.md' - - 'LICENSE' - pull_request: - branches: [ "main" ] - -jobs: - build-windows: - name: Windows Build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Setup Go environment - uses: actions/setup-go@v4 - with: - go-version: '1.21.0' - architecture: amd64 - - name: Build - run: cd cmd ; env GOOS=windows GOARCH=amd64 go build . - build-linux: - name: Linux Build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Setup Go environment - uses: actions/setup-go@v4 - with: - go-version: '1.21.0' - architecture: amd64 - - name: Build - run: cd cmd ; env GOOS=linux GOARCH=amd64 go build . diff --git a/cmd/parser.go b/cmd/parser.go index d03fa9c..98f4637 100644 --- a/cmd/parser.go +++ b/cmd/parser.go @@ -9,6 +9,8 @@ import ( "github.com/pektezol/demoparser/pkg/packets" ) +const littleEndian bool = true + func main() { if len(os.Args) != 2 { panic("specify file in command line arguments") @@ -19,32 +21,29 @@ func main() { if err != nil { panic(err) } - reader := bitreader.Reader(file, true) + reader := bitreader.NewReader(file, littleEndian) demoParserHandler(reader) defer file.Close() + return } for _, fileinfo := range files { // If it is a directory file, err := os.Open(os.Args[1] + fileinfo.Name()) if err != nil { panic(err) } - reader := bitreader.Reader(file, true) + reader := bitreader.NewReader(file, littleEndian) demoParserHandler(reader) defer file.Close() } - // fmt.Scanln() } -func demoParserHandler(reader *bitreader.ReaderType) { +func demoParserHandler(reader *bitreader.Reader) { packets.ParseHeaders(reader) for { packet := packets.ParsePackets(reader) + fmt.Printf("[%d] %s (%d):\n\t%+v\n", packet.TickNumber, reflect.ValueOf(packet.Data).Type(), packet.PacketType, packet.Data) if packet.PacketType == 7 { break } - // if packet.PacketType != 5 { - // continue - // } - fmt.Printf("[%d] %s (%d):\n\t%+v\n", packet.TickNumber, reflect.ValueOf(packet.Data).Type(), packet.PacketType, packet.Data) } } diff --git a/go.mod b/go.mod index 408c7e3..e9749c8 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,4 @@ module github.com/pektezol/demoparser go 1.21.0 -require github.com/pektezol/bitreader v1.3.0 +require github.com/pektezol/bitreader v1.4.3 diff --git a/go.sum b/go.sum index 190a8a8..ea9b0d8 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,2 @@ -github.com/pektezol/bitreader v1.3.0 h1:VOj1M+vw0+xuBUlD4HPHdkjnVdUrHw2nwa5Ccxxm2ek= -github.com/pektezol/bitreader v1.3.0/go.mod h1:RKAUiA//jCPJzO10P+VSkBq4wfY38TaNjpCjQ+DmbcQ= +github.com/pektezol/bitreader v1.4.3 h1:+WjsD6qOAaI6Q1jOOlEJcnaEso8vPMKRZnnaDnZhTSg= +github.com/pektezol/bitreader v1.4.3/go.mod h1:xBQEsQpOf8B5yPrnOTkirZGyVUV6Bqp0ups2RIlTskk= diff --git a/pkg/classes/cmdInfo.go b/pkg/classes/cmdInfo.go index 6e56c41..b56afed 100644 --- a/pkg/classes/cmdInfo.go +++ b/pkg/classes/cmdInfo.go @@ -14,7 +14,7 @@ type CmdInfo struct { LocalViewAngles2 []float32 } -func ParseCmdInfo(reader *bitreader.ReaderType) CmdInfo { +func ParseCmdInfo(reader *bitreader.Reader) CmdInfo { return CmdInfo{ Flags: int32(reader.TryReadBits(32)), ViewOrigin: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, diff --git a/pkg/classes/sarData.go b/pkg/classes/sarData.go new file mode 100644 index 0000000..133b67a --- /dev/null +++ b/pkg/classes/sarData.go @@ -0,0 +1,378 @@ +package classes + +import ( + "errors" + "fmt" + + "github.com/pektezol/bitreader" +) + +type SarDataType uint8 + +const ( + ESarDataTimescaleCheat SarDataType = 0x01 + ESarDataInitialCVar SarDataType = 0x02 + ESarDataEntityInput SarDataType = 0x03 + ESarDataEntityInputSlot SarDataType = 0x04 + ESarDataPortalPlacement SarDataType = 0x05 + ESarDataChallengeFlags SarDataType = 0x06 + ESarDataCrouchFly SarDataType = 0x07 + ESarDataPause SarDataType = 0x08 + ESarDataWaitRun SarDataType = 0x09 + ESarDataSpeedrunTime SarDataType = 0x0A + ESarDataTimestamp SarDataType = 0x0B + ESarDataFileChecksum SarDataType = 0x0C + ESarDataHWaitRun SarDataType = 0x0D + ESarDataChecksum SarDataType = 0xFF + ESarDataChecksumV2 SarDataType = 0xFE + ESarDataInvalid SarDataType = iota +) + +func (t SarDataType) String() string { + switch t { + case ESarDataTimescaleCheat: + return "SarDataTimescaleCheat" + case ESarDataInitialCVar: + return "SarDataInitialCVar" + case ESarDataEntityInput: + return "SarDataEntityInput" + case ESarDataEntityInputSlot: + return "SarDataEntityInputSlot" + case ESarDataPortalPlacement: + return "SarDataPortalPlacement" + case ESarDataChallengeFlags: + return "SarDataChallengeFlags" + case ESarDataCrouchFly: + return "SarDataCrouchFly" + case ESarDataPause: + return "SarDataPause" + case ESarDataWaitRun: + return "SarDataWaitRun" + case ESarDataSpeedrunTime: + return "SarDataSpeedrunTime" + case ESarDataTimestamp: + return "SarDataTimestamp" + case ESarDataFileChecksum: + return "SarDataFileChecksum" + case ESarDataHWaitRun: + return "SarDataHWaitRun" + case ESarDataChecksum: + return "SarDataChecksum" + case ESarDataChecksumV2: + return "SarDataChecksumV2" + case ESarDataInvalid: + return "SarDataInvalid" + default: + return fmt.Sprintf("%d", int(t)) + } +} + +type SarData struct { + Type SarDataType + Slot int + Data any +} + +type SarDataTimescaleCheat struct { + Timescale float32 +} + +type SarDataInitialCVar struct { + CVar string + Val string +} + +type SarDataChecksum struct { + DemoSum uint32 + SarSum uint32 +} + +type SarDataChecksumV2 struct { + SarSum uint32 + Signature [64]byte +} + +type SarDataEntityInput struct { + TargetName string + ClassName string + InputName string + Parameter string +} + +type SarDataPortalPlacement struct { + Orange bool + X float32 + Y float32 + Z float32 +} + +type SarDataPause struct { + PauseTicks uint32 +} + +type SarDataWaitRun struct { + Ticks int + Cmd string +} + +type SarDataHWaitRun struct { + Ticks int + Cmd string +} + +type SarDataSpeedrunTime struct { + NSplits uint32 + Splits []SarDataSpeedrunTimeSplits +} + +type SarDataSpeedrunTimeSegs struct { + Name string + Ticks uint32 +} + +type SarDataSpeedrunTimeSplits struct { + Name string + NSegs uint32 + Segs []SarDataSpeedrunTimeSegs +} + +type SarDataTimestamp struct { + Year uint16 + Mon uint8 + Day uint8 + Hour uint8 + Min uint8 + Sec uint8 +} + +type SarDataFileChecksum struct { + Sum uint32 + Path string +} + +func (sarData *SarData) ParseSarData(reader *bitreader.Reader) (err error) { + reader.SkipBytes(8) + len := reader.TryReadRemainingBits() / 8 + if len == 0 { + sarData.Type = ESarDataInvalid + err = errors.New("sar data invalid") + return err + } + sarData.Type = SarDataType(reader.TryReadBytes(1)) + if sarData.Type == ESarDataChecksum && len == 5 { + len = 9 + } + dataReader := bitreader.NewReaderFromBytes(reader.TryReadBytesToSlice(len-1), true) + switch sarData.Type { + case ESarDataTimescaleCheat: + sarData.Data, err = parseTimescaleCheatData(dataReader, len) + if err != nil { + sarData.Data = nil + } + case ESarDataInitialCVar: + sarData.Data = parseInitialCVarData(dataReader) + case ESarDataEntityInputSlot: + sarData.Slot = int(dataReader.TryReadBytes(1)) + case ESarDataEntityInput: + sarData.Data = parseEntityInputData(dataReader) + case ESarDataChecksum: + sarData.Data, err = parseChecksumData(dataReader, len) + if err != nil { + sarData.Data = nil + } + case ESarDataChecksumV2: + sarData.Data, err = parseChecksumV2Data(dataReader, len) + if err != nil { + sarData.Data = nil + } + case ESarDataPortalPlacement: + data, slot, err := parsePortalPlacementData(dataReader, len) + if err != nil { + sarData.Data = nil + } else { + sarData.Data = data + sarData.Slot = slot + } + case ESarDataChallengeFlags, ESarDataCrouchFly: + sarData.Slot, err = parseChallengeFlagsCrouchFlyData(dataReader, len) + if err != nil { + sarData.Data = nil + } + case ESarDataPause: + sarData.Data, err = parsePauseData(dataReader, len) + if err != nil { + sarData.Data = nil + } + case ESarDataWaitRun: + sarData.Data, err = parseWaitRunData(dataReader, len) + if err != nil { + sarData.Data = nil + } + case ESarDataHWaitRun: + sarData.Data, err = parseHWaitRunData(dataReader, len) + if err != nil { + sarData.Data = nil + } + case ESarDataSpeedrunTime: + sarData.Data, err = parseSpeedrunTimeData(dataReader, len) + if err != nil { + sarData.Data = nil + } + case ESarDataTimestamp: + sarData.Data, err = parseTimestampData(dataReader, len) + if err != nil { + sarData.Data = nil + } + case ESarDataFileChecksum: + sarData.Data, err = parseFileChecksumData(dataReader, len) + if err != nil { + sarData.Data = nil + } + default: + err = errors.New("unsupported SAR data type") + return err + } + return nil +} + +func parseTimescaleCheatData(reader *bitreader.Reader, length uint64) (SarDataTimescaleCheat, error) { + if length != 5 { + return SarDataTimescaleCheat{}, errors.New("sar data invalid") + } + return SarDataTimescaleCheat{ + Timescale: reader.TryReadFloat32(), + }, nil +} + +func parseInitialCVarData(reader *bitreader.Reader) SarDataInitialCVar { + return SarDataInitialCVar{ + CVar: reader.TryReadString(), + Val: reader.TryReadString(), + } +} + +func parseEntityInputData(reader *bitreader.Reader) SarDataEntityInput { + return SarDataEntityInput{ + TargetName: reader.TryReadString(), + ClassName: reader.TryReadString(), + InputName: reader.TryReadString(), + Parameter: reader.TryReadString(), + } +} + +func parseChecksumData(reader *bitreader.Reader, length uint64) (SarDataChecksum, error) { + if length != 9 { + return SarDataChecksum{}, errors.New("sar data invalid") + } + return SarDataChecksum{ + DemoSum: reader.TryReadUInt32(), + SarSum: reader.TryReadUInt32(), + }, nil +} + +func parseChecksumV2Data(reader *bitreader.Reader, length uint64) (SarDataChecksumV2, error) { + if length != 69 { + return SarDataChecksumV2{}, errors.New("sar data invalid") + } + return SarDataChecksumV2{ + SarSum: reader.TryReadUInt32(), + Signature: [64]byte(reader.TryReadBytesToSlice(60)), + }, nil +} + +func parsePortalPlacementData(reader *bitreader.Reader, length uint64) (SarDataPortalPlacement, int, error) { + if length != 15 { + return SarDataPortalPlacement{}, 0, errors.New("sar data invalid") + } + slot := int(reader.TryReadBytes(1)) + orange := reader.TryReadBool() + reader.SkipBits(7) + return SarDataPortalPlacement{ + Orange: orange, + X: reader.TryReadFloat32(), + Y: reader.TryReadFloat32(), + Z: reader.TryReadFloat32(), + }, slot, nil +} + +func parseChallengeFlagsCrouchFlyData(reader *bitreader.Reader, length uint64) (int, error) { + if length != 2 { + return 0, errors.New("sar data invalid") + } + return int(reader.TryReadBytes(1)), nil +} + +func parsePauseData(reader *bitreader.Reader, length uint64) (SarDataPause, error) { + if length != 5 { + return SarDataPause{}, errors.New("sar data invalid") + } + return SarDataPause{ + PauseTicks: reader.TryReadUInt32(), + }, nil +} + +func parseWaitRunData(reader *bitreader.Reader, length uint64) (SarDataWaitRun, error) { + if length < 6 { + return SarDataWaitRun{}, errors.New("sar data invalid") + } + return SarDataWaitRun{ + Ticks: int(reader.TryReadUInt32()), + Cmd: reader.TryReadString(), + }, nil +} + +func parseHWaitRunData(reader *bitreader.Reader, length uint64) (SarDataHWaitRun, error) { + if length < 6 { + return SarDataHWaitRun{}, errors.New("sar data invalid") + } + return SarDataHWaitRun{ + Ticks: int(reader.TryReadUInt32()), + Cmd: reader.TryReadString(), + }, nil +} + +func parseSpeedrunTimeData(reader *bitreader.Reader, length uint64) (SarDataSpeedrunTime, error) { + if length < 5 { + return SarDataSpeedrunTime{}, errors.New("sar data invalid") + } + numberOfSplits := reader.TryReadUInt32() + splits := make([]SarDataSpeedrunTimeSplits, numberOfSplits) + for splitCount := 0; splitCount < int(numberOfSplits); splitCount++ { + splits[splitCount].Name = reader.TryReadString() + splits[splitCount].NSegs = reader.TryReadUInt32() + splits[splitCount].Segs = make([]SarDataSpeedrunTimeSegs, splits[splitCount].NSegs) + for segCount := 0; segCount < int(splits[splitCount].NSegs); segCount++ { + splits[splitCount].Segs[segCount].Name = reader.TryReadString() + splits[splitCount].Segs[segCount].Ticks = reader.TryReadUInt32() + } + } + return SarDataSpeedrunTime{ + NSplits: numberOfSplits, + Splits: splits, + }, nil +} + +func parseTimestampData(reader *bitreader.Reader, length uint64) (SarDataTimestamp, error) { + if length != 8 { + return SarDataTimestamp{}, errors.New("sar data invalid") + } + timestamp := reader.TryReadBytesToSlice(7) + return SarDataTimestamp{ + Year: uint16(timestamp[0]) | uint16(timestamp[1])<<8, + Mon: timestamp[2] + 1, + Day: timestamp[3], + Hour: timestamp[4], + Min: timestamp[5], + Sec: timestamp[6], + }, nil +} + +func parseFileChecksumData(reader *bitreader.Reader, length uint64) (SarDataFileChecksum, error) { + if length < 6 { + return SarDataFileChecksum{}, errors.New("sar data invalid") + } + return SarDataFileChecksum{ + Sum: reader.TryReadUInt32(), + Path: reader.TryReadString(), + }, nil +} diff --git a/pkg/classes/sendTable.go b/pkg/classes/sendTable.go index 4521464..bc36d75 100644 --- a/pkg/classes/sendTable.go +++ b/pkg/classes/sendTable.go @@ -59,7 +59,7 @@ const ( DataTable ) -func ParseSendTable(reader *bitreader.ReaderType) SendTable { +func ParseSendTable(reader *bitreader.Reader) SendTable { sendTable := SendTable{ NeedsDecoder: reader.TryReadBool(), NetTableName: reader.TryReadString(), diff --git a/pkg/classes/serverClassInfo.go b/pkg/classes/serverClassInfo.go index c60dad1..fbccffb 100644 --- a/pkg/classes/serverClassInfo.go +++ b/pkg/classes/serverClassInfo.go @@ -10,7 +10,7 @@ type ServerClassInfo struct { DataTableName string } -func ParseServerClassInfo(reader *bitreader.ReaderType, count int, numOfClasses int) ServerClassInfo { +func ParseServerClassInfo(reader *bitreader.Reader, count int, numOfClasses int) ServerClassInfo { return ServerClassInfo{ ClassId: int16(reader.TryReadBits(16)), ClassName: reader.TryReadString(), diff --git a/pkg/classes/stringTable.go b/pkg/classes/stringTable.go index c6709f5..3983c1f 100644 --- a/pkg/classes/stringTable.go +++ b/pkg/classes/stringTable.go @@ -1,8 +1,6 @@ package classes import ( - "bytes" - "github.com/pektezol/bitreader" ) @@ -26,7 +24,7 @@ type StringTableClass struct { Data string } -func ParseStringTables(reader *bitreader.ReaderType) []StringTable { +func ParseStringTables(reader *bitreader.Reader) []StringTable { tableCount := reader.TryReadBits(8) stringTables := make([]StringTable, tableCount) for i := 0; i < int(tableCount); i++ { @@ -37,7 +35,7 @@ func ParseStringTables(reader *bitreader.ReaderType) []StringTable { return stringTables } -func (stringTable *StringTable) ParseStream(reader *bitreader.ReaderType) { +func (stringTable *StringTable) ParseStream(reader *bitreader.Reader) { stringTable.Name = reader.TryReadString() entryCount := reader.TryReadBits(16) stringTable.TableEntries = make([]StringTableEntry, entryCount) @@ -60,23 +58,23 @@ func (stringTable *StringTable) ParseStream(reader *bitreader.ReaderType) { } } -func (stringTableEntry *StringTableEntry) Parse(reader *bitreader.ReaderType) { +func (stringTableEntry *StringTableEntry) Parse(reader *bitreader.Reader) { stringTableEntry.Name = reader.TryReadString() if reader.TryReadBool() { byteLen, err := reader.ReadBits(16) if err != nil { return } - dataBsr := reader.TryReadBytesToSlice(int(byteLen)) - _ = bitreader.Reader(bytes.NewReader(dataBsr), true) // TODO: Parse StringTableEntry + dataBsr := reader.TryReadBytesToSlice(byteLen) + _ = bitreader.NewReaderFromBytes(dataBsr, true) // TODO: Parse StringTableEntry // stringTableEntry.EntryData.ParseStream(entryReader) } } -func (stringTableClass *StringTableClass) Parse(reader *bitreader.ReaderType) { +func (stringTableClass *StringTableClass) Parse(reader *bitreader.Reader) { stringTableClass.Name = reader.TryReadString() if reader.TryReadBool() { dataLen := reader.TryReadBits(16) - stringTableClass.Data = reader.TryReadStringLen(int(dataLen)) + stringTableClass.Data = reader.TryReadStringLength(dataLen) } } diff --git a/pkg/classes/userCmdInfo.go b/pkg/classes/userCmdInfo.go index a6d9091..04d76b6 100644 --- a/pkg/classes/userCmdInfo.go +++ b/pkg/classes/userCmdInfo.go @@ -24,7 +24,7 @@ type UserCmdInfo struct { } func ParseUserCmdInfo(data []byte) UserCmdInfo { - reader := bitreader.Reader(bytes.NewReader(data), true) + reader := bitreader.NewReader(bytes.NewReader(data), true) userCmdInfo := UserCmdInfo{} if reader.TryReadBool() { userCmdInfo.CommandNumber = int32(reader.TryReadBits(32)) diff --git a/pkg/messages/messages.go b/pkg/messages/messages.go index 39f89e9..6fa58fc 100644 --- a/pkg/messages/messages.go +++ b/pkg/messages/messages.go @@ -8,7 +8,7 @@ import ( messages "github.com/pektezol/demoparser/pkg/messages/types" ) -func ParseMessages(messageType int, reader *bitreader.ReaderType) any { +func ParseMessages(messageType int, reader *bitreader.Reader) any { var messageData any switch messageType { case 0: diff --git a/pkg/messages/types/netDisconnect.go b/pkg/messages/types/netDisconnect.go index 69d4a67..3ecf8e1 100644 --- a/pkg/messages/types/netDisconnect.go +++ b/pkg/messages/types/netDisconnect.go @@ -6,7 +6,7 @@ type NetDisconnect struct { Text string } -func ParseNetDisconnect(reader *bitreader.ReaderType) NetDisconnect { +func ParseNetDisconnect(reader *bitreader.Reader) NetDisconnect { return NetDisconnect{ Text: reader.TryReadString(), } diff --git a/pkg/messages/types/netFile.go b/pkg/messages/types/netFile.go index a41a0cf..328900c 100644 --- a/pkg/messages/types/netFile.go +++ b/pkg/messages/types/netFile.go @@ -8,7 +8,7 @@ type NetFile struct { FileRequested bool } -func ParseNetFile(reader *bitreader.ReaderType) NetFile { +func ParseNetFile(reader *bitreader.Reader) NetFile { return NetFile{ TransferId: int32(reader.TryReadBits(32)), FileName: reader.TryReadString(), diff --git a/pkg/messages/types/netNop.go b/pkg/messages/types/netNop.go index 33f8e25..f942786 100644 --- a/pkg/messages/types/netNop.go +++ b/pkg/messages/types/netNop.go @@ -4,6 +4,6 @@ import "github.com/pektezol/bitreader" type NetNop struct{} -func ParseNetNop(reader *bitreader.ReaderType) NetNop { +func ParseNetNop(reader *bitreader.Reader) NetNop { return NetNop{} } diff --git a/pkg/messages/types/netSetConVar.go b/pkg/messages/types/netSetConVar.go index 08042ae..f04f564 100644 --- a/pkg/messages/types/netSetConVar.go +++ b/pkg/messages/types/netSetConVar.go @@ -12,7 +12,7 @@ type conVar struct { Value string } -func ParseNetSetConVar(reader *bitreader.ReaderType) NetSetConVar { +func ParseNetSetConVar(reader *bitreader.Reader) NetSetConVar { length := reader.TryReadBits(8) convars := []conVar{} for count := 0; count < int(length); count++ { diff --git a/pkg/messages/types/netSignOnState.go b/pkg/messages/types/netSignOnState.go index 4609ff2..277a6ee 100644 --- a/pkg/messages/types/netSignOnState.go +++ b/pkg/messages/types/netSignOnState.go @@ -12,15 +12,15 @@ type NetSignOnState struct { MapName string } -func ParseNetSignOnState(reader *bitreader.ReaderType) NetSignOnState { +func ParseNetSignOnState(reader *bitreader.Reader) NetSignOnState { netSignOnState := NetSignOnState{ SignOnState: int8(reader.TryReadBits(8)), SpawnCount: int32(reader.TryReadBits(32)), NumServerPlayers: int32(reader.TryReadBits(32)), IdsLength: int32(reader.TryReadBits(32)), } - netSignOnState.PlayersNetworksIds = reader.TryReadBytesToSlice(int(netSignOnState.IdsLength)) + netSignOnState.PlayersNetworksIds = reader.TryReadBytesToSlice(uint64(netSignOnState.IdsLength)) netSignOnState.MapNameLength = int32(reader.TryReadBits(32)) - netSignOnState.MapName = reader.TryReadStringLen(int(netSignOnState.MapNameLength)) + netSignOnState.MapName = reader.TryReadStringLength(uint64(netSignOnState.MapNameLength)) return netSignOnState } diff --git a/pkg/messages/types/netSplitScreenUser.go b/pkg/messages/types/netSplitScreenUser.go index 65e85f3..9e4caa8 100644 --- a/pkg/messages/types/netSplitScreenUser.go +++ b/pkg/messages/types/netSplitScreenUser.go @@ -6,7 +6,7 @@ type NetSplitScreenUser struct { Unknown bool } -func ParseNetSplitScreenUser(reader *bitreader.ReaderType) NetSplitScreenUser { +func ParseNetSplitScreenUser(reader *bitreader.Reader) NetSplitScreenUser { return NetSplitScreenUser{ Unknown: reader.TryReadBool(), } diff --git a/pkg/messages/types/netStringCmd.go b/pkg/messages/types/netStringCmd.go index 158658e..da5a75b 100644 --- a/pkg/messages/types/netStringCmd.go +++ b/pkg/messages/types/netStringCmd.go @@ -6,7 +6,7 @@ type NetStringCmd struct { Command string } -func ParseNetStringCmd(reader *bitreader.ReaderType) NetStringCmd { +func ParseNetStringCmd(reader *bitreader.Reader) NetStringCmd { return NetStringCmd{ Command: reader.TryReadString(), } diff --git a/pkg/messages/types/netTick.go b/pkg/messages/types/netTick.go index e14f259..bd3464a 100644 --- a/pkg/messages/types/netTick.go +++ b/pkg/messages/types/netTick.go @@ -8,7 +8,7 @@ type NetTick struct { HostFrameTimeStdDeviation int16 } -func ParseNetTick(reader *bitreader.ReaderType) NetTick { +func ParseNetTick(reader *bitreader.Reader) NetTick { return NetTick{ Tick: int32(reader.TryReadBits(32)), HostFrameTime: int16(reader.TryReadBits(16) / 10e5), diff --git a/pkg/messages/types/svcBspDecal.go b/pkg/messages/types/svcBspDecal.go index 484497f..dda81dd 100644 --- a/pkg/messages/types/svcBspDecal.go +++ b/pkg/messages/types/svcBspDecal.go @@ -17,7 +17,7 @@ type vectorCoord struct { Valid bool } -func ParseSvcBspDecal(reader *bitreader.ReaderType) SvcBspDecal { +func ParseSvcBspDecal(reader *bitreader.Reader) SvcBspDecal { svcBspDecal := SvcBspDecal{ Pos: readVectorCoords(reader), DecalTextureIndex: int16(reader.TryReadBits(9)), @@ -30,7 +30,7 @@ func ParseSvcBspDecal(reader *bitreader.ReaderType) SvcBspDecal { return svcBspDecal } -func readVectorCoords(reader *bitreader.ReaderType) []vectorCoord { +func readVectorCoords(reader *bitreader.Reader) []vectorCoord { const COORD_INTEGER_BITS uint8 = 14 const COORD_FRACTIONAL_BITS uint8 = 5 const COORD_DENOMINATOR uint8 = 1 << COORD_FRACTIONAL_BITS @@ -42,10 +42,10 @@ func readVectorCoords(reader *bitreader.ReaderType) []vectorCoord { if integer != 0 || fraction != 0 { sign := reader.TryReadBits(1) if integer != 0 { - integer = reader.TryReadBits(int(COORD_INTEGER_BITS)) + 1 + integer = reader.TryReadBits(uint64(COORD_INTEGER_BITS)) + 1 } if fraction != 0 { - fraction = reader.TryReadBits(int(COORD_FRACTIONAL_BITS)) + fraction = reader.TryReadBits(uint64(COORD_FRACTIONAL_BITS)) } value = float32(integer) + float32(fraction)*COORD_RESOLUTION if sign != 0 { diff --git a/pkg/messages/types/svcClassInfo.go b/pkg/messages/types/svcClassInfo.go index 9f367d3..27862bf 100644 --- a/pkg/messages/types/svcClassInfo.go +++ b/pkg/messages/types/svcClassInfo.go @@ -19,7 +19,7 @@ type serverClass struct { DataTableName string } -func ParseSvcClassInfo(reader *bitreader.ReaderType) SvcClassInfo { +func ParseSvcClassInfo(reader *bitreader.Reader) SvcClassInfo { svcClassInfo := SvcClassInfo{ Length: int16(reader.TryReadBits(16)), CreateOnClient: reader.TryReadBool(), @@ -29,7 +29,7 @@ func ParseSvcClassInfo(reader *bitreader.ReaderType) SvcClassInfo { for count := 0; count < int(svcClassInfo.Length); count++ { fmt.Println(classes) classes = append(classes, serverClass{ - ClassId: int16(reader.TryReadBits(int(math.Log2(float64(svcClassInfo.Length)) + 1))), + ClassId: int16(reader.TryReadBits(uint64(math.Log2(float64(svcClassInfo.Length)) + 1))), ClassName: reader.TryReadString(), DataTableName: reader.TryReadString(), }) diff --git a/pkg/messages/types/svcCmdKeyValues.go b/pkg/messages/types/svcCmdKeyValues.go index 1c4d819..35a8a8d 100644 --- a/pkg/messages/types/svcCmdKeyValues.go +++ b/pkg/messages/types/svcCmdKeyValues.go @@ -7,10 +7,10 @@ type SvcCmdKeyValues struct { Data []byte } -func ParseSvcCmdKeyValues(reader *bitreader.ReaderType) SvcCmdKeyValues { +func ParseSvcCmdKeyValues(reader *bitreader.Reader) SvcCmdKeyValues { svcCmdKeyValues := SvcCmdKeyValues{ Length: int32(reader.TryReadBits(32)), } - svcCmdKeyValues.Data = reader.TryReadBytesToSlice(int(svcCmdKeyValues.Length)) + svcCmdKeyValues.Data = reader.TryReadBytesToSlice(uint64(svcCmdKeyValues.Length)) return svcCmdKeyValues } diff --git a/pkg/messages/types/svcCreateStringTable.go b/pkg/messages/types/svcCreateStringTable.go index ed9e477..3c15e5c 100644 --- a/pkg/messages/types/svcCreateStringTable.go +++ b/pkg/messages/types/svcCreateStringTable.go @@ -18,12 +18,12 @@ type SvcCreateStringTable struct { StringData int } -func ParseSvcCreateStringTable(reader *bitreader.ReaderType) SvcCreateStringTable { +func ParseSvcCreateStringTable(reader *bitreader.Reader) SvcCreateStringTable { svcCreateStringTable := SvcCreateStringTable{ Name: reader.TryReadString(), MaxEntries: int16(reader.TryReadBits(16)), } - svcCreateStringTable.NumEntries = int8(reader.TryReadBits(int(math.Log2(float64(svcCreateStringTable.MaxEntries))) + 1)) + svcCreateStringTable.NumEntries = int8(reader.TryReadBits(uint64(math.Log2(float64(svcCreateStringTable.MaxEntries))) + 1)) svcCreateStringTable.Length = int32(reader.TryReadBits(20)) svcCreateStringTable.UserDataFixedSize = reader.TryReadBool() if svcCreateStringTable.UserDataFixedSize { @@ -31,6 +31,6 @@ func ParseSvcCreateStringTable(reader *bitreader.ReaderType) SvcCreateStringTabl svcCreateStringTable.UserDataSizeBits = int8(reader.TryReadBits(4)) } svcCreateStringTable.Flags = int8(reader.TryReadBits(2)) - reader.SkipBits(int(svcCreateStringTable.Length)) // TODO: StringTable parsing + reader.SkipBits(uint64(svcCreateStringTable.Length)) // TODO: StringTable parsing return svcCreateStringTable } diff --git a/pkg/messages/types/svcCrosshairAngle.go b/pkg/messages/types/svcCrosshairAngle.go index cf18212..e8424e1 100644 --- a/pkg/messages/types/svcCrosshairAngle.go +++ b/pkg/messages/types/svcCrosshairAngle.go @@ -6,7 +6,7 @@ type SvcCrosshairAngle struct { Angle []int16 } -func ParseSvcCrosshairAngle(reader *bitreader.ReaderType) SvcCrosshairAngle { +func ParseSvcCrosshairAngle(reader *bitreader.Reader) SvcCrosshairAngle { return SvcCrosshairAngle{ Angle: []int16{int16(reader.TryReadBits(16)), int16(reader.TryReadBits(16)), int16(reader.TryReadBits(16))}, } diff --git a/pkg/messages/types/svcEntityMessage.go b/pkg/messages/types/svcEntityMessage.go index 9726ced..8d5c4aa 100644 --- a/pkg/messages/types/svcEntityMessage.go +++ b/pkg/messages/types/svcEntityMessage.go @@ -9,12 +9,12 @@ type SvcEntityMessage struct { Data []byte } -func ParseSvcEntityMessage(reader *bitreader.ReaderType) SvcEntityMessage { +func ParseSvcEntityMessage(reader *bitreader.Reader) SvcEntityMessage { svcEntityMessage := SvcEntityMessage{ EntityIndex: int16(reader.TryReadBits(11)), ClassId: int16(reader.TryReadBits(9)), Length: int16(reader.TryReadBits(11)), } - svcEntityMessage.Data = reader.TryReadBitsToSlice(int(svcEntityMessage.Length)) + svcEntityMessage.Data = reader.TryReadBitsToSlice(uint64(svcEntityMessage.Length)) return svcEntityMessage } diff --git a/pkg/messages/types/svcFixAngle.go b/pkg/messages/types/svcFixAngle.go index 56acf04..675c50e 100644 --- a/pkg/messages/types/svcFixAngle.go +++ b/pkg/messages/types/svcFixAngle.go @@ -7,7 +7,7 @@ type SvcFixAngle struct { Angle []int16 } -func ParseSvcFixAngle(reader *bitreader.ReaderType) SvcFixAngle { +func ParseSvcFixAngle(reader *bitreader.Reader) SvcFixAngle { return SvcFixAngle{ Relative: reader.TryReadBool(), Angle: []int16{int16(reader.TryReadBits(16)), int16(reader.TryReadBits(16)), int16(reader.TryReadBits(16))}, diff --git a/pkg/messages/types/svcGameEvent.go b/pkg/messages/types/svcGameEvent.go index 6ee4d01..44d6dd5 100644 --- a/pkg/messages/types/svcGameEvent.go +++ b/pkg/messages/types/svcGameEvent.go @@ -7,10 +7,10 @@ type SvcGameEvent struct { Data []byte // TODO: GameEvent[] } -func ParseSvcGameEvent(reader *bitreader.ReaderType) SvcGameEvent { +func ParseSvcGameEvent(reader *bitreader.Reader) SvcGameEvent { svcGameEvent := SvcGameEvent{ Length: int16(reader.TryReadBits(11)), } - svcGameEvent.Data = reader.TryReadBitsToSlice(int(svcGameEvent.Length)) + svcGameEvent.Data = reader.TryReadBitsToSlice(uint64(svcGameEvent.Length)) return svcGameEvent } diff --git a/pkg/messages/types/svcGameEventList.go b/pkg/messages/types/svcGameEventList.go index b99ce28..c6eb896 100644 --- a/pkg/messages/types/svcGameEventList.go +++ b/pkg/messages/types/svcGameEventList.go @@ -11,11 +11,11 @@ type SvcGameEventList struct { type gameEventDescriptor struct { } -func ParseSvcGameEventList(reader *bitreader.ReaderType) SvcGameEventList { +func ParseSvcGameEventList(reader *bitreader.Reader) SvcGameEventList { svcGameEventList := SvcGameEventList{ Events: int16(reader.TryReadBits(9)), Length: int32(reader.TryReadBits(20)), } - reader.TryReadBitsToSlice(int(svcGameEventList.Length)) + reader.TryReadBitsToSlice(uint64(svcGameEventList.Length)) return svcGameEventList } diff --git a/pkg/messages/types/svcGetCvarValue.go b/pkg/messages/types/svcGetCvarValue.go index aef5c8e..0598722 100644 --- a/pkg/messages/types/svcGetCvarValue.go +++ b/pkg/messages/types/svcGetCvarValue.go @@ -7,9 +7,9 @@ type SvcGetCvarValue struct { CvarName string } -func ParseSvcGetCvarValue(reader *bitreader.ReaderType) SvcGetCvarValue { +func ParseSvcGetCvarValue(reader *bitreader.Reader) SvcGetCvarValue { svcGetCvarValue := SvcGetCvarValue{ - Cookie: reader.TryReadStringLen(4), + Cookie: reader.TryReadStringLength(4), CvarName: reader.TryReadString(), } return svcGetCvarValue diff --git a/pkg/messages/types/svcMenu.go b/pkg/messages/types/svcMenu.go index d89f52c..9958e99 100644 --- a/pkg/messages/types/svcMenu.go +++ b/pkg/messages/types/svcMenu.go @@ -8,11 +8,11 @@ type SvcMenu struct { Data []byte } -func ParseSvcMenu(reader *bitreader.ReaderType) SvcMenu { +func ParseSvcMenu(reader *bitreader.Reader) SvcMenu { svcMenu := SvcMenu{ MenuType: int16(reader.TryReadBits(16)), Length: int32(reader.TryReadBits(32)), } - svcMenu.Data = reader.TryReadBitsToSlice(int(svcMenu.Length)) + svcMenu.Data = reader.TryReadBitsToSlice(uint64(svcMenu.Length)) return svcMenu } diff --git a/pkg/messages/types/svcPacketEntities.go b/pkg/messages/types/svcPacketEntities.go index b1c23e5..54e4a2a 100644 --- a/pkg/messages/types/svcPacketEntities.go +++ b/pkg/messages/types/svcPacketEntities.go @@ -1,6 +1,8 @@ package messages -import "github.com/pektezol/bitreader" +import ( + "github.com/pektezol/bitreader" +) type SvcPacketEntities struct { MaxEntries int16 @@ -13,18 +15,23 @@ type SvcPacketEntities struct { Data []byte } -func ParseSvcPacketEntities(reader *bitreader.ReaderType) SvcPacketEntities { +func ParseSvcPacketEntities(reader *bitreader.Reader) SvcPacketEntities { svcPacketEntities := SvcPacketEntities{ MaxEntries: int16(reader.TryReadBits(11)), IsDelta: reader.TryReadBool(), } if svcPacketEntities.IsDelta { svcPacketEntities.DeltaFrom = int32(reader.TryReadBits(32)) + } else { + svcPacketEntities.DeltaFrom = -1 } svcPacketEntities.BaseLine = reader.TryReadBool() svcPacketEntities.UpdatedEntries = int16(reader.TryReadBits(11)) svcPacketEntities.Length = int32(reader.TryReadBits(20)) svcPacketEntities.UpdatedBaseline = reader.TryReadBool() - svcPacketEntities.Data = reader.TryReadBitsToSlice(int(svcPacketEntities.Length)) + svcPacketEntities.Data = reader.TryReadBitsToSlice(uint64(svcPacketEntities.Length)) //, dataReader = reader.ForkAndSkip(int(svcPacketEntities.Length)) + // for count := 0; count < int(svcPacketEntities.UpdatedEntries); count++ { + // dataReader.TryReadBool() + // } return svcPacketEntities } diff --git a/pkg/messages/types/svcPaintmapData.go b/pkg/messages/types/svcPaintmapData.go index 6b041da..41ef515 100644 --- a/pkg/messages/types/svcPaintmapData.go +++ b/pkg/messages/types/svcPaintmapData.go @@ -7,10 +7,10 @@ type SvcPaintmapData struct { Data []byte } -func ParseSvcPaintmapData(reader *bitreader.ReaderType) SvcPaintmapData { +func ParseSvcPaintmapData(reader *bitreader.Reader) SvcPaintmapData { svcPaintmapData := SvcPaintmapData{ Length: int32(reader.TryReadBits(32)), } - svcPaintmapData.Data = reader.TryReadBitsToSlice(int(svcPaintmapData.Length)) + svcPaintmapData.Data = reader.TryReadBitsToSlice(uint64(svcPaintmapData.Length)) return svcPaintmapData } diff --git a/pkg/messages/types/svcPrefetch.go b/pkg/messages/types/svcPrefetch.go index 549f926..50d01e9 100644 --- a/pkg/messages/types/svcPrefetch.go +++ b/pkg/messages/types/svcPrefetch.go @@ -6,7 +6,7 @@ type SvcPrefetch struct { SoundIndex int16 } -func ParseSvcPrefetch(reader *bitreader.ReaderType) SvcPrefetch { +func ParseSvcPrefetch(reader *bitreader.Reader) SvcPrefetch { return SvcPrefetch{ SoundIndex: int16(reader.TryReadBits(13)), } diff --git a/pkg/messages/types/svcPrint.go b/pkg/messages/types/svcPrint.go index 8aff927..f31d046 100644 --- a/pkg/messages/types/svcPrint.go +++ b/pkg/messages/types/svcPrint.go @@ -6,7 +6,7 @@ type SvcPrint struct { Message string } -func ParseSvcPrint(reader *bitreader.ReaderType) SvcPrint { +func ParseSvcPrint(reader *bitreader.Reader) SvcPrint { return SvcPrint{ Message: reader.TryReadString(), } diff --git a/pkg/messages/types/svcSendTable.go b/pkg/messages/types/svcSendTable.go index ae8960b..9eb47fc 100644 --- a/pkg/messages/types/svcSendTable.go +++ b/pkg/messages/types/svcSendTable.go @@ -8,7 +8,7 @@ type SvcSendTable struct { Props int32 } -func ParseSvcSendTable(reader *bitreader.ReaderType) SvcSendTable { +func ParseSvcSendTable(reader *bitreader.Reader) SvcSendTable { return SvcSendTable{ NeedsDecoder: int8(reader.TryReadBits(8)), Length: int8(reader.TryReadBits(8)), diff --git a/pkg/messages/types/svcServerInfo.go b/pkg/messages/types/svcServerInfo.go index b8bb308..c699eca 100644 --- a/pkg/messages/types/svcServerInfo.go +++ b/pkg/messages/types/svcServerInfo.go @@ -21,7 +21,7 @@ type SvcServerInfo struct { HostName string } -func ParseSvcServerInfo(reader *bitreader.ReaderType) SvcServerInfo { +func ParseSvcServerInfo(reader *bitreader.Reader) SvcServerInfo { return SvcServerInfo{ Protocol: int16(reader.TryReadBits(16)), ServerCount: int32(reader.TryReadBits(32)), diff --git a/pkg/messages/types/svcSetPause.go b/pkg/messages/types/svcSetPause.go index 94303b7..551a4d3 100644 --- a/pkg/messages/types/svcSetPause.go +++ b/pkg/messages/types/svcSetPause.go @@ -6,7 +6,7 @@ type SvcSetPause struct { Paused bool } -func ParseSvcSetPause(reader *bitreader.ReaderType) SvcSetPause { +func ParseSvcSetPause(reader *bitreader.Reader) SvcSetPause { return SvcSetPause{ Paused: reader.TryReadBool(), } diff --git a/pkg/messages/types/svcSetView.go b/pkg/messages/types/svcSetView.go index 70d1e2b..266a539 100644 --- a/pkg/messages/types/svcSetView.go +++ b/pkg/messages/types/svcSetView.go @@ -6,7 +6,7 @@ type SvcSetView struct { EntityIndex int16 } -func ParseSvcSetView(reader *bitreader.ReaderType) SvcSetView { +func ParseSvcSetView(reader *bitreader.Reader) SvcSetView { return SvcSetView{ EntityIndex: int16(reader.TryReadBits(11)), } diff --git a/pkg/messages/types/svcSounds.go b/pkg/messages/types/svcSounds.go index e87d584..22d4a66 100644 --- a/pkg/messages/types/svcSounds.go +++ b/pkg/messages/types/svcSounds.go @@ -9,7 +9,7 @@ type SvcSounds struct { Data []byte } -func ParseSvcSounds(reader *bitreader.ReaderType) SvcSounds { +func ParseSvcSounds(reader *bitreader.Reader) SvcSounds { svcSounds := SvcSounds{ ReliableSound: reader.TryReadBool(), } @@ -20,6 +20,6 @@ func ParseSvcSounds(reader *bitreader.ReaderType) SvcSounds { svcSounds.Size = int8(reader.TryReadBits(8)) svcSounds.Length = int16(reader.TryReadBits(16)) } - svcSounds.Data = reader.TryReadBitsToSlice(int(svcSounds.Length)) + svcSounds.Data = reader.TryReadBitsToSlice(uint64(svcSounds.Length)) return svcSounds } diff --git a/pkg/messages/types/svcSplitScreen.go b/pkg/messages/types/svcSplitScreen.go index 9c808bc..3ba6ee8 100644 --- a/pkg/messages/types/svcSplitScreen.go +++ b/pkg/messages/types/svcSplitScreen.go @@ -8,11 +8,11 @@ type SvcSplitScreen struct { Data []byte } -func ParseSvcSplitScreen(reader *bitreader.ReaderType) SvcSplitScreen { +func ParseSvcSplitScreen(reader *bitreader.Reader) SvcSplitScreen { svcSplitScreen := SvcSplitScreen{ Unk: reader.TryReadBool(), Length: int16(reader.TryReadBits(11)), } - svcSplitScreen.Data = reader.TryReadBitsToSlice(int(svcSplitScreen.Length)) + svcSplitScreen.Data = reader.TryReadBitsToSlice(uint64(svcSplitScreen.Length)) return svcSplitScreen } diff --git a/pkg/messages/types/svcTempEntities.go b/pkg/messages/types/svcTempEntities.go index d22423d..ca4b995 100644 --- a/pkg/messages/types/svcTempEntities.go +++ b/pkg/messages/types/svcTempEntities.go @@ -8,11 +8,11 @@ type SvcTempEntities struct { Data []byte } -func ParseSvcTempEntities(reader *bitreader.ReaderType) SvcTempEntities { +func ParseSvcTempEntities(reader *bitreader.Reader) SvcTempEntities { svcTempEntities := SvcTempEntities{ NumEntries: int8(reader.TryReadBits(8)), Length: int32(reader.TryReadBits(17)), } - svcTempEntities.Data = reader.TryReadBitsToSlice(int(svcTempEntities.Length)) + svcTempEntities.Data = reader.TryReadBitsToSlice(uint64(svcTempEntities.Length)) return svcTempEntities } diff --git a/pkg/messages/types/svcUpdateStringTable.go b/pkg/messages/types/svcUpdateStringTable.go index 2840482..c606141 100644 --- a/pkg/messages/types/svcUpdateStringTable.go +++ b/pkg/messages/types/svcUpdateStringTable.go @@ -9,7 +9,7 @@ type SvcUpdateStringTable struct { Data []byte } -func ParseSvcUpdateStringTable(reader *bitreader.ReaderType) SvcUpdateStringTable { +func ParseSvcUpdateStringTable(reader *bitreader.Reader) SvcUpdateStringTable { svcUpdateStringTable := SvcUpdateStringTable{ TableId: int8(reader.TryReadBits(5)), } @@ -17,6 +17,6 @@ func ParseSvcUpdateStringTable(reader *bitreader.ReaderType) SvcUpdateStringTabl svcUpdateStringTable.NumChangedEntries = int16(reader.TryReadBits(16)) } svcUpdateStringTable.Length = int32(reader.TryReadBits(20)) - svcUpdateStringTable.Data = reader.TryReadBitsToSlice(int(svcUpdateStringTable.Length)) + svcUpdateStringTable.Data = reader.TryReadBitsToSlice(uint64(svcUpdateStringTable.Length)) return svcUpdateStringTable } diff --git a/pkg/messages/types/svcUserMessage.go b/pkg/messages/types/svcUserMessage.go index b53c7c0..fb8be20 100644 --- a/pkg/messages/types/svcUserMessage.go +++ b/pkg/messages/types/svcUserMessage.go @@ -8,11 +8,11 @@ type SvcUserMessage struct { Data []byte } -func ParseSvcUserMessage(reader *bitreader.ReaderType) SvcUserMessage { +func ParseSvcUserMessage(reader *bitreader.Reader) SvcUserMessage { svcUserMessage := SvcUserMessage{ MsgType: int8(reader.TryReadBits(8)), Length: int16(reader.TryReadBits(12)), } - svcUserMessage.Data = reader.TryReadBitsToSlice(int(svcUserMessage.Length)) + svcUserMessage.Data = reader.TryReadBitsToSlice(uint64(svcUserMessage.Length)) return svcUserMessage } diff --git a/pkg/messages/types/svcVoiceData.go b/pkg/messages/types/svcVoiceData.go index b6c81d4..9609d80 100644 --- a/pkg/messages/types/svcVoiceData.go +++ b/pkg/messages/types/svcVoiceData.go @@ -9,12 +9,12 @@ type SvcVoiceData struct { Data []byte } -func ParseSvcVoiceData(reader *bitreader.ReaderType) SvcVoiceData { +func ParseSvcVoiceData(reader *bitreader.Reader) SvcVoiceData { svcVoiceData := SvcVoiceData{ Client: int8(reader.TryReadBits(8)), Proximity: int8(reader.TryReadBits(8)), Length: int16(reader.TryReadBits(16)), } - svcVoiceData.Data = reader.TryReadBitsToSlice(int(svcVoiceData.Length)) + svcVoiceData.Data = reader.TryReadBitsToSlice(uint64(svcVoiceData.Length)) return svcVoiceData } diff --git a/pkg/messages/types/svcVoiceInit.go b/pkg/messages/types/svcVoiceInit.go index 4c95aab..afabfc9 100644 --- a/pkg/messages/types/svcVoiceInit.go +++ b/pkg/messages/types/svcVoiceInit.go @@ -8,7 +8,7 @@ type SvcVoiceInit struct { Unk float32 } -func ParseSvcVoiceInit(reader *bitreader.ReaderType) SvcVoiceInit { +func ParseSvcVoiceInit(reader *bitreader.Reader) SvcVoiceInit { svcVoiceInit := SvcVoiceInit{ Codec: reader.TryReadString(), Quality: uint8(reader.TryReadBits(8)), diff --git a/pkg/packets/headers.go b/pkg/packets/headers.go index 543476b..dbeab87 100644 --- a/pkg/packets/headers.go +++ b/pkg/packets/headers.go @@ -20,19 +20,19 @@ type Headers struct { SignOnLength int32 } -func ParseHeaders(reader *bitreader.ReaderType) Headers { +func ParseHeaders(reader *bitreader.Reader) Headers { headers := Headers{ DemoFileStamp: reader.TryReadString(), - DemoProtocol: int32(reader.TryReadInt32()), - NetworkProtocol: int32(reader.TryReadInt32()), - ServerName: reader.TryReadStringLen(260), - ClientName: reader.TryReadStringLen(260), - MapName: reader.TryReadStringLen(260), - GameDirectory: reader.TryReadStringLen(260), + DemoProtocol: int32(reader.TryReadSInt32()), + NetworkProtocol: int32(reader.TryReadSInt32()), + ServerName: reader.TryReadStringLength(260), + ClientName: reader.TryReadStringLength(260), + MapName: reader.TryReadStringLength(260), + GameDirectory: reader.TryReadStringLength(260), PlaybackTime: reader.TryReadFloat32(), - PlaybackTicks: int32(reader.TryReadInt32()), - PlaybackFrames: int32(reader.TryReadInt32()), - SignOnLength: int32(reader.TryReadInt32()), + PlaybackTicks: int32(reader.TryReadSInt32()), + PlaybackFrames: int32(reader.TryReadSInt32()), + SignOnLength: int32(reader.TryReadSInt32()), } if headers.DemoFileStamp != "HL2DEMO" { panic("invalid demo file stamp") diff --git a/pkg/packets/packets.go b/pkg/packets/packets.go index a84da21..fd5a14b 100644 --- a/pkg/packets/packets.go +++ b/pkg/packets/packets.go @@ -1,8 +1,6 @@ package packets import ( - "bytes" - "github.com/pektezol/bitreader" "github.com/pektezol/demoparser/pkg/classes" "github.com/pektezol/demoparser/pkg/messages" @@ -15,9 +13,9 @@ type PacketMessageInfo struct { Data any } -const MSSC = 2 +const MSSC int = 2 -func ParsePackets(reader *bitreader.ReaderType) PacketMessageInfo { +func ParsePackets(reader *bitreader.Reader) PacketMessageInfo { packetType := reader.TryReadBits(8) tickNumber := reader.TryReadBits(32) slotNumber := reader.TryReadBits(8) @@ -30,9 +28,9 @@ func ParsePackets(reader *bitreader.ReaderType) PacketMessageInfo { } signOn.InSequence = int32(reader.TryReadBits(32)) signOn.OutSequence = int32(reader.TryReadBits(32)) - signOn.Size = int32(reader.TryReadInt32()) - data := reader.TryReadBytesToSlice(int(signOn.Size)) - packetReader := bitreader.Reader(bytes.NewReader(data), true) + signOn.Size = int32(reader.TryReadSInt32()) + data := reader.TryReadBytesToSlice(uint64(signOn.Size)) + packetReader := bitreader.NewReaderFromBytes(data, true) for { messageType, err := packetReader.ReadBits(6) if err != nil { @@ -48,9 +46,9 @@ func ParsePackets(reader *bitreader.ReaderType) PacketMessageInfo { } packet.InSequence = int32(reader.TryReadBits(32)) packet.OutSequence = int32(reader.TryReadBits(32)) - packet.Size = int32(reader.TryReadInt32()) - data := reader.TryReadBytesToSlice(int(packet.Size)) - packetReader := bitreader.Reader(bytes.NewReader(data), true) + packet.Size = int32(reader.TryReadSInt32()) + data := reader.TryReadBytesToSlice(uint64(packet.Size)) + packetReader := bitreader.NewReaderFromBytes(data, true) for { messageType, err := packetReader.ReadBits(6) if err != nil { @@ -63,24 +61,24 @@ func ParsePackets(reader *bitreader.ReaderType) PacketMessageInfo { syncTick := SyncTick{} packetData = syncTick case 4: // ConsoleCmd - size := reader.TryReadInt32() + size := reader.TryReadSInt32() consoleCmd := ConsoleCmd{ Size: int32(size), - Data: reader.TryReadStringLen(int(size)), + Data: reader.TryReadStringLength(uint64(size)), } packetData = consoleCmd case 5: // UserCmd userCmd := UserCmd{} - userCmd.Cmd = int32(reader.TryReadInt32()) - userCmd.Size = int32(reader.TryReadInt32()) - data := reader.TryReadBytesToSlice(int(userCmd.Size)) + userCmd.Cmd = int32(reader.TryReadSInt32()) + userCmd.Size = int32(reader.TryReadSInt32()) + data := reader.TryReadBytesToSlice(uint64(userCmd.Size)) userCmd.Data = classes.ParseUserCmdInfo(data) packetData = userCmd case 6: // DataTables dataTables := DataTables{} - dataTables.Size = int32(reader.TryReadInt32()) - data := reader.TryReadBytesToSlice(int(dataTables.Size)) - dataTableReader := bitreader.Reader(bytes.NewReader(data), true) + dataTables.Size = int32(reader.TryReadSInt32()) + data := reader.TryReadBytesToSlice(uint64(dataTables.Size)) + dataTableReader := bitreader.NewReaderFromBytes(data, true) count := 0 for dataTableReader.TryReadBool() { count++ @@ -94,8 +92,7 @@ func ParsePackets(reader *bitreader.ReaderType) PacketMessageInfo { case 7: // Stop stop := Stop{} if reader.TryReadBool() { - // read remaining data - stop.RemainingData = []byte{} + stop.RemainingData = reader.TryReadBitsToSlice(uint64(reader.TryReadRemainingBits())) } packetData = stop case 8: // CustomData @@ -103,14 +100,24 @@ func ParsePackets(reader *bitreader.ReaderType) PacketMessageInfo { Unknown: int32(reader.TryReadBits(32)), Size: int32(reader.TryReadBits(32)), } - customData.Data = string(reader.TryReadBytesToSlice(int(customData.Size))) - packetData = customData + if customData.Unknown != 0 || customData.Size == 8 { + // Not SAR data + customData.Data = string(reader.TryReadBytesToSlice(uint64(customData.Size))) + packetData = customData + break + } + // SAR data + sarData := classes.SarData{} + data := reader.TryReadBytesToSlice(uint64(customData.Size)) + sarReader := bitreader.NewReaderFromBytes(data, true) + sarData.ParseSarData(sarReader) + packetData = sarData case 9: // StringTables stringTables := StringTables{ - Size: int32(reader.TryReadInt32()), + Size: int32(reader.TryReadSInt32()), } - data := reader.TryReadBytesToSlice(int(stringTables.Size)) - stringTableReader := bitreader.Reader(bytes.NewReader(data), true) + data := reader.TryReadBytesToSlice(uint64(stringTables.Size)) + stringTableReader := bitreader.NewReaderFromBytes(data, true) stringTables.Data = classes.ParseStringTables(stringTableReader) packetData = stringTables default: // invalid -- cgit v1.2.3