aboutsummaryrefslogtreecommitdiff
path: root/pkg/classes/dataTables.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/classes/dataTables.go')
-rw-r--r--pkg/classes/dataTables.go245
1 files changed, 245 insertions, 0 deletions
diff --git a/pkg/classes/dataTables.go b/pkg/classes/dataTables.go
new file mode 100644
index 0000000..27ab9e4
--- /dev/null
+++ b/pkg/classes/dataTables.go
@@ -0,0 +1,245 @@
1package classes
2
3import (
4 "fmt"
5
6 "github.com/pektezol/bitreader"
7 "github.com/pektezol/demoparser/pkg/writer"
8)
9
10type DataTables struct {
11 Size int32
12 SendTable []SendTable
13 ServerClassInfo []ServerClassInfo
14}
15
16type SendTable struct {
17 NeedsDecoder bool
18 NetTableName string
19 NumOfProps int16
20 Props []prop
21}
22
23type ServerClassInfo struct {
24 ClassId uint16
25 ClassName string
26 DataTableName string
27}
28
29type prop struct {
30 SendPropType sendPropType
31 SendPropName string
32 SendPropFlags uint32
33 Priority uint8
34 ExcludeDtName string
35 LowValue float32
36 HighValue float32
37 NumBits int32
38 NumElements int32
39}
40
41func (dataTables *DataTables) ParseDataTables(reader *bitreader.Reader) {
42 dataTables.Size = int32(reader.TryReadSInt32())
43 dataTableReader := bitreader.NewReaderFromBytes(reader.TryReadBytesToSlice(uint64(dataTables.Size)), true)
44 count := 0
45 for dataTableReader.TryReadBool() {
46 count++
47 dataTables.SendTable = append(dataTables.SendTable, ParseSendTable(dataTableReader))
48 }
49 writer.AppendLine("\t%d Send Tables:", count)
50 writer.AppendOutputFromTemp()
51 numOfClasses := dataTableReader.TryReadBits(16)
52 for count = 0; count < int(numOfClasses); count++ {
53 dataTables.ServerClassInfo = append(dataTables.ServerClassInfo, ParseServerClassInfo(dataTableReader, count, int(numOfClasses)))
54 }
55 writer.AppendLine("\t%d Classes:", count)
56 writer.AppendOutputFromTemp()
57}
58
59func ParseSendTable(reader *bitreader.Reader) SendTable {
60 sendTable := SendTable{
61 NeedsDecoder: reader.TryReadBool(),
62 NetTableName: reader.TryReadString(),
63 NumOfProps: int16(reader.TryReadBits(10)),
64 }
65 if sendTable.NumOfProps < 0 {
66 return sendTable
67 }
68 writer.TempAppendLine("\t\t%s (%d Props):", sendTable.NetTableName, sendTable.NumOfProps)
69 for count := 0; count < int(sendTable.NumOfProps); count++ {
70 propType := int8(reader.TryReadBits(5))
71 if propType >= int8(7) {
72 return sendTable
73 }
74 prop := prop{
75 SendPropType: sendPropType(propType),
76 SendPropName: reader.TryReadString(),
77 SendPropFlags: uint32(reader.TryReadBits(19)),
78 Priority: reader.TryReadUInt8(),
79 }
80 writer.TempAppend("\t\t\t%s\t", prop.SendPropType)
81 if propType == int8(ESendPropTypeDataTable) || checkBit(prop.SendPropFlags, 6) {
82 prop.ExcludeDtName = reader.TryReadString()
83 writer.TempAppend(":\t%s\t", prop.ExcludeDtName)
84 } else {
85 switch propType {
86 case int8(ESendPropTypeString), int8(ESendPropTypeInt), int8(ESendPropTypeFloat), int8(ESendPropTypeVector3), int8(ESendPropTypeVector2):
87 prop.LowValue = reader.TryReadFloat32()
88 prop.HighValue = reader.TryReadFloat32()
89 prop.NumBits = int32(reader.TryReadBits(7))
90 writer.TempAppend("Low: %f\tHigh: %f\t%d bits\t", prop.LowValue, prop.HighValue, prop.NumBits)
91 case int8(ESendPropTypeArray):
92 prop.NumElements = int32(reader.TryReadBits(10))
93 writer.TempAppend("Elements: %d\t", prop.NumElements)
94 default:
95 writer.TempAppend("Unknown Prop Type: %v\t", propType)
96 return sendTable
97 }
98 }
99 writer.TempAppend("Flags: %v\tPriority: %d\n", prop.GetFlags(), prop.Priority)
100 sendTable.Props = append(sendTable.Props, prop)
101 }
102 return sendTable
103}
104
105func ParseServerClassInfo(reader *bitreader.Reader, count int, numOfClasses int) ServerClassInfo {
106 serverClassInfo := ServerClassInfo{
107 ClassId: reader.TryReadUInt16(),
108 ClassName: reader.TryReadString(),
109 DataTableName: reader.TryReadString(),
110 }
111 writer.TempAppendLine("\t\t\t[%d] %s (%s)", serverClassInfo.ClassId, serverClassInfo.ClassName, serverClassInfo.DataTableName)
112 return serverClassInfo
113}
114
115// func serverClassBits(numOfClasses int) int {
116// return highestBitIndex(uint(numOfClasses)) + 1
117// }
118
119// func highestBitIndex(i uint) int {
120// var j int
121// for j = 31; j >= 0 && (i&(1<<j)) == 0; j-- {
122// }
123// return j
124// }
125
126func checkBit(val uint32, bit int) bool {
127 return (val & (uint32(1) << bit)) != 0
128}
129
130type sendPropType int
131
132const (
133 ESendPropTypeInt sendPropType = iota
134 ESendPropTypeFloat
135 ESendPropTypeVector3
136 ESendPropTypeVector2
137 ESendPropTypeString
138 ESendPropTypeArray
139 ESendPropTypeDataTable
140)
141
142const (
143 ESendPropFlagUnsigned string = "Unsigned"
144 ESendPropFlagCoord string = "Coord"
145 ESendPropFlagNoScale string = "NoScale"
146 ESendPropFlagRoundDown string = "RoundDown"
147 ESendPropFlagRoundUp string = "RoundUp"
148 ESendPropFlagNormal string = "Normal"
149 ESendPropFlagExclude string = "Exclude"
150 ESendPropFlagXyze string = "Xyze"
151 ESendPropFlagInsideArray string = "InsideArray"
152 ESendPropFlagProxyAlwaysYes string = "ProxyAlwaysYes"
153 ESendPropFlagIsVectorElem string = "IsVectorElem"
154 ESendPropFlagCollapsible string = "Collapsible"
155 ESendPropFlagCoordMp string = "CoordMp"
156 ESendPropFlagCoordMpLp string = "CoordMpLp"
157 ESendPropFlagCoordMpInt string = "CoordMpInt"
158 ESendPropFlagCellCoord string = "CellCoord"
159 ESendPropFlagCellCoordLp string = "CellCoordLp"
160 ESendPropFlagCellCoordInt string = "CellCoordInt"
161 ESendPropFlagChangesOften string = "ChangesOften"
162)
163
164func (prop prop) GetFlags() []string {
165 flags := []string{}
166 if checkBit(prop.SendPropFlags, 0) {
167 flags = append(flags, ESendPropFlagUnsigned)
168 }
169 if checkBit(prop.SendPropFlags, 1) {
170 flags = append(flags, ESendPropFlagCoord)
171 }
172 if checkBit(prop.SendPropFlags, 2) {
173 flags = append(flags, ESendPropFlagNoScale)
174 }
175 if checkBit(prop.SendPropFlags, 3) {
176 flags = append(flags, ESendPropFlagRoundDown)
177 }
178 if checkBit(prop.SendPropFlags, 4) {
179 flags = append(flags, ESendPropFlagRoundUp)
180 }
181 if checkBit(prop.SendPropFlags, 5) {
182 flags = append(flags, ESendPropFlagNormal)
183 }
184 if checkBit(prop.SendPropFlags, 6) {
185 flags = append(flags, ESendPropFlagExclude)
186 }
187 if checkBit(prop.SendPropFlags, 7) {
188 flags = append(flags, ESendPropFlagXyze)
189 }
190 if checkBit(prop.SendPropFlags, 8) {
191 flags = append(flags, ESendPropFlagInsideArray)
192 }
193 if checkBit(prop.SendPropFlags, 9) {
194 flags = append(flags, ESendPropFlagProxyAlwaysYes)
195 }
196 if checkBit(prop.SendPropFlags, 10) {
197 flags = append(flags, ESendPropFlagIsVectorElem)
198 }
199 if checkBit(prop.SendPropFlags, 11) {
200 flags = append(flags, ESendPropFlagCollapsible)
201 }
202 if checkBit(prop.SendPropFlags, 12) {
203 flags = append(flags, ESendPropFlagCoordMp)
204 }
205 if checkBit(prop.SendPropFlags, 13) {
206 flags = append(flags, ESendPropFlagCoordMpLp)
207 }
208 if checkBit(prop.SendPropFlags, 14) {
209 flags = append(flags, ESendPropFlagCoordMpInt)
210 }
211 if checkBit(prop.SendPropFlags, 15) {
212 flags = append(flags, ESendPropFlagCellCoord)
213 }
214 if checkBit(prop.SendPropFlags, 16) {
215 flags = append(flags, ESendPropFlagCellCoordLp)
216 }
217 if checkBit(prop.SendPropFlags, 17) {
218 flags = append(flags, ESendPropFlagCellCoordInt)
219 }
220 if checkBit(prop.SendPropFlags, 18) {
221 flags = append(flags, ESendPropFlagChangesOften)
222 }
223 return flags
224}
225
226func (sendPropType sendPropType) String() string {
227 switch sendPropType {
228 case ESendPropTypeInt:
229 return "Int"
230 case ESendPropTypeFloat:
231 return "Float"
232 case ESendPropTypeVector3:
233 return "Vector3"
234 case ESendPropTypeVector2:
235 return "Vector2"
236 case ESendPropTypeString:
237 return "String"
238 case ESendPropTypeArray:
239 return "Array"
240 case ESendPropTypeDataTable:
241 return "DataTable"
242 default:
243 return fmt.Sprintf("%d", int(sendPropType))
244 }
245}