diff options
| author | Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> | 2023-11-06 18:37:11 +0300 |
|---|---|---|
| committer | Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> | 2023-11-06 18:37:11 +0300 |
| commit | 2f8c92f261586f68a976efce0cfcdd0401f402e0 (patch) | |
| tree | 33189cc48987789dff4e7fba0a74d2b2326f0a04 /pkg/classes | |
| parent | convert cm ticks correctly (diff) | |
| download | sdp.go-lp-parser.tar.gz sdp.go-lp-parser.tar.bz2 sdp.go-lp-parser.zip | |
dont try to understand it, feel itlp-parser
Diffstat (limited to 'pkg/classes')
| -rw-r--r-- | pkg/classes/consoleCmd.go | 15 | ||||
| -rw-r--r-- | pkg/classes/customData.go | 26 | ||||
| -rw-r--r-- | pkg/classes/dataTables.go | 232 | ||||
| -rw-r--r-- | pkg/classes/packet.go | 81 | ||||
| -rw-r--r-- | pkg/classes/sarData.go | 403 | ||||
| -rw-r--r-- | pkg/classes/signOn.go | 43 | ||||
| -rw-r--r-- | pkg/classes/stop.go | 15 | ||||
| -rw-r--r-- | pkg/classes/stringTables.go | 86 | ||||
| -rw-r--r-- | pkg/classes/syncTick.go | 5 | ||||
| -rw-r--r-- | pkg/classes/userCmd.go | 222 |
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 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type ConsoleCmd struct { | ||
| 8 | Size int32 | ||
| 9 | Data string | ||
| 10 | } | ||
| 11 | |||
| 12 | func (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 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type CustomData struct { | ||
| 8 | Type int32 | ||
| 9 | Size int32 | ||
| 10 | Data string | ||
| 11 | } | ||
| 12 | |||
| 13 | func (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 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | ) | ||
| 8 | |||
| 9 | type DataTables struct { | ||
| 10 | Size int32 | ||
| 11 | SendTable []SendTable | ||
| 12 | ServerClassInfo []ServerClassInfo | ||
| 13 | } | ||
| 14 | |||
| 15 | type SendTable struct { | ||
| 16 | NeedsDecoder bool | ||
| 17 | NetTableName string | ||
| 18 | NumOfProps int16 | ||
| 19 | Props []prop | ||
| 20 | } | ||
| 21 | |||
| 22 | type ServerClassInfo struct { | ||
| 23 | ClassId uint16 | ||
| 24 | ClassName string | ||
| 25 | DataTableName string | ||
| 26 | } | ||
| 27 | |||
| 28 | type 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 | |||
| 40 | func (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 | |||
| 54 | func 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 | |||
| 93 | func 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 | |||
| 113 | func checkBit(val uint32, bit int) bool { | ||
| 114 | return (val & (uint32(1) << bit)) != 0 | ||
| 115 | } | ||
| 116 | |||
| 117 | type sendPropType int | ||
| 118 | |||
| 119 | const ( | ||
| 120 | ESendPropTypeInt sendPropType = iota | ||
| 121 | ESendPropTypeFloat | ||
| 122 | ESendPropTypeVector3 | ||
| 123 | ESendPropTypeVector2 | ||
| 124 | ESendPropTypeString | ||
| 125 | ESendPropTypeArray | ||
| 126 | ESendPropTypeDataTable | ||
| 127 | ) | ||
| 128 | |||
| 129 | const ( | ||
| 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 | |||
| 151 | func (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 | |||
| 213 | func (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 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | "github.com/pektezol/demoparser/pkg/messages" | ||
| 8 | ) | ||
| 9 | |||
| 10 | const MSSC int = 2 | ||
| 11 | |||
| 12 | type Packet struct { | ||
| 13 | PacketInfo []CmdInfo | ||
| 14 | InSequence uint32 | ||
| 15 | OutSequence uint32 | ||
| 16 | Size uint32 | ||
| 17 | Data []any | ||
| 18 | } | ||
| 19 | |||
| 20 | type 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 | |||
| 30 | func (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 | |||
| 47 | func (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 | |||
| 59 | type CmdInfoFlags int | ||
| 60 | |||
| 61 | const ( | ||
| 62 | ECmdInfoFlagsNone = 0 | ||
| 63 | ECmdInfoFlagsUseOrigin2 = 1 | ||
| 64 | ECmdInfoFlagsUserAngles2 = 1 << 1 | ||
| 65 | ECmdInfoFlagsNoInterp = 1 << 2 | ||
| 66 | ) | ||
| 67 | |||
| 68 | func (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 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "errors" | ||
| 5 | "fmt" | ||
| 6 | |||
| 7 | "github.com/pektezol/bitreader" | ||
| 8 | ) | ||
| 9 | |||
| 10 | type SarDataType uint8 | ||
| 11 | |||
| 12 | const ( | ||
| 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 | |||
| 31 | func (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 | |||
| 70 | type SarData struct { | ||
| 71 | Type SarDataType | ||
| 72 | Slot int | ||
| 73 | Data any | ||
| 74 | } | ||
| 75 | |||
| 76 | type SarDataTimescaleCheat struct { | ||
| 77 | Timescale float32 | ||
| 78 | } | ||
| 79 | |||
| 80 | type SarDataInitialCVar struct { | ||
| 81 | CVar string | ||
| 82 | Val string | ||
| 83 | } | ||
| 84 | |||
| 85 | type SarDataChecksum struct { | ||
| 86 | DemoSum uint32 | ||
| 87 | SarSum uint32 | ||
| 88 | } | ||
| 89 | |||
| 90 | type SarDataChecksumV2 struct { | ||
| 91 | SarSum uint32 | ||
| 92 | Signature [64]byte | ||
| 93 | } | ||
| 94 | |||
| 95 | type SarDataEntityInput struct { | ||
| 96 | TargetName string | ||
| 97 | ClassName string | ||
| 98 | InputName string | ||
| 99 | Parameter string | ||
| 100 | } | ||
| 101 | |||
| 102 | type SarDataPortalPlacement struct { | ||
| 103 | Orange bool | ||
| 104 | X float32 | ||
| 105 | Y float32 | ||
| 106 | Z float32 | ||
| 107 | } | ||
| 108 | |||
| 109 | type SarDataPause struct { | ||
| 110 | PauseTicks uint32 | ||
| 111 | } | ||
| 112 | |||
| 113 | type SarDataWaitRun struct { | ||
| 114 | Ticks int | ||
| 115 | Cmd string | ||
| 116 | } | ||
| 117 | |||
| 118 | type SarDataHWaitRun struct { | ||
| 119 | Ticks int | ||
| 120 | Cmd string | ||
| 121 | } | ||
| 122 | |||
| 123 | type SarDataSpeedrunTime struct { | ||
| 124 | NSplits uint32 | ||
| 125 | Splits []SarDataSpeedrunTimeSplits | ||
| 126 | } | ||
| 127 | |||
| 128 | type SarDataSpeedrunTimeSegs struct { | ||
| 129 | Name string | ||
| 130 | Ticks uint32 | ||
| 131 | } | ||
| 132 | |||
| 133 | type SarDataSpeedrunTimeSplits struct { | ||
| 134 | Name string | ||
| 135 | NSegs uint32 | ||
| 136 | Segs []SarDataSpeedrunTimeSegs | ||
| 137 | } | ||
| 138 | |||
| 139 | type SarDataTimestamp struct { | ||
| 140 | Year uint16 | ||
| 141 | Month uint8 | ||
| 142 | Day uint8 | ||
| 143 | Hour uint8 | ||
| 144 | Minute uint8 | ||
| 145 | Second uint8 | ||
| 146 | } | ||
| 147 | |||
| 148 | type SarDataFileChecksum struct { | ||
| 149 | Sum uint32 | ||
| 150 | Path string | ||
| 151 | } | ||
| 152 | |||
| 153 | func (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 | |||
| 239 | func 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 | |||
| 250 | func parseInitialCVarData(reader *bitreader.Reader) SarDataInitialCVar { | ||
| 251 | sarDataInitialCvar := SarDataInitialCVar{ | ||
| 252 | CVar: reader.TryReadString(), | ||
| 253 | Val: reader.TryReadString(), | ||
| 254 | } | ||
| 255 | |||
| 256 | return sarDataInitialCvar | ||
| 257 | } | ||
| 258 | |||
| 259 | func 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 | |||
| 270 | func 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 | |||
| 282 | func 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 | |||
| 294 | func 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 | |||
| 311 | func 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 | |||
| 318 | func 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 | |||
| 329 | func 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 | |||
| 341 | func 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 | |||
| 353 | func 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 | |||
| 376 | func 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 | |||
| 393 | func 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 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | "github.com/pektezol/demoparser/pkg/messages" | ||
| 6 | ) | ||
| 7 | |||
| 8 | type SignOn struct { | ||
| 9 | PacketInfo []CmdInfo | ||
| 10 | InSequence uint32 | ||
| 11 | OutSequence uint32 | ||
| 12 | Size uint32 | ||
| 13 | Data []any | ||
| 14 | } | ||
| 15 | |||
| 16 | func (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 | |||
| 33 | func (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 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type Stop struct { | ||
| 8 | RemainingData []byte | ||
| 9 | } | ||
| 10 | |||
| 11 | func (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 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type StringTables struct { | ||
| 8 | Size int32 | ||
| 9 | Data []StringTable | ||
| 10 | } | ||
| 11 | |||
| 12 | type StringTable struct { | ||
| 13 | Name string | ||
| 14 | TableEntries []StringTableEntry | ||
| 15 | Classes []StringTableClass | ||
| 16 | } | ||
| 17 | |||
| 18 | type StringTableEntry struct { | ||
| 19 | Name string | ||
| 20 | EntryData StringTableEntryData | ||
| 21 | } | ||
| 22 | |||
| 23 | type StringTableEntryData struct { | ||
| 24 | // TODO: Parse StringTableEntry | ||
| 25 | } | ||
| 26 | |||
| 27 | type StringTableClass struct { | ||
| 28 | Name string | ||
| 29 | Data string | ||
| 30 | } | ||
| 31 | |||
| 32 | func (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 | |||
| 45 | func (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 | |||
| 67 | func (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 | |||
| 80 | func (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 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | type SyncTick struct{} | ||
| 4 | |||
| 5 | func (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 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "github.com/pektezol/bitreader" | ||
| 5 | ) | ||
| 6 | |||
| 7 | type UserCmd struct { | ||
| 8 | Cmd uint32 | ||
| 9 | Size uint32 | ||
| 10 | Data UserCmdInfo | ||
| 11 | } | ||
| 12 | |||
| 13 | type 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 | |||
| 30 | func (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 | |||
| 37 | func (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 | |||
| 82 | func (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 | |||
| 186 | type Buttons int | ||
| 187 | |||
| 188 | const ( | ||
| 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 | ) | ||