aboutsummaryrefslogtreecommitdiff
path: root/pkg/classes
diff options
context:
space:
mode:
authorArda Serdar Pektezol <1669855+pektezol@users.noreply.github.com>2023-11-06 18:37:11 +0300
committerArda Serdar Pektezol <1669855+pektezol@users.noreply.github.com>2023-11-06 18:37:11 +0300
commit2f8c92f261586f68a976efce0cfcdd0401f402e0 (patch)
tree33189cc48987789dff4e7fba0a74d2b2326f0a04 /pkg/classes
parentconvert cm ticks correctly (diff)
downloadsdp.go-2f8c92f261586f68a976efce0cfcdd0401f402e0.tar.gz
sdp.go-2f8c92f261586f68a976efce0cfcdd0401f402e0.tar.bz2
sdp.go-2f8c92f261586f68a976efce0cfcdd0401f402e0.zip
dont try to understand it, feel itlp-parser
Diffstat (limited to 'pkg/classes')
-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
10 files changed, 0 insertions, 1128 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)