From 77e4b066cb8d506b4bc944ab4eb2d6e4679e2202 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Sat, 15 Jun 2024 13:58:30 +0300 Subject: enable multithreading with goroutines (#20) --- pkg/classes/consoleCmd.go | 10 +- pkg/classes/customData.go | 19 +- pkg/classes/dataTables.go | 74 ++--- pkg/classes/packet.go | 50 +-- pkg/classes/sarData.go | 196 ++++++------ pkg/classes/signOn.go | 36 +-- pkg/classes/stop.go | 8 +- pkg/classes/stringTables.go | 128 ++++---- pkg/classes/userCmd.go | 58 ++-- pkg/messages/messages.go | 76 ++--- pkg/messages/types/netDisconnect.go | 8 +- pkg/messages/types/netFile.go | 16 +- pkg/messages/types/netNop.go | 6 +- pkg/messages/types/netSetConVar.go | 16 +- pkg/messages/types/netSignOnState.go | 28 +- pkg/messages/types/netSplitScreenUser.go | 8 +- pkg/messages/types/netStringCmd.go | 8 +- pkg/messages/types/netTick.go | 16 +- pkg/messages/types/svcBspDecal.go | 28 +- pkg/messages/types/svcClassInfo.go | 24 +- pkg/messages/types/svcCmdKeyValues.go | 10 +- pkg/messages/types/svcCreateStringTable.go | 36 +-- pkg/messages/types/svcCrosshairAngle.go | 18 +- pkg/messages/types/svcEntityMessage.go | 18 +- pkg/messages/types/svcFixAngle.go | 22 +- pkg/messages/types/svcGameEvent.go | 40 +-- pkg/messages/types/svcGameEventList.go | 89 +----- pkg/messages/types/svcGetCvarValue.go | 12 +- pkg/messages/types/svcMenu.go | 14 +- pkg/messages/types/svcPacketEntities.go | 34 +- pkg/messages/types/svcPaintmapData.go | 10 +- pkg/messages/types/svcPrefetch.go | 8 +- pkg/messages/types/svcPrint.go | 8 +- pkg/messages/types/svcSendTable.go | 16 +- pkg/messages/types/svcServerInfo.go | 68 ++-- pkg/messages/types/svcSetPause.go | 8 +- pkg/messages/types/svcSetView.go | 8 +- pkg/messages/types/svcSounds.go | 18 +- pkg/messages/types/svcSplitScreen.go | 14 +- pkg/messages/types/svcTempEntities.go | 14 +- pkg/messages/types/svcUpdateStringTable.go | 16 +- pkg/messages/types/svcUserMessage.go | 495 +++++++++++++++-------------- pkg/messages/types/svcVoiceData.go | 18 +- pkg/messages/types/svcVoiceInit.go | 16 +- pkg/packets/headers.go | 42 +-- pkg/packets/packets.go | 89 ++---- pkg/types/gameevent.go | 80 +++++ pkg/types/types.go | 71 +++++ pkg/writer/writer.go | 50 +-- 49 files changed, 1098 insertions(+), 1057 deletions(-) create mode 100644 pkg/types/gameevent.go create mode 100644 pkg/types/types.go (limited to 'pkg') diff --git a/pkg/classes/consoleCmd.go b/pkg/classes/consoleCmd.go index 47a44e0..83f7333 100644 --- a/pkg/classes/consoleCmd.go +++ b/pkg/classes/consoleCmd.go @@ -4,16 +4,16 @@ import ( "strings" "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type ConsoleCmd struct { - Size int32 - Data string + Size int32 `json:"size"` + Data string `json:"data"` } -func (consoleCmd *ConsoleCmd) ParseConsoleCmd(reader *bitreader.Reader) { +func (consoleCmd *ConsoleCmd) ParseConsoleCmd(reader *bitreader.Reader, demo *types.Demo) { consoleCmd.Size = reader.TryReadSInt32() consoleCmd.Data = reader.TryReadStringLength(uint64(consoleCmd.Size)) - writer.AppendLine("\t%s", strings.TrimSpace(consoleCmd.Data)) + demo.Writer.AppendLine("\t%s", strings.TrimSpace(consoleCmd.Data)) } diff --git a/pkg/classes/customData.go b/pkg/classes/customData.go index 1d6f30a..4c1a79e 100644 --- a/pkg/classes/customData.go +++ b/pkg/classes/customData.go @@ -2,29 +2,30 @@ package classes import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type CustomData struct { - Type int32 - Size int32 - Data string + Type int32 `json:"type"` + Size int32 `json:"size"` + Data any `json:"data"` } -func (customData *CustomData) ParseCustomData(reader *bitreader.Reader, tickNumber int32, packetType uint8) { +func (customData *CustomData) ParseCustomData(reader *bitreader.Reader, tickNumber int32, packetType uint8, demo *types.Demo) { customData.Type = reader.TryReadSInt32() customData.Size = reader.TryReadSInt32() if customData.Type != 0 || customData.Size == 8 { // Not SAR data - writer.AppendLine("[%d] %s (%d):", tickNumber, "CUSTOMDATA", packetType) + demo.Writer.AppendLine("[%d] %s (%d):", tickNumber, "CUSTOMDATA", packetType) customData.Data = string(reader.TryReadBytesToSlice(uint64(customData.Size))) - writer.AppendLine("\t%s", customData.Data) + demo.Writer.AppendLine("\t%s", customData.Data) return } // SAR data - writer.AppendLine("[%d] %s (%d):", tickNumber, "SARDATA", packetType) + demo.Writer.AppendLine("[%d] %s (%d):", tickNumber, "SARDATA", packetType) sarData := SarData{} data := reader.TryReadBytesToSlice(uint64(customData.Size)) sarReader := bitreader.NewReaderFromBytes(data, true) - sarData.ParseSarData(sarReader) + sarData.ParseSarData(sarReader, demo) + customData.Data = sarData } diff --git a/pkg/classes/dataTables.go b/pkg/classes/dataTables.go index 50be8fe..cf3762a 100644 --- a/pkg/classes/dataTables.go +++ b/pkg/classes/dataTables.go @@ -4,59 +4,59 @@ import ( "fmt" "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type DataTables struct { - Size int32 - SendTable []SendTable - ServerClassInfo []ServerClassInfo + Size int32 `json:"size"` + SendTable []SendTable `json:"send_table"` + ServerClassInfo []ServerClassInfo `json:"server_class_info"` } type SendTable struct { - NeedsDecoder bool - NetTableName string - NumOfProps int16 - Props []SendTableProp + NeedsDecoder bool `json:"needs_decoder"` + NetTableName string `json:"net_table_name"` + NumOfProps int16 `json:"num_of_props"` + Props []SendTableProp `json:"props"` } type ServerClassInfo struct { - DataTableID uint16 - ClassName string - DataTableName string + DataTableID uint16 `json:"data_table_id"` + ClassName string `json:"class_name"` + DataTableName string `json:"data_table_name"` } type SendTableProp struct { - SendPropType SendPropType - SendPropName string - SendPropFlags uint32 - Priority uint8 - ExcludeDtName string - LowValue float32 - HighValue float32 - NumBits int32 - NumElements int32 + SendPropType SendPropType `json:"send_prop_type"` + SendPropName string `json:"send_prop_name"` + SendPropFlags uint32 `json:"send_prop_flags"` + Priority uint8 `json:"priority"` + ExcludeDtName string `json:"exclude_dt_name"` + LowValue float32 `json:"low_value"` + HighValue float32 `json:"high_value"` + NumBits int32 `json:"num_bits"` + NumElements int32 `json:"num_elements"` } -func (dataTables *DataTables) ParseDataTables(reader *bitreader.Reader) { +func (dataTables *DataTables) ParseDataTables(reader *bitreader.Reader, demo *types.Demo) { dataTables.Size = int32(reader.TryReadSInt32()) dataTableReader := bitreader.NewReaderFromBytes(reader.TryReadBytesToSlice(uint64(dataTables.Size)), true) count := 0 for dataTableReader.TryReadBool() { count++ - dataTables.SendTable = append(dataTables.SendTable, ParseSendTable(dataTableReader)) + dataTables.SendTable = append(dataTables.SendTable, ParseSendTable(dataTableReader, demo)) } - writer.AppendLine("\t%d Send Tables:", count) - writer.AppendOutputFromTemp() + demo.Writer.AppendLine("\t%d Send Tables:", count) + demo.Writer.AppendOutputFromTemp() numOfClasses := dataTableReader.TryReadBits(16) for count = 0; count < int(numOfClasses); count++ { - dataTables.ServerClassInfo = append(dataTables.ServerClassInfo, ParseServerClassInfo(dataTableReader, count, int(numOfClasses))) + dataTables.ServerClassInfo = append(dataTables.ServerClassInfo, ParseServerClassInfo(dataTableReader, count, int(numOfClasses), demo)) } - writer.AppendLine("\t%d Classes:", count) - writer.AppendOutputFromTemp() + demo.Writer.AppendLine("\t%d Classes:", count) + demo.Writer.AppendOutputFromTemp() } -func ParseSendTable(reader *bitreader.Reader) SendTable { +func ParseSendTable(reader *bitreader.Reader, demo *types.Demo) SendTable { sendTable := SendTable{ NeedsDecoder: reader.TryReadBool(), NetTableName: reader.TryReadString(), @@ -65,7 +65,7 @@ func ParseSendTable(reader *bitreader.Reader) SendTable { if sendTable.NumOfProps < 0 { return sendTable } - writer.TempAppendLine("\t\t%s (%d Props):", sendTable.NetTableName, sendTable.NumOfProps) + demo.Writer.TempAppendLine("\t\t%s (%d Props):", sendTable.NetTableName, sendTable.NumOfProps) for count := 0; count < int(sendTable.NumOfProps); count++ { propType := int8(reader.TryReadBits(5)) if propType >= int8(7) { @@ -77,38 +77,38 @@ func ParseSendTable(reader *bitreader.Reader) SendTable { SendPropFlags: uint32(reader.TryReadBits(19)), Priority: reader.TryReadUInt8(), } - writer.TempAppend("\t\t\t%s\t", prop.SendPropType) + demo.Writer.TempAppend("\t\t\t%s\t", prop.SendPropType) if propType == int8(ESendPropTypeDataTable) || checkBit(prop.SendPropFlags, 6) { prop.ExcludeDtName = reader.TryReadString() - writer.TempAppend(":\t%s\t", prop.ExcludeDtName) + demo.Writer.TempAppend(":\t%s\t", prop.ExcludeDtName) } else { switch propType { case int8(ESendPropTypeString), int8(ESendPropTypeInt), int8(ESendPropTypeFloat), int8(ESendPropTypeVector3), int8(ESendPropTypeVector2): prop.LowValue = reader.TryReadFloat32() prop.HighValue = reader.TryReadFloat32() prop.NumBits = int32(reader.TryReadBits(7)) - writer.TempAppend("Low: %f\tHigh: %f\t%d bits\t", prop.LowValue, prop.HighValue, prop.NumBits) + demo.Writer.TempAppend("Low: %f\tHigh: %f\t%d bits\t", prop.LowValue, prop.HighValue, prop.NumBits) case int8(ESendPropTypeArray): prop.NumElements = int32(reader.TryReadBits(10)) - writer.TempAppend("Elements: %d\t", prop.NumElements) + demo.Writer.TempAppend("Elements: %d\t", prop.NumElements) default: - writer.TempAppend("Unknown Prop Type: %v\t", propType) + demo.Writer.TempAppend("Unknown Prop Type: %v\t", propType) return sendTable } } - writer.TempAppend("Flags: %v\tPriority: %d\n", prop.GetFlags(), prop.Priority) + demo.Writer.TempAppend("Flags: %v\tPriority: %d\n", prop.GetFlags(), prop.Priority) sendTable.Props = append(sendTable.Props, prop) } return sendTable } -func ParseServerClassInfo(reader *bitreader.Reader, count int, numOfClasses int) ServerClassInfo { +func ParseServerClassInfo(reader *bitreader.Reader, count int, numOfClasses int, demo *types.Demo) ServerClassInfo { serverClassInfo := ServerClassInfo{ DataTableID: reader.TryReadUInt16(), ClassName: reader.TryReadString(), DataTableName: reader.TryReadString(), } - writer.TempAppendLine("\t\t\t[%d] %s (%s)", serverClassInfo.DataTableID, serverClassInfo.ClassName, serverClassInfo.DataTableName) + demo.Writer.TempAppendLine("\t\t\t[%d] %s (%s)", serverClassInfo.DataTableID, serverClassInfo.ClassName, serverClassInfo.DataTableName) return serverClassInfo } diff --git a/pkg/classes/packet.go b/pkg/classes/packet.go index 445ae91..c4f9676 100644 --- a/pkg/classes/packet.go +++ b/pkg/classes/packet.go @@ -5,32 +5,32 @@ import ( "github.com/pektezol/bitreader" "github.com/pektezol/sdp.go/pkg/messages" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) const MSSC int = 2 type Packet struct { - PacketInfo []CmdInfo - InSequence uint32 - OutSequence uint32 - Size uint32 - Data []any + PacketInfo []CmdInfo `json:"packet_info"` + InSequence uint32 `json:"in_sequence"` + OutSequence uint32 `json:"out_sequence"` + Size uint32 `json:"size"` + Data []any `json:"data"` } type CmdInfo struct { - Flags uint32 - ViewOrigin []float32 - ViewAngles []float32 - LocalViewAngles []float32 - ViewOrigin2 []float32 - ViewAngles2 []float32 - LocalViewAngles2 []float32 + Flags uint32 `json:"flags"` + ViewOrigin []float32 `json:"view_origin"` + ViewAngles []float32 `json:"view_angles"` + LocalViewAngles []float32 `json:"local_view_angles"` + ViewOrigin2 []float32 `json:"view_origin_2"` + ViewAngles2 []float32 `json:"view_angles_2"` + LocalViewAngles2 []float32 `json:"local_view_angles_2"` } -func (packet *Packet) ParsePacket(reader *bitreader.Reader) { +func (packet *Packet) ParsePacket(reader *bitreader.Reader, demo *types.Demo) { for count := 0; count < MSSC; count++ { - packet.ParseCmdInfo(reader) + packet.ParseCmdInfo(reader, demo) } packet.InSequence = reader.TryReadUInt32() packet.OutSequence = reader.TryReadUInt32() @@ -41,11 +41,11 @@ func (packet *Packet) ParsePacket(reader *bitreader.Reader) { if err != nil { break } - packet.Data = append(packet.Data, messages.ParseMessages(messageType, packetReader)) + packet.Data = append(packet.Data, messages.ParseMessages(messageType, packetReader, demo)) } } -func (packet *Packet) ParseCmdInfo(reader *bitreader.Reader) { +func (packet *Packet) ParseCmdInfo(reader *bitreader.Reader, demo *types.Demo) { packet.PacketInfo = append(packet.PacketInfo, CmdInfo{ Flags: reader.TryReadUInt32(), ViewOrigin: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, @@ -55,14 +55,14 @@ func (packet *Packet) ParseCmdInfo(reader *bitreader.Reader) { ViewAngles2: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, LocalViewAngles2: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, }) - writer.AppendLine("\tFlags: %s", CmdInfoFlags(packet.PacketInfo[len(packet.PacketInfo)-1].Flags).String()) - writer.AppendLine("\tView Origin: %v", packet.PacketInfo[len(packet.PacketInfo)-1].ViewOrigin) - writer.AppendLine("\tView Angles: %v", packet.PacketInfo[len(packet.PacketInfo)-1].ViewAngles) - writer.AppendLine("\tLocal View Angles: %v", packet.PacketInfo[len(packet.PacketInfo)-1].LocalViewAngles) - writer.AppendLine("\tView Origin 2: %v", packet.PacketInfo[len(packet.PacketInfo)-1].ViewOrigin2) - writer.AppendLine("\tView Angles 2: %v", packet.PacketInfo[len(packet.PacketInfo)-1].ViewAngles2) - writer.AppendLine("\tLocal View Angles 2: %v", packet.PacketInfo[len(packet.PacketInfo)-1].LocalViewAngles2) - writer.AppendLine("") + demo.Writer.AppendLine("\tFlags: %s", CmdInfoFlags(packet.PacketInfo[len(packet.PacketInfo)-1].Flags).String()) + demo.Writer.AppendLine("\tView Origin: %v", packet.PacketInfo[len(packet.PacketInfo)-1].ViewOrigin) + demo.Writer.AppendLine("\tView Angles: %v", packet.PacketInfo[len(packet.PacketInfo)-1].ViewAngles) + demo.Writer.AppendLine("\tLocal View Angles: %v", packet.PacketInfo[len(packet.PacketInfo)-1].LocalViewAngles) + demo.Writer.AppendLine("\tView Origin 2: %v", packet.PacketInfo[len(packet.PacketInfo)-1].ViewOrigin2) + demo.Writer.AppendLine("\tView Angles 2: %v", packet.PacketInfo[len(packet.PacketInfo)-1].ViewAngles2) + demo.Writer.AppendLine("\tLocal View Angles 2: %v", packet.PacketInfo[len(packet.PacketInfo)-1].LocalViewAngles2) + demo.Writer.AppendLine("") } type CmdInfoFlags int diff --git a/pkg/classes/sarData.go b/pkg/classes/sarData.go index 4a5bfed..ec2830e 100644 --- a/pkg/classes/sarData.go +++ b/pkg/classes/sarData.go @@ -5,7 +5,7 @@ import ( "fmt" "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SarDataType uint8 @@ -69,89 +69,89 @@ func (sarDataType SarDataType) String() string { } type SarData struct { - Type SarDataType - Slot int - Data any + Type SarDataType `json:"type"` + Slot int `json:"slot"` + Data any `json:"data"` } type SarDataTimescaleCheat struct { - Timescale float32 + Timescale float32 `json:"timescale"` } type SarDataInitialCVar struct { - CVar string - Val string + CVar string `json:"cvar"` + Val string `json:"val"` } type SarDataChecksum struct { - DemoSum uint32 - SarSum uint32 + DemoSum uint32 `json:"demo_sum"` + SarSum uint32 `json:"sar_sum"` } type SarDataChecksumV2 struct { - SarSum uint32 - Signature [64]byte + SarSum uint32 `json:"sar_sum"` + Signature [64]byte `json:"signature"` } type SarDataEntityInput struct { - TargetName string - ClassName string - InputName string - Parameter string + TargetName string `json:"target_name"` + ClassName string `json:"class_name"` + InputName string `json:"input_name"` + Parameter string `json:"parameter"` } type SarDataPortalPlacement struct { - Orange bool - X float32 - Y float32 - Z float32 + Orange bool `json:"orange"` + X float32 `json:"x"` + Y float32 `json:"y"` + Z float32 `json:"z"` } type SarDataPause struct { - PauseTicks uint32 + PauseTicks uint32 `json:"pause_ticks"` } type SarDataWaitRun struct { - Ticks int - Cmd string + Ticks int `json:"ticks"` + Cmd string `json:"cmd"` } type SarDataHWaitRun struct { - Ticks int - Cmd string + Ticks int `json:"ticks"` + Cmd string `json:"cmd"` } type SarDataSpeedrunTime struct { - NSplits uint32 - Splits []SarDataSpeedrunTimeSplits + NSplits uint32 `json:"n_splits"` + Splits []SarDataSpeedrunTimeSplits `json:"splits"` } type SarDataSpeedrunTimeSegs struct { - Name string - Ticks uint32 + Name string `json:"name"` + Ticks uint32 `json:"ticks"` } type SarDataSpeedrunTimeSplits struct { - Name string - NSegs uint32 - Segs []SarDataSpeedrunTimeSegs + Name string `json:"name"` + NSegs uint32 `json:"n_segs"` + Segs []SarDataSpeedrunTimeSegs `json:"segs"` } type SarDataTimestamp struct { - Year uint16 - Month uint8 - Day uint8 - Hour uint8 - Minute uint8 - Second uint8 + Year uint16 `json:"year"` + Month uint8 `json:"month"` + Day uint8 `json:"day"` + Hour uint8 `json:"hour"` + Minute uint8 `json:"minute"` + Second uint8 `json:"second"` } type SarDataFileChecksum struct { - Sum uint32 - Path string + Sum uint32 `json:"sum"` + Path string `json:"path"` } -func (sarData *SarData) ParseSarData(reader *bitreader.Reader) (err error) { +func (sarData *SarData) ParseSarData(reader *bitreader.Reader, demo *types.Demo) (err error) { reader.SkipBytes(8) len := reader.TryReadRemainingBits() / 8 if len == 0 { @@ -164,32 +164,32 @@ func (sarData *SarData) ParseSarData(reader *bitreader.Reader) (err error) { len = 9 } dataReader := bitreader.NewReaderFromBytes(reader.TryReadBytesToSlice(len-1), true) - writer.AppendLine("\tMessage: %s (%d):", sarData.Type.String(), sarData.Type) + demo.Writer.AppendLine("\tMessage: %s (%d):", sarData.Type.String(), sarData.Type) switch sarData.Type { case ESarDataTimescaleCheat: - sarData.Data, err = parseTimescaleCheatData(dataReader, len) + sarData.Data, err = parseTimescaleCheatData(dataReader, len, demo) if err != nil { sarData.Data = nil } case ESarDataInitialCVar: - sarData.Data = parseInitialCVarData(dataReader) + sarData.Data = parseInitialCVarData(dataReader, demo) case ESarDataEntityInputSlot: sarData.Slot = int(dataReader.TryReadBytes(1)) - writer.AppendLine("\t\tSlot: %d", sarData.Slot) + demo.Writer.AppendLine("\t\tSlot: %d", sarData.Slot) case ESarDataEntityInput: - sarData.Data = parseEntityInputData(dataReader) + sarData.Data = parseEntityInputData(dataReader, demo) case ESarDataChecksum: - sarData.Data, err = parseChecksumData(dataReader, len) + sarData.Data, err = parseChecksumData(dataReader, len, demo) if err != nil { sarData.Data = nil } case ESarDataChecksumV2: - sarData.Data, err = parseChecksumV2Data(dataReader, len) + sarData.Data, err = parseChecksumV2Data(dataReader, len, demo) if err != nil { sarData.Data = nil } case ESarDataPortalPlacement: - data, slot, err := parsePortalPlacementData(dataReader, len) + data, slot, err := parsePortalPlacementData(dataReader, len, demo) if err != nil { sarData.Data = nil } else { @@ -201,34 +201,34 @@ func (sarData *SarData) ParseSarData(reader *bitreader.Reader) (err error) { if err != nil { sarData.Data = nil } - writer.AppendLine("\t\tSlot: %d", sarData.Slot) + demo.Writer.AppendLine("\t\tSlot: %d", sarData.Slot) case ESarDataPause: - sarData.Data, err = parsePauseData(dataReader, len) + sarData.Data, err = parsePauseData(dataReader, len, demo) if err != nil { sarData.Data = nil } case ESarDataWaitRun: - sarData.Data, err = parseWaitRunData(dataReader, len) + sarData.Data, err = parseWaitRunData(dataReader, len, demo) if err != nil { sarData.Data = nil } case ESarDataHWaitRun: - sarData.Data, err = parseHWaitRunData(dataReader, len) + sarData.Data, err = parseHWaitRunData(dataReader, len, demo) if err != nil { sarData.Data = nil } case ESarDataSpeedrunTime: - sarData.Data, err = parseSpeedrunTimeData(dataReader, len) + sarData.Data, err = parseSpeedrunTimeData(dataReader, len, demo) if err != nil { sarData.Data = nil } case ESarDataTimestamp: - sarData.Data, err = parseTimestampData(dataReader, len) + sarData.Data, err = parseTimestampData(dataReader, len, demo) if err != nil { sarData.Data = nil } case ESarDataFileChecksum: - sarData.Data, err = parseFileChecksumData(dataReader, len) + sarData.Data, err = parseFileChecksumData(dataReader, len, demo) if err != nil { sarData.Data = nil } @@ -239,41 +239,41 @@ func (sarData *SarData) ParseSarData(reader *bitreader.Reader) (err error) { return nil } -func parseTimescaleCheatData(reader *bitreader.Reader, length uint64) (SarDataTimescaleCheat, error) { +func parseTimescaleCheatData(reader *bitreader.Reader, length uint64, demo *types.Demo) (SarDataTimescaleCheat, error) { if length != 5 { return SarDataTimescaleCheat{}, errors.New("sar data invalid") } sarDataTimescaleCheat := SarDataTimescaleCheat{ Timescale: reader.TryReadFloat32(), } - writer.AppendLine("\t\tTimescale: %f", sarDataTimescaleCheat.Timescale) + demo.Writer.AppendLine("\t\tTimescale: %f", sarDataTimescaleCheat.Timescale) return sarDataTimescaleCheat, nil } -func parseInitialCVarData(reader *bitreader.Reader) SarDataInitialCVar { +func parseInitialCVarData(reader *bitreader.Reader, demo *types.Demo) SarDataInitialCVar { sarDataInitialCvar := SarDataInitialCVar{ CVar: reader.TryReadString(), Val: reader.TryReadString(), } - writer.AppendLine("\t\tCvar: \"%s\" = \"%s\"", sarDataInitialCvar.CVar, sarDataInitialCvar.Val) + demo.Writer.AppendLine("\t\tCvar: \"%s\" = \"%s\"", sarDataInitialCvar.CVar, sarDataInitialCvar.Val) return sarDataInitialCvar } -func parseEntityInputData(reader *bitreader.Reader) SarDataEntityInput { +func parseEntityInputData(reader *bitreader.Reader, demo *types.Demo) SarDataEntityInput { sarDataEntityInput := SarDataEntityInput{ TargetName: reader.TryReadString(), ClassName: reader.TryReadString(), InputName: reader.TryReadString(), Parameter: reader.TryReadString(), } - writer.AppendLine("\t\tTarget: %s", sarDataEntityInput.TargetName) - writer.AppendLine("\t\tClass: %s", sarDataEntityInput.ClassName) - writer.AppendLine("\t\tInput: %s", sarDataEntityInput.InputName) - writer.AppendLine("\t\tParameter: %s", sarDataEntityInput.Parameter) + demo.Writer.AppendLine("\t\tTarget: %s", sarDataEntityInput.TargetName) + demo.Writer.AppendLine("\t\tClass: %s", sarDataEntityInput.ClassName) + demo.Writer.AppendLine("\t\tInput: %s", sarDataEntityInput.InputName) + demo.Writer.AppendLine("\t\tParameter: %s", sarDataEntityInput.Parameter) return sarDataEntityInput } -func parseChecksumData(reader *bitreader.Reader, length uint64) (SarDataChecksum, error) { +func parseChecksumData(reader *bitreader.Reader, length uint64, demo *types.Demo) (SarDataChecksum, error) { if length != 9 { return SarDataChecksum{}, errors.New("sar data invalid") } @@ -281,12 +281,12 @@ func parseChecksumData(reader *bitreader.Reader, length uint64) (SarDataChecksum DemoSum: reader.TryReadUInt32(), SarSum: reader.TryReadUInt32(), } - writer.AppendLine("\t\tDemo Checksum: %d", sarDataChecksum.DemoSum) - writer.AppendLine("\t\tSAR Checksum: %d", sarDataChecksum.SarSum) + demo.Writer.AppendLine("\t\tDemo Checksum: %d", sarDataChecksum.DemoSum) + demo.Writer.AppendLine("\t\tSAR Checksum: %d", sarDataChecksum.SarSum) return sarDataChecksum, nil } -func parseChecksumV2Data(reader *bitreader.Reader, length uint64) (SarDataChecksumV2, error) { +func parseChecksumV2Data(reader *bitreader.Reader, length uint64, demo *types.Demo) (SarDataChecksumV2, error) { if length != 69 { return SarDataChecksumV2{}, errors.New("sar data invalid") } @@ -294,12 +294,12 @@ func parseChecksumV2Data(reader *bitreader.Reader, length uint64) (SarDataChecks SarSum: reader.TryReadUInt32(), Signature: [64]byte(reader.TryReadBytesToSlice(60)), } - writer.AppendLine("\t\tSAR Checksum: %d", sarDataChecksumV2.SarSum) - writer.AppendLine("\t\tSignature: %v", sarDataChecksumV2.Signature) + demo.Writer.AppendLine("\t\tSAR Checksum: %d", sarDataChecksumV2.SarSum) + demo.Writer.AppendLine("\t\tSignature: %v", sarDataChecksumV2.Signature) return sarDataChecksumV2, nil } -func parsePortalPlacementData(reader *bitreader.Reader, length uint64) (SarDataPortalPlacement, int, error) { +func parsePortalPlacementData(reader *bitreader.Reader, length uint64, demo *types.Demo) (SarDataPortalPlacement, int, error) { if length != 15 { return SarDataPortalPlacement{}, 0, errors.New("sar data invalid") } @@ -312,10 +312,10 @@ func parsePortalPlacementData(reader *bitreader.Reader, length uint64) (SarDataP Y: reader.TryReadFloat32(), Z: reader.TryReadFloat32(), } - writer.AppendLine("\t\tOrange: %t", orange) - writer.AppendLine("\t\tX: %f", sarDataPortalPlacement.X) - writer.AppendLine("\t\tY: %f", sarDataPortalPlacement.Y) - writer.AppendLine("\t\tZ: %f", sarDataPortalPlacement.Z) + demo.Writer.AppendLine("\t\tOrange: %t", orange) + demo.Writer.AppendLine("\t\tX: %f", sarDataPortalPlacement.X) + demo.Writer.AppendLine("\t\tY: %f", sarDataPortalPlacement.Y) + demo.Writer.AppendLine("\t\tZ: %f", sarDataPortalPlacement.Z) return sarDataPortalPlacement, slot, nil } @@ -326,18 +326,18 @@ func parseChallengeFlagsCrouchFlyData(reader *bitreader.Reader, length uint64) ( return int(reader.TryReadBytes(1)), nil } -func parsePauseData(reader *bitreader.Reader, length uint64) (SarDataPause, error) { +func parsePauseData(reader *bitreader.Reader, length uint64, demo *types.Demo) (SarDataPause, error) { if length != 5 { return SarDataPause{}, errors.New("sar data invalid") } sarDataPause := SarDataPause{ PauseTicks: reader.TryReadUInt32(), } - writer.AppendLine("\t\tPause Ticks: %d", sarDataPause.PauseTicks) + demo.Writer.AppendLine("\t\tPause Ticks: %d", sarDataPause.PauseTicks) return sarDataPause, nil } -func parseWaitRunData(reader *bitreader.Reader, length uint64) (SarDataWaitRun, error) { +func parseWaitRunData(reader *bitreader.Reader, length uint64, demo *types.Demo) (SarDataWaitRun, error) { if length < 6 { return SarDataWaitRun{}, errors.New("sar data invalid") } @@ -345,12 +345,12 @@ func parseWaitRunData(reader *bitreader.Reader, length uint64) (SarDataWaitRun, Ticks: int(reader.TryReadUInt32()), Cmd: reader.TryReadString(), } - writer.AppendLine("\t\tTicks: %d", sarDataWaitRun.Ticks) - writer.AppendLine("\t\tCmd: \"%s\"", sarDataWaitRun.Cmd) + demo.Writer.AppendLine("\t\tTicks: %d", sarDataWaitRun.Ticks) + demo.Writer.AppendLine("\t\tCmd: \"%s\"", sarDataWaitRun.Cmd) return sarDataWaitRun, nil } -func parseHWaitRunData(reader *bitreader.Reader, length uint64) (SarDataHWaitRun, error) { +func parseHWaitRunData(reader *bitreader.Reader, length uint64, demo *types.Demo) (SarDataHWaitRun, error) { if length < 6 { return SarDataHWaitRun{}, errors.New("sar data invalid") } @@ -358,12 +358,12 @@ func parseHWaitRunData(reader *bitreader.Reader, length uint64) (SarDataHWaitRun Ticks: int(reader.TryReadUInt32()), Cmd: reader.TryReadString(), } - writer.AppendLine("\t\tTicks: %d", sarDataHWaitRun.Ticks) - writer.AppendLine("\t\tCmd: \"%s\"", sarDataHWaitRun.Cmd) + demo.Writer.AppendLine("\t\tTicks: %d", sarDataHWaitRun.Ticks) + demo.Writer.AppendLine("\t\tCmd: \"%s\"", sarDataHWaitRun.Cmd) return sarDataHWaitRun, nil } -func parseSpeedrunTimeData(reader *bitreader.Reader, length uint64) (SarDataSpeedrunTime, error) { +func parseSpeedrunTimeData(reader *bitreader.Reader, length uint64, demo *types.Demo) (SarDataSpeedrunTime, error) { if length < 5 { return SarDataSpeedrunTime{}, errors.New("sar data invalid") } @@ -372,14 +372,14 @@ func parseSpeedrunTimeData(reader *bitreader.Reader, length uint64) (SarDataSpee for splitCount := 0; splitCount < int(numberOfSplits); splitCount++ { splits[splitCount].Name = reader.TryReadString() splits[splitCount].NSegs = reader.TryReadUInt32() - writer.AppendLine("\t\t[%d] Split Name: \"%s\"", splitCount, splits[splitCount].Name) - writer.AppendLine("\t\t[%d] Number of Segments: %d", splitCount, splits[splitCount].NSegs) + demo.Writer.AppendLine("\t\t[%d] Split Name: \"%s\"", splitCount, splits[splitCount].Name) + demo.Writer.AppendLine("\t\t[%d] Number of Segments: %d", splitCount, splits[splitCount].NSegs) 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() - writer.AppendLine("\t\t\t[%d] Segment Name: \"%s\"", segCount, splits[splitCount].Segs[segCount].Name) - writer.AppendLine("\t\t\t[%d] Segment Ticks: %d", segCount, splits[splitCount].Segs[segCount].Ticks) + demo.Writer.AppendLine("\t\t\t[%d] Segment Name: \"%s\"", segCount, splits[splitCount].Segs[segCount].Name) + demo.Writer.AppendLine("\t\t\t[%d] Segment Ticks: %d", segCount, splits[splitCount].Segs[segCount].Ticks) } } return SarDataSpeedrunTime{ @@ -388,7 +388,7 @@ func parseSpeedrunTimeData(reader *bitreader.Reader, length uint64) (SarDataSpee }, nil } -func parseTimestampData(reader *bitreader.Reader, length uint64) (SarDataTimestamp, error) { +func parseTimestampData(reader *bitreader.Reader, length uint64, demo *types.Demo) (SarDataTimestamp, error) { if length != 8 { return SarDataTimestamp{}, errors.New("sar data invalid") } @@ -401,16 +401,16 @@ func parseTimestampData(reader *bitreader.Reader, length uint64) (SarDataTimesta Minute: timestamp[5], Second: timestamp[6], } - writer.AppendLine("\t\tYear: %d", sarDataTimeStamp.Year) - writer.AppendLine("\t\tMonth: %d", sarDataTimeStamp.Month) - writer.AppendLine("\t\tDay: %d", sarDataTimeStamp.Day) - writer.AppendLine("\t\tHour: %d", sarDataTimeStamp.Hour) - writer.AppendLine("\t\tMinute: %d", sarDataTimeStamp.Minute) - writer.AppendLine("\t\tSecond: %d", sarDataTimeStamp.Second) + demo.Writer.AppendLine("\t\tYear: %d", sarDataTimeStamp.Year) + demo.Writer.AppendLine("\t\tMonth: %d", sarDataTimeStamp.Month) + demo.Writer.AppendLine("\t\tDay: %d", sarDataTimeStamp.Day) + demo.Writer.AppendLine("\t\tHour: %d", sarDataTimeStamp.Hour) + demo.Writer.AppendLine("\t\tMinute: %d", sarDataTimeStamp.Minute) + demo.Writer.AppendLine("\t\tSecond: %d", sarDataTimeStamp.Second) return sarDataTimeStamp, nil } -func parseFileChecksumData(reader *bitreader.Reader, length uint64) (SarDataFileChecksum, error) { +func parseFileChecksumData(reader *bitreader.Reader, length uint64, demo *types.Demo) (SarDataFileChecksum, error) { if length < 6 { return SarDataFileChecksum{}, errors.New("sar data invalid") } @@ -418,7 +418,7 @@ func parseFileChecksumData(reader *bitreader.Reader, length uint64) (SarDataFile Sum: reader.TryReadUInt32(), Path: reader.TryReadString(), } - writer.AppendLine("\t\tChecksum: %d", sarDataFileChecksum.Sum) - writer.AppendLine("\t\tPath: \"%s\"", sarDataFileChecksum.Path) + demo.Writer.AppendLine("\t\tChecksum: %d", sarDataFileChecksum.Sum) + demo.Writer.AppendLine("\t\tPath: \"%s\"", sarDataFileChecksum.Path) return sarDataFileChecksum, nil } diff --git a/pkg/classes/signOn.go b/pkg/classes/signOn.go index 0d5ca55..e6d2f4e 100644 --- a/pkg/classes/signOn.go +++ b/pkg/classes/signOn.go @@ -3,20 +3,20 @@ package classes import ( "github.com/pektezol/bitreader" "github.com/pektezol/sdp.go/pkg/messages" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SignOn struct { - PacketInfo []CmdInfo - InSequence uint32 - OutSequence uint32 - Size uint32 - Data []any + PacketInfo []CmdInfo `json:"packet_info"` + InSequence uint32 `json:"in_sequence"` + OutSequence uint32 `json:"out_sequence"` + Size uint32 `json:"size"` + Data []any `json:"data"` } -func (signOn *SignOn) ParseSignOn(reader *bitreader.Reader) { +func (signOn *SignOn) ParseSignOn(reader *bitreader.Reader, demo *types.Demo) { for count := 0; count < MSSC; count++ { - signOn.ParseCmdInfo(reader) + signOn.ParseCmdInfo(reader, demo) } signOn.InSequence = reader.TryReadUInt32() signOn.OutSequence = reader.TryReadUInt32() @@ -27,11 +27,11 @@ func (signOn *SignOn) ParseSignOn(reader *bitreader.Reader) { if err != nil { break } - signOn.Data = append(signOn.Data, messages.ParseMessages(messageType, packetReader)) + signOn.Data = append(signOn.Data, messages.ParseMessages(messageType, packetReader, demo)) } } -func (signOn *SignOn) ParseCmdInfo(reader *bitreader.Reader) { +func (signOn *SignOn) ParseCmdInfo(reader *bitreader.Reader, demo *types.Demo) { signOn.PacketInfo = append(signOn.PacketInfo, CmdInfo{ Flags: reader.TryReadUInt32(), ViewOrigin: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, @@ -41,12 +41,12 @@ func (signOn *SignOn) ParseCmdInfo(reader *bitreader.Reader) { ViewAngles2: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, LocalViewAngles2: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, }) - writer.AppendLine("\tFlags: %s", CmdInfoFlags(signOn.PacketInfo[len(signOn.PacketInfo)-1].Flags).String()) - writer.AppendLine("\tView Origin: %v", signOn.PacketInfo[len(signOn.PacketInfo)-1].ViewOrigin) - writer.AppendLine("\tView Angles: %v", signOn.PacketInfo[len(signOn.PacketInfo)-1].ViewAngles) - writer.AppendLine("\tLocal View Angles: %v", signOn.PacketInfo[len(signOn.PacketInfo)-1].LocalViewAngles) - writer.AppendLine("\tView Origin 2: %v", signOn.PacketInfo[len(signOn.PacketInfo)-1].ViewOrigin2) - writer.AppendLine("\tView Angles 2: %v", signOn.PacketInfo[len(signOn.PacketInfo)-1].ViewAngles2) - writer.AppendLine("\tLocal View Angles 2: %v", signOn.PacketInfo[len(signOn.PacketInfo)-1].LocalViewAngles2) - writer.AppendLine("") + demo.Writer.AppendLine("\tFlags: %s", CmdInfoFlags(signOn.PacketInfo[len(signOn.PacketInfo)-1].Flags).String()) + demo.Writer.AppendLine("\tView Origin: %v", signOn.PacketInfo[len(signOn.PacketInfo)-1].ViewOrigin) + demo.Writer.AppendLine("\tView Angles: %v", signOn.PacketInfo[len(signOn.PacketInfo)-1].ViewAngles) + demo.Writer.AppendLine("\tLocal View Angles: %v", signOn.PacketInfo[len(signOn.PacketInfo)-1].LocalViewAngles) + demo.Writer.AppendLine("\tView Origin 2: %v", signOn.PacketInfo[len(signOn.PacketInfo)-1].ViewOrigin2) + demo.Writer.AppendLine("\tView Angles 2: %v", signOn.PacketInfo[len(signOn.PacketInfo)-1].ViewAngles2) + demo.Writer.AppendLine("\tLocal View Angles 2: %v", signOn.PacketInfo[len(signOn.PacketInfo)-1].LocalViewAngles2) + demo.Writer.AppendLine("") } diff --git a/pkg/classes/stop.go b/pkg/classes/stop.go index 97db6cf..c6b52a9 100644 --- a/pkg/classes/stop.go +++ b/pkg/classes/stop.go @@ -2,16 +2,16 @@ package classes import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type Stop struct { - RemainingData []byte + RemainingData []byte `json:"remaining_data"` } -func (stop *Stop) ParseStop(reader *bitreader.Reader) { +func (stop *Stop) ParseStop(reader *bitreader.Reader, demo *types.Demo) { if reader.TryReadBool() { stop.RemainingData = reader.TryReadBitsToSlice(uint64(reader.TryReadRemainingBits())) - writer.AppendLine("\tRemaining Data: %v", stop.RemainingData) + demo.Writer.AppendLine("\tRemaining Data: %v", stop.RemainingData) } } diff --git a/pkg/classes/stringTables.go b/pkg/classes/stringTables.go index 7848b1c..6e1510c 100644 --- a/pkg/classes/stringTables.go +++ b/pkg/classes/stringTables.go @@ -5,58 +5,58 @@ import ( "strings" "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type StringTables struct { - Size int32 - Data []StringTable + Size int32 `json:"size"` + Data []StringTable `json:"data"` } type StringTable struct { - Name string - TableEntries []StringTableEntry - Classes []StringTableClass + Name string `json:"name"` + TableEntries []StringTableEntry `json:"table_entries"` + Classes []StringTableClass `json:"classes"` } type StringTableClass struct { - Name string - Data string + Name string `json:"name"` + Data string `json:"data"` } type StringTableEntry struct { - Name string - EntryData any + Name string `json:"name"` + EntryData any `json:"entry_data"` } -func (stringTables *StringTables) ParseStringTables(reader *bitreader.Reader) { +func (stringTables *StringTables) ParseStringTables(reader *bitreader.Reader, demo *types.Demo) { stringTables.Size = reader.TryReadSInt32() stringTableReader := bitreader.NewReaderFromBytes(reader.TryReadBytesToSlice(uint64(stringTables.Size)), true) tableCount := stringTableReader.TryReadBits(8) tables := make([]StringTable, tableCount) for i := 0; i < int(tableCount); i++ { var table StringTable - table.ParseStream(stringTableReader) + table.ParseStream(stringTableReader, demo) tables[i] = table } stringTables.Data = tables } -func (stringTable *StringTable) ParseStream(reader *bitreader.Reader) { +func (stringTable *StringTable) ParseStream(reader *bitreader.Reader, demo *types.Demo) { stringTable.Name = reader.TryReadString() entryCount := reader.TryReadBits(16) - writer.AppendLine("\tTable Name: %s", stringTable.Name) + demo.Writer.AppendLine("\tTable Name: %s", stringTable.Name) stringTable.TableEntries = make([]StringTableEntry, entryCount) for i := 0; i < int(entryCount); i++ { var entry StringTableEntry - entry.Parse(stringTable.Name, reader) + entry.Parse(stringTable.Name, reader, demo) stringTable.TableEntries[i] = entry } if entryCount != 0 { - writer.AppendLine("\t\t%d Table Entries:", entryCount) - writer.AppendOutputFromTemp() + demo.Writer.AppendLine("\t\t%d Table Entries:", entryCount) + demo.Writer.AppendOutputFromTemp() } else { - writer.AppendLine("\t\tNo Table Entries") + demo.Writer.AppendLine("\t\tNo Table Entries") } if reader.TryReadBool() { classCount := reader.TryReadBits(16) @@ -64,28 +64,28 @@ func (stringTable *StringTable) ParseStream(reader *bitreader.Reader) { for i := 0; i < int(classCount); i++ { var class StringTableClass - class.Parse(reader) + class.Parse(reader, demo) stringTable.Classes[i] = class } - writer.AppendLine("\t\t%d Classes:", classCount) - writer.AppendOutputFromTemp() + demo.Writer.AppendLine("\t\t%d Classes:", classCount) + demo.Writer.AppendOutputFromTemp() } else { - writer.AppendLine("\t\tNo Class Entries") + demo.Writer.AppendLine("\t\tNo Class Entries") } } -func (stringTableClass *StringTableClass) Parse(reader *bitreader.Reader) { +func (stringTableClass *StringTableClass) Parse(reader *bitreader.Reader, demo *types.Demo) { stringTableClass.Name = reader.TryReadString() - writer.TempAppendLine("\t\t\tName: %s", stringTableClass.Name) + demo.Writer.TempAppendLine("\t\t\tName: %s", stringTableClass.Name) if reader.TryReadBool() { stringTableClass.Data = reader.TryReadStringLength(uint64(reader.TryReadUInt16())) - writer.TempAppendLine("\t\t\tData: %s", stringTableClass.Data) + demo.Writer.TempAppendLine("\t\t\tData: %s", stringTableClass.Data) } } -func (stringTableEntry *StringTableEntry) Parse(tableName string, reader *bitreader.Reader) { +func (stringTableEntry *StringTableEntry) Parse(tableName string, reader *bitreader.Reader, demo *types.Demo) { stringTableEntry.Name = reader.TryReadString() - writer.TempAppendLine("\t\t\tName: %s", stringTableEntry.Name) + demo.Writer.TempAppendLine("\t\t\tName: %s", stringTableEntry.Name) if reader.TryReadBool() { byteLen, err := reader.ReadBits(16) if err != nil { @@ -94,30 +94,30 @@ func (stringTableEntry *StringTableEntry) Parse(tableName string, reader *bitrea stringTableEntryReader := bitreader.NewReaderFromBytes(reader.TryReadBytesToSlice(byteLen), true) switch tableName { case StringTableUserInfo: - stringTableEntry.ParseUserInfo(stringTableEntryReader) + stringTableEntry.ParseUserInfo(stringTableEntryReader, demo) case StringTableServerQueryInfo: - stringTableEntry.ParseServerQueryInfo(stringTableEntryReader) + stringTableEntry.ParseServerQueryInfo(stringTableEntryReader, demo) case StringTableGameRulesCreation: - stringTableEntry.ParseGamesRulesCreation(stringTableEntryReader) + stringTableEntry.ParseGamesRulesCreation(stringTableEntryReader, demo) case StringTableInfoPanel: - stringTableEntry.ParseInfoPanel(stringTableEntryReader) + stringTableEntry.ParseInfoPanel(stringTableEntryReader, demo) case StringTableLightStyles: - stringTableEntry.ParseLightStyles(stringTableEntryReader) + stringTableEntry.ParseLightStyles(stringTableEntryReader, demo) case StringTableModelPreCache: - stringTableEntry.ParsePrecacheData(stringTableEntryReader) + stringTableEntry.ParsePrecacheData(stringTableEntryReader, demo) case StringTableGenericPreCache: - stringTableEntry.ParsePrecacheData(stringTableEntryReader) + stringTableEntry.ParsePrecacheData(stringTableEntryReader, demo) case StringTableSoundPreCache: - stringTableEntry.ParsePrecacheData(stringTableEntryReader) + stringTableEntry.ParsePrecacheData(stringTableEntryReader, demo) case StringTableDecalPreCache: - stringTableEntry.ParsePrecacheData(stringTableEntryReader) + stringTableEntry.ParsePrecacheData(stringTableEntryReader, demo) default: - stringTableEntry.ParseUnknown(stringTableEntryReader) + stringTableEntry.ParseUnknown(stringTableEntryReader, demo) } } } -func (stringTableEntry *StringTableEntry) ParseUserInfo(reader *bitreader.Reader) { +func (stringTableEntry *StringTableEntry) ParseUserInfo(reader *bitreader.Reader, demo *types.Demo) { const SignedGuidLen int32 = 32 const MaxPlayerNameLength int32 = 32 userInfo := struct { @@ -147,48 +147,48 @@ func (stringTableEntry *StringTableEntry) ParseUserInfo(reader *bitreader.Reader userInfo.FilesDownloaded = reader.TryReadUInt8() reader.SkipBytes(3) stringTableEntry.EntryData = userInfo - writer.TempAppendLine("\t\t\t\tSteam Account ID: %d", uint32((userInfo.SteamID&0xFFFFFFFF00000000)|userInfo.SteamID)) - writer.TempAppendLine("\t\t\t\tSteam Account Instance: %d", uint32(userInfo.SteamID>>32)&0x000FFFFF) - writer.TempAppendLine("\t\t\t\tSteam Account Type: %d", uint32(userInfo.SteamID>>52)&0xF) - writer.TempAppendLine("\t\t\t\tSteam Account Universe: %d", uint32(userInfo.SteamID>>56)&0xFF) - writer.TempAppendLine("\t\t\t\tName: %s", userInfo.Name) - writer.TempAppendLine("\t\t\t\tUser ID: %d", userInfo.UserID) - writer.TempAppendLine("\t\t\t\tGUID: %s", userInfo.GUID) - writer.TempAppendLine("\t\t\t\tFriends ID: %d", userInfo.FriendsID) - writer.TempAppendLine("\t\t\t\tFriends Name: %s", userInfo.FriendsName) - writer.TempAppendLine("\t\t\t\tFake Player: %t", userInfo.FakePlayer) - writer.TempAppendLine("\t\t\t\tIs Htlv: %t", userInfo.IsHltv) + demo.Writer.TempAppendLine("\t\t\t\tSteam Account ID: %d", uint32((userInfo.SteamID&0xFFFFFFFF00000000)|userInfo.SteamID)) + demo.Writer.TempAppendLine("\t\t\t\tSteam Account Instance: %d", uint32(userInfo.SteamID>>32)&0x000FFFFF) + demo.Writer.TempAppendLine("\t\t\t\tSteam Account Type: %d", uint32(userInfo.SteamID>>52)&0xF) + demo.Writer.TempAppendLine("\t\t\t\tSteam Account Universe: %d", uint32(userInfo.SteamID>>56)&0xFF) + demo.Writer.TempAppendLine("\t\t\t\tName: %s", userInfo.Name) + demo.Writer.TempAppendLine("\t\t\t\tUser ID: %d", userInfo.UserID) + demo.Writer.TempAppendLine("\t\t\t\tGUID: %s", userInfo.GUID) + demo.Writer.TempAppendLine("\t\t\t\tFriends ID: %d", userInfo.FriendsID) + demo.Writer.TempAppendLine("\t\t\t\tFriends Name: %s", userInfo.FriendsName) + demo.Writer.TempAppendLine("\t\t\t\tFake Player: %t", userInfo.FakePlayer) + demo.Writer.TempAppendLine("\t\t\t\tIs Htlv: %t", userInfo.IsHltv) if userInfo.CustomFiles != nil { - writer.TempAppendLine("\t\t\t\tCustom File CRCs: [logo: 0x%d, sounds: 0x%d, models: 0x%d, txt: 0x%d]", userInfo.CustomFiles[0], userInfo.CustomFiles[1], userInfo.CustomFiles[2], userInfo.CustomFiles[3]) + demo.Writer.TempAppendLine("\t\t\t\tCustom File CRCs: [logo: 0x%d, sounds: 0x%d, models: 0x%d, txt: 0x%d]", userInfo.CustomFiles[0], userInfo.CustomFiles[1], userInfo.CustomFiles[2], userInfo.CustomFiles[3]) } - writer.TempAppendLine("\t\t\t\tFiles Downloaded: %d", userInfo.FilesDownloaded) + demo.Writer.TempAppendLine("\t\t\t\tFiles Downloaded: %d", userInfo.FilesDownloaded) } -func (stringTableEntry *StringTableEntry) ParseServerQueryInfo(reader *bitreader.Reader) { +func (stringTableEntry *StringTableEntry) ParseServerQueryInfo(reader *bitreader.Reader, demo *types.Demo) { serverQueryInfo := struct{ Port uint32 }{ Port: reader.TryReadUInt32(), } stringTableEntry.EntryData = serverQueryInfo - writer.TempAppendLine("\t\t\t\tPort: %d", serverQueryInfo.Port) + demo.Writer.TempAppendLine("\t\t\t\tPort: %d", serverQueryInfo.Port) } -func (stringTableEntry *StringTableEntry) ParseGamesRulesCreation(reader *bitreader.Reader) { +func (stringTableEntry *StringTableEntry) ParseGamesRulesCreation(reader *bitreader.Reader, demo *types.Demo) { gamesRulesCreation := struct{ Message string }{ Message: reader.TryReadString(), } stringTableEntry.EntryData = gamesRulesCreation - writer.TempAppendLine("\t\t\t\tMessage: %s", gamesRulesCreation.Message) + demo.Writer.TempAppendLine("\t\t\t\tMessage: %s", gamesRulesCreation.Message) } -func (stringTableEntry *StringTableEntry) ParseInfoPanel(reader *bitreader.Reader) { +func (stringTableEntry *StringTableEntry) ParseInfoPanel(reader *bitreader.Reader, demo *types.Demo) { infoPanel := struct{ Message string }{ Message: reader.TryReadString(), } stringTableEntry.EntryData = infoPanel - writer.TempAppendLine("\t\t\t\tMessage: %s", infoPanel.Message) + demo.Writer.TempAppendLine("\t\t\t\tMessage: %s", infoPanel.Message) } -func (stringTableEntry *StringTableEntry) ParseLightStyles(reader *bitreader.Reader) { +func (stringTableEntry *StringTableEntry) ParseLightStyles(reader *bitreader.Reader, demo *types.Demo) { lightStyles := struct{ Values []byte }{} str := reader.TryReadString() if len(str) != 0 { @@ -199,13 +199,13 @@ func (stringTableEntry *StringTableEntry) ParseLightStyles(reader *bitreader.Rea } stringTableEntry.EntryData = lightStyles if lightStyles.Values == nil { - writer.TempAppendLine("\t\t\t\t0 Frames (256)") + demo.Writer.TempAppendLine("\t\t\t\t0 Frames (256)") } else { - writer.TempAppendLine("\t\t\t\t%d frames: %v", len(lightStyles.Values), lightStyles.Values) + demo.Writer.TempAppendLine("\t\t\t\t%d frames: %v", len(lightStyles.Values), lightStyles.Values) } } -func (stringTableEntry *StringTableEntry) ParsePrecacheData(reader *bitreader.Reader) { +func (stringTableEntry *StringTableEntry) ParsePrecacheData(reader *bitreader.Reader, demo *types.Demo) { type PrecacheFlag uint16 const ( None PrecacheFlag = 0 @@ -225,16 +225,16 @@ func (stringTableEntry *StringTableEntry) ParsePrecacheData(reader *bitreader.Re } return flagStrings } - writer.TempAppendLine("\t\t\t\tFlags: %v", getFlags(PrecacheFlag(precacheData.Flags))) + demo.Writer.TempAppendLine("\t\t\t\tFlags: %v", getFlags(PrecacheFlag(precacheData.Flags))) } -func (stringTableEntry *StringTableEntry) ParseUnknown(reader *bitreader.Reader) { +func (stringTableEntry *StringTableEntry) ParseUnknown(reader *bitreader.Reader, demo *types.Demo) { unknown := reader.TryReadBitsToSlice(reader.TryReadRemainingBits()) binaryString := "" for _, byteValue := range unknown { binaryString += fmt.Sprintf("%08b ", byteValue) } - writer.TempAppendLine("\t\t\t\tUnknown: (%s)", strings.TrimSpace(binaryString)) + demo.Writer.TempAppendLine("\t\t\t\tUnknown: (%s)", strings.TrimSpace(binaryString)) } const ( diff --git a/pkg/classes/userCmd.go b/pkg/classes/userCmd.go index dc0b56d..14ef4e0 100644 --- a/pkg/classes/userCmd.go +++ b/pkg/classes/userCmd.go @@ -2,40 +2,40 @@ package classes import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type UserCmd struct { - Cmd uint32 - Size uint32 - Data UserCmdInfo + Cmd uint32 `json:"cmd"` + Size uint32 `json:"size"` + Data UserCmdInfo `json:"data"` } type UserCmdInfo struct { - CommandNumber uint32 - TickCount uint32 - ViewAnglesX float32 - ViewAnglesY float32 - ViewAnglesZ float32 - ForwardMove float32 - SideMove float32 - UpMove float32 - Buttons uint32 - Impulse uint8 - WeaponSelect uint16 - WeaponSubType uint8 - MouseDx uint16 - MouseDy uint16 + CommandNumber uint32 `json:"command_number"` + TickCount uint32 `json:"tick_count"` + ViewAnglesX float32 `json:"view_angles_x"` + ViewAnglesY float32 `json:"view_angles_y"` + ViewAnglesZ float32 `json:"view_angles_z"` + ForwardMove float32 `json:"forward_move"` + SideMove float32 `json:"side_move"` + UpMove float32 `json:"up_move"` + Buttons uint32 `json:"buttons"` + Impulse uint8 `json:"impulse"` + WeaponSelect uint16 `json:"weapon_select"` + WeaponSubType uint8 `json:"weapon_sub_type"` + MouseDx uint16 `json:"mouse_dx"` + MouseDy uint16 `json:"mouse_dy"` } -func (userCmd *UserCmd) ParseUserCmd(reader *bitreader.Reader) { +func (userCmd *UserCmd) ParseUserCmd(reader *bitreader.Reader, demo *types.Demo) { userCmd.Cmd = reader.TryReadUInt32() userCmd.Size = reader.TryReadUInt32() userCmdReader := bitreader.NewReaderFromBytes(reader.TryReadBytesToSlice(uint64(userCmd.Size)), true) - userCmd.ParseUserCmdInfo(userCmdReader) + userCmd.ParseUserCmdInfo(userCmdReader, demo) } -func (userCmd *UserCmd) ParseUserCmdInfo(reader *bitreader.Reader) { +func (userCmd *UserCmd) ParseUserCmdInfo(reader *bitreader.Reader, demo *types.Demo) { if reader.TryReadBool() { userCmd.Data.CommandNumber = reader.TryReadUInt32() } @@ -78,14 +78,14 @@ func (userCmd *UserCmd) ParseUserCmdInfo(reader *bitreader.Reader) { if reader.TryReadBool() { userCmd.Data.MouseDy = reader.TryReadUInt16() } - writer.AppendLine("\tCommand Number: %v", userCmd.Data.CommandNumber) - writer.AppendLine("\tTick Count: %v", userCmd.Data.TickCount) - writer.AppendLine("\tView Angles: %v", []float32{userCmd.Data.ViewAnglesX, userCmd.Data.ViewAnglesY, userCmd.Data.ViewAnglesZ}) - writer.AppendLine("\tMovement: %v", []float32{userCmd.Data.ForwardMove, userCmd.Data.SideMove, userCmd.Data.UpMove}) - writer.AppendLine("\tButtons: %v", Buttons(userCmd.Data.Buttons).GetButtons()) - writer.AppendLine("\tImpulse: %v", userCmd.Data.Impulse) - writer.AppendLine("\tWeapon, Subtype: %v, %v", userCmd.Data.WeaponSelect, userCmd.Data.WeaponSubType) - writer.AppendLine("\tMouse Dx, Mouse Dy: %v, %v", userCmd.Data.MouseDx, userCmd.Data.MouseDy) + demo.Writer.AppendLine("\tCommand Number: %v", userCmd.Data.CommandNumber) + demo.Writer.AppendLine("\tTick Count: %v", userCmd.Data.TickCount) + demo.Writer.AppendLine("\tView Angles: %v", []float32{userCmd.Data.ViewAnglesX, userCmd.Data.ViewAnglesY, userCmd.Data.ViewAnglesZ}) + demo.Writer.AppendLine("\tMovement: %v", []float32{userCmd.Data.ForwardMove, userCmd.Data.SideMove, userCmd.Data.UpMove}) + demo.Writer.AppendLine("\tButtons: %v", Buttons(userCmd.Data.Buttons).GetButtons()) + demo.Writer.AppendLine("\tImpulse: %v", userCmd.Data.Impulse) + demo.Writer.AppendLine("\tWeapon, Subtype: %v, %v", userCmd.Data.WeaponSelect, userCmd.Data.WeaponSubType) + demo.Writer.AppendLine("\tMouse Dx, Mouse Dy: %v, %v", userCmd.Data.MouseDx, userCmd.Data.MouseDy) } func (button Buttons) GetButtons() []string { diff --git a/pkg/messages/messages.go b/pkg/messages/messages.go index 0dca169..1c6cf1f 100644 --- a/pkg/messages/messages.go +++ b/pkg/messages/messages.go @@ -5,84 +5,84 @@ import ( "github.com/pektezol/bitreader" messages "github.com/pektezol/sdp.go/pkg/messages/types" - "github.com/pektezol/sdp.go/pkg/writer" + types "github.com/pektezol/sdp.go/pkg/types" ) -func ParseMessages(messageType uint64, reader *bitreader.Reader) any { +func ParseMessages(messageType uint64, reader *bitreader.Reader, demo *types.Demo) any { var messageData any switch messageType { case 0: - messageData = messages.ParseNetNop(reader) + messageData = messages.ParseNetNop(reader, demo) case 1: - messageData = messages.ParseNetDisconnect(reader) + messageData = messages.ParseNetDisconnect(reader, demo) case 2: - messageData = messages.ParseNetFile(reader) + messageData = messages.ParseNetFile(reader, demo) case 3: - messageData = messages.ParseNetSplitScreenUser(reader) + messageData = messages.ParseNetSplitScreenUser(reader, demo) case 4: - messageData = messages.ParseNetTick(reader) + messageData = messages.ParseNetTick(reader, demo) case 5: - messageData = messages.ParseNetStringCmd(reader) + messageData = messages.ParseNetStringCmd(reader, demo) case 6: - messageData = messages.ParseNetSetConVar(reader) + messageData = messages.ParseNetSetConVar(reader, demo) case 7: - messageData = messages.ParseNetSignOnState(reader) + messageData = messages.ParseNetSignOnState(reader, demo) case 8: - messageData = messages.ParseSvcServerInfo(reader) + messageData = messages.ParseSvcServerInfo(reader, demo) case 9: - messageData = messages.ParseSvcSendTable(reader) + messageData = messages.ParseSvcSendTable(reader, demo) case 10: - messageData = messages.ParseSvcClassInfo(reader) + messageData = messages.ParseSvcClassInfo(reader, demo) case 11: - messageData = messages.ParseSvcSetPause(reader) + messageData = messages.ParseSvcSetPause(reader, demo) case 12: - messageData = messages.ParseSvcCreateStringTable(reader) // TODO: + messageData = messages.ParseSvcCreateStringTable(reader, demo) // TODO: case 13: - messageData = messages.ParseSvcUpdateStringTable(reader) // TODO: + messageData = messages.ParseSvcUpdateStringTable(reader, demo) // TODO: case 14: - messageData = messages.ParseSvcVoiceInit(reader) + messageData = messages.ParseSvcVoiceInit(reader, demo) case 15: - messageData = messages.ParseSvcVoiceData(reader) + messageData = messages.ParseSvcVoiceData(reader, demo) case 16: - messageData = messages.ParseSvcPrint(reader) + messageData = messages.ParseSvcPrint(reader, demo) case 17: - messageData = messages.ParseSvcSounds(reader) // TODO: + messageData = messages.ParseSvcSounds(reader, demo) // TODO: case 18: - messageData = messages.ParseSvcSetView(reader) + messageData = messages.ParseSvcSetView(reader, demo) case 19: - messageData = messages.ParseSvcFixAngle(reader) + messageData = messages.ParseSvcFixAngle(reader, demo) case 20: - messageData = messages.ParseSvcCrosshairAngle(reader) + messageData = messages.ParseSvcCrosshairAngle(reader, demo) case 21: - messageData = messages.ParseSvcBspDecal(reader) // untested + messageData = messages.ParseSvcBspDecal(reader, demo) // untested case 22: - messageData = messages.ParseSvcSplitScreen(reader) // skipped + messageData = messages.ParseSvcSplitScreen(reader, demo) // skipped case 23: - messageData = messages.ParseSvcUserMessage(reader) + messageData = messages.ParseSvcUserMessage(reader, demo) case 24: - messageData = messages.ParseSvcEntityMessage(reader) // skipped + messageData = messages.ParseSvcEntityMessage(reader, demo) // skipped case 25: - messageData = messages.ParseSvcGameEvent(reader) + messageData = messages.ParseSvcGameEvent(reader, demo) case 26: - messageData = messages.ParseSvcPacketEntities(reader) // TODO: + messageData = messages.ParseSvcPacketEntities(reader, demo) // TODO: case 27: - messageData = messages.ParseSvcTempEntities(reader) // skipped + messageData = messages.ParseSvcTempEntities(reader, demo) // skipped case 28: - messageData = messages.ParseSvcPrefetch(reader) + messageData = messages.ParseSvcPrefetch(reader, demo) case 29: - messageData = messages.ParseSvcMenu(reader) // skipped + messageData = messages.ParseSvcMenu(reader, demo) // skipped case 30: - messageData = messages.ParseSvcGameEventList(reader) + messageData = messages.ParseSvcGameEventList(reader, demo) case 31: - messageData = messages.ParseSvcGetCvarValue(reader) + messageData = messages.ParseSvcGetCvarValue(reader, demo) case 32: - messageData = messages.ParseSvcCmdKeyValues(reader) + messageData = messages.ParseSvcCmdKeyValues(reader, demo) case 33: - messageData = messages.ParseSvcPaintmapData(reader) // skipped + messageData = messages.ParseSvcPaintmapData(reader, demo) // skipped default: return nil } - writer.AppendLine("\tMessage: %s (%d):", reflect.ValueOf(messageData).Type(), messageType) - writer.AppendOutputFromTemp() + demo.Writer.AppendLine("\tMessage: %s (%d):", reflect.ValueOf(messageData).Type(), messageType) + demo.Writer.AppendOutputFromTemp() return messageData } diff --git a/pkg/messages/types/netDisconnect.go b/pkg/messages/types/netDisconnect.go index c3c857e..c8514c0 100644 --- a/pkg/messages/types/netDisconnect.go +++ b/pkg/messages/types/netDisconnect.go @@ -2,17 +2,17 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type NetDisconnect struct { - Text string + Text string `json:"text"` } -func ParseNetDisconnect(reader *bitreader.Reader) NetDisconnect { +func ParseNetDisconnect(reader *bitreader.Reader, demo *types.Demo) NetDisconnect { netDisconnect := NetDisconnect{ Text: reader.TryReadString(), } - writer.TempAppendLine("\t\tText: %s", netDisconnect.Text) + demo.Writer.TempAppendLine("\t\tText: %s", netDisconnect.Text) return netDisconnect } diff --git a/pkg/messages/types/netFile.go b/pkg/messages/types/netFile.go index e74cdb3..837a4c0 100644 --- a/pkg/messages/types/netFile.go +++ b/pkg/messages/types/netFile.go @@ -4,13 +4,13 @@ import ( "fmt" "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type NetFile struct { - TransferId uint32 - FileName string - FileFlags string + TransferId uint32 `json:"transfer_id"` + FileName string `json:"file_name"` + FileFlags string `json:"file_flags"` } type NetFileFlags int @@ -34,14 +34,14 @@ func (netFileFlags NetFileFlags) String() string { } } -func ParseNetFile(reader *bitreader.Reader) NetFile { +func ParseNetFile(reader *bitreader.Reader, demo *types.Demo) NetFile { netFile := NetFile{ TransferId: reader.TryReadUInt32(), FileName: reader.TryReadString(), FileFlags: NetFileFlags(reader.TryReadBits(2)).String(), } - writer.TempAppendLine("\t\tTransfer ID: %d", netFile.TransferId) - writer.TempAppendLine("\t\tFile Name: %s", netFile.FileName) - writer.TempAppendLine("\t\tFile Flags: %s", netFile.FileFlags) + demo.Writer.TempAppendLine("\t\tTransfer ID: %d", netFile.TransferId) + demo.Writer.TempAppendLine("\t\tFile Name: %s", netFile.FileName) + demo.Writer.TempAppendLine("\t\tFile Flags: %s", netFile.FileFlags) return netFile } diff --git a/pkg/messages/types/netNop.go b/pkg/messages/types/netNop.go index c7ba66c..5405659 100644 --- a/pkg/messages/types/netNop.go +++ b/pkg/messages/types/netNop.go @@ -2,12 +2,12 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type NetNop struct{} -func ParseNetNop(reader *bitreader.Reader) NetNop { - writer.TempAppendLine("\t\t{}") +func ParseNetNop(reader *bitreader.Reader, demo *types.Demo) NetNop { + demo.Writer.TempAppendLine("\t\t{}") return NetNop{} } diff --git a/pkg/messages/types/netSetConVar.go b/pkg/messages/types/netSetConVar.go index e9902b5..0c62fdd 100644 --- a/pkg/messages/types/netSetConVar.go +++ b/pkg/messages/types/netSetConVar.go @@ -2,29 +2,29 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type NetSetConVar struct { - Length uint8 - ConVars []conVar + Length uint8 `json:"length"` + ConVars []conVar `json:"con_vars"` } type conVar struct { - Name string - Value string + Name string `json:"name"` + Value string `json:"value"` } -func ParseNetSetConVar(reader *bitreader.Reader) NetSetConVar { +func ParseNetSetConVar(reader *bitreader.Reader, demo *types.Demo) NetSetConVar { length := reader.TryReadUInt8() convars := []conVar{} - writer.TempAppendLine("\t\tLength: %d", length) + demo.Writer.TempAppendLine("\t\tLength: %d", length) for count := 0; count < int(length); count++ { convar := conVar{ Name: reader.TryReadString(), Value: reader.TryReadString(), } - writer.TempAppendLine("\t\t[%d] %s: %s", count, convar.Name, convar.Value) + demo.Writer.TempAppendLine("\t\t[%d] %s: %s", count, convar.Name, convar.Value) convars = append(convars, convar) } return NetSetConVar{ diff --git a/pkg/messages/types/netSignOnState.go b/pkg/messages/types/netSignOnState.go index e25eaed..0043465 100644 --- a/pkg/messages/types/netSignOnState.go +++ b/pkg/messages/types/netSignOnState.go @@ -4,17 +4,17 @@ import ( "fmt" "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type NetSignOnState struct { - SignOnState string - SpawnCount int32 - NumServerPlayers uint32 - IdsLength uint32 - PlayersNetworksIds []byte - MapNameLength uint32 - MapName string + SignOnState string `json:"sign_on_state"` + SpawnCount int32 `json:"spawn_count"` + NumServerPlayers uint32 `json:"num_server_players"` + IdsLength uint32 `json:"ids_length"` + PlayersNetworksIds []byte `json:"players_networks_ids"` + MapNameLength uint32 `json:"map_name_length"` + MapName string `json:"map_name"` } type SignOnState int @@ -53,24 +53,24 @@ func (signOnState SignOnState) String() string { } } -func ParseNetSignOnState(reader *bitreader.Reader) NetSignOnState { +func ParseNetSignOnState(reader *bitreader.Reader, demo *types.Demo) NetSignOnState { netSignOnState := NetSignOnState{ SignOnState: SignOnState(reader.TryReadUInt8()).String(), SpawnCount: reader.TryReadSInt32(), NumServerPlayers: reader.TryReadUInt32(), IdsLength: reader.TryReadUInt32(), } - writer.TempAppendLine("\t\tSign On State: %s", netSignOnState.SignOnState) - writer.TempAppendLine("\t\tSpawn Count: %d", netSignOnState.SpawnCount) - writer.TempAppendLine("\t\tNumber Of Server Players: %d", netSignOnState.NumServerPlayers) + demo.Writer.TempAppendLine("\t\tSign On State: %s", netSignOnState.SignOnState) + demo.Writer.TempAppendLine("\t\tSpawn Count: %d", netSignOnState.SpawnCount) + demo.Writer.TempAppendLine("\t\tNumber Of Server Players: %d", netSignOnState.NumServerPlayers) if netSignOnState.IdsLength > 0 { netSignOnState.PlayersNetworksIds = reader.TryReadBytesToSlice(uint64(netSignOnState.IdsLength)) - writer.TempAppendLine("\t\tPlayer Network IDs: %v", netSignOnState.PlayersNetworksIds) + demo.Writer.TempAppendLine("\t\tPlayer Network IDs: %v", netSignOnState.PlayersNetworksIds) } netSignOnState.MapNameLength = reader.TryReadUInt32() if netSignOnState.MapNameLength > 0 { netSignOnState.MapName = reader.TryReadStringLength(uint64(netSignOnState.MapNameLength)) - writer.TempAppendLine("\t\tMap Name: %s", netSignOnState.MapName) + demo.Writer.TempAppendLine("\t\tMap Name: %s", netSignOnState.MapName) } return netSignOnState } diff --git a/pkg/messages/types/netSplitScreenUser.go b/pkg/messages/types/netSplitScreenUser.go index 535552a..691c723 100644 --- a/pkg/messages/types/netSplitScreenUser.go +++ b/pkg/messages/types/netSplitScreenUser.go @@ -2,17 +2,17 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type NetSplitScreenUser struct { - Slot bool + Slot bool `json:"slot"` } -func ParseNetSplitScreenUser(reader *bitreader.Reader) NetSplitScreenUser { +func ParseNetSplitScreenUser(reader *bitreader.Reader, demo *types.Demo) NetSplitScreenUser { netSplitScreenUser := NetSplitScreenUser{ Slot: reader.TryReadBool(), } - writer.TempAppendLine("\t\tSlot: %t", netSplitScreenUser.Slot) + demo.Writer.TempAppendLine("\t\tSlot: %t", netSplitScreenUser.Slot) return netSplitScreenUser } diff --git a/pkg/messages/types/netStringCmd.go b/pkg/messages/types/netStringCmd.go index 13d5a13..fb6af2e 100644 --- a/pkg/messages/types/netStringCmd.go +++ b/pkg/messages/types/netStringCmd.go @@ -4,17 +4,17 @@ import ( "strings" "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type NetStringCmd struct { - Command string + Command string `json:"command"` } -func ParseNetStringCmd(reader *bitreader.Reader) NetStringCmd { +func ParseNetStringCmd(reader *bitreader.Reader, demo *types.Demo) NetStringCmd { netStringCmd := NetStringCmd{ Command: reader.TryReadString(), } - writer.TempAppendLine("\t\tCommand: \"%s\"", strings.TrimSpace(netStringCmd.Command)) + demo.Writer.TempAppendLine("\t\tCommand: \"%s\"", strings.TrimSpace(netStringCmd.Command)) return netStringCmd } diff --git a/pkg/messages/types/netTick.go b/pkg/messages/types/netTick.go index 9ef1ce2..0bcbc05 100644 --- a/pkg/messages/types/netTick.go +++ b/pkg/messages/types/netTick.go @@ -2,23 +2,23 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type NetTick struct { - Tick uint32 - HostFrameTime float32 - HostFrameTimeStdDeviation float32 + Tick uint32 `json:"tick"` + HostFrameTime float32 `json:"host_frame_time"` + HostFrameTimeStdDeviation float32 `json:"host_frame_time_std_deviation"` } -func ParseNetTick(reader *bitreader.Reader) NetTick { +func ParseNetTick(reader *bitreader.Reader, demo *types.Demo) NetTick { netTick := NetTick{ Tick: reader.TryReadUInt32(), HostFrameTime: float32(reader.TryReadUInt16()) / 1e5, HostFrameTimeStdDeviation: float32(reader.TryReadUInt16()) / 1e5, } - writer.TempAppendLine("\t\tTick: %d", netTick.Tick) - writer.TempAppendLine("\t\tHost Frame Time: %f", netTick.HostFrameTime) - writer.TempAppendLine("\t\tHost Frame Time Std Deviation: %f", netTick.HostFrameTimeStdDeviation) + demo.Writer.TempAppendLine("\t\tTick: %d", netTick.Tick) + demo.Writer.TempAppendLine("\t\tHost Frame Time: %f", netTick.HostFrameTime) + demo.Writer.TempAppendLine("\t\tHost Frame Time Std Deviation: %f", netTick.HostFrameTimeStdDeviation) return netTick } diff --git a/pkg/messages/types/svcBspDecal.go b/pkg/messages/types/svcBspDecal.go index fc5698f..9ef2458 100644 --- a/pkg/messages/types/svcBspDecal.go +++ b/pkg/messages/types/svcBspDecal.go @@ -2,23 +2,23 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcBspDecal struct { - Pos []vectorCoord - DecalTextureIndex int16 - EntityIndex uint16 - ModelIndex uint16 - LowPriority bool + Pos []vectorCoord `json:"pos"` + DecalTextureIndex int16 `json:"decal_texture_index"` + EntityIndex uint16 `json:"entity_index"` + ModelIndex uint16 `json:"model_index"` + LowPriority bool `json:"low_priority"` } type vectorCoord struct { - Value float32 - Valid bool + Value float32 `json:"value"` + Valid bool `json:"valid"` } -func ParseSvcBspDecal(reader *bitreader.Reader) SvcBspDecal { +func ParseSvcBspDecal(reader *bitreader.Reader, demo *types.Demo) SvcBspDecal { svcBspDecal := SvcBspDecal{ Pos: readVectorCoords(reader), DecalTextureIndex: int16(reader.TryReadBits(9)), @@ -28,11 +28,11 @@ func ParseSvcBspDecal(reader *bitreader.Reader) SvcBspDecal { svcBspDecal.ModelIndex = uint16(reader.TryReadBits(11)) } svcBspDecal.LowPriority = reader.TryReadBool() - writer.TempAppendLine("\t\tPosition: %v", svcBspDecal.Pos) - writer.TempAppendLine("\t\tDecal Texture Index: %d", svcBspDecal.DecalTextureIndex) - writer.TempAppendLine("\t\tEntity Index: %d", svcBspDecal.EntityIndex) - writer.TempAppendLine("\t\tModel Index: %d", svcBspDecal.ModelIndex) - writer.TempAppendLine("\t\tLow Priority: %t", svcBspDecal.LowPriority) + demo.Writer.TempAppendLine("\t\tPosition: %v", svcBspDecal.Pos) + demo.Writer.TempAppendLine("\t\tDecal Texture Index: %d", svcBspDecal.DecalTextureIndex) + demo.Writer.TempAppendLine("\t\tEntity Index: %d", svcBspDecal.EntityIndex) + demo.Writer.TempAppendLine("\t\tModel Index: %d", svcBspDecal.ModelIndex) + demo.Writer.TempAppendLine("\t\tLow Priority: %t", svcBspDecal.LowPriority) return svcBspDecal } diff --git a/pkg/messages/types/svcClassInfo.go b/pkg/messages/types/svcClassInfo.go index af382a8..995c61d 100644 --- a/pkg/messages/types/svcClassInfo.go +++ b/pkg/messages/types/svcClassInfo.go @@ -4,40 +4,40 @@ import ( "math" "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcClassInfo struct { - ClassCount uint16 - CreateOnClient bool - ServerClasses []serverClass + ClassCount uint16 `json:"class_count"` + CreateOnClient bool `json:"create_on_client"` + ServerClasses []serverClass `json:"server_classes"` } type serverClass struct { - ClassId int16 - ClassName string - DataTableName string + ClassId int16 `json:"class_id"` + ClassName string `json:"class_name"` + DataTableName string `json:"data_table_name"` } -func ParseSvcClassInfo(reader *bitreader.Reader) SvcClassInfo { +func ParseSvcClassInfo(reader *bitreader.Reader, demo *types.Demo) SvcClassInfo { svcClassInfo := SvcClassInfo{ ClassCount: reader.TryReadUInt16(), CreateOnClient: reader.TryReadBool(), } classes := []serverClass{} - writer.TempAppendLine("\t\tCreate On Client: %t", svcClassInfo.CreateOnClient) + demo.Writer.TempAppendLine("\t\tCreate On Client: %t", svcClassInfo.CreateOnClient) if !svcClassInfo.CreateOnClient { - writer.TempAppendLine("\t\t%d Server Classes:", svcClassInfo.ClassCount) + demo.Writer.TempAppendLine("\t\t%d Server Classes:", svcClassInfo.ClassCount) for count := 0; count < int(svcClassInfo.ClassCount); count++ { classes = append(classes, serverClass{ ClassId: int16(reader.TryReadBits(uint64(math.Log2(float64(svcClassInfo.ClassCount)) + 1))), ClassName: reader.TryReadString(), DataTableName: reader.TryReadString(), }) - writer.TempAppendLine("\t\t\t[%d] %s (%s)", classes[len(classes)-1].ClassId, classes[len(classes)-1].ClassName, classes[len(classes)-1].DataTableName) + demo.Writer.TempAppendLine("\t\t\t[%d] %s (%s)", classes[len(classes)-1].ClassId, classes[len(classes)-1].ClassName, classes[len(classes)-1].DataTableName) } } else { - writer.TempAppendLine("\t\t%d Server Classes", svcClassInfo.ClassCount) + demo.Writer.TempAppendLine("\t\t%d Server Classes", svcClassInfo.ClassCount) } svcClassInfo.ServerClasses = classes return svcClassInfo diff --git a/pkg/messages/types/svcCmdKeyValues.go b/pkg/messages/types/svcCmdKeyValues.go index a5d8f62..6ab9c99 100644 --- a/pkg/messages/types/svcCmdKeyValues.go +++ b/pkg/messages/types/svcCmdKeyValues.go @@ -2,19 +2,19 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcCmdKeyValues struct { - Length uint32 - Data []byte + Length uint32 `json:"length"` + Data []byte `json:"data"` } -func ParseSvcCmdKeyValues(reader *bitreader.Reader) SvcCmdKeyValues { +func ParseSvcCmdKeyValues(reader *bitreader.Reader, demo *types.Demo) SvcCmdKeyValues { svcCmdKeyValues := SvcCmdKeyValues{ Length: reader.TryReadUInt32(), } svcCmdKeyValues.Data = reader.TryReadBytesToSlice(uint64(svcCmdKeyValues.Length)) - writer.TempAppendLine("\t\tData: %v", svcCmdKeyValues.Data) + demo.Writer.TempAppendLine("\t\tData: %v", svcCmdKeyValues.Data) return svcCmdKeyValues } diff --git a/pkg/messages/types/svcCreateStringTable.go b/pkg/messages/types/svcCreateStringTable.go index 0fc07cd..9a0c3e0 100644 --- a/pkg/messages/types/svcCreateStringTable.go +++ b/pkg/messages/types/svcCreateStringTable.go @@ -4,22 +4,22 @@ import ( "math" "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcCreateStringTable struct { - Name string - MaxEntries int16 - NumEntries int8 - Length int32 - UserDataFixedSize bool - UserDataSize int16 - UserDataSizeBits int8 - Flags int8 - StringData int + Name string `json:"name"` + MaxEntries int16 `json:"max_entries"` + NumEntries int8 `json:"num_entries"` + Length int32 `json:"length"` + UserDataFixedSize bool `json:"user_data_fixed_size"` + UserDataSize int16 `json:"user_data_size"` + UserDataSizeBits int8 `json:"user_data_size_bits"` + Flags int8 `json:"flags"` + StringData int `json:"string_data"` } -func ParseSvcCreateStringTable(reader *bitreader.Reader) SvcCreateStringTable { +func ParseSvcCreateStringTable(reader *bitreader.Reader, demo *types.Demo) SvcCreateStringTable { svcCreateStringTable := SvcCreateStringTable{ Name: reader.TryReadString(), MaxEntries: reader.TryReadSInt16(), @@ -32,13 +32,13 @@ func ParseSvcCreateStringTable(reader *bitreader.Reader) SvcCreateStringTable { svcCreateStringTable.UserDataSizeBits = int8(reader.TryReadBits(4)) } svcCreateStringTable.Flags = int8(reader.TryReadBits(2)) - writer.TempAppendLine("\t\tName: %s", svcCreateStringTable.Name) - writer.TempAppendLine("\t\tMax Enties: %d", svcCreateStringTable.MaxEntries) - writer.TempAppendLine("\t\tNumber Of Entiries: %d", svcCreateStringTable.NumEntries) - writer.TempAppendLine("\t\tUser Data Fixed Size: %t", svcCreateStringTable.UserDataFixedSize) - writer.TempAppendLine("\t\tUser Data Size: %d", svcCreateStringTable.UserDataSize) - writer.TempAppendLine("\t\tUser Data Size In Bits: %d", svcCreateStringTable.UserDataSizeBits) - writer.TempAppendLine("\t\tFlags: %d", svcCreateStringTable.Flags) + demo.Writer.TempAppendLine("\t\tName: %s", svcCreateStringTable.Name) + demo.Writer.TempAppendLine("\t\tMax Enties: %d", svcCreateStringTable.MaxEntries) + demo.Writer.TempAppendLine("\t\tNumber Of Entiries: %d", svcCreateStringTable.NumEntries) + demo.Writer.TempAppendLine("\t\tUser Data Fixed Size: %t", svcCreateStringTable.UserDataFixedSize) + demo.Writer.TempAppendLine("\t\tUser Data Size: %d", svcCreateStringTable.UserDataSize) + demo.Writer.TempAppendLine("\t\tUser Data Size In Bits: %d", svcCreateStringTable.UserDataSizeBits) + demo.Writer.TempAppendLine("\t\tFlags: %d", svcCreateStringTable.Flags) 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 dd57f79..31da616 100644 --- a/pkg/messages/types/svcCrosshairAngle.go +++ b/pkg/messages/types/svcCrosshairAngle.go @@ -2,20 +2,20 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcCrosshairAngle struct { - Angle crosshairAngles + Angle crosshairAngles `json:"angle"` } type crosshairAngles struct { - X float32 - Y float32 - Z float32 + X float32 `json:"x"` + Y float32 `json:"y"` + Z float32 `json:"z"` } -func ParseSvcCrosshairAngle(reader *bitreader.Reader) SvcCrosshairAngle { +func ParseSvcCrosshairAngle(reader *bitreader.Reader, demo *types.Demo) SvcCrosshairAngle { svcCrosshairAngle := SvcCrosshairAngle{ Angle: crosshairAngles{ X: float32(reader.TryReadBits(16)), @@ -23,8 +23,8 @@ func ParseSvcCrosshairAngle(reader *bitreader.Reader) SvcCrosshairAngle { Z: float32(reader.TryReadBits(16)), }, } - writer.TempAppendLine("\t\tX: %f", svcCrosshairAngle.Angle.X) - writer.TempAppendLine("\t\tY: %f", svcCrosshairAngle.Angle.Y) - writer.TempAppendLine("\t\tZ: %f", svcCrosshairAngle.Angle.Z) + demo.Writer.TempAppendLine("\t\tX: %f", svcCrosshairAngle.Angle.X) + demo.Writer.TempAppendLine("\t\tY: %f", svcCrosshairAngle.Angle.Y) + demo.Writer.TempAppendLine("\t\tZ: %f", svcCrosshairAngle.Angle.Z) return svcCrosshairAngle } diff --git a/pkg/messages/types/svcEntityMessage.go b/pkg/messages/types/svcEntityMessage.go index b955da5..87d7e1b 100644 --- a/pkg/messages/types/svcEntityMessage.go +++ b/pkg/messages/types/svcEntityMessage.go @@ -2,25 +2,25 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcEntityMessage struct { - EntityIndex uint16 - ClassId uint16 - Length uint16 - Data []byte + EntityIndex uint16 `json:"entity_index"` + ClassId uint16 `json:"class_id"` + Length uint16 `json:"length"` + Data []byte `json:"data"` } -func ParseSvcEntityMessage(reader *bitreader.Reader) SvcEntityMessage { +func ParseSvcEntityMessage(reader *bitreader.Reader, demo *types.Demo) SvcEntityMessage { svcEntityMessage := SvcEntityMessage{ EntityIndex: uint16(reader.TryReadBits(11)), ClassId: uint16(reader.TryReadBits(9)), Length: uint16(reader.TryReadBits(11)), } svcEntityMessage.Data = reader.TryReadBitsToSlice(uint64(svcEntityMessage.Length)) - writer.TempAppendLine("\t\tEntity Index: %d", svcEntityMessage.EntityIndex) - writer.TempAppendLine("\t\tClass ID: %d", svcEntityMessage.ClassId) - writer.TempAppendLine("\t\tData: %v", svcEntityMessage.Data) + demo.Writer.TempAppendLine("\t\tEntity Index: %d", svcEntityMessage.EntityIndex) + demo.Writer.TempAppendLine("\t\tClass ID: %d", svcEntityMessage.ClassId) + demo.Writer.TempAppendLine("\t\tData: %v", svcEntityMessage.Data) return svcEntityMessage } diff --git a/pkg/messages/types/svcFixAngle.go b/pkg/messages/types/svcFixAngle.go index d5e7b0f..924bba2 100644 --- a/pkg/messages/types/svcFixAngle.go +++ b/pkg/messages/types/svcFixAngle.go @@ -2,21 +2,21 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcFixAngle struct { - Relative bool - Angle fixAngles + Relative bool `json:"relative"` + Angle fixAngles `json:"angle"` } type fixAngles struct { - X float32 - Y float32 - Z float32 + X float32 `json:"x"` + Y float32 `json:"y"` + Z float32 `json:"z"` } -func ParseSvcFixAngle(reader *bitreader.Reader) SvcFixAngle { +func ParseSvcFixAngle(reader *bitreader.Reader, demo *types.Demo) SvcFixAngle { svcFixAngle := SvcFixAngle{ Relative: reader.TryReadBool(), Angle: fixAngles{ @@ -25,9 +25,9 @@ func ParseSvcFixAngle(reader *bitreader.Reader) SvcFixAngle { Z: float32(reader.TryReadBits(16)), }, } - writer.TempAppendLine("\t\tRelative: %t", svcFixAngle.Relative) - writer.TempAppendLine("\t\tX: %f", svcFixAngle.Angle.X) - writer.TempAppendLine("\t\tY: %f", svcFixAngle.Angle.Y) - writer.TempAppendLine("\t\tZ: %f", svcFixAngle.Angle.Z) + demo.Writer.TempAppendLine("\t\tRelative: %t", svcFixAngle.Relative) + demo.Writer.TempAppendLine("\t\tX: %f", svcFixAngle.Angle.X) + demo.Writer.TempAppendLine("\t\tY: %f", svcFixAngle.Angle.Y) + demo.Writer.TempAppendLine("\t\tZ: %f", svcFixAngle.Angle.Z) return svcFixAngle } diff --git a/pkg/messages/types/svcGameEvent.go b/pkg/messages/types/svcGameEvent.go index b325472..cb1e91d 100644 --- a/pkg/messages/types/svcGameEvent.go +++ b/pkg/messages/types/svcGameEvent.go @@ -2,56 +2,56 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcGameEvent struct { - Length uint16 - EventID uint32 - EventDescription GameEventDescriptor - EventDescriptors []EventDescriptorKey + Length uint16 `json:"length"` + EventID uint32 `json:"event_id"` + EventDescription types.GameEventDescriptor `json:"event_description"` + EventDescriptors []EventDescriptorKey `json:"event_descriptors"` } type EventDescriptorKey struct { - Name string - Descriptor any + Name string `json:"name"` + Descriptor any `json:"descriptor"` } -func ParseSvcGameEvent(reader *bitreader.Reader) SvcGameEvent { +func ParseSvcGameEvent(reader *bitreader.Reader, demo *types.Demo) SvcGameEvent { svcGameEvent := SvcGameEvent{ Length: uint16(reader.TryReadBits(11)), } gameEventReader := bitreader.NewReaderFromBytes(reader.TryReadBitsToSlice(uint64(svcGameEvent.Length)), true) - svcGameEvent.parseGameEvent(gameEventReader) + svcGameEvent.parseGameEvent(gameEventReader, demo) return svcGameEvent } -func (svcGameEvent *SvcGameEvent) parseGameEvent(reader *bitreader.Reader) { +func (svcGameEvent *SvcGameEvent) parseGameEvent(reader *bitreader.Reader, demo *types.Demo) { svcGameEvent.EventID = uint32(reader.TryReadBits(9)) - svcGameEvent.EventDescription = GameEventList.GameEventDescriptor[svcGameEvent.EventID] - writer.TempAppendLine("\t\t%s (%d):", svcGameEvent.EventDescription.Name, svcGameEvent.EventID) + svcGameEvent.EventDescription = demo.GameEventList.GameEventDescriptor[svcGameEvent.EventID] + demo.Writer.TempAppendLine("\t\t%s (%d):", svcGameEvent.EventDescription.Name, svcGameEvent.EventID) for _, descriptor := range svcGameEvent.EventDescription.Keys { var value any switch descriptor.Type { - case EventDescriptorString: + case types.EventDescriptorString: value = reader.TryReadString() - case EventDescriptorFloat: + case types.EventDescriptorFloat: value = reader.TryReadFloat32() - case EventDescriptorInt32: + case types.EventDescriptorInt32: value = reader.TryReadSInt32() - case EventDescriptorInt16: + case types.EventDescriptorInt16: value = reader.TryReadSInt16() - case EventDescriptorInt8: + case types.EventDescriptorInt8: value = reader.TryReadUInt8() - case EventDescriptorBool: + case types.EventDescriptorBool: value = reader.TryReadBool() - case EventDescriptorUInt64: + case types.EventDescriptorUInt64: value = reader.TryReadUInt64() } svcGameEvent.EventDescriptors = append(svcGameEvent.EventDescriptors, EventDescriptorKey{ Name: descriptor.Name, Descriptor: value, }) - writer.TempAppendLine("\t\t\t%s: %v", descriptor.Name, value) + demo.Writer.TempAppendLine("\t\t\t%s: %v", descriptor.Name, value) } } diff --git a/pkg/messages/types/svcGameEventList.go b/pkg/messages/types/svcGameEventList.go index 9a194fd..dafe9b7 100644 --- a/pkg/messages/types/svcGameEventList.go +++ b/pkg/messages/types/svcGameEventList.go @@ -1,95 +1,18 @@ package messages import ( - "fmt" - "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) -var GameEventList *SvcGameEventList - -type SvcGameEventList struct { - Events int16 - Length int32 - GameEventDescriptor []GameEventDescriptor -} - -type GameEventDescriptor struct { - EventID uint32 - Name string - Keys []GameEventDescriptorKey -} - -type GameEventDescriptorKey struct { - Name string - Type EventDescriptor -} - -type EventDescriptor uint8 - -func ParseSvcGameEventList(reader *bitreader.Reader) SvcGameEventList { - svcGameEventList := SvcGameEventList{ +func ParseSvcGameEventList(reader *bitreader.Reader, demo *types.Demo) types.SvcGameEventList { + svcGameEventList := types.SvcGameEventList{ Events: int16(reader.TryReadBits(9)), Length: int32(reader.TryReadBits(20)), } gameEventListReader := bitreader.NewReaderFromBytes(reader.TryReadBitsToSlice(uint64(svcGameEventList.Length)), true) - writer.TempAppendLine("\t\t%d Events:", svcGameEventList.Events) - svcGameEventList.parseGameEventDescriptor(gameEventListReader) - GameEventList = &svcGameEventList + demo.Writer.TempAppendLine("\t\t%d Events:", svcGameEventList.Events) + svcGameEventList.ParseGameEventDescriptor(gameEventListReader, demo) + demo.GameEventList = &svcGameEventList return svcGameEventList } - -func (svcGameEventList *SvcGameEventList) parseGameEventDescriptor(reader *bitreader.Reader) { - svcGameEventList.GameEventDescriptor = make([]GameEventDescriptor, svcGameEventList.Events) - for event := 0; event < int(svcGameEventList.Events); event++ { - svcGameEventList.GameEventDescriptor[event] = GameEventDescriptor{ - EventID: uint32(reader.TryReadBits(9)), - Name: reader.TryReadString(), - } - writer.TempAppendLine("\t\t\t%d: %s", svcGameEventList.GameEventDescriptor[event].EventID, svcGameEventList.GameEventDescriptor[event].Name) - for { - descriptorType := reader.TryReadBits(3) - if descriptorType == 0 { - break - } - KeyName := reader.TryReadString() - svcGameEventList.GameEventDescriptor[event].Keys = append(svcGameEventList.GameEventDescriptor[event].Keys, GameEventDescriptorKey{ - Name: KeyName, - Type: EventDescriptor(descriptorType), - }) - } - writer.TempAppendLine("\t\t\t\tKeys: %v", svcGameEventList.GameEventDescriptor[event].Keys) - } -} - -const ( - EventDescriptorString EventDescriptor = iota + 1 - EventDescriptorFloat - EventDescriptorInt32 - EventDescriptorInt16 - EventDescriptorInt8 - EventDescriptorBool - EventDescriptorUInt64 -) - -func (eventDescriptor EventDescriptor) String() string { - switch eventDescriptor { - case EventDescriptorString: - return "String" - case EventDescriptorFloat: - return "Float" - case EventDescriptorInt32: - return "Int32" - case EventDescriptorInt16: - return "Int16" - case EventDescriptorInt8: - return "Int8" - case EventDescriptorBool: - return "Bool" - case EventDescriptorUInt64: - return "UInt64" - default: - return fmt.Sprintf("%d", eventDescriptor) - } -} diff --git a/pkg/messages/types/svcGetCvarValue.go b/pkg/messages/types/svcGetCvarValue.go index 5deb9ef..1c3e54c 100644 --- a/pkg/messages/types/svcGetCvarValue.go +++ b/pkg/messages/types/svcGetCvarValue.go @@ -2,20 +2,20 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcGetCvarValue struct { - Cookie int32 - CvarName string + Cookie int32 `json:"cookie"` + CvarName string `json:"cvar_name"` } -func ParseSvcGetCvarValue(reader *bitreader.Reader) SvcGetCvarValue { +func ParseSvcGetCvarValue(reader *bitreader.Reader, demo *types.Demo) SvcGetCvarValue { svcGetCvarValue := SvcGetCvarValue{ Cookie: reader.TryReadSInt32(), CvarName: reader.TryReadString(), } - writer.TempAppendLine("\t\tCookie: %d", svcGetCvarValue.Cookie) - writer.TempAppendLine("\t\tCvar: \"%s\"", svcGetCvarValue.CvarName) + demo.Writer.TempAppendLine("\t\tCookie: %d", svcGetCvarValue.Cookie) + demo.Writer.TempAppendLine("\t\tCvar: \"%s\"", svcGetCvarValue.CvarName) return svcGetCvarValue } diff --git a/pkg/messages/types/svcMenu.go b/pkg/messages/types/svcMenu.go index ffbb86b..b1da594 100644 --- a/pkg/messages/types/svcMenu.go +++ b/pkg/messages/types/svcMenu.go @@ -2,22 +2,22 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcMenu struct { - Type uint16 - Length uint32 - Data []byte + Type uint16 `json:"type"` + Length uint32 `json:"length"` + Data []byte `json:"data"` } -func ParseSvcMenu(reader *bitreader.Reader) SvcMenu { +func ParseSvcMenu(reader *bitreader.Reader, demo *types.Demo) SvcMenu { svcMenu := SvcMenu{ Type: reader.TryReadUInt16(), Length: reader.TryReadUInt32(), } svcMenu.Data = reader.TryReadBitsToSlice(uint64(svcMenu.Length)) - writer.TempAppendLine("\t\tType: %d", svcMenu.Type) - writer.TempAppendLine("\t\tData: %v", svcMenu.Data) + demo.Writer.TempAppendLine("\t\tType: %d", svcMenu.Type) + demo.Writer.TempAppendLine("\t\tData: %v", svcMenu.Data) return svcMenu } diff --git a/pkg/messages/types/svcPacketEntities.go b/pkg/messages/types/svcPacketEntities.go index 188f827..abef83d 100644 --- a/pkg/messages/types/svcPacketEntities.go +++ b/pkg/messages/types/svcPacketEntities.go @@ -2,21 +2,21 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcPacketEntities struct { - MaxEntries uint16 - IsDelta bool - DeltaFrom int32 - BaseLine bool - UpdatedEntries uint16 - Length uint32 - UpdatedBaseline bool - Data []byte + MaxEntries uint16 `json:"max_entries"` + IsDelta bool `json:"is_delta"` + DeltaFrom int32 `json:"delta_from"` + BaseLine bool `json:"base_line"` + UpdatedEntries uint16 `json:"updated_entries"` + Length uint32 `json:"length"` + UpdatedBaseline bool `json:"updated_baseline"` + Data []byte `json:"data"` } -func ParseSvcPacketEntities(reader *bitreader.Reader) SvcPacketEntities { +func ParseSvcPacketEntities(reader *bitreader.Reader, demo *types.Demo) SvcPacketEntities { svcPacketEntities := SvcPacketEntities{ MaxEntries: uint16(reader.TryReadBits(11)), IsDelta: reader.TryReadBool(), @@ -31,12 +31,12 @@ func ParseSvcPacketEntities(reader *bitreader.Reader) SvcPacketEntities { svcPacketEntities.Length = uint32(reader.TryReadBits(20)) svcPacketEntities.UpdatedBaseline = reader.TryReadBool() svcPacketEntities.Data = reader.TryReadBitsToSlice(uint64(svcPacketEntities.Length)) - writer.TempAppendLine("\t\tMax Entries: %d", svcPacketEntities.MaxEntries) - writer.TempAppendLine("\t\tIs Delta: %t", svcPacketEntities.IsDelta) - writer.TempAppendLine("\t\tDelta From: %d", svcPacketEntities.DeltaFrom) - writer.TempAppendLine("\t\tBaseline: %t", svcPacketEntities.BaseLine) - writer.TempAppendLine("\t\tUpdated Baseline: %t", svcPacketEntities.UpdatedBaseline) - writer.TempAppendLine("\t\t%d Updated Entries:", svcPacketEntities.UpdatedEntries) - writer.TempAppendLine("\t\tData: %v", svcPacketEntities.Data) + demo.Writer.TempAppendLine("\t\tMax Entries: %d", svcPacketEntities.MaxEntries) + demo.Writer.TempAppendLine("\t\tIs Delta: %t", svcPacketEntities.IsDelta) + demo.Writer.TempAppendLine("\t\tDelta From: %d", svcPacketEntities.DeltaFrom) + demo.Writer.TempAppendLine("\t\tBaseline: %t", svcPacketEntities.BaseLine) + demo.Writer.TempAppendLine("\t\tUpdated Baseline: %t", svcPacketEntities.UpdatedBaseline) + demo.Writer.TempAppendLine("\t\t%d Updated Entries:", svcPacketEntities.UpdatedEntries) + demo.Writer.TempAppendLine("\t\tData: %v", svcPacketEntities.Data) return svcPacketEntities } diff --git a/pkg/messages/types/svcPaintmapData.go b/pkg/messages/types/svcPaintmapData.go index 10f8031..2455f83 100644 --- a/pkg/messages/types/svcPaintmapData.go +++ b/pkg/messages/types/svcPaintmapData.go @@ -2,19 +2,19 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcPaintmapData struct { - Length uint32 - Data []byte + Length uint32 `json:"length"` + Data []byte `json:"data"` } -func ParseSvcPaintmapData(reader *bitreader.Reader) SvcPaintmapData { +func ParseSvcPaintmapData(reader *bitreader.Reader, demo *types.Demo) SvcPaintmapData { svcPaintmapData := SvcPaintmapData{ Length: reader.TryReadUInt32(), } svcPaintmapData.Data = reader.TryReadBitsToSlice(uint64(svcPaintmapData.Length)) - writer.TempAppendLine("\t\tData: %v", svcPaintmapData.Data) + demo.Writer.TempAppendLine("\t\tData: %v", svcPaintmapData.Data) return svcPaintmapData } diff --git a/pkg/messages/types/svcPrefetch.go b/pkg/messages/types/svcPrefetch.go index 6aa39aa..55b6713 100644 --- a/pkg/messages/types/svcPrefetch.go +++ b/pkg/messages/types/svcPrefetch.go @@ -2,17 +2,17 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcPrefetch struct { - SoundIndex int16 + SoundIndex int16 `json:"sound_index"` } -func ParseSvcPrefetch(reader *bitreader.Reader) SvcPrefetch { +func ParseSvcPrefetch(reader *bitreader.Reader, demo *types.Demo) SvcPrefetch { svcPrefetch := SvcPrefetch{ SoundIndex: int16(reader.TryReadBits(13)), } - writer.TempAppendLine("\t\tSound Index: %d", svcPrefetch.SoundIndex) + demo.Writer.TempAppendLine("\t\tSound Index: %d", svcPrefetch.SoundIndex) return svcPrefetch } diff --git a/pkg/messages/types/svcPrint.go b/pkg/messages/types/svcPrint.go index 56f0d08..0db7ffd 100644 --- a/pkg/messages/types/svcPrint.go +++ b/pkg/messages/types/svcPrint.go @@ -4,18 +4,18 @@ import ( "strings" "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcPrint struct { - Message string + Message string `json:"message"` } -func ParseSvcPrint(reader *bitreader.Reader) SvcPrint { +func ParseSvcPrint(reader *bitreader.Reader, demo *types.Demo) SvcPrint { svcPrint := SvcPrint{ Message: reader.TryReadString(), } // common psycopath behaviour - writer.TempAppendLine("\t\t%s", strings.Replace(strings.ReplaceAll(strings.ReplaceAll(svcPrint.Message, "\n", "\n\t\t"), "\n\t\t\n\t\t", ""), "\n\t\t", "", 1)) + demo.Writer.TempAppendLine("\t\t%s", strings.Replace(strings.ReplaceAll(strings.ReplaceAll(svcPrint.Message, "\n", "\n\t\t"), "\n\t\t\n\t\t", ""), "\n\t\t", "", 1)) return svcPrint } diff --git a/pkg/messages/types/svcSendTable.go b/pkg/messages/types/svcSendTable.go index d0def36..fc98eb6 100644 --- a/pkg/messages/types/svcSendTable.go +++ b/pkg/messages/types/svcSendTable.go @@ -2,23 +2,23 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcSendTable struct { - NeedsDecoder bool - Length uint8 - Props uint32 + NeedsDecoder bool `json:"needs_decoder"` + Length uint8 `json:"length"` + Props uint32 `json:"props"` } -func ParseSvcSendTable(reader *bitreader.Reader) SvcSendTable { +func ParseSvcSendTable(reader *bitreader.Reader, demo *types.Demo) SvcSendTable { svcSendTable := SvcSendTable{ NeedsDecoder: reader.TryReadBool(), Length: reader.TryReadUInt8(), } svcSendTable.Props = uint32(reader.TryReadBits(uint64(svcSendTable.Length))) - writer.TempAppendLine("\t\tNeeds Decoder: %t", svcSendTable.NeedsDecoder) - writer.TempAppendLine("\t\tLength: %d", svcSendTable.Length) - writer.TempAppendLine("\t\tProps: %d", svcSendTable.Props) + demo.Writer.TempAppendLine("\t\tNeeds Decoder: %t", svcSendTable.NeedsDecoder) + demo.Writer.TempAppendLine("\t\tLength: %d", svcSendTable.Length) + demo.Writer.TempAppendLine("\t\tProps: %d", svcSendTable.Props) return svcSendTable } diff --git a/pkg/messages/types/svcServerInfo.go b/pkg/messages/types/svcServerInfo.go index 9e3113c..2aabccd 100644 --- a/pkg/messages/types/svcServerInfo.go +++ b/pkg/messages/types/svcServerInfo.go @@ -2,29 +2,29 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcServerInfo struct { - Protocol uint16 - ServerCount uint32 - IsHltv bool - IsDedicated bool - ClientCrc int32 - StringTableCrc uint32 - MaxServerClasses uint16 - MapCrc uint32 - PlayerCount uint8 - MaxClients uint8 - TickInterval float32 - Platform string - GameDir string - MapName string - SkyName string - HostName string + Protocol uint16 `json:"protocol"` + ServerCount uint32 `json:"server_count"` + IsHltv bool `json:"is_hltv"` + IsDedicated bool `json:"is_dedicated"` + ClientCrc int32 `json:"client_crc"` + StringTableCrc uint32 `json:"string_table_crc"` + MaxServerClasses uint16 `json:"max_server_classes"` + MapCrc uint32 `json:"map_crc"` + PlayerCount uint8 `json:"player_count"` + MaxClients uint8 `json:"max_clients"` + TickInterval float32 `json:"tick_interval"` + Platform string `json:"platform"` + GameDir string `json:"game_dir"` + MapName string `json:"map_name"` + SkyName string `json:"sky_name"` + HostName string `json:"host_name"` } -func ParseSvcServerInfo(reader *bitreader.Reader) SvcServerInfo { +func ParseSvcServerInfo(reader *bitreader.Reader, demo *types.Demo) SvcServerInfo { svcServerInfo := SvcServerInfo{ Protocol: reader.TryReadUInt16(), ServerCount: reader.TryReadUInt32(), @@ -43,21 +43,21 @@ func ParseSvcServerInfo(reader *bitreader.Reader) SvcServerInfo { SkyName: reader.TryReadString(), HostName: reader.TryReadString(), } - writer.TempAppendLine("\t\tNetwork Protocol: %d", svcServerInfo.Protocol) - writer.TempAppendLine("\t\tServer Count: %d", svcServerInfo.ServerCount) - writer.TempAppendLine("\t\tIs Hltv: %t", svcServerInfo.IsHltv) - writer.TempAppendLine("\t\tIs Dedicated: %t", svcServerInfo.IsDedicated) - writer.TempAppendLine("\t\tServer Client CRC: %d", svcServerInfo.ClientCrc) - writer.TempAppendLine("\t\tString Table CRC: %d", svcServerInfo.StringTableCrc) - writer.TempAppendLine("\t\tMax Server Classes: %d", svcServerInfo.MaxServerClasses) - writer.TempAppendLine("\t\tServer Map CRC: %d", svcServerInfo.MapCrc) - writer.TempAppendLine("\t\tCurrent Player Count: %d", svcServerInfo.PlayerCount) - writer.TempAppendLine("\t\tMax Player Count: %d", svcServerInfo.MaxClients) - writer.TempAppendLine("\t\tInterval Per Tick: %f", svcServerInfo.TickInterval) - writer.TempAppendLine("\t\tPlatform: %s", svcServerInfo.Platform) - writer.TempAppendLine("\t\tGame Directory: %s", svcServerInfo.GameDir) - writer.TempAppendLine("\t\tMap Name: %s", svcServerInfo.MapName) - writer.TempAppendLine("\t\tSky Name: %s", svcServerInfo.SkyName) - writer.TempAppendLine("\t\tHost Name: %s", svcServerInfo.HostName) + demo.Writer.TempAppendLine("\t\tNetwork Protocol: %d", svcServerInfo.Protocol) + demo.Writer.TempAppendLine("\t\tServer Count: %d", svcServerInfo.ServerCount) + demo.Writer.TempAppendLine("\t\tIs Hltv: %t", svcServerInfo.IsHltv) + demo.Writer.TempAppendLine("\t\tIs Dedicated: %t", svcServerInfo.IsDedicated) + demo.Writer.TempAppendLine("\t\tServer Client CRC: %d", svcServerInfo.ClientCrc) + demo.Writer.TempAppendLine("\t\tString Table CRC: %d", svcServerInfo.StringTableCrc) + demo.Writer.TempAppendLine("\t\tMax Server Classes: %d", svcServerInfo.MaxServerClasses) + demo.Writer.TempAppendLine("\t\tServer Map CRC: %d", svcServerInfo.MapCrc) + demo.Writer.TempAppendLine("\t\tCurrent Player Count: %d", svcServerInfo.PlayerCount) + demo.Writer.TempAppendLine("\t\tMax Player Count: %d", svcServerInfo.MaxClients) + demo.Writer.TempAppendLine("\t\tInterval Per Tick: %f", svcServerInfo.TickInterval) + demo.Writer.TempAppendLine("\t\tPlatform: %s", svcServerInfo.Platform) + demo.Writer.TempAppendLine("\t\tGame Directory: %s", svcServerInfo.GameDir) + demo.Writer.TempAppendLine("\t\tMap Name: %s", svcServerInfo.MapName) + demo.Writer.TempAppendLine("\t\tSky Name: %s", svcServerInfo.SkyName) + demo.Writer.TempAppendLine("\t\tHost Name: %s", svcServerInfo.HostName) return svcServerInfo } diff --git a/pkg/messages/types/svcSetPause.go b/pkg/messages/types/svcSetPause.go index b69779f..ad9f2d5 100644 --- a/pkg/messages/types/svcSetPause.go +++ b/pkg/messages/types/svcSetPause.go @@ -2,17 +2,17 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcSetPause struct { - Paused bool + Paused bool `json:"paused"` } -func ParseSvcSetPause(reader *bitreader.Reader) SvcSetPause { +func ParseSvcSetPause(reader *bitreader.Reader, demo *types.Demo) SvcSetPause { svcSetPause := SvcSetPause{ Paused: reader.TryReadBool(), } - writer.TempAppendLine("\t\tPaused: %t", svcSetPause.Paused) + demo.Writer.TempAppendLine("\t\tPaused: %t", svcSetPause.Paused) return svcSetPause } diff --git a/pkg/messages/types/svcSetView.go b/pkg/messages/types/svcSetView.go index a392d36..55b2065 100644 --- a/pkg/messages/types/svcSetView.go +++ b/pkg/messages/types/svcSetView.go @@ -2,17 +2,17 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcSetView struct { - EntityIndex uint16 + EntityIndex uint16 `json:"entity_index"` } -func ParseSvcSetView(reader *bitreader.Reader) SvcSetView { +func ParseSvcSetView(reader *bitreader.Reader, demo *types.Demo) SvcSetView { svcSetView := SvcSetView{ EntityIndex: uint16(reader.TryReadBits(11)), } - writer.TempAppendLine("\t\tEntity Index: %d", svcSetView.EntityIndex) + demo.Writer.TempAppendLine("\t\tEntity Index: %d", svcSetView.EntityIndex) return svcSetView } diff --git a/pkg/messages/types/svcSounds.go b/pkg/messages/types/svcSounds.go index 5391af1..cc155e5 100644 --- a/pkg/messages/types/svcSounds.go +++ b/pkg/messages/types/svcSounds.go @@ -2,17 +2,17 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcSounds struct { - ReliableSound bool - SoundCount uint8 - Length uint16 - Data []byte + ReliableSound bool `json:"reliable_sound"` + SoundCount uint8 `json:"sound_count"` + Length uint16 `json:"length"` + Data []byte `json:"data"` } -func ParseSvcSounds(reader *bitreader.Reader) SvcSounds { +func ParseSvcSounds(reader *bitreader.Reader, demo *types.Demo) SvcSounds { svcSounds := SvcSounds{ ReliableSound: reader.TryReadBool(), } @@ -24,8 +24,8 @@ func ParseSvcSounds(reader *bitreader.Reader) SvcSounds { svcSounds.Length = reader.TryReadUInt16() } svcSounds.Data = reader.TryReadBitsToSlice(uint64(svcSounds.Length)) - writer.TempAppendLine("\t\tReliable Sound: %t", svcSounds.ReliableSound) - writer.TempAppendLine("\t\tSound Count: %d", svcSounds.SoundCount) - writer.TempAppendLine("\t\tData: %v", svcSounds.Data) + demo.Writer.TempAppendLine("\t\tReliable Sound: %t", svcSounds.ReliableSound) + demo.Writer.TempAppendLine("\t\tSound Count: %d", svcSounds.SoundCount) + demo.Writer.TempAppendLine("\t\tData: %v", svcSounds.Data) return svcSounds } diff --git a/pkg/messages/types/svcSplitScreen.go b/pkg/messages/types/svcSplitScreen.go index e7f77c0..a4d4e48 100644 --- a/pkg/messages/types/svcSplitScreen.go +++ b/pkg/messages/types/svcSplitScreen.go @@ -2,22 +2,22 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcSplitScreen struct { - RemoveUser bool - Length uint16 - Data []byte + RemoveUser bool `json:"remove_user"` + Length uint16 `json:"length"` + Data []byte `json:"data"` } -func ParseSvcSplitScreen(reader *bitreader.Reader) SvcSplitScreen { +func ParseSvcSplitScreen(reader *bitreader.Reader, demo *types.Demo) SvcSplitScreen { svcSplitScreen := SvcSplitScreen{ RemoveUser: reader.TryReadBool(), Length: uint16(reader.TryReadBits(11)), } svcSplitScreen.Data = reader.TryReadBitsToSlice(uint64(svcSplitScreen.Length)) - writer.TempAppendLine("\t\tRemove User: %t", svcSplitScreen.RemoveUser) - writer.TempAppendLine("\t\tData: %v", svcSplitScreen.Data) + demo.Writer.TempAppendLine("\t\tRemove User: %t", svcSplitScreen.RemoveUser) + demo.Writer.TempAppendLine("\t\tData: %v", svcSplitScreen.Data) return svcSplitScreen } diff --git a/pkg/messages/types/svcTempEntities.go b/pkg/messages/types/svcTempEntities.go index 08c0af4..452e712 100644 --- a/pkg/messages/types/svcTempEntities.go +++ b/pkg/messages/types/svcTempEntities.go @@ -2,22 +2,22 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcTempEntities struct { - NumEntries uint8 - Length uint32 - Data []byte + NumEntries uint8 `json:"num_entries"` + Length uint32 `json:"length"` + Data []byte `json:"data"` } -func ParseSvcTempEntities(reader *bitreader.Reader) SvcTempEntities { +func ParseSvcTempEntities(reader *bitreader.Reader, demo *types.Demo) SvcTempEntities { svcTempEntities := SvcTempEntities{ NumEntries: reader.TryReadUInt8(), Length: uint32(reader.TryReadBits(17)), } svcTempEntities.Data = reader.TryReadBitsToSlice(uint64(svcTempEntities.Length)) - writer.TempAppendLine("\t\tNumber Of Entries: %d", svcTempEntities.NumEntries) - writer.TempAppendLine("\t\tData: %v", svcTempEntities.Data) + demo.Writer.TempAppendLine("\t\tNumber Of Entries: %d", svcTempEntities.NumEntries) + demo.Writer.TempAppendLine("\t\tData: %v", svcTempEntities.Data) return svcTempEntities } diff --git a/pkg/messages/types/svcUpdateStringTable.go b/pkg/messages/types/svcUpdateStringTable.go index 11e63d4..7e15cd2 100644 --- a/pkg/messages/types/svcUpdateStringTable.go +++ b/pkg/messages/types/svcUpdateStringTable.go @@ -2,17 +2,17 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcUpdateStringTable struct { - TableId uint8 - NumChangedEntries uint16 - Length int32 - Data []byte + TableId uint8 `json:"table_id"` + NumChangedEntries uint16 `json:"num_changed_entries"` + Length int32 `json:"length"` + Data []byte `json:"data"` } -func ParseSvcUpdateStringTable(reader *bitreader.Reader) SvcUpdateStringTable { +func ParseSvcUpdateStringTable(reader *bitreader.Reader, demo *types.Demo) SvcUpdateStringTable { svcUpdateStringTable := SvcUpdateStringTable{ TableId: uint8(reader.TryReadBits(5)), } @@ -21,7 +21,7 @@ func ParseSvcUpdateStringTable(reader *bitreader.Reader) SvcUpdateStringTable { } svcUpdateStringTable.Length = int32(reader.TryReadBits(20)) svcUpdateStringTable.Data = reader.TryReadBitsToSlice(uint64(svcUpdateStringTable.Length)) - writer.TempAppendLine("\t\tTable ID: %d", svcUpdateStringTable.TableId) - writer.TempAppendLine("\t\tNumber Of Changed Entries: %d", svcUpdateStringTable.NumChangedEntries) + demo.Writer.TempAppendLine("\t\tTable ID: %d", svcUpdateStringTable.TableId) + demo.Writer.TempAppendLine("\t\tNumber Of Changed Entries: %d", svcUpdateStringTable.NumChangedEntries) return svcUpdateStringTable } diff --git a/pkg/messages/types/svcUserMessage.go b/pkg/messages/types/svcUserMessage.go index 138f8d3..1bb0e0e 100644 --- a/pkg/messages/types/svcUserMessage.go +++ b/pkg/messages/types/svcUserMessage.go @@ -5,134 +5,134 @@ import ( "math" "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcUserMessage struct { - Type int8 - Length int16 - Data any + Type int8 `json:"type"` + Length int16 `json:"length"` + Data any `json:"data"` } -func ParseSvcUserMessage(reader *bitreader.Reader) SvcUserMessage { +func ParseSvcUserMessage(reader *bitreader.Reader, demo *types.Demo) SvcUserMessage { svcUserMessage := SvcUserMessage{ Type: int8(reader.TryReadBits(8)), Length: int16(reader.TryReadBits(12)), } svcUserMessage.Data = reader.TryReadBitsToSlice(uint64(svcUserMessage.Length)) userMessageReader := bitreader.NewReaderFromBytes(svcUserMessage.Data.([]byte), true) - writer.TempAppendLine("\t\t%s (%d):", UserMessageType(svcUserMessage.Type).String(), svcUserMessage.Type) + demo.Writer.TempAppendLine("\t\t%s (%d):", UserMessageType(svcUserMessage.Type).String(), svcUserMessage.Type) switch UserMessageType(svcUserMessage.Type) { case EUserMessageTypeGeiger: - svcUserMessage.parseGeiger(userMessageReader) + svcUserMessage.parseGeiger(userMessageReader, demo) case EUserMessageTypeTrain: - svcUserMessage.parseTrain(userMessageReader) + svcUserMessage.parseTrain(userMessageReader, demo) case EUserMessageTypeHudText: - svcUserMessage.parseHUDText(userMessageReader) + svcUserMessage.parseHUDText(userMessageReader, demo) case EUserMessageTypeSayText: - svcUserMessage.parseSayText(userMessageReader) + svcUserMessage.parseSayText(userMessageReader, demo) case EUserMessageTypeSayText2: - svcUserMessage.parseSayText2(userMessageReader) + svcUserMessage.parseSayText2(userMessageReader, demo) case EUserMessageTypeTextMsg: - svcUserMessage.parseTextMsg(userMessageReader) + svcUserMessage.parseTextMsg(userMessageReader, demo) case EUserMessageTypeHUDMsg: - svcUserMessage.parseHUDMsg(userMessageReader) + svcUserMessage.parseHUDMsg(userMessageReader, demo) case EUserMessageTypeResetHUD: - svcUserMessage.parseResetHUD(userMessageReader) + svcUserMessage.parseResetHUD(userMessageReader, demo) case EUserMessageTypeShake: - svcUserMessage.parseShake(userMessageReader) + svcUserMessage.parseShake(userMessageReader, demo) case EUserMessageTypeFade: - svcUserMessage.parseFade(userMessageReader) + svcUserMessage.parseFade(userMessageReader, demo) case EUserMessageTypeVGUIMenu: - svcUserMessage.parseVguiMenu(userMessageReader) + svcUserMessage.parseVguiMenu(userMessageReader, demo) case EUserMessageTypeRumble: - svcUserMessage.parseRumble(userMessageReader) + svcUserMessage.parseRumble(userMessageReader, demo) case EUserMessageTypeBattery: - svcUserMessage.parseBattery(userMessageReader) + svcUserMessage.parseBattery(userMessageReader, demo) case EUserMessageTypeDamage: - svcUserMessage.parseDamage(userMessageReader) + svcUserMessage.parseDamage(userMessageReader, demo) case EUserMessageTypeVoiceMask: - svcUserMessage.parseVoiceMask(userMessageReader) + svcUserMessage.parseVoiceMask(userMessageReader, demo) case EUserMessageTypeCloseCaption: - svcUserMessage.parseCloseCaption(userMessageReader) + svcUserMessage.parseCloseCaption(userMessageReader, demo) case EUserMessageTypeKeyHintText: - svcUserMessage.parseKeyHintText(userMessageReader) + svcUserMessage.parseKeyHintText(userMessageReader, demo) case EUserMessageTypeLogoTimeMsg: - svcUserMessage.parseLogoTimeMsg(userMessageReader) + svcUserMessage.parseLogoTimeMsg(userMessageReader, demo) case EUserMessageTypeAchievementEvent: - svcUserMessage.parseAchivementEvent(userMessageReader) + svcUserMessage.parseAchivementEvent(userMessageReader, demo) case EUserMessageTypeCurrentTimescale: - svcUserMessage.parseCurrentTimescale(userMessageReader) + svcUserMessage.parseCurrentTimescale(userMessageReader, demo) case EUserMessageTypeDesiredTimescale: - svcUserMessage.parseDesiredTimescale(userMessageReader) + svcUserMessage.parseDesiredTimescale(userMessageReader, demo) case EUserMessageTypeMPMapCompleted: - svcUserMessage.parseMpMapCompleted(userMessageReader) + svcUserMessage.parseMpMapCompleted(userMessageReader, demo) case EUserMessageTypeMPMapIncomplete: - svcUserMessage.parseMpMapIncomplete(userMessageReader) + svcUserMessage.parseMpMapIncomplete(userMessageReader, demo) case EUserMessageTypeMPTauntEarned: - svcUserMessage.parseMpTauntEarned(userMessageReader) + svcUserMessage.parseMpTauntEarned(userMessageReader, demo) case EUserMessageTypeMPTauntLocked: - svcUserMessage.parseMpTauntLocked(userMessageReader) + svcUserMessage.parseMpTauntLocked(userMessageReader, demo) case EUserMessageTypePortalFX_Surface: - svcUserMessage.parsePortalFxSurface(userMessageReader) + svcUserMessage.parsePortalFxSurface(userMessageReader, demo) case EUserMessageTypePaintWorld: - svcUserMessage.parsePaintWorld(userMessageReader) + svcUserMessage.parsePaintWorld(userMessageReader, demo) case EUserMessageTypeTransitionFade: - svcUserMessage.parseTransitionFade(userMessageReader) + svcUserMessage.parseTransitionFade(userMessageReader, demo) case EUserMessageTypeScoreboardTempUpdate: - svcUserMessage.parseScoreboardTempUpdate(userMessageReader) + svcUserMessage.parseScoreboardTempUpdate(userMessageReader, demo) default: - writer.TempAppendLine("\t\t\tData: %v", svcUserMessage.Data) + demo.Writer.TempAppendLine("\t\t\tData: %v", svcUserMessage.Data) } return svcUserMessage } -func (svcUserMessage *SvcUserMessage) parseGeiger(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseGeiger(reader *bitreader.Reader, demo *types.Demo) { geiger := struct{ Range uint8 }{ Range: reader.TryReadUInt8(), } svcUserMessage.Data = geiger - writer.TempAppendLine("\t\t\tGeiger Range: %d", geiger.Range) + demo.Writer.TempAppendLine("\t\t\tGeiger Range: %d", geiger.Range) } -func (svcUserMessage *SvcUserMessage) parseTrain(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseTrain(reader *bitreader.Reader, demo *types.Demo) { train := struct{ Pos uint8 }{ Pos: reader.TryReadUInt8(), } svcUserMessage.Data = train - writer.TempAppendLine("\t\t\tPos: %d", train.Pos) + demo.Writer.TempAppendLine("\t\t\tPos: %d", train.Pos) } -func (svcUserMessage *SvcUserMessage) parseHUDText(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseHUDText(reader *bitreader.Reader, demo *types.Demo) { hudText := struct{ Text string }{ Text: reader.TryReadString(), } svcUserMessage.Data = hudText - writer.TempAppendLine("\t\t\tText: %s", hudText.Text) + demo.Writer.TempAppendLine("\t\t\tText: %s", hudText.Text) } -func (svcUserMessage *SvcUserMessage) parseSayText(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseSayText(reader *bitreader.Reader, demo *types.Demo) { sayText := struct { - Client uint8 - Message string - WantsToChat bool + Client uint8 `json:"client"` + Message string `json:"message"` + WantsToChat bool `json:"wants_to_chat"` }{ Client: reader.TryReadUInt8(), Message: reader.TryReadString(), WantsToChat: reader.TryReadUInt8() != 0, } svcUserMessage.Data = sayText - writer.TempAppendLine("\t\t\tClient: %d", sayText.Client) - writer.TempAppendLine("\t\t\tMessage: %s", sayText.Message) - writer.TempAppendLine("\t\t\tWants To Chat: %t", sayText.WantsToChat) + demo.Writer.TempAppendLine("\t\t\tClient: %d", sayText.Client) + demo.Writer.TempAppendLine("\t\t\tMessage: %s", sayText.Message) + demo.Writer.TempAppendLine("\t\t\tWants To Chat: %t", sayText.WantsToChat) } -func (svcUserMessage *SvcUserMessage) parseSayText2(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseSayText2(reader *bitreader.Reader, demo *types.Demo) { sayText2 := struct { - Client uint8 - WantsToChat bool - MessageName string - Messages []string + Client uint8 `json:"client"` + WantsToChat bool `json:"wants_to_chat"` + MessageName string `json:"message_name"` + Messages []string `json:"messages"` }{ Client: reader.TryReadUInt8(), WantsToChat: reader.TryReadUInt8() != 0, @@ -140,15 +140,15 @@ func (svcUserMessage *SvcUserMessage) parseSayText2(reader *bitreader.Reader) { Messages: []string{reader.TryReadString(), reader.TryReadString(), reader.TryReadString()}, } svcUserMessage.Data = sayText2 - writer.TempAppendLine("\t\t\tClient: %d", sayText2.Client) - writer.TempAppendLine("\t\t\tWants To Chat: %t", sayText2.WantsToChat) - writer.TempAppendLine("\t\t\tName: %s", sayText2.MessageName) + demo.Writer.TempAppendLine("\t\t\tClient: %d", sayText2.Client) + demo.Writer.TempAppendLine("\t\t\tWants To Chat: %t", sayText2.WantsToChat) + demo.Writer.TempAppendLine("\t\t\tName: %s", sayText2.MessageName) for index, message := range sayText2.Messages { - writer.TempAppendLine("\t\t\tMessage %d: %s", index, message) + demo.Writer.TempAppendLine("\t\t\tMessage %d: %s", index, message) } } -func (svcUserMessage *SvcUserMessage) parseTextMsg(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseTextMsg(reader *bitreader.Reader, demo *types.Demo) { const MessageCount int = 5 textMsg := struct { Destination uint8 @@ -161,47 +161,57 @@ func (svcUserMessage *SvcUserMessage) parseTextMsg(reader *bitreader.Reader) { textMsg.Messages[i] = reader.TryReadString() } svcUserMessage.Data = textMsg - writer.TempAppendLine("\t\t\tDestination: %d", textMsg.Destination) + demo.Writer.TempAppendLine("\t\t\tDestination: %d", textMsg.Destination) for i := 0; i < MessageCount; i++ { - writer.TempAppendLine("\t\t\tMessage %d: %s", i+1, textMsg.Messages) + demo.Writer.TempAppendLine("\t\t\tMessage %d: %s", i+1, textMsg.Messages) } } -func (svcUserMessage *SvcUserMessage) parseHUDMsg(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseHUDMsg(reader *bitreader.Reader, demo *types.Demo) { const MaxNetMessage uint8 = 6 hudMsg := struct { - Channel uint8 + Channel uint8 `json:"channel"` Info struct { - X, Y float32 // 0-1 & resolution independent, -1 means center in each dimension - R1, G1, B1, A1 uint8 - R2, G2, B2, A2 uint8 - Effect uint8 - FadeIn, FadeOut, HoldTime, FxTime float32 // the fade times seem to be per character - Message string - } + X float32 `json:"x"` // 0-1 & resolution independent, -1 means center in each dimension + Y float32 `json:"y"` + R1 uint8 `json:"r_1"` + G1 uint8 `json:"g_1"` + B1 uint8 `json:"b_1"` + A1 uint8 `json:"a_1"` + R2 uint8 `json:"r_2"` + G2 uint8 `json:"g_2"` + B2 uint8 `json:"b_2"` + A2 uint8 `json:"a_2"` + Effect uint8 `json:"effect"` + FadeIn float32 `json:"fade_in"` // the fade times seem to be per character + FadeOut float32 `json:"fade_out"` + HoldTime float32 `json:"hold_time"` + FxTime float32 `json:"fx_time"` + Message string `json:"message"` + } `json:"info"` }{ Channel: reader.TryReadUInt8() % MaxNetMessage, } svcUserMessage.Data = hudMsg - writer.TempAppendLine("\t\t\tChannel: %d", hudMsg.Channel) + demo.Writer.TempAppendLine("\t\t\tChannel: %d", hudMsg.Channel) if reader.TryReadRemainingBits() >= 148 { hudMsg.Info = struct { - X float32 - Y float32 - R1 uint8 - G1 uint8 - B1 uint8 - A1 uint8 - R2 uint8 - G2 uint8 - B2 uint8 - A2 uint8 - Effect uint8 - FadeIn float32 - FadeOut float32 - HoldTime float32 - FxTime float32 - Message string + X float32 `json:"x"` + Y float32 `json:"y"` + R1 uint8 `json:"r_1"` + G1 uint8 `json:"g_1"` + B1 uint8 `json:"b_1"` + A1 uint8 `json:"a_1"` + R2 uint8 `json:"r_2"` + G2 uint8 `json:"g_2"` + B2 uint8 `json:"b_2"` + A2 uint8 `json:"a_2"` + Effect uint8 `json:"effect"` + FadeIn float32 `json:"fade_in"` + FadeOut float32 `json:"fade_out"` + HoldTime float32 `json:"hold_time"` + FxTime float32 `json:"fx_time"` + Message string `json:"message"` }{ X: reader.TryReadFloat32(), Y: reader.TryReadFloat32(), @@ -221,27 +231,27 @@ func (svcUserMessage *SvcUserMessage) parseHUDMsg(reader *bitreader.Reader) { Message: reader.TryReadString(), } svcUserMessage.Data = hudMsg - writer.TempAppendLine("\t\t\tX: %f, Y: %f", hudMsg.Info.X, hudMsg.Info.Y) - writer.TempAppendLine("\t\t\tRGBA1: %3d %3d %3d %3d", hudMsg.Info.R1, hudMsg.Info.G1, hudMsg.Info.B1, hudMsg.Info.A1) - writer.TempAppendLine("\t\t\tRGBA2: %3d %3d %3d %3d", hudMsg.Info.R2, hudMsg.Info.G2, hudMsg.Info.B2, hudMsg.Info.A2) - writer.TempAppendLine("\t\t\tEffect: %d", hudMsg.Info.Effect) - writer.TempAppendLine("\t\t\tFade In: %f", hudMsg.Info.FadeIn) - writer.TempAppendLine("\t\t\tFade Out: %f", hudMsg.Info.FadeOut) - writer.TempAppendLine("\t\t\tHold Time: %f", hudMsg.Info.HoldTime) - writer.TempAppendLine("\t\t\tFX Time: %f", hudMsg.Info.FxTime) - writer.TempAppendLine("\t\t\tMessage: %s", hudMsg.Info.Message) + demo.Writer.TempAppendLine("\t\t\tX: %f, Y: %f", hudMsg.Info.X, hudMsg.Info.Y) + demo.Writer.TempAppendLine("\t\t\tRGBA1: %3d %3d %3d %3d", hudMsg.Info.R1, hudMsg.Info.G1, hudMsg.Info.B1, hudMsg.Info.A1) + demo.Writer.TempAppendLine("\t\t\tRGBA2: %3d %3d %3d %3d", hudMsg.Info.R2, hudMsg.Info.G2, hudMsg.Info.B2, hudMsg.Info.A2) + demo.Writer.TempAppendLine("\t\t\tEffect: %d", hudMsg.Info.Effect) + demo.Writer.TempAppendLine("\t\t\tFade In: %f", hudMsg.Info.FadeIn) + demo.Writer.TempAppendLine("\t\t\tFade Out: %f", hudMsg.Info.FadeOut) + demo.Writer.TempAppendLine("\t\t\tHold Time: %f", hudMsg.Info.HoldTime) + demo.Writer.TempAppendLine("\t\t\tFX Time: %f", hudMsg.Info.FxTime) + demo.Writer.TempAppendLine("\t\t\tMessage: %s", hudMsg.Info.Message) } } -func (svcUserMessage *SvcUserMessage) parseResetHUD(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseResetHUD(reader *bitreader.Reader, demo *types.Demo) { resetHUD := struct{ Unknown uint8 }{ Unknown: reader.TryReadUInt8(), } svcUserMessage.Data = resetHUD - writer.TempAppendLine("\t\t\tUnknown: %d", resetHUD.Unknown) + demo.Writer.TempAppendLine("\t\t\tUnknown: %d", resetHUD.Unknown) } -func (svcUserMessage *SvcUserMessage) parseShake(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseShake(reader *bitreader.Reader, demo *types.Demo) { type ShakeCommand uint8 const ( Start ShakeCommand = iota // Starts the screen shake for all players within the radius. @@ -252,10 +262,10 @@ func (svcUserMessage *SvcUserMessage) parseShake(reader *bitreader.Reader) { NoRumble // Starts a shake that does NOT rumble the controller. ) shake := struct { - Command uint8 - Amplitude float32 - Frequency float32 - Duration float32 + Command uint8 `json:"command"` + Amplitude float32 `json:"amplitude"` + Frequency float32 `json:"frequency"` + Duration float32 `json:"duration"` }{ Command: reader.TryReadUInt8(), Amplitude: reader.TryReadFloat32(), @@ -281,13 +291,13 @@ func (svcUserMessage *SvcUserMessage) parseShake(reader *bitreader.Reader) { } } svcUserMessage.Data = shake - writer.TempAppendLine("\t\t\tCommand: %s", shakeCommandToString(ShakeCommand(shake.Command))) - writer.TempAppendLine("\t\t\tAmplitude: %f", shake.Amplitude) - writer.TempAppendLine("\t\t\tFrequency: %f", shake.Frequency) - writer.TempAppendLine("\t\t\tDuration: %f", shake.Duration) + demo.Writer.TempAppendLine("\t\t\tCommand: %s", shakeCommandToString(ShakeCommand(shake.Command))) + demo.Writer.TempAppendLine("\t\t\tAmplitude: %f", shake.Amplitude) + demo.Writer.TempAppendLine("\t\t\tFrequency: %f", shake.Frequency) + demo.Writer.TempAppendLine("\t\t\tDuration: %f", shake.Duration) } -func (svcUserMessage *SvcUserMessage) parseFade(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseFade(reader *bitreader.Reader, demo *types.Demo) { type FadeFlag uint16 const ( None FadeFlag = 0 @@ -298,13 +308,13 @@ func (svcUserMessage *SvcUserMessage) parseFade(reader *bitreader.Reader) { Purge FadeFlag = 1 << 4 // Purges all other fades, replacing them with this one ) fade := struct { - Duration float32 - HoldTime uint16 - Flags uint16 - R uint8 - G uint8 - B uint8 - A uint8 + Duration float32 `json:"duration"` + HoldTime uint16 `json:"hold_time"` + Flags uint16 `json:"flags"` + R uint8 `json:"r"` + G uint8 `json:"g"` + B uint8 `json:"b"` + A uint8 `json:"a"` }{ Duration: float32(reader.TryReadUInt16()) / float32(1<<9), // might be useful: #define SCREENFADE_FRACBITS 9 HoldTime: reader.TryReadUInt16(), @@ -334,17 +344,17 @@ func (svcUserMessage *SvcUserMessage) parseFade(reader *bitreader.Reader) { return flagStrings } svcUserMessage.Data = fade - writer.TempAppendLine("\t\t\tDuration: %f", fade.Duration) - writer.TempAppendLine("\t\t\tHold Time: %d", fade.HoldTime) - writer.TempAppendLine("\t\t\tFlags: %v", getFlags(FadeFlag(fade.Flags))) - writer.TempAppendLine("\t\t\tRGBA: %3d %3d %3d %3d", fade.R, fade.G, fade.B, fade.A) + demo.Writer.TempAppendLine("\t\t\tDuration: %f", fade.Duration) + demo.Writer.TempAppendLine("\t\t\tHold Time: %d", fade.HoldTime) + demo.Writer.TempAppendLine("\t\t\tFlags: %v", getFlags(FadeFlag(fade.Flags))) + demo.Writer.TempAppendLine("\t\t\tRGBA: %3d %3d %3d %3d", fade.R, fade.G, fade.B, fade.A) } -func (svcUserMessage *SvcUserMessage) parseVguiMenu(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseVguiMenu(reader *bitreader.Reader, demo *types.Demo) { vguiMenu := struct { - Message string - Show bool - KeyValues []map[string]string + Message string `json:"message"` + Show bool `json:"show"` + KeyValues []map[string]string `json:"key_values"` }{ Message: reader.TryReadString(), Show: reader.TryReadUInt8() != 0, @@ -354,19 +364,19 @@ func (svcUserMessage *SvcUserMessage) parseVguiMenu(reader *bitreader.Reader) { vguiMenu.KeyValues = append(vguiMenu.KeyValues, map[string]string{"Key": reader.TryReadString(), "Value": reader.TryReadString()}) } svcUserMessage.Data = vguiMenu - writer.TempAppendLine("\t\t\tMessage: %s", vguiMenu.Message) - writer.TempAppendLine("\t\t\tShow: %t", vguiMenu.Show) + demo.Writer.TempAppendLine("\t\t\tMessage: %s", vguiMenu.Message) + demo.Writer.TempAppendLine("\t\t\tShow: %t", vguiMenu.Show) if len(vguiMenu.KeyValues) > 0 { - writer.TempAppendLine("\t\t\t%d Key Value Pairs:", len(vguiMenu.KeyValues)) + demo.Writer.TempAppendLine("\t\t\t%d Key Value Pairs:", len(vguiMenu.KeyValues)) for _, kv := range vguiMenu.KeyValues { - writer.TempAppendLine("\t\t\t\t%s: %s", kv["Key"], kv["Value"]) + demo.Writer.TempAppendLine("\t\t\t\t%s: %s", kv["Key"], kv["Value"]) } } else { - writer.TempAppendLine("\t\t\tNo Key Value Pairs") + demo.Writer.TempAppendLine("\t\t\tNo Key Value Pairs") } } -func (svcUserMessage *SvcUserMessage) parseRumble(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseRumble(reader *bitreader.Reader, demo *types.Demo) { type RumbleLookup int8 const ( RumbleInvalid RumbleLookup = -1 @@ -418,9 +428,9 @@ func (svcUserMessage *SvcUserMessage) parseRumble(reader *bitreader.Reader) { InitialScale RumbleFlag = 1 << 4 // Data is the initial scale to start this effect ( * 100 ) ) rumble := struct { - Type int8 - Scale float32 - Flags uint8 + Type int8 `json:"type"` + Scale float32 `json:"scale"` + Flags uint8 `json:"flags"` }{ Type: reader.TryReadSInt8(), Scale: float32(reader.TryReadUInt8()) / 100, @@ -452,25 +462,25 @@ func (svcUserMessage *SvcUserMessage) parseRumble(reader *bitreader.Reader) { return flagStrings } svcUserMessage.Data = rumble - writer.TempAppendLine("\t\t\tType: %s", getRumbleLookup(RumbleLookup(rumble.Type))) - writer.TempAppendLine("\t\t\tScale: %f", rumble.Scale) - writer.TempAppendLine("\t\t\tFlags: %v", getFlags(RumbleFlag(rumble.Flags))) + demo.Writer.TempAppendLine("\t\t\tType: %s", getRumbleLookup(RumbleLookup(rumble.Type))) + demo.Writer.TempAppendLine("\t\t\tScale: %f", rumble.Scale) + demo.Writer.TempAppendLine("\t\t\tFlags: %v", getFlags(RumbleFlag(rumble.Flags))) } -func (svcUserMessage *SvcUserMessage) parseBattery(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseBattery(reader *bitreader.Reader, demo *types.Demo) { battery := struct{ BatteryVal uint16 }{ BatteryVal: reader.TryReadUInt16(), } svcUserMessage.Data = battery - writer.TempAppendLine("\t\t\tBattery: %d", battery.BatteryVal) + demo.Writer.TempAppendLine("\t\t\tBattery: %d", battery.BatteryVal) } -func (svcUserMessage *SvcUserMessage) parseDamage(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseDamage(reader *bitreader.Reader, demo *types.Demo) { damage := struct { - Armor uint8 - DamageTaken uint8 - BitsDamage int32 - VecFrom []float32 + Armor uint8 `json:"armor"` + DamageTaken uint8 `json:"damage_taken"` + BitsDamage int32 `json:"bits_damage"` + VecFrom []float32 `json:"vec_from"` }{ Armor: reader.TryReadUInt8(), DamageTaken: reader.TryReadUInt8(), @@ -478,24 +488,24 @@ func (svcUserMessage *SvcUserMessage) parseDamage(reader *bitreader.Reader) { VecFrom: []float32{reader.TryReadFloat32(), reader.TryReadFloat32(), reader.TryReadFloat32()}, } svcUserMessage.Data = damage - writer.TempAppendLine("\t\t\tArmor: %d", damage.Armor) - writer.TempAppendLine("\t\t\tDamage Taken: %d", damage.DamageTaken) - writer.TempAppendLine("\t\t\tBits Damage: %d", damage.BitsDamage) - writer.TempAppendLine("\t\t\tVecFrom: %v", damage.VecFrom) + demo.Writer.TempAppendLine("\t\t\tArmor: %d", damage.Armor) + demo.Writer.TempAppendLine("\t\t\tDamage Taken: %d", damage.DamageTaken) + demo.Writer.TempAppendLine("\t\t\tBits Damage: %d", damage.BitsDamage) + demo.Writer.TempAppendLine("\t\t\tVecFrom: %v", damage.VecFrom) } -func (svcUserMessage *SvcUserMessage) parseVoiceMask(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseVoiceMask(reader *bitreader.Reader, demo *types.Demo) { // const VoiceMaxPlayers = 2 voiceMask := struct { PlayerMasks []struct { - GameRulesMask int32 - BanMask int32 - } - PlayerModEnable bool + GameRulesMask int32 `json:"game_rules_mask"` + BanMask int32 `json:"ban_mask"` + } `json:"player_masks"` + PlayerModEnable bool `json:"player_mod_enable"` }{ PlayerMasks: []struct { - GameRulesMask int32 - BanMask int32 + GameRulesMask int32 `json:"game_rules_mask"` + BanMask int32 `json:"ban_mask"` }{ { GameRulesMask: reader.TryReadSInt32(), @@ -509,15 +519,15 @@ func (svcUserMessage *SvcUserMessage) parseVoiceMask(reader *bitreader.Reader) { PlayerModEnable: reader.TryReadUInt8() != 0, } svcUserMessage.Data = voiceMask - writer.TempAppendLine("\t\t\tPlayer Masks:") - writer.TempAppendLine("\t\t\t\t[0] Game Rules Mask: %d", voiceMask.PlayerMasks[0].GameRulesMask) - writer.TempAppendLine("\t\t\t\t[0] Ban Mask: %d", voiceMask.PlayerMasks[0].BanMask) - writer.TempAppendLine("\t\t\t\t[1] Game Rules Mask: %d", voiceMask.PlayerMasks[1].GameRulesMask) - writer.TempAppendLine("\t\t\t\t[1] Ban Mask: %d", voiceMask.PlayerMasks[1].BanMask) - writer.TempAppendLine("\t\t\t\tPlayer Mod Enable: %t", voiceMask.PlayerModEnable) + demo.Writer.TempAppendLine("\t\t\tPlayer Masks:") + demo.Writer.TempAppendLine("\t\t\t\t[0] Game Rules Mask: %d", voiceMask.PlayerMasks[0].GameRulesMask) + demo.Writer.TempAppendLine("\t\t\t\t[0] Ban Mask: %d", voiceMask.PlayerMasks[0].BanMask) + demo.Writer.TempAppendLine("\t\t\t\t[1] Game Rules Mask: %d", voiceMask.PlayerMasks[1].GameRulesMask) + demo.Writer.TempAppendLine("\t\t\t\t[1] Ban Mask: %d", voiceMask.PlayerMasks[1].BanMask) + demo.Writer.TempAppendLine("\t\t\t\tPlayer Mod Enable: %t", voiceMask.PlayerModEnable) } -func (svcUserMessage *SvcUserMessage) parseCloseCaption(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseCloseCaption(reader *bitreader.Reader, demo *types.Demo) { type CloseCaptionFlag uint8 const ( None CloseCaptionFlag = 0 @@ -527,9 +537,9 @@ func (svcUserMessage *SvcUserMessage) parseCloseCaption(reader *bitreader.Reader GenderFemale CloseCaptionFlag = 1 << 3 ) closeCaption := struct { - TokenName string - Duration float32 - Flags uint8 + TokenName string `json:"token_name"` + Duration float32 `json:"duration"` + Flags uint8 `json:"flags"` }{ TokenName: reader.TryReadString(), Duration: float32(reader.TryReadSInt16()) * 0.1, @@ -552,54 +562,58 @@ func (svcUserMessage *SvcUserMessage) parseCloseCaption(reader *bitreader.Reader return flagStrings } svcUserMessage.Data = closeCaption - writer.TempAppendLine("\t\t\tToken Name: %s", closeCaption.TokenName) - writer.TempAppendLine("\t\t\tDuration: %f", closeCaption.Duration) - writer.TempAppendLine("\t\t\tFlags: %v", getFlags(CloseCaptionFlag(closeCaption.Flags))) + demo.Writer.TempAppendLine("\t\t\tToken Name: %s", closeCaption.TokenName) + demo.Writer.TempAppendLine("\t\t\tDuration: %f", closeCaption.Duration) + demo.Writer.TempAppendLine("\t\t\tFlags: %v", getFlags(CloseCaptionFlag(closeCaption.Flags))) } -func (svcUserMessage *SvcUserMessage) parseKeyHintText(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseKeyHintText(reader *bitreader.Reader, demo *types.Demo) { keyHintText := struct { - Count uint8 - KeyString string + Count uint8 `json:"count"` + KeyString string `json:"key_string"` }{ Count: reader.TryReadUInt8(), KeyString: reader.TryReadString(), } svcUserMessage.Data = keyHintText - writer.TempAppendLine("\t\t\tCount: %d", keyHintText.Count) - writer.TempAppendLine("\t\t\tString: %s", keyHintText.KeyString) + demo.Writer.TempAppendLine("\t\t\tCount: %d", keyHintText.Count) + demo.Writer.TempAppendLine("\t\t\tString: %s", keyHintText.KeyString) } -func (svcUserMessage *SvcUserMessage) parseLogoTimeMsg(reader *bitreader.Reader) { - logoTimeMsg := struct{ Time float32 }{ +func (svcUserMessage *SvcUserMessage) parseLogoTimeMsg(reader *bitreader.Reader, demo *types.Demo) { + logoTimeMsg := struct { + Time float32 `json:"time"` + }{ Time: reader.TryReadFloat32(), } svcUserMessage.Data = logoTimeMsg - writer.TempAppendLine("\t\t\tTime: %f", logoTimeMsg.Time) + demo.Writer.TempAppendLine("\t\t\tTime: %f", logoTimeMsg.Time) } -func (svcUserMessage *SvcUserMessage) parseAchivementEvent(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseAchivementEvent(reader *bitreader.Reader, demo *types.Demo) { achivementEvent := struct{ AchivementID int32 }{ AchivementID: reader.TryReadSInt32(), } svcUserMessage.Data = achivementEvent - writer.TempAppendLine("\t\t\tAchivement ID: %d", achivementEvent.AchivementID) + demo.Writer.TempAppendLine("\t\t\tAchivement ID: %d", achivementEvent.AchivementID) } -func (svcUserMessage *SvcUserMessage) parseCurrentTimescale(reader *bitreader.Reader) { - currentTimescale := struct{ Timescale float32 }{ +func (svcUserMessage *SvcUserMessage) parseCurrentTimescale(reader *bitreader.Reader, demo *types.Demo) { + currentTimescale := struct { + Timescale float32 `json:"timescale"` + }{ Timescale: reader.TryReadFloat32(), } svcUserMessage.Data = currentTimescale - writer.TempAppendLine("\t\t\tTimescale: %f", currentTimescale.Timescale) + demo.Writer.TempAppendLine("\t\t\tTimescale: %f", currentTimescale.Timescale) } -func (svcUserMessage *SvcUserMessage) parseDesiredTimescale(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseDesiredTimescale(reader *bitreader.Reader, demo *types.Demo) { desiredTimescale := struct { - Unk1 float32 - Unk2 float32 - Unk3 uint8 - Unk4 float32 + Unk1 float32 `json:"unk_1"` + Unk2 float32 `json:"unk_2"` + Unk3 uint8 `json:"unk_3"` + Unk4 float32 `json:"unk_4"` }{ Unk1: reader.TryReadFloat32(), Unk2: reader.TryReadFloat32(), @@ -607,49 +621,52 @@ func (svcUserMessage *SvcUserMessage) parseDesiredTimescale(reader *bitreader.Re Unk4: reader.TryReadFloat32(), } svcUserMessage.Data = desiredTimescale - writer.TempAppendLine("\t\t\tUnk1: %f", desiredTimescale.Unk1) - writer.TempAppendLine("\t\t\tUnk2: %f", desiredTimescale.Unk2) - writer.TempAppendLine("\t\t\tUnk3: %d", desiredTimescale.Unk3) - writer.TempAppendLine("\t\t\tUnk4: %f", desiredTimescale.Unk4) + demo.Writer.TempAppendLine("\t\t\tUnk1: %f", desiredTimescale.Unk1) + demo.Writer.TempAppendLine("\t\t\tUnk2: %f", desiredTimescale.Unk2) + demo.Writer.TempAppendLine("\t\t\tUnk3: %d", desiredTimescale.Unk3) + demo.Writer.TempAppendLine("\t\t\tUnk4: %f", desiredTimescale.Unk4) } -func (svcUserMessage *SvcUserMessage) parseMpMapCompleted(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseMpMapCompleted(reader *bitreader.Reader, demo *types.Demo) { mpMapCompleted := struct { - Branch uint8 - Level uint8 + Branch uint8 `json:"branch"` + Level uint8 `json:"level"` }{ Branch: reader.TryReadUInt8(), Level: reader.TryReadUInt8(), } svcUserMessage.Data = mpMapCompleted - writer.TempAppendLine("\t\t\tBranch: %d", mpMapCompleted.Branch) - writer.TempAppendLine("\t\t\tLevel: %d", mpMapCompleted.Level) + demo.Writer.TempAppendLine("\t\t\tBranch: %d", mpMapCompleted.Branch) + demo.Writer.TempAppendLine("\t\t\tLevel: %d", mpMapCompleted.Level) } -func (svcUserMessage *SvcUserMessage) parseMpMapIncomplete(reader *bitreader.Reader) {} +func (svcUserMessage *SvcUserMessage) parseMpMapIncomplete(reader *bitreader.Reader, demo *types.Demo) { +} -func (svcUserMessage *SvcUserMessage) parseMpTauntEarned(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseMpTauntEarned(reader *bitreader.Reader, demo *types.Demo) { mpTauntEarned := struct { - TauntName string - AwardSilently bool + TauntName string `json:"taunt_name"` + AwardSilently bool `json:"award_silently"` }{ TauntName: reader.TryReadString(), AwardSilently: reader.TryReadBool(), } svcUserMessage.Data = mpTauntEarned - writer.TempAppendLine("\t\t\tTaunt Name: %s", mpTauntEarned.TauntName) - writer.TempAppendLine("\t\t\tAward Silently: %t", mpTauntEarned.AwardSilently) + demo.Writer.TempAppendLine("\t\t\tTaunt Name: %s", mpTauntEarned.TauntName) + demo.Writer.TempAppendLine("\t\t\tAward Silently: %t", mpTauntEarned.AwardSilently) } -func (svcUserMessage *SvcUserMessage) parseMpTauntLocked(reader *bitreader.Reader) { - mpTauntLocked := struct{ TauntName string }{ +func (svcUserMessage *SvcUserMessage) parseMpTauntLocked(reader *bitreader.Reader, demo *types.Demo) { + mpTauntLocked := struct { + TauntName string `json:"taunt_name"` + }{ TauntName: reader.TryReadString(), } svcUserMessage.Data = mpTauntLocked - writer.TempAppendLine("\t\t\tTaunt Name: %s", mpTauntLocked.TauntName) + demo.Writer.TempAppendLine("\t\t\tTaunt Name: %s", mpTauntLocked.TauntName) } -func (svcUserMessage *SvcUserMessage) parsePortalFxSurface(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parsePortalFxSurface(reader *bitreader.Reader, demo *types.Demo) { type PortalFizzleType int8 const ( PortalFizzleSuccess PortalFizzleType = iota // Placed fine (no fizzle) @@ -693,13 +710,13 @@ func (svcUserMessage *SvcUserMessage) parsePortalFxSurface(reader *bitreader.Rea } } portalFxSurface := struct { - PortalEnt uint16 - OwnerEnt uint16 - Team uint8 - PortalNum uint8 - Effect uint8 - Origin []float32 - Angles []float32 + PortalEnt uint16 `json:"portal_ent"` + OwnerEnt uint16 `json:"owner_ent"` + Team uint8 `json:"team"` + PortalNum uint8 `json:"portal_num"` + Effect uint8 `json:"effect"` + Origin []float32 `json:"origin"` + Angles []float32 `json:"angles"` }{ PortalEnt: reader.TryReadUInt16(), OwnerEnt: reader.TryReadUInt16(), @@ -743,23 +760,23 @@ func (svcUserMessage *SvcUserMessage) parsePortalFxSurface(reader *bitreader.Rea } svcUserMessage.Data = portalFxSurface _ = getPortalFizzleType(PortalFizzleType(2)) - writer.TempAppendLine("\t\t\tPortal Entity: %d", portalFxSurface.PortalEnt) - writer.TempAppendLine("\t\t\tOwner Entity: %d", portalFxSurface.OwnerEnt) - writer.TempAppendLine("\t\t\tTeam: %d", portalFxSurface.Team) - writer.TempAppendLine("\t\t\tPortal Number: %d", portalFxSurface.PortalNum) - writer.TempAppendLine("\t\t\tEffect: %s", getPortalFizzleType(PortalFizzleType(portalFxSurface.Effect))) - writer.TempAppendLine("\t\t\tOrigin: %v", portalFxSurface.Origin) - writer.TempAppendLine("\t\t\tAngles: %v", portalFxSurface.Angles) + demo.Writer.TempAppendLine("\t\t\tPortal Entity: %d", portalFxSurface.PortalEnt) + demo.Writer.TempAppendLine("\t\t\tOwner Entity: %d", portalFxSurface.OwnerEnt) + demo.Writer.TempAppendLine("\t\t\tTeam: %d", portalFxSurface.Team) + demo.Writer.TempAppendLine("\t\t\tPortal Number: %d", portalFxSurface.PortalNum) + demo.Writer.TempAppendLine("\t\t\tEffect: %s", getPortalFizzleType(PortalFizzleType(portalFxSurface.Effect))) + demo.Writer.TempAppendLine("\t\t\tOrigin: %v", portalFxSurface.Origin) + demo.Writer.TempAppendLine("\t\t\tAngles: %v", portalFxSurface.Angles) } -func (svcUserMessage *SvcUserMessage) parsePaintWorld(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parsePaintWorld(reader *bitreader.Reader, demo *types.Demo) { paintWorld := struct { - Type uint8 - EHandle uint32 - UnkHf1 float32 - UnkHf2 float32 - Center []float32 - Positions [][]float32 + Type uint8 `json:"type"` + EHandle uint32 `json:"e_handle"` + UnkHf1 float32 `json:"unk_hf_1"` + UnkHf2 float32 `json:"unk_hf_2"` + Center []float32 `json:"center"` + Positions [][]float32 `json:"positions"` }{ Type: reader.TryReadUInt8(), EHandle: reader.TryReadUInt32(), @@ -775,37 +792,37 @@ func (svcUserMessage *SvcUserMessage) parsePaintWorld(reader *bitreader.Reader) paintWorld.Positions[i] = []float32{paintWorld.Center[0] + float32(reader.TryReadSInt16()), paintWorld.Center[1] + float32(reader.TryReadSInt16()), paintWorld.Center[2] + float32(reader.TryReadSInt16())} } svcUserMessage.Data = paintWorld - writer.TempAppendLine("\t\t\tType: %d", paintWorld.Type) - writer.TempAppendLine("\t\t\tEHandle: %d", paintWorld.EHandle) - writer.TempAppendLine("\t\t\tUnkHf1: %f", paintWorld.UnkHf1) - writer.TempAppendLine("\t\t\tUnkHf2: %f", paintWorld.UnkHf2) - writer.TempAppendLine("\t\t\tCenter: %v", paintWorld.Center) - writer.TempAppendLine("\t\t\tPositions: %v", paintWorld.Positions) + demo.Writer.TempAppendLine("\t\t\tType: %d", paintWorld.Type) + demo.Writer.TempAppendLine("\t\t\tEHandle: %d", paintWorld.EHandle) + demo.Writer.TempAppendLine("\t\t\tUnkHf1: %f", paintWorld.UnkHf1) + demo.Writer.TempAppendLine("\t\t\tUnkHf2: %f", paintWorld.UnkHf2) + demo.Writer.TempAppendLine("\t\t\tCenter: %v", paintWorld.Center) + demo.Writer.TempAppendLine("\t\t\tPositions: %v", paintWorld.Positions) } -func (svcUserMessage *SvcUserMessage) parseTransitionFade(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseTransitionFade(reader *bitreader.Reader, demo *types.Demo) { transitionFade := struct { - Seconds float32 + Seconds float32 `json:"seconds"` }{ Seconds: reader.TryReadFloat32(), } svcUserMessage.Data = transitionFade - writer.TempAppendLine("\t\t\tSeconds: %f", transitionFade.Seconds) + demo.Writer.TempAppendLine("\t\t\tSeconds: %f", transitionFade.Seconds) } -func (svcUserMessage *SvcUserMessage) parseScoreboardTempUpdate(reader *bitreader.Reader) { +func (svcUserMessage *SvcUserMessage) parseScoreboardTempUpdate(reader *bitreader.Reader, demo *types.Demo) { scoreboardTempUpdate := struct { - NumPortals int32 - TimeTaken int32 + NumPortals int32 `json:"num_portals"` + TimeTaken int32 `json:"time_taken"` }{ NumPortals: reader.TryReadSInt32(), TimeTaken: reader.TryReadSInt32(), } svcUserMessage.Data = scoreboardTempUpdate - writer.TempAppendLine("\t\t\tPortal Count: %d", scoreboardTempUpdate.NumPortals) - writer.TempAppendLine("\t\t\tTime Taken: %.2f", float32(scoreboardTempUpdate.TimeTaken)/100.0) + demo.Writer.TempAppendLine("\t\t\tPortal Count: %d", scoreboardTempUpdate.NumPortals) + demo.Writer.TempAppendLine("\t\t\tTime Taken: %.2f", float32(scoreboardTempUpdate.TimeTaken)/100.0) - writer.TempAppendLine("\t\t\tTicks Taken: %d", int(math.Round(float64((float32(scoreboardTempUpdate.TimeTaken)/100.0)/float32(1.0/60.0))))) + demo.Writer.TempAppendLine("\t\t\tTicks Taken: %d", int(math.Round(float64((float32(scoreboardTempUpdate.TimeTaken)/100.0)/float32(1.0/60.0))))) } type UserMessageType uint8 diff --git a/pkg/messages/types/svcVoiceData.go b/pkg/messages/types/svcVoiceData.go index 30436eb..dbc07a6 100644 --- a/pkg/messages/types/svcVoiceData.go +++ b/pkg/messages/types/svcVoiceData.go @@ -2,17 +2,17 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcVoiceData struct { - FromClient uint8 - Proximity bool - Length int16 - Data []byte + FromClient uint8 `json:"from_client"` + Proximity bool `json:"proximity"` + Length int16 `json:"length"` + Data []byte `json:"data"` } -func ParseSvcVoiceData(reader *bitreader.Reader) SvcVoiceData { +func ParseSvcVoiceData(reader *bitreader.Reader, demo *types.Demo) SvcVoiceData { svcVoiceData := SvcVoiceData{ FromClient: reader.TryReadUInt8(), } @@ -21,8 +21,8 @@ func ParseSvcVoiceData(reader *bitreader.Reader) SvcVoiceData { svcVoiceData.Proximity = true } svcVoiceData.Data = reader.TryReadBitsToSlice(uint64(svcVoiceData.Length)) - writer.TempAppendLine("\t\tFrom Client: %d", svcVoiceData.FromClient) - writer.TempAppendLine("\t\tProximity: %t", svcVoiceData.Proximity) - writer.TempAppendLine("\t\tData: %v", svcVoiceData.Data) + demo.Writer.TempAppendLine("\t\tFrom Client: %d", svcVoiceData.FromClient) + demo.Writer.TempAppendLine("\t\tProximity: %t", svcVoiceData.Proximity) + demo.Writer.TempAppendLine("\t\tData: %v", svcVoiceData.Data) return svcVoiceData } diff --git a/pkg/messages/types/svcVoiceInit.go b/pkg/messages/types/svcVoiceInit.go index bdab51a..1baa971 100644 --- a/pkg/messages/types/svcVoiceInit.go +++ b/pkg/messages/types/svcVoiceInit.go @@ -2,16 +2,16 @@ package messages import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) type SvcVoiceInit struct { - Codec string - Quality uint8 - SampleRate int32 + Codec string `json:"codec"` + Quality uint8 `json:"quality"` + SampleRate int32 `json:"sample_rate"` } -func ParseSvcVoiceInit(reader *bitreader.Reader) SvcVoiceInit { +func ParseSvcVoiceInit(reader *bitreader.Reader, demo *types.Demo) SvcVoiceInit { svcVoiceInit := SvcVoiceInit{ Codec: reader.TryReadString(), Quality: reader.TryReadUInt8(), @@ -25,8 +25,8 @@ func ParseSvcVoiceInit(reader *bitreader.Reader) SvcVoiceInit { svcVoiceInit.SampleRate = 11025 } } - writer.TempAppendLine("\t\tCodec: %s", svcVoiceInit.Codec) - writer.TempAppendLine("\t\tQuality: %d", svcVoiceInit.Quality) - writer.TempAppendLine("\t\tSample Rate: %d", svcVoiceInit.SampleRate) + demo.Writer.TempAppendLine("\t\tCodec: %s", svcVoiceInit.Codec) + demo.Writer.TempAppendLine("\t\tQuality: %d", svcVoiceInit.Quality) + demo.Writer.TempAppendLine("\t\tSample Rate: %d", svcVoiceInit.SampleRate) return svcVoiceInit } diff --git a/pkg/packets/headers.go b/pkg/packets/headers.go index 6c5ab10..bee8ddf 100644 --- a/pkg/packets/headers.go +++ b/pkg/packets/headers.go @@ -2,25 +2,11 @@ package packets import ( "github.com/pektezol/bitreader" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) -type Headers struct { - DemoFileStamp string - DemoProtocol int32 - NetworkProtocol int32 - ServerName string - ClientName string - MapName string - GameDirectory string - PlaybackTime float32 - PlaybackTicks int32 - PlaybackFrames int32 - SignOnLength int32 -} - -func ParseHeaders(reader *bitreader.Reader) Headers { - headers := Headers{ +func ParseHeaders(reader *bitreader.Reader, demo *types.Demo) types.Headers { + headers := types.Headers{ DemoFileStamp: reader.TryReadString(), DemoProtocol: int32(reader.TryReadSInt32()), NetworkProtocol: int32(reader.TryReadSInt32()), @@ -42,16 +28,16 @@ func ParseHeaders(reader *bitreader.Reader) Headers { if headers.NetworkProtocol != 2001 { panic("this parser only supports demos from portal 2") } - writer.AppendLine("\nDemo File Stamp: %s", headers.DemoFileStamp) - writer.AppendLine("Demo Protocol: %d", headers.DemoProtocol) - writer.AppendLine("Network Protocol: %d", headers.NetworkProtocol) - writer.AppendLine("Server Name: %s", headers.ServerName) - writer.AppendLine("Client Name: %s", headers.ClientName) - writer.AppendLine("Map Name: %s", headers.MapName) - writer.AppendLine("Game Directory: %s", headers.GameDirectory) - writer.AppendLine("Playback Time: %f", headers.PlaybackTime) - writer.AppendLine("Playback Ticks: %d", headers.PlaybackTicks) - writer.AppendLine("Playback Frames: %d", headers.PlaybackFrames) - writer.AppendLine("Sign On Length: %d\n", headers.SignOnLength) + demo.Writer.AppendLine("\nDemo File Stamp: %s", headers.DemoFileStamp) + demo.Writer.AppendLine("Demo Protocol: %d", headers.DemoProtocol) + demo.Writer.AppendLine("Network Protocol: %d", headers.NetworkProtocol) + demo.Writer.AppendLine("Server Name: %s", headers.ServerName) + demo.Writer.AppendLine("Client Name: %s", headers.ClientName) + demo.Writer.AppendLine("Map Name: %s", headers.MapName) + demo.Writer.AppendLine("Game Directory: %s", headers.GameDirectory) + demo.Writer.AppendLine("Playback Time: %f", headers.PlaybackTime) + demo.Writer.AppendLine("Playback Ticks: %d", headers.PlaybackTicks) + demo.Writer.AppendLine("Playback Frames: %d", headers.PlaybackFrames) + demo.Writer.AppendLine("Sign On Length: %d\n", headers.SignOnLength) return headers } diff --git a/pkg/packets/packets.go b/pkg/packets/packets.go index 1bf3f57..6ae8a44 100644 --- a/pkg/packets/packets.go +++ b/pkg/packets/packets.go @@ -3,100 +3,55 @@ package packets import ( "github.com/pektezol/bitreader" "github.com/pektezol/sdp.go/pkg/classes" - "github.com/pektezol/sdp.go/pkg/writer" + "github.com/pektezol/sdp.go/pkg/types" ) -type MessageType uint8 - -const ( - SignOn MessageType = iota + 1 - Packet - SyncTick - ConsoleCmd - UserCmd - DataTables - Stop - CustomData - StringTables -) - -type Message struct { - PacketType MessageType - TickNumber int32 - SlotNumber uint8 - Data any -} - -func ParseMessage(reader *bitreader.Reader) Message { - message := Message{ - PacketType: MessageType(reader.TryReadUInt8()), +func ParseMessage(reader *bitreader.Reader, demo *types.Demo) types.Message { + message := types.Message{ + PacketType: types.MessageType(reader.TryReadUInt8()), TickNumber: reader.TryReadSInt32(), SlotNumber: reader.TryReadUInt8(), } - writer.AppendLine("[%d] %s (%d):", message.TickNumber, message.PacketType.String(), message.PacketType) + demo.Writer.AppendLine("[%d] %s (%d):", message.TickNumber, message.PacketType.String(), message.PacketType) switch message.PacketType { - case SignOn: + case types.SignOn: signOn := classes.SignOn{} - signOn.ParseSignOn(reader) + signOn.ParseSignOn(reader, demo) message.Data = signOn - case Packet: + case types.Packet: packet := classes.Packet{} - packet.ParsePacket(reader) + packet.ParsePacket(reader, demo) message.Data = packet - case SyncTick: + case types.SyncTick: syncTick := classes.SyncTick{} syncTick.ParseSyncTick() message.Data = syncTick - case ConsoleCmd: + case types.ConsoleCmd: consoleCmd := classes.ConsoleCmd{} - consoleCmd.ParseConsoleCmd(reader) + consoleCmd.ParseConsoleCmd(reader, demo) message.Data = consoleCmd - case UserCmd: + case types.UserCmd: userCmd := classes.UserCmd{} - userCmd.ParseUserCmd(reader) + userCmd.ParseUserCmd(reader, demo) message.Data = userCmd - case DataTables: + case types.DataTables: dataTables := classes.DataTables{} - dataTables.ParseDataTables(reader) + dataTables.ParseDataTables(reader, demo) message.Data = dataTables - case Stop: + case types.Stop: stop := classes.Stop{} - stop.ParseStop(reader) + stop.ParseStop(reader, demo) message.Data = stop - case CustomData: // TODO: not sar data + case types.CustomData: // TODO: not sar data customData := classes.CustomData{} - customData.ParseCustomData(reader, message.TickNumber, uint8(message.PacketType)) + customData.ParseCustomData(reader, message.TickNumber, uint8(message.PacketType), demo) message.Data = customData - case StringTables: // TODO: parsing string table data + case types.StringTables: // TODO: parsing string table data stringTables := classes.StringTables{} - stringTables.ParseStringTables(reader) + stringTables.ParseStringTables(reader, demo) message.Data = stringTables default: panic("invalid packet type") } return message } - -func (t MessageType) String() string { - switch t { - case SignOn: - return "SIGNON" - case Packet: - return "PACKET" - case SyncTick: - return "SYNCTICK" - case ConsoleCmd: - return "CONSOLECMD" - case UserCmd: - return "USERCMD" - case DataTables: - return "DATATABLES" - case Stop: - return "STOP" - case CustomData: - return "CUSTOMDATA" - case StringTables: - return "STRINGTABLES" - } - return "INVALID" -} diff --git a/pkg/types/gameevent.go b/pkg/types/gameevent.go new file mode 100644 index 0000000..4f00bc0 --- /dev/null +++ b/pkg/types/gameevent.go @@ -0,0 +1,80 @@ +package types + +import ( + "fmt" + + "github.com/pektezol/bitreader" +) + +type SvcGameEventList struct { + Events int16 `json:"events"` + Length int32 `json:"length"` + GameEventDescriptor []GameEventDescriptor `json:"game_event_descriptor"` +} + +type GameEventDescriptor struct { + EventID uint32 `json:"event_id"` + Name string `json:"name"` + Keys []GameEventDescriptorKey `json:"keys"` +} + +type GameEventDescriptorKey struct { + Name string `json:"name"` + Type EventDescriptor `json:"type"` +} + +type EventDescriptor uint8 + +func (svcGameEventList *SvcGameEventList) ParseGameEventDescriptor(reader *bitreader.Reader, demo *Demo) { + svcGameEventList.GameEventDescriptor = make([]GameEventDescriptor, svcGameEventList.Events) + for event := 0; event < int(svcGameEventList.Events); event++ { + svcGameEventList.GameEventDescriptor[event] = GameEventDescriptor{ + EventID: uint32(reader.TryReadBits(9)), + Name: reader.TryReadString(), + } + demo.Writer.TempAppendLine("\t\t\t%d: %s", svcGameEventList.GameEventDescriptor[event].EventID, svcGameEventList.GameEventDescriptor[event].Name) + for { + descriptorType := reader.TryReadBits(3) + if descriptorType == 0 { + break + } + KeyName := reader.TryReadString() + svcGameEventList.GameEventDescriptor[event].Keys = append(svcGameEventList.GameEventDescriptor[event].Keys, GameEventDescriptorKey{ + Name: KeyName, + Type: EventDescriptor(descriptorType), + }) + } + demo.Writer.TempAppendLine("\t\t\t\tKeys: %v", svcGameEventList.GameEventDescriptor[event].Keys) + } +} + +const ( + EventDescriptorString EventDescriptor = iota + 1 + EventDescriptorFloat + EventDescriptorInt32 + EventDescriptorInt16 + EventDescriptorInt8 + EventDescriptorBool + EventDescriptorUInt64 +) + +func (eventDescriptor EventDescriptor) String() string { + switch eventDescriptor { + case EventDescriptorString: + return "String" + case EventDescriptorFloat: + return "Float" + case EventDescriptorInt32: + return "Int32" + case EventDescriptorInt16: + return "Int16" + case EventDescriptorInt8: + return "Int8" + case EventDescriptorBool: + return "Bool" + case EventDescriptorUInt64: + return "UInt64" + default: + return fmt.Sprintf("%d", eventDescriptor) + } +} diff --git a/pkg/types/types.go b/pkg/types/types.go new file mode 100644 index 0000000..341e875 --- /dev/null +++ b/pkg/types/types.go @@ -0,0 +1,71 @@ +package types + +import ( + "github.com/pektezol/sdp.go/pkg/writer" +) + +type Demo struct { + Headers Headers `json:"headers"` + Messages []Message `json:"messages"` + Writer *writer.Writer `json:"-"` + GameEventList *SvcGameEventList `json:"-"` +} + +type Headers struct { + DemoFileStamp string `json:"demo_file_stamp"` + DemoProtocol int32 `json:"demo_protocol"` + NetworkProtocol int32 `json:"network_protocol"` + ServerName string `json:"server_name"` + ClientName string `json:"client_name"` + MapName string `json:"map_name"` + GameDirectory string `json:"game_directory"` + PlaybackTime float32 `json:"playback_time"` + PlaybackTicks int32 `json:"playback_ticks"` + PlaybackFrames int32 `json:"playback_frames"` + SignOnLength int32 `json:"sign_on_length"` +} + +type Message struct { + PacketType MessageType `json:"packet_type"` + TickNumber int32 `json:"tick_number"` + SlotNumber uint8 `json:"slot_number"` + Data any `json:"data"` +} + +type MessageType uint8 + +const ( + SignOn MessageType = iota + 1 + Packet + SyncTick + ConsoleCmd + UserCmd + DataTables + Stop + CustomData + StringTables +) + +func (t MessageType) String() string { + switch t { + case SignOn: + return "SIGNON" + case Packet: + return "PACKET" + case SyncTick: + return "SYNCTICK" + case ConsoleCmd: + return "CONSOLECMD" + case UserCmd: + return "USERCMD" + case DataTables: + return "DATATABLES" + case Stop: + return "STOP" + case CustomData: + return "CUSTOMDATA" + case StringTables: + return "STRINGTABLES" + } + return "INVALID" +} diff --git a/pkg/writer/writer.go b/pkg/writer/writer.go index f3af2fc..abfbf3d 100644 --- a/pkg/writer/writer.go +++ b/pkg/writer/writer.go @@ -5,43 +5,51 @@ import ( "strings" ) -var output strings.Builder +type Writer struct { + output strings.Builder + temp strings.Builder +} -var temp strings.Builder +func NewWriter() *Writer { + return &Writer{ + output: strings.Builder{}, + temp: strings.Builder{}, + } +} -func Append(str string, a ...any) { - _, err := output.WriteString(fmt.Sprintf(str, a...)) +func (w *Writer) Append(str string, a ...any) { + _, err := w.output.WriteString(fmt.Sprintf(str, a...)) if err != nil { - output.WriteString(err.Error()) + w.output.WriteString(err.Error()) } } -func AppendLine(str string, a ...any) { - Append(str, a...) - output.WriteString("\n") +func (w *Writer) AppendLine(str string, a ...any) { + w.Append(str, a...) + w.output.WriteString("\n") } -func GetWriter() strings.Builder { - return output +func (w *Writer) GetOutputString() string { + return w.output.String() } -func TempAppend(str string, a ...any) { - _, err := temp.WriteString(fmt.Sprintf(str, a...)) +func (w *Writer) TempAppend(str string, a ...any) { + _, err := w.temp.WriteString(fmt.Sprintf(str, a...)) if err != nil { - temp.WriteString(err.Error()) + w.temp.WriteString(err.Error()) } } -func TempAppendLine(str string, a ...any) { - TempAppend(str, a...) - temp.WriteString("\n") +func (w *Writer) TempAppendLine(str string, a ...any) { + w.TempAppend(str, a...) + w.temp.WriteString("\n") } -func TempGetString() string { - return temp.String() +func (w *Writer) TempGetString() string { + return w.temp.String() } -func AppendOutputFromTemp() { - output.WriteString(temp.String()) - temp.Reset() +func (w *Writer) AppendOutputFromTemp() { + w.output.WriteString(w.temp.String()) + w.temp.Reset() } -- cgit v1.2.3