aboutsummaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/parser.go251
1 files changed, 221 insertions, 30 deletions
diff --git a/cmd/parser.go b/cmd/parser.go
index 5b84781..12a3562 100644
--- a/cmd/parser.go
+++ b/cmd/parser.go
@@ -1,46 +1,237 @@
1package main 1package main
2 2
3import ( 3import (
4 "errors"
5 "math"
4 "os" 6 "os"
5 7
6 "github.com/pektezol/bitreader" 8 "github.com/pektezol/bitreader"
7 "github.com/pektezol/demoparser/pkg/packets"
8) 9)
9 10
10const littleEndian bool = true 11// Don't try to understand it, feel it.
11 12func getScoreboard(filePath string) (portalCount int32, tickCount int64, err error) {
12func main() { 13 file, err := os.Open(filePath)
13 if len(os.Args) != 2 { 14 if err != nil {
14 panic("specify file in command line arguments") 15 return 0, 0, err
15 } 16 }
16 files, err := os.ReadDir(os.Args[1]) 17 reader := bitreader.NewReader(file, true)
17 if err != nil { // If it's not a directory 18 demoFileStamp := reader.TryReadString()
18 file, err := os.Open(os.Args[1]) 19 demoProtocol := reader.TryReadSInt32()
19 if err != nil { 20 networkProtocol := reader.TryReadSInt32()
20 panic(err) 21 reader.SkipBytes(1056)
21 } 22 if demoFileStamp != "HL2DEMO" {
22 reader := bitreader.NewReader(file, littleEndian) 23 return 0, 0, errors.New("invalid demo file stamp")
23 demoParserHandler(reader)
24 defer file.Close()
25 return
26 } 24 }
27 for _, fileinfo := range files { // If it is a directory 25 if demoProtocol != 4 {
28 file, err := os.Open(os.Args[1] + fileinfo.Name()) 26 return 0, 0, errors.New("this parser only supports demos from new engine")
29 if err != nil { 27 }
30 panic(err) 28 if networkProtocol != 2001 {
31 } 29 return 0, 0, errors.New("this parser only supports demos from portal 2")
32 reader := bitreader.NewReader(file, littleEndian)
33 demoParserHandler(reader)
34 defer file.Close()
35 } 30 }
36}
37
38func demoParserHandler(reader *bitreader.Reader) {
39 packets.ParseHeaders(reader)
40 for { 31 for {
41 packet := packets.ParsePackets(reader) 32 packetType := reader.TryReadUInt8()
42 if packet.PacketType == 7 { 33 reader.SkipBits(40)
34 switch packetType {
35 case 1:
36 reader.SkipBytes(160)
37 reader.SkipBytes(uint64(reader.TryReadSInt32()))
38 case 2:
39 reader.SkipBytes(160)
40 size := reader.TryReadUInt32()
41 packetReader := bitreader.NewReaderFromBytes(reader.TryReadBytesToSlice(uint64(size)), true)
42 for {
43 messageType, err := packetReader.ReadBits(6)
44 if err != nil {
45 break
46 }
47 switch messageType {
48 case 0:
49 case 1:
50 packetReader.TryReadString()
51 case 2:
52 packetReader.SkipBytes(4)
53 packetReader.TryReadString()
54 packetReader.SkipBits(2)
55 case 3:
56 packetReader.SkipBits(1)
57 case 4:
58 packetReader.SkipBytes(8)
59 case 5:
60 packetReader.TryReadString()
61 case 6:
62 for count := 0; count < int(packetReader.TryReadUInt8()); count++ {
63 packetReader.TryReadString()
64 packetReader.TryReadString()
65 }
66 case 7:
67 packetReader.SkipBytes(9)
68 idsLength := packetReader.TryReadUInt32()
69 if idsLength > 0 {
70 packetReader.SkipBytes(uint64(idsLength))
71 }
72 mapLength := packetReader.TryReadUInt32()
73 if mapLength > 0 {
74 packetReader.TryReadStringLength(uint64(mapLength))
75 }
76 case 8:
77 packetReader.SkipBits(210)
78 packetReader.TryReadStringLength(1)
79 packetReader.TryReadString()
80 packetReader.TryReadString()
81 packetReader.TryReadString()
82 packetReader.TryReadString()
83 case 9:
84 packetReader.SkipBits(1)
85 packetReader.SkipBits(uint64(packetReader.TryReadUInt8()))
86 case 10:
87 classCount := packetReader.TryReadUInt16()
88 if !packetReader.TryReadBool() {
89 for count := 0; count < int(classCount); count++ {
90 packetReader.SkipBits(uint64(math.Log2(float64(classCount)) + 1))
91 packetReader.TryReadString()
92 packetReader.TryReadString()
93 }
94 }
95 case 11:
96 packetReader.SkipBits(1)
97 case 12:
98 packetReader.TryReadString()
99 maxEntries := packetReader.TryReadSInt16()
100 packetReader.SkipBits(uint64(math.Log2(float64(maxEntries))) + 1)
101 length := packetReader.TryReadBits(20)
102 if packetReader.TryReadBool() {
103 packetReader.SkipBytes(2)
104 }
105 packetReader.SkipBits(2)
106 packetReader.SkipBits(length)
107 case 13:
108 packetReader.SkipBits(5)
109 if packetReader.TryReadBool() {
110 packetReader.SkipBytes(2)
111 }
112 packetReader.SkipBits(packetReader.TryReadBits(20))
113 case 14:
114 packetReader.TryReadString()
115 if packetReader.TryReadUInt8() == 255 {
116 packetReader.SkipBytes(4)
117 }
118 case 15:
119 packetReader.SkipBytes(2)
120 packetReader.SkipBits(uint64(packetReader.TryReadUInt16()))
121 case 16:
122 packetReader.TryReadString()
123 case 17:
124 var length uint16
125 if packetReader.TryReadBool() {
126 length = uint16(packetReader.TryReadUInt8())
127 } else {
128 packetReader.SkipBytes(1)
129 length = packetReader.TryReadUInt16()
130 }
131 packetReader.SkipBits(uint64(length))
132 case 18:
133 packetReader.SkipBits(11)
134 case 19:
135 packetReader.SkipBits(49)
136 case 20:
137 packetReader.SkipBits(48)
138 case 21:
139 readVectorCoord := func() float32 {
140 value := float32(0)
141 integer := packetReader.TryReadBits(1)
142 fraction := packetReader.TryReadBits(1)
143 if integer != 0 || fraction != 0 {
144 sign := packetReader.TryReadBits(1)
145 if integer != 0 {
146 integer = packetReader.TryReadBits(uint64(14)) + 1
147 }
148 if fraction != 0 {
149 fraction = packetReader.TryReadBits(uint64(5))
150 }
151 value = float32(integer) + float32(fraction)*(1.0/float32(1<<5))
152 if sign != 0 {
153 value = -value
154 }
155 }
156 return value
157 }
158 packetReader.SkipBits(3)
159 readVectorCoord()
160 readVectorCoord()
161 readVectorCoord()
162 packetReader.SkipBits(9)
163 if packetReader.TryReadBool() {
164 packetReader.SkipBits(22)
165 }
166 packetReader.SkipBits(1)
167 case 22:
168 packetReader.SkipBits(1)
169 packetReader.SkipBits(packetReader.TryReadBits(11))
170 case 23:
171 msgType := int8(packetReader.TryReadBits(8))
172 msgLength := packetReader.TryReadBits(12)
173 userMessageReader := bitreader.NewReaderFromBytes(packetReader.TryReadBitsToSlice(msgLength), true)
174 switch msgType {
175 case 60:
176 scoreboardTempUpdate := struct {
177 NumPortals int32
178 TimeTaken int32
179 }{
180 NumPortals: userMessageReader.TryReadSInt32(),
181 TimeTaken: userMessageReader.TryReadSInt32(),
182 }
183 portalCount = scoreboardTempUpdate.NumPortals
184 tickCount = int64(math.Round(float64((float32(scoreboardTempUpdate.TimeTaken) / 100.0) / float32(1.0/60.0))))
185 }
186 case 24:
187 packetReader.SkipBits(20)
188 packetReader.SkipBits(packetReader.TryReadBits(11))
189 case 25:
190 packetReader.SkipBits(packetReader.TryReadBits(11))
191 case 26:
192 packetReader.SkipBits(11)
193 if packetReader.TryReadBool() {
194 packetReader.SkipBytes(4)
195 }
196 packetReader.SkipBits(12)
197 length := packetReader.TryReadBits(20)
198 packetReader.SkipBits(1)
199 packetReader.SkipBits(length)
200
201 case 27:
202 packetReader.SkipBits(8)
203 packetReader.SkipBits(packetReader.TryReadBits(17))
204 case 28:
205 packetReader.SkipBits(13)
206 case 29:
207 packetReader.SkipBits(16)
208 packetReader.SkipBits(packetReader.TryReadBits(32))
209 case 30:
210 packetReader.SkipBits(9)
211 packetReader.SkipBits(packetReader.TryReadBits(20))
212 case 31:
213 packetReader.SkipBits(32)
214 packetReader.TryReadString()
215 case 32:
216 packetReader.SkipBytes(packetReader.TryReadBits(32))
217 case 33:
218 packetReader.SkipBits(packetReader.TryReadBits(32))
219 default:
220 panic("unknown msg type")
221 }
222 }
223 case 3, 7:
224 case 4, 6, 9:
225 reader.SkipBytes(uint64(reader.TryReadSInt32()))
226 case 5, 8:
227 reader.SkipBits(32)
228 reader.SkipBytes(uint64(reader.TryReadSInt32()))
229 default:
230 return 0, 0, errors.New("invalid packet type")
231 }
232 if packetType == 7 {
43 break 233 break
44 } 234 }
45 } 235 }
236 return portalCount, tickCount, nil
46} 237}