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