diff options
| author | Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> | 2022-11-07 16:09:44 +0300 |
|---|---|---|
| committer | Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> | 2023-09-16 21:39:37 +0300 |
| commit | a77cf8169b42a4394e62f7a381ca546b27d0f723 (patch) | |
| tree | 2dd8d4f51c5841b806e9b5ed6fe9054bce06e2e0 | |
| parent | changed github username + other stuff that i don't remember (diff) | |
| download | sdp.go-a77cf8169b42a4394e62f7a381ca546b27d0f723.tar.gz sdp.go-a77cf8169b42a4394e62f7a381ca546b27d0f723.tar.bz2 sdp.go-a77cf8169b42a4394e62f7a381ca546b27d0f723.zip | |
starting fresh for the third time
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | classes/classes.go | 199 | ||||
| -rw-r--r-- | classes/netsvc/netsvc.go | 32 | ||||
| -rw-r--r-- | classes/netsvc/types.go | 106 | ||||
| -rw-r--r-- | classes/types.go | 60 | ||||
| -rw-r--r-- | go.mod | 2 | ||||
| -rw-r--r-- | go.sum | 4 | ||||
| -rw-r--r-- | main.go | 8 | ||||
| -rw-r--r-- | messages/header.go | 29 | ||||
| -rw-r--r-- | messages/messages.go | 78 | ||||
| -rw-r--r-- | packets/header.go | 33 | ||||
| -rw-r--r-- | packets/message.go | 64 | ||||
| -rw-r--r-- | packets/types.go (renamed from messages/types.go) | 36 | ||||
| -rw-r--r-- | utils/utils.go | 62 |
14 files changed, 133 insertions, 583 deletions
| @@ -1,2 +1,3 @@ | |||
| 1 | .vscode | 1 | .vscode |
| 2 | *.dem \ No newline at end of file | 2 | *.dem |
| 3 | *.txt \ No newline at end of file | ||
diff --git a/classes/classes.go b/classes/classes.go deleted file mode 100644 index 4d6acb0..0000000 --- a/classes/classes.go +++ /dev/null | |||
| @@ -1,199 +0,0 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "encoding/binary" | ||
| 5 | "os" | ||
| 6 | |||
| 7 | "github.com/pektezol/bitreader" | ||
| 8 | "github.com/pektezol/demoparser/utils" | ||
| 9 | ) | ||
| 10 | |||
| 11 | func ParseCmdInfo(file *os.File, MSSC int) []CmdInfo { | ||
| 12 | array := utils.ReadByteFromFile(file, 76*int32(MSSC)) | ||
| 13 | var cmdinfoarray []CmdInfo | ||
| 14 | for count := 0; count < MSSC; count++ { | ||
| 15 | var cmdinfo CmdInfo | ||
| 16 | cmdinfo.Flags = int32(binary.LittleEndian.Uint32(array[0+76*count : 4+76*count])) | ||
| 17 | cmdinfo.ViewOrigin = utils.FloatArrFromBytes(array[4+76*count : 16+76*count]) | ||
| 18 | cmdinfo.ViewAngles = utils.FloatArrFromBytes(array[16+76*count : 28+76*count]) | ||
| 19 | cmdinfo.LocalViewAngles = utils.FloatArrFromBytes(array[28+76*count : 40+76*count]) | ||
| 20 | cmdinfo.ViewOrigin2 = utils.FloatArrFromBytes(array[40+76*count : 52+76*count]) | ||
| 21 | cmdinfo.ViewAngles2 = utils.FloatArrFromBytes(array[52+76*count : 64+76*count]) | ||
| 22 | cmdinfo.LocalViewAngles2 = utils.FloatArrFromBytes(array[64+76*count : 76+76*count]) | ||
| 23 | cmdinfoarray = append(cmdinfoarray, cmdinfo) | ||
| 24 | } | ||
| 25 | return cmdinfoarray | ||
| 26 | } | ||
| 27 | |||
| 28 | func ParseUserCmdInfo(file *os.File, size int) UserCmdInfo { | ||
| 29 | reader := bitreader.Reader(file, true) | ||
| 30 | var usercmd UserCmdInfo | ||
| 31 | count := 0 | ||
| 32 | flag, err := reader.ReadBool() | ||
| 33 | utils.CheckError(err) | ||
| 34 | if flag { | ||
| 35 | usercmd.CommandNumber = int32(reader.TryReadInt32()) | ||
| 36 | count += 32 | ||
| 37 | } | ||
| 38 | count++ | ||
| 39 | flag, err = reader.ReadBool() | ||
| 40 | utils.CheckError(err) | ||
| 41 | if flag { | ||
| 42 | usercmd.TickCount = int32(reader.TryReadInt32()) | ||
| 43 | count += 32 | ||
| 44 | } | ||
| 45 | count++ | ||
| 46 | flag, err = reader.ReadBool() | ||
| 47 | utils.CheckError(err) | ||
| 48 | if flag { | ||
| 49 | usercmd.ViewAnglesX = reader.TryReadFloat32() | ||
| 50 | count += 32 | ||
| 51 | } | ||
| 52 | count++ | ||
| 53 | flag, err = reader.ReadBool() | ||
| 54 | utils.CheckError(err) | ||
| 55 | if flag { | ||
| 56 | usercmd.ViewAnglesY = reader.TryReadFloat32() | ||
| 57 | count += 32 | ||
| 58 | } | ||
| 59 | count++ | ||
| 60 | flag, err = reader.ReadBool() | ||
| 61 | utils.CheckError(err) | ||
| 62 | if flag { | ||
| 63 | usercmd.ViewAnglesZ = reader.TryReadFloat32() | ||
| 64 | count += 32 | ||
| 65 | } | ||
| 66 | count++ | ||
| 67 | flag, err = reader.ReadBool() | ||
| 68 | utils.CheckError(err) | ||
| 69 | if flag { | ||
| 70 | usercmd.ForwardMove = reader.TryReadFloat32() | ||
| 71 | count += 32 | ||
| 72 | } | ||
| 73 | count++ | ||
| 74 | flag, err = reader.ReadBool() | ||
| 75 | utils.CheckError(err) | ||
| 76 | if flag { | ||
| 77 | usercmd.SideMove = reader.TryReadFloat32() | ||
| 78 | count += 32 | ||
| 79 | } | ||
| 80 | count++ | ||
| 81 | flag, err = reader.ReadBool() | ||
| 82 | utils.CheckError(err) | ||
| 83 | if flag { | ||
| 84 | usercmd.UpMove = reader.TryReadFloat32() | ||
| 85 | count += 32 | ||
| 86 | } | ||
| 87 | count++ | ||
| 88 | flag, err = reader.ReadBool() | ||
| 89 | utils.CheckError(err) | ||
| 90 | if flag { | ||
| 91 | usercmd.Buttons = int32(reader.TryReadInt32()) | ||
| 92 | count += 32 | ||
| 93 | } | ||
| 94 | count++ | ||
| 95 | flag, err = reader.ReadBool() | ||
| 96 | utils.CheckError(err) | ||
| 97 | if flag { | ||
| 98 | //reader.SkipBits(8) | ||
| 99 | usercmd.Impulse = int8(reader.TryReadInt8()) | ||
| 100 | count += 8 | ||
| 101 | } | ||
| 102 | count++ | ||
| 103 | flag, err = reader.ReadBool() | ||
| 104 | utils.CheckError(err) | ||
| 105 | if flag { | ||
| 106 | value, err := reader.ReadBits(11) | ||
| 107 | utils.CheckError(err) | ||
| 108 | usercmd.WeaponSelect = int(value) | ||
| 109 | flag, err = reader.ReadBool() | ||
| 110 | utils.CheckError(err) | ||
| 111 | count += 11 | ||
| 112 | if flag { | ||
| 113 | value, err := reader.ReadBits(6) | ||
| 114 | utils.CheckError(err) | ||
| 115 | usercmd.WeaponSubtype = int(value) | ||
| 116 | count += 6 | ||
| 117 | } | ||
| 118 | count++ | ||
| 119 | } | ||
| 120 | count++ | ||
| 121 | flag, err = reader.ReadBool() | ||
| 122 | utils.CheckError(err) | ||
| 123 | if flag { | ||
| 124 | usercmd.MouseDx = int16(reader.TryReadInt16()) | ||
| 125 | count += 16 | ||
| 126 | } | ||
| 127 | count++ | ||
| 128 | flag, err = reader.ReadBool() | ||
| 129 | utils.CheckError(err) | ||
| 130 | if flag { | ||
| 131 | usercmd.MouseDy = int16(reader.TryReadInt16()) | ||
| 132 | count += 16 | ||
| 133 | } | ||
| 134 | count++ | ||
| 135 | reader.SkipBits(size*8 - count) // Skip remaining bits from specified size | ||
| 136 | return usercmd | ||
| 137 | } | ||
| 138 | |||
| 139 | /*func ParseStringTable(file *os.File, size int) []StringTable { | ||
| 140 | reader := bitreader.Reader(file, true) | ||
| 141 | var stringtable StringTable | ||
| 142 | var stringtablearray []StringTable | ||
| 143 | //count := 0 | ||
| 144 | stringtable.NumOfTables = int8(reader.TryReadInt8()) | ||
| 145 | for i := 0; i < int(stringtable.NumOfTables); i++ { | ||
| 146 | stringtable.TableName = utils.ReadStringFromFile(file) | ||
| 147 | stringtable.NumOfEntries = int16(reader.TryReadInt16()) | ||
| 148 | stringtable.EntryName = utils.ReadStringFromFile(file) | ||
| 149 | flag, err := reader.ReadBool() | ||
| 150 | utils.CheckError(err) | ||
| 151 | if flag { | ||
| 152 | stringtable.EntrySize = int16(reader.TryReadInt16()) | ||
| 153 | } | ||
| 154 | flag, err = reader.ReadBool() | ||
| 155 | utils.CheckError(err) | ||
| 156 | if flag { | ||
| 157 | fmt.Println(int(stringtable.EntrySize)) | ||
| 158 | reader.SkipBytes(int(stringtable.EntrySize)) | ||
| 159 | var bytearray []byte | ||
| 160 | for i := 0; i < int(stringtable.EntrySize); i++ { | ||
| 161 | value, err := reader.ReadBytes(1) | ||
| 162 | utils.CheckError(err) | ||
| 163 | bytearray = append(bytearray, byte(value)) | ||
| 164 | } | ||
| 165 | stringtable.EntryData = bytearrray | ||
| 166 | } | ||
| 167 | flag, err = reader.ReadBool() | ||
| 168 | utils.CheckError(err) | ||
| 169 | if flag { | ||
| 170 | stringtable.NumOfClientEntries = int16(reader.TryReadInt16()) | ||
| 171 | } | ||
| 172 | flag, err = reader.ReadBool() | ||
| 173 | utils.CheckError(err) | ||
| 174 | if flag { | ||
| 175 | stringtable.ClientEntryName = utils.ReadStringFromFile(file) | ||
| 176 | } | ||
| 177 | flag, err = reader.ReadBool() | ||
| 178 | utils.CheckError(err) | ||
| 179 | if flag { | ||
| 180 | stringtable.ClientEntrySize = int16(reader.TryReadInt16()) | ||
| 181 | } | ||
| 182 | flag, err = reader.ReadBool() | ||
| 183 | utils.CheckError(err) | ||
| 184 | if flag { | ||
| 185 | reader.SkipBytes(int(stringtable.ClientEntrySize)) | ||
| 186 | /*var bytearray []byte | ||
| 187 | for i := 0; i < int(stringtable.ClientEntrySize); i++ { | ||
| 188 | value, err := reader.ReadBytes(1) | ||
| 189 | utils.CheckError(err) | ||
| 190 | bytearray = append(bytearray, byte(value)) | ||
| 191 | } | ||
| 192 | stringtable.ClientEntryData = bytearrray | ||
| 193 | } | ||
| 194 | stringtablearray = append(stringtablearray, stringtable) | ||
| 195 | } | ||
| 196 | |||
| 197 | //reader.SkipBits(size*8 - 8) | ||
| 198 | return stringtablearray | ||
| 199 | }*/ | ||
diff --git a/classes/netsvc/netsvc.go b/classes/netsvc/netsvc.go deleted file mode 100644 index a454310..0000000 --- a/classes/netsvc/netsvc.go +++ /dev/null | |||
| @@ -1,32 +0,0 @@ | |||
| 1 | package netsvc | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "bytes" | ||
| 5 | "fmt" | ||
| 6 | |||
| 7 | "github.com/pektezol/bitreader" | ||
| 8 | "github.com/pektezol/demoparser/utils" | ||
| 9 | ) | ||
| 10 | |||
| 11 | const NET_TICK_SCALEUP = 10000 | ||
| 12 | |||
| 13 | func ParseNetSvcMessage(file []byte) { | ||
| 14 | reader := bitreader.Reader(bytes.NewReader(file), true) | ||
| 15 | bitsRead := 0 | ||
| 16 | for { | ||
| 17 | messageType, err := reader.ReadBits(6) | ||
| 18 | if err != nil { // No remaining bits left | ||
| 19 | break | ||
| 20 | } | ||
| 21 | switch messageType { | ||
| 22 | case 16: | ||
| 23 | var svcprint SvcPrint | ||
| 24 | svcprint.Message = utils.ReadStringFromSlice(file) | ||
| 25 | fmt.Println(svcprint) | ||
| 26 | bitsRead += len(svcprint.Message) * 8 | ||
| 27 | default: | ||
| 28 | //fmt.Println("default") | ||
| 29 | break | ||
| 30 | } | ||
| 31 | } | ||
| 32 | } | ||
diff --git a/classes/netsvc/types.go b/classes/netsvc/types.go deleted file mode 100644 index 2a52f96..0000000 --- a/classes/netsvc/types.go +++ /dev/null | |||
| @@ -1,106 +0,0 @@ | |||
| 1 | package netsvc | ||
| 2 | |||
| 3 | type NetDisconnect struct { | ||
| 4 | Text string | ||
| 5 | } | ||
| 6 | |||
| 7 | type NetFile struct { | ||
| 8 | TransferId int32 | ||
| 9 | FileName string | ||
| 10 | FileRequested bool | ||
| 11 | } | ||
| 12 | |||
| 13 | type NetSplitScreenUser struct { | ||
| 14 | Unknown bool | ||
| 15 | } | ||
| 16 | |||
| 17 | type NetTick struct { | ||
| 18 | Tick int32 | ||
| 19 | HostFrameTime int16 | ||
| 20 | HostFrameTimeStdDeviation int16 | ||
| 21 | } | ||
| 22 | |||
| 23 | type NetStringCmd struct { | ||
| 24 | Command string | ||
| 25 | } | ||
| 26 | |||
| 27 | type ConVar struct { | ||
| 28 | Name string | ||
| 29 | Value string | ||
| 30 | } | ||
| 31 | |||
| 32 | type NetSetConVar struct { | ||
| 33 | Length int8 | ||
| 34 | ConVars []ConVar | ||
| 35 | } | ||
| 36 | |||
| 37 | type NetSignonStateOE struct { | ||
| 38 | SignonState int8 | ||
| 39 | SpawnCount int32 | ||
| 40 | } | ||
| 41 | |||
| 42 | type NetSignonStateNE struct { | ||
| 43 | NetSignonStateOE | ||
| 44 | NumServerPlayers int32 | ||
| 45 | IdsLength int32 | ||
| 46 | PlayerNetworkIds []byte | ||
| 47 | MapNameLength int32 | ||
| 48 | MapName string | ||
| 49 | } | ||
| 50 | |||
| 51 | type SvcServerInfo struct { | ||
| 52 | Protocol int8 | ||
| 53 | ServerCount int32 | ||
| 54 | IsHltv bool | ||
| 55 | IsDedicated bool | ||
| 56 | ClientCrc int32 | ||
| 57 | MaxClasses int16 | ||
| 58 | MapCrc int32 | ||
| 59 | PlayerSlot int8 | ||
| 60 | MaxClients int8 | ||
| 61 | Unk int32 // NE | ||
| 62 | TickInterval float32 | ||
| 63 | COs byte | ||
| 64 | GameDir string | ||
| 65 | MapName string | ||
| 66 | SkyName string | ||
| 67 | HostName string | ||
| 68 | } | ||
| 69 | |||
| 70 | type SvcSendTable struct { | ||
| 71 | NeedsDecoder bool | ||
| 72 | Length int8 | ||
| 73 | Props int // ? | ||
| 74 | } | ||
| 75 | |||
| 76 | type ServerClass struct { | ||
| 77 | ClassId int8 | ||
| 78 | ClassName string | ||
| 79 | DataTableName string | ||
| 80 | } | ||
| 81 | |||
| 82 | type SvcClassInfo struct { | ||
| 83 | Length int16 | ||
| 84 | CreateOnClient bool | ||
| 85 | ServerClasses []ServerClass | ||
| 86 | } | ||
| 87 | |||
| 88 | type SvcSetPause struct { | ||
| 89 | Paused bool | ||
| 90 | } | ||
| 91 | |||
| 92 | type SvcCreateStringTable struct { | ||
| 93 | Name string | ||
| 94 | MaxEntries int16 | ||
| 95 | NumEntries int8 | ||
| 96 | Length int32 | ||
| 97 | UserDataFixedSize bool | ||
| 98 | UserDataSize int32 | ||
| 99 | UserDataSizeBits int8 | ||
| 100 | Flags int8 | ||
| 101 | StringData int // ? | ||
| 102 | } | ||
| 103 | |||
| 104 | type SvcPrint struct { | ||
| 105 | Message string | ||
| 106 | } | ||
diff --git a/classes/types.go b/classes/types.go deleted file mode 100644 index 20c793a..0000000 --- a/classes/types.go +++ /dev/null | |||
| @@ -1,60 +0,0 @@ | |||
| 1 | package classes | ||
| 2 | |||
| 3 | type CmdInfo struct { | ||
| 4 | Flags int32 | ||
| 5 | ViewOrigin []float32 | ||
| 6 | ViewAngles []float32 | ||
| 7 | LocalViewAngles []float32 | ||
| 8 | ViewOrigin2 []float32 | ||
| 9 | ViewAngles2 []float32 | ||
| 10 | LocalViewAngles2 []float32 | ||
| 11 | } | ||
| 12 | |||
| 13 | type UserCmdInfo struct { | ||
| 14 | CommandNumber int32 | ||
| 15 | TickCount int32 | ||
| 16 | ViewAnglesX float32 | ||
| 17 | ViewAnglesY float32 | ||
| 18 | ViewAnglesZ float32 | ||
| 19 | ForwardMove float32 | ||
| 20 | SideMove float32 | ||
| 21 | UpMove float32 | ||
| 22 | Buttons int32 | ||
| 23 | Impulse int8 | ||
| 24 | WeaponSelect int | ||
| 25 | WeaponSubtype int | ||
| 26 | MouseDx int16 | ||
| 27 | MouseDy int16 | ||
| 28 | } | ||
| 29 | |||
| 30 | type DataTables struct { | ||
| 31 | SendTable []SendTable | ||
| 32 | ServerClassInfo []ServerClassInfo | ||
| 33 | } | ||
| 34 | |||
| 35 | type SendTable struct { | ||
| 36 | NetTableName string | ||
| 37 | NumOfProps int | ||
| 38 | SendPropType int | ||
| 39 | SendPropName string | ||
| 40 | SendPropFlags int | ||
| 41 | } | ||
| 42 | |||
| 43 | type ServerClassInfo struct { | ||
| 44 | } | ||
| 45 | |||
| 46 | type StringTable struct { | ||
| 47 | NumOfTables int8 | ||
| 48 | TableName string | ||
| 49 | NumOfEntries int16 | ||
| 50 | EntryName string | ||
| 51 | EntrySize int16 | ||
| 52 | EntryData []byte | ||
| 53 | NumOfClientEntries int16 | ||
| 54 | ClientEntryName string | ||
| 55 | ClientEntrySize int16 | ||
| 56 | ClientEntryData []byte | ||
| 57 | } | ||
| 58 | |||
| 59 | type GameEvent struct { | ||
| 60 | } | ||
| @@ -2,4 +2,4 @@ module github.com/pektezol/demoparser | |||
| 2 | 2 | ||
| 3 | go 1.19 | 3 | go 1.19 |
| 4 | 4 | ||
| 5 | require github.com/pektezol/bitreader v1.1.2 | 5 | require github.com/pektezol/bitreader v1.2.1 |
| @@ -1,2 +1,6 @@ | |||
| 1 | github.com/pektezol/bitreader v1.1.2 h1:F0u8qiauIwh52lwiwy7UMQ03/bw4NuEXQU0UFBL+A2w= | 1 | github.com/pektezol/bitreader v1.1.2 h1:F0u8qiauIwh52lwiwy7UMQ03/bw4NuEXQU0UFBL+A2w= |
| 2 | github.com/pektezol/bitreader v1.1.2/go.mod h1:RKAUiA//jCPJzO10P+VSkBq4wfY38TaNjpCjQ+DmbcQ= | 2 | github.com/pektezol/bitreader v1.1.2/go.mod h1:RKAUiA//jCPJzO10P+VSkBq4wfY38TaNjpCjQ+DmbcQ= |
| 3 | github.com/pektezol/bitreader v1.2.0 h1:7sr46Rgx06j5+adLn3xOUSHc+Pz2GoFC1BIk+2ktdxg= | ||
| 4 | github.com/pektezol/bitreader v1.2.0/go.mod h1:RKAUiA//jCPJzO10P+VSkBq4wfY38TaNjpCjQ+DmbcQ= | ||
| 5 | github.com/pektezol/bitreader v1.2.1 h1:ChmgZjsi1hftUgH2LkfttjsER5UGYxrwwfsH2QCx/SU= | ||
| 6 | github.com/pektezol/bitreader v1.2.1/go.mod h1:RKAUiA//jCPJzO10P+VSkBq4wfY38TaNjpCjQ+DmbcQ= | ||
| @@ -6,7 +6,8 @@ import ( | |||
| 6 | "log" | 6 | "log" |
| 7 | "os" | 7 | "os" |
| 8 | 8 | ||
| 9 | "github.com/pektezol/demoparser/messages" | 9 | "github.com/pektezol/bitreader" |
| 10 | "github.com/pektezol/demoparser/packets" | ||
| 10 | ) | 11 | ) |
| 11 | 12 | ||
| 12 | func main() { | 13 | func main() { |
| @@ -19,9 +20,10 @@ func main() { | |||
| 19 | if err != nil { | 20 | if err != nil { |
| 20 | panic(err) | 21 | panic(err) |
| 21 | } | 22 | } |
| 22 | messages.ParseHeader(file) | 23 | reader := bitreader.Reader(file, true) |
| 24 | packets.ParseHeader(reader) | ||
| 23 | for { | 25 | for { |
| 24 | code := messages.ParseMessage(file) | 26 | code := packets.ParseMessage(reader) |
| 25 | if code == 7 { | 27 | if code == 7 { |
| 26 | break | 28 | break |
| 27 | } | 29 | } |
diff --git a/messages/header.go b/messages/header.go deleted file mode 100644 index 34b36d3..0000000 --- a/messages/header.go +++ /dev/null | |||
| @@ -1,29 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | "os" | ||
| 6 | |||
| 7 | "github.com/pektezol/bitreader" | ||
| 8 | "github.com/pektezol/demoparser/utils" | ||
| 9 | ) | ||
| 10 | |||
| 11 | func ParseHeader(file *os.File) { | ||
| 12 | var header Header | ||
| 13 | reader := bitreader.Reader(file, true) | ||
| 14 | header.DemoFileStamp = string(utils.ReadByteFromFile(file, 8)) | ||
| 15 | header.DemoProtocol = int32(reader.TryReadInt32()) | ||
| 16 | header.NetworkProtocol = int32(reader.TryReadInt32()) | ||
| 17 | header.ServerName = string(utils.ReadByteFromFile(file, 260)) | ||
| 18 | header.ClientName = string(utils.ReadByteFromFile(file, 260)) | ||
| 19 | header.MapName = string(utils.ReadByteFromFile(file, 260)) | ||
| 20 | header.GameDirectory = string(utils.ReadByteFromFile(file, 260)) | ||
| 21 | header.PlaybackTime = float32(reader.TryReadFloat32()) | ||
| 22 | header.PlaybackTicks = int32(reader.TryReadInt32()) | ||
| 23 | header.PlaybackFrames = int32(reader.TryReadInt32()) | ||
| 24 | header.SignOnLength = int32(reader.TryReadInt32()) | ||
| 25 | if header.DemoProtocol != 4 { // Old Engine == 2, 3 / New Engine == 4 | ||
| 26 | panic("Only New Engine is supported.") | ||
| 27 | } | ||
| 28 | fmt.Printf("%+v", header) | ||
| 29 | } | ||
diff --git a/messages/messages.go b/messages/messages.go deleted file mode 100644 index b40684b..0000000 --- a/messages/messages.go +++ /dev/null | |||
| @@ -1,78 +0,0 @@ | |||
| 1 | package messages | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | "os" | ||
| 6 | |||
| 7 | "github.com/pektezol/bitreader" | ||
| 8 | "github.com/pektezol/demoparser/classes" | ||
| 9 | "github.com/pektezol/demoparser/classes/netsvc" | ||
| 10 | "github.com/pektezol/demoparser/utils" | ||
| 11 | ) | ||
| 12 | |||
| 13 | func ParseMessage(file *os.File) (statusCode int) { | ||
| 14 | reader := bitreader.Reader(file, true) | ||
| 15 | messageType := reader.TryReadInt8() | ||
| 16 | messageTick := reader.TryReadInt32() | ||
| 17 | messageSlot := reader.TryReadInt8() | ||
| 18 | //fmt.Println(messageType, messageTick, messageSlot) | ||
| 19 | switch messageType { | ||
| 20 | case 0x01: // SignOn | ||
| 21 | var packet Packet | ||
| 22 | packet.PacketInfo = classes.ParseCmdInfo(file, 2) | ||
| 23 | packet.InSequence = int32(reader.TryReadInt32()) | ||
| 24 | packet.OutSequence = int32(reader.TryReadInt32()) | ||
| 25 | packet.Size = int32(reader.TryReadInt32()) | ||
| 26 | data := utils.ReadByteFromFile(file, packet.Size) | ||
| 27 | //fmt.Println(data) | ||
| 28 | netsvc.ParseNetSvcMessage(data) | ||
| 29 | //reader.SkipBytes(int(packet.Size)) // TODO: NET/SVC Message Parsing | ||
| 30 | fmt.Printf("[%d] (%d) SignOn: %v\n", messageTick, messageSlot, packet) | ||
| 31 | return 1 | ||
| 32 | case 0x02: // Packet | ||
| 33 | var packet Packet | ||
| 34 | packet.PacketInfo = classes.ParseCmdInfo(file, 2) | ||
| 35 | packet.InSequence = int32(reader.TryReadInt32()) | ||
| 36 | packet.OutSequence = int32(reader.TryReadInt32()) | ||
| 37 | packet.Size = int32(reader.TryReadInt32()) | ||
| 38 | reader.SkipBytes(int(packet.Size)) // TODO: NET/SVC Message Parsing | ||
| 39 | //fmt.Printf("[%d] Packet: %v\n", messageTick, packet) | ||
| 40 | return 2 | ||
| 41 | case 0x03: // SyncTick | ||
| 42 | return 3 | ||
| 43 | case 0x04: // ConsoleCmd | ||
| 44 | var consolecmd ConsoleCmd | ||
| 45 | consolecmd.Size = int32(reader.TryReadInt32()) | ||
| 46 | consolecmd.Data = string(utils.ReadByteFromFile(file, consolecmd.Size)) | ||
| 47 | //fmt.Printf("[%d] ConsoleCmd: %s\n", messageTick, consolecmd.Data) | ||
| 48 | return 4 | ||
| 49 | case 0x05: // UserCmd | ||
| 50 | var usercmd UserCmd | ||
| 51 | usercmd.Cmd = int32(reader.TryReadInt32()) | ||
| 52 | usercmd.Size = int32(reader.TryReadInt32()) | ||
| 53 | usercmd.Data = classes.ParseUserCmdInfo(file, int(usercmd.Size)) | ||
| 54 | //fmt.Printf("[%d] UserCmd: %v\n", messageTick, usercmd.Data) | ||
| 55 | return 5 | ||
| 56 | case 0x06: // DataTables | ||
| 57 | var datatables DataTables | ||
| 58 | datatables.Size = int32(reader.TryReadInt32()) | ||
| 59 | reader.SkipBytes(int(datatables.Size)) // TODO: DataTables Data | ||
| 60 | return 6 | ||
| 61 | case 0x07: // Stop | ||
| 62 | fmt.Printf("[%d] Stop\n", messageTick) | ||
| 63 | return 7 | ||
| 64 | case 0x08: // CustomData | ||
| 65 | var customdata CustomData | ||
| 66 | customdata.Unknown = int32(reader.TryReadInt32()) | ||
| 67 | customdata.Size = int32(reader.TryReadInt32()) | ||
| 68 | reader.SkipBytes(int(customdata.Size)) // TODO: CustomData Data | ||
| 69 | return 8 | ||
| 70 | case 0x09: // StringTables | ||
| 71 | var stringtables StringTables | ||
| 72 | stringtables.Size = int32(reader.TryReadInt32()) | ||
| 73 | reader.SkipBytes(int(stringtables.Size)) // TODO: StringTables Data | ||
| 74 | return 9 | ||
| 75 | default: | ||
| 76 | return 0 | ||
| 77 | } | ||
| 78 | } | ||
diff --git a/packets/header.go b/packets/header.go new file mode 100644 index 0000000..60cd146 --- /dev/null +++ b/packets/header.go | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | package packets | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | ) | ||
| 8 | |||
| 9 | func ParseHeader(reader *bitreader.ReaderType) { | ||
| 10 | header := Header{ | ||
| 11 | DemoFileStamp: reader.TryReadStringLen(8), | ||
| 12 | DemoProtocol: uint(reader.TryReadInt32()), | ||
| 13 | NetworkProtocol: uint(reader.TryReadInt32()), | ||
| 14 | ServerName: reader.TryReadStringLen(260), | ||
| 15 | ClientName: reader.TryReadStringLen(260), | ||
| 16 | MapName: reader.TryReadStringLen(260), | ||
| 17 | GameDirectory: reader.TryReadStringLen(260), | ||
| 18 | PlaybackTime: reader.TryReadFloat32(), | ||
| 19 | PlaybackTicks: int(reader.TryReadInt32()), | ||
| 20 | PlaybackFrames: int(reader.TryReadInt32()), | ||
| 21 | SignOnLength: uint(reader.TryReadInt32()), | ||
| 22 | } | ||
| 23 | if header.DemoFileStamp != "HL2DEMO" { | ||
| 24 | panic("Invalid demo file stamp. Make sure a valid demo file is given.") | ||
| 25 | } | ||
| 26 | if header.DemoProtocol != 4 { | ||
| 27 | panic("Given demo is from old engine. This parser is only supported for new engine.") | ||
| 28 | } | ||
| 29 | if header.NetworkProtocol != 2001 { | ||
| 30 | panic("Given demo is not from Portal2. This parser currently only supports Portal 2.") | ||
| 31 | } | ||
| 32 | fmt.Println(header) | ||
| 33 | } | ||
diff --git a/packets/message.go b/packets/message.go new file mode 100644 index 0000000..a8e830d --- /dev/null +++ b/packets/message.go | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | package packets | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | |||
| 6 | "github.com/pektezol/bitreader" | ||
| 7 | ) | ||
| 8 | |||
| 9 | func ParseMessage(reader *bitreader.ReaderType) (status int) { | ||
| 10 | messageType := reader.TryReadInt8() | ||
| 11 | messageTick := reader.TryReadInt32() | ||
| 12 | messageSlot := reader.TryReadInt8() | ||
| 13 | //fmt.Println(messageType, messageTick, messageSlot) | ||
| 14 | switch messageType { | ||
| 15 | case 0x01: | ||
| 16 | //signOn := SignOn{} | ||
| 17 | reader.SkipBytes(76*2 + 8) | ||
| 18 | val := reader.TryReadInt32() | ||
| 19 | reader.SkipBytes(int(val)) | ||
| 20 | fmt.Printf("[%d] (%d) {%d} SignOn: \n", messageTick, messageType, messageSlot) | ||
| 21 | return 1 | ||
| 22 | case 0x02: | ||
| 23 | reader.SkipBytes(76*2 + 8) | ||
| 24 | val := reader.TryReadInt32() | ||
| 25 | reader.SkipBytes(int(val)) | ||
| 26 | // fmt.Printf("[%d] (%d) Packet: \n", messageTick, messageType) | ||
| 27 | return 2 | ||
| 28 | case 0x03: | ||
| 29 | fmt.Printf("[%d] (%d) SyncTick: \n", messageTick, messageType) | ||
| 30 | return 3 | ||
| 31 | case 0x04: | ||
| 32 | val := reader.TryReadInt32() | ||
| 33 | reader.SkipBytes(int(val)) | ||
| 34 | // fmt.Printf("[%d] (%d) ConsoleCmd: \n", messageTick, messageType) | ||
| 35 | return 4 | ||
| 36 | case 0x05: | ||
| 37 | reader.SkipBytes(4) | ||
| 38 | val := reader.TryReadInt32() | ||
| 39 | reader.SkipBytes(int(val)) | ||
| 40 | // fmt.Printf("[%d] (%d) UserCmd: \n", messageTick, messageType) | ||
| 41 | return 5 | ||
| 42 | case 0x06: | ||
| 43 | val := reader.TryReadInt32() | ||
| 44 | reader.SkipBytes(int(val)) | ||
| 45 | // fmt.Printf("[%d] (%d) DataTables: \n", messageTick, messageType) | ||
| 46 | return 6 | ||
| 47 | case 0x07: | ||
| 48 | fmt.Printf("[%d] (%d) Stop: \n", messageTick, messageType) | ||
| 49 | return 7 | ||
| 50 | case 0x08: | ||
| 51 | reader.SkipBytes(4) | ||
| 52 | val := reader.TryReadInt32() | ||
| 53 | reader.SkipBytes(int(val)) | ||
| 54 | // fmt.Printf("[%d] (%d) CustomData: \n", messageTick, messageType) | ||
| 55 | return 8 | ||
| 56 | case 0x09: | ||
| 57 | val := reader.TryReadInt32() | ||
| 58 | reader.SkipBytes(int(val)) | ||
| 59 | // fmt.Printf("[%d] (%d) StringTables: \n", messageTick, messageType) | ||
| 60 | return 9 | ||
| 61 | default: | ||
| 62 | return 0 | ||
| 63 | } | ||
| 64 | } | ||
diff --git a/messages/types.go b/packets/types.go index 9c92c54..5f7a29b 100644 --- a/messages/types.go +++ b/packets/types.go | |||
| @@ -1,29 +1,37 @@ | |||
| 1 | package messages | 1 | package packets |
| 2 | |||
| 3 | import "github.com/pektezol/demoparser/classes" | ||
| 4 | 2 | ||
| 5 | type Header struct { | 3 | type Header struct { |
| 6 | DemoFileStamp string | 4 | DemoFileStamp string |
| 7 | DemoProtocol int32 | 5 | DemoProtocol uint |
| 8 | NetworkProtocol int32 | 6 | NetworkProtocol uint |
| 9 | ServerName string | 7 | ServerName string |
| 10 | ClientName string | 8 | ClientName string |
| 11 | MapName string | 9 | MapName string |
| 12 | GameDirectory string | 10 | GameDirectory string |
| 13 | PlaybackTime float32 | 11 | PlaybackTime float32 |
| 14 | PlaybackTicks int32 | 12 | PlaybackTicks int |
| 15 | PlaybackFrames int32 | 13 | PlaybackFrames int |
| 16 | SignOnLength int32 | 14 | SignOnLength uint |
| 15 | } | ||
| 16 | |||
| 17 | type SignOn struct { | ||
| 18 | PacketInfo []byte | ||
| 19 | InSequence int32 | ||
| 20 | OutSequence int32 | ||
| 21 | Size int32 | ||
| 22 | Data []byte | ||
| 17 | } | 23 | } |
| 18 | 24 | ||
| 19 | type Packet struct { | 25 | type Packet struct { |
| 20 | PacketInfo []classes.CmdInfo | 26 | PacketInfo []byte |
| 21 | InSequence int32 | 27 | InSequence int32 |
| 22 | OutSequence int32 | 28 | OutSequence int32 |
| 23 | Size int32 | 29 | Size int32 |
| 24 | Data []byte | 30 | Data []byte |
| 25 | } | 31 | } |
| 26 | 32 | ||
| 33 | type SyncTick struct{} | ||
| 34 | |||
| 27 | type ConsoleCmd struct { | 35 | type ConsoleCmd struct { |
| 28 | Size int32 | 36 | Size int32 |
| 29 | Data string | 37 | Data string |
| @@ -32,12 +40,16 @@ type ConsoleCmd struct { | |||
| 32 | type UserCmd struct { | 40 | type UserCmd struct { |
| 33 | Cmd int32 | 41 | Cmd int32 |
| 34 | Size int32 | 42 | Size int32 |
| 35 | Data classes.UserCmdInfo | 43 | Data []byte |
| 36 | } | 44 | } |
| 37 | 45 | ||
| 38 | type DataTables struct { | 46 | type DataTables struct { |
| 39 | Size int32 | 47 | Size int32 |
| 40 | Data classes.DataTables | 48 | Data []byte |
| 49 | } | ||
| 50 | |||
| 51 | type Stop struct { | ||
| 52 | RemainingData []byte | ||
| 41 | } | 53 | } |
| 42 | 54 | ||
| 43 | type CustomData struct { | 55 | type CustomData struct { |
| @@ -48,5 +60,5 @@ type CustomData struct { | |||
| 48 | 60 | ||
| 49 | type StringTables struct { | 61 | type StringTables struct { |
| 50 | Size int32 | 62 | Size int32 |
| 51 | Data []classes.StringTable | 63 | Data []byte |
| 52 | } | 64 | } |
diff --git a/utils/utils.go b/utils/utils.go deleted file mode 100644 index db1b02f..0000000 --- a/utils/utils.go +++ /dev/null | |||
| @@ -1,62 +0,0 @@ | |||
| 1 | package utils | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "bytes" | ||
| 5 | "os" | ||
| 6 | "unsafe" | ||
| 7 | |||
| 8 | "github.com/pektezol/bitreader" | ||
| 9 | ) | ||
| 10 | |||
| 11 | func CheckError(e error) { | ||
| 12 | if e != nil { | ||
| 13 | panic(e) | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | func ReadByteFromFile(file *os.File, size int32) []byte { | ||
| 18 | tmp := make([]byte, size) | ||
| 19 | file.Read(tmp) | ||
| 20 | return tmp | ||
| 21 | } | ||
| 22 | |||
| 23 | func ReadStringFromFile(file *os.File) string { | ||
| 24 | var output string | ||
| 25 | reader := bitreader.Reader(file, true) | ||
| 26 | for { | ||
| 27 | value, err := reader.ReadBytes(1) | ||
| 28 | CheckError(err) | ||
| 29 | if value == 0 { | ||
| 30 | break | ||
| 31 | } | ||
| 32 | output += string(rune(value)) | ||
| 33 | } | ||
| 34 | return output | ||
| 35 | } | ||
| 36 | |||
| 37 | func ReadStringFromSlice(file []byte) string { | ||
| 38 | var output string | ||
| 39 | reader := bitreader.Reader(bytes.NewReader(file), true) | ||
| 40 | for { | ||
| 41 | value, err := reader.ReadBytes(1) | ||
| 42 | CheckError(err) | ||
| 43 | if value == 0 { | ||
| 44 | break | ||
| 45 | } | ||
| 46 | output += string(rune(value)) | ||
| 47 | } | ||
| 48 | return output | ||
| 49 | } | ||
| 50 | |||
| 51 | func FloatArrFromBytes(byteArr []byte) []float32 { | ||
| 52 | if len(byteArr) == 0 { | ||
| 53 | return nil | ||
| 54 | } | ||
| 55 | l := len(byteArr) / 4 | ||
| 56 | ptr := unsafe.Pointer(&byteArr[0]) | ||
| 57 | // It is important to keep in mind that the Go garbage collector | ||
| 58 | // will not interact with this data, and that if src if freed, | ||
| 59 | // the behavior of any Go code using the slice is nondeterministic. | ||
| 60 | // Reference: https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices | ||
| 61 | return (*[1 << 26]float32)((*[1 << 26]float32)(ptr))[:l:l] | ||
| 62 | } | ||