aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBiSaXa <1669855+BiSaXa@users.noreply.github.com>2022-08-27 13:02:35 +0300
committerBiSaXa <1669855+BiSaXa@users.noreply.github.com>2022-08-27 13:02:35 +0300
commitf108a577658c9aab8496da4ebd0fb4f0216093e8 (patch)
treee484a8a8b54c92ca4a393f267ebc755ec6434c8d
downloadsdp.go-f108a577658c9aab8496da4ebd0fb4f0216093e8.tar.gz
sdp.go-f108a577658c9aab8496da4ebd0fb4f0216093e8.tar.bz2
sdp.go-f108a577658c9aab8496da4ebd0fb4f0216093e8.zip
init
-rw-r--r--.gitignore2
-rw-r--r--classes/cmdInfo.go25
-rw-r--r--classes/stringTable.go27
-rw-r--r--classes/userCmdInfo.go57
-rw-r--r--go.mod5
-rw-r--r--go.sum2
-rw-r--r--main.go26
-rw-r--r--messages/messages.go89
-rw-r--r--messages/types.go36
-rw-r--r--utils/header.go43
-rw-r--r--utils/utils.go57
11 files changed, 369 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..55fc782
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
1.vscode
2*.dem \ No newline at end of file
diff --git a/classes/cmdInfo.go b/classes/cmdInfo.go
new file mode 100644
index 0000000..c1faadd
--- /dev/null
+++ b/classes/cmdInfo.go
@@ -0,0 +1,25 @@
1package classes
2
3import "parser/utils"
4
5type CmdInfo struct {
6 Flags int32
7 ViewOrigin []float32
8 ViewAngles []float32
9 LocalViewAngles []float32
10 ViewOrigin2 []float32
11 ViewAngles2 []float32
12 LocalViewAngles2 []float32
13}
14
15func CmdInfoInit(bytes []byte) (output CmdInfo) {
16 var class CmdInfo
17 class.Flags = int32(utils.IntFromBytes(bytes[:4]))
18 class.ViewOrigin = utils.FloatArrFromBytes(bytes[4:16])
19 class.ViewAngles = utils.FloatArrFromBytes(bytes[16:28])
20 class.LocalViewAngles = utils.FloatArrFromBytes(bytes[28:40])
21 class.ViewOrigin2 = utils.FloatArrFromBytes(bytes[40:52])
22 class.ViewAngles2 = utils.FloatArrFromBytes(bytes[52:64])
23 class.LocalViewAngles2 = utils.FloatArrFromBytes(bytes[64:76])
24 return class
25}
diff --git a/classes/stringTable.go b/classes/stringTable.go
new file mode 100644
index 0000000..0833612
--- /dev/null
+++ b/classes/stringTable.go
@@ -0,0 +1,27 @@
1package classes
2
3type StringTable struct {
4 NumOfTables int32
5 TableName string
6 NumOfEntries int16
7 EntryName string
8 EntrySize int16
9 EntryData []byte
10 NumOfClientEntries int16
11 ClientEntryName string
12 ClientEntrySize int16
13 ClientEntryData []byte
14}
15
16/*
17func StringTableInit(bytes []byte) (output StringTable) {
18 var class StringTable
19 class.NumOfTables = int(utils.IntFromBytes(bytes[:1]))
20 class.TableName = string(bytes[1:16])
21 class.ViewAngles = utils.FloatArrFromBytes(bytes[16:28])
22 class.LocalViewAngles = utils.FloatArrFromBytes(bytes[28:40])
23 class.ViewOrigin2 = utils.FloatArrFromBytes(bytes[40:52])
24 class.ViewAngles2 = utils.FloatArrFromBytes(bytes[52:64])
25 class.LocalViewAngles2 = utils.FloatArrFromBytes(bytes[64:76])
26 return class
27}*/
diff --git a/classes/userCmdInfo.go b/classes/userCmdInfo.go
new file mode 100644
index 0000000..ae27e9a
--- /dev/null
+++ b/classes/userCmdInfo.go
@@ -0,0 +1,57 @@
1package classes
2
3import (
4 "parser/utils"
5)
6
7type UserCmdInfo struct {
8 CommandNumber int32
9 TickCount int32
10 ViewAnglesX float32
11 ViewAnglesY float32
12 ViewAnglesZ float32
13 ForwardMove float32
14 SideMove float32
15 UpMove float32
16 Buttons int32
17 Impulse byte
18 /*WeaponSelect int
19 WeaponSubtype int
20 MouseDx int16
21 MouseDy int16*/
22}
23
24func UserCmdInfoInit(byteArr []byte, size int) (output UserCmdInfo) {
25 var class UserCmdInfo
26 if size-1 >= 4 {
27 class.CommandNumber = int32(utils.IntFromBytes(byteArr[:4]))
28 }
29 if size-1 >= 8 {
30 class.TickCount = int32(utils.IntFromBytes(byteArr[4:8]))
31 }
32 if size-1 >= 12 {
33 class.ViewAnglesX = utils.FloatFromBytes(byteArr[8:12])
34 }
35 if size-1 >= 16 {
36 class.ViewAnglesY = utils.FloatFromBytes(byteArr[12:16])
37 }
38 if size-1 >= 20 {
39 class.ViewAnglesZ = utils.FloatFromBytes(byteArr[16:20])
40 }
41 if size-1 >= 24 {
42 class.ForwardMove = utils.FloatFromBytes(byteArr[20:24])
43 }
44 if size-1 >= 28 {
45 class.SideMove = utils.FloatFromBytes(byteArr[24:28])
46 }
47 if size-1 >= 32 {
48 class.UpMove = utils.FloatFromBytes(byteArr[28:32])
49 }
50 if size-1 >= 36 {
51 class.Buttons = int32(utils.IntFromBytes(byteArr[32:36]))
52 }
53 if size-1 >= 40 {
54 class.Impulse = byteArr[36]
55 }
56 return class
57}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..e58d4e9
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,5 @@
1module parser
2
3go 1.19
4
5require github.com/potterxu/bitreader v0.0.2
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..7476ab8
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,2 @@
1github.com/potterxu/bitreader v0.0.2 h1:oFOXpMwuatGrIY6pmBAQRpwt1lRWfINOtU+XT03/eTc=
2github.com/potterxu/bitreader v0.0.2/go.mod h1:zvQewWmu5YxT6gjvCjlpziVv3S/CTHMeRqo+pcgROmo=
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..6f9acb4
--- /dev/null
+++ b/main.go
@@ -0,0 +1,26 @@
1package main
2
3import (
4 "log"
5 "os"
6 "parser/messages"
7 "parser/utils"
8)
9
10func main() {
11 if len(os.Args) != 2 {
12 log.Fatal("Specifiy file in command line arguments.")
13 }
14 file, err := os.Open(os.Args[1])
15 utils.CheckError(err)
16 utils.HeaderOut(file)
17 for {
18 code := messages.MessageTypeCheck(file)
19 if code == 7 {
20 messages.MessageTypeCheck(file)
21 break // TODO: Check last CustomData
22 }
23 }
24
25 //defer file.Close()
26}
diff --git a/messages/messages.go b/messages/messages.go
new file mode 100644
index 0000000..db9d027
--- /dev/null
+++ b/messages/messages.go
@@ -0,0 +1,89 @@
1package messages
2
3import (
4 "fmt"
5 "os"
6 "parser/classes"
7 "parser/utils"
8)
9
10func MessageTypeCheck(file *os.File) (statusCode int) {
11 var MSSC int32 = 2
12 Type := make([]byte, 1)
13 Tick := make([]byte, 4)
14 Slot := make([]byte, 1)
15 file.Read(Type)
16 file.Read(Tick)
17 file.Read(Slot)
18 switch Type[0] {
19 case 0x01: // SignOn
20 var packet Packet
21 var cmdinfo classes.CmdInfo
22 packet.PacketInfo = utils.ReadByteFromFile(file, 76*MSSC)
23 packet.InSequence = int32(utils.IntFromBytes(utils.ReadByteFromFile(file, 4)))
24 packet.OutSequence = int32(utils.IntFromBytes(utils.ReadByteFromFile(file, 4)))
25 packet.Size = int32(utils.IntFromBytes(utils.ReadByteFromFile(file, 4)))
26 packet.Data = utils.ReadByteFromFile(file, packet.Size)
27 cmdinfo = classes.CmdInfoInit(packet.PacketInfo)
28 fmt.Println(cmdinfo)
29 return 1
30 case 0x02: // Packet
31 var packet Packet
32 var cmdinfo classes.CmdInfo
33 packet.PacketInfo = utils.ReadByteFromFile(file, 76*MSSC)
34 packet.InSequence = int32(utils.IntFromBytes(utils.ReadByteFromFile(file, 4)))
35 packet.OutSequence = int32(utils.IntFromBytes(utils.ReadByteFromFile(file, 4)))
36 packet.Size = int32(utils.IntFromBytes(utils.ReadByteFromFile(file, 4)))
37 packet.Data = utils.ReadByteFromFile(file, packet.Size)
38 cmdinfo = classes.CmdInfoInit(packet.PacketInfo)
39 fmt.Printf("[%d] %v\n", utils.IntFromBytes(Tick), cmdinfo)
40 return 2
41 case 0x03: // SyncTick
42 return 3
43 case 0x04: // Consolecmd
44 var consolecmd ConsoleCmd
45 consolecmd.Size = int32(utils.IntFromBytes(utils.ReadByteFromFile(file, 4)))
46 consolecmd.Data = string(utils.ReadByteFromFile(file, consolecmd.Size))
47 fmt.Printf("[%d] %s\n", utils.IntFromBytes(Tick), consolecmd.Data)
48 return 4
49 case 0x05: // Usercmd FIXME: Correct bit-packing inside classes
50 var usercmd UserCmd
51 //var usercmdinfo classes.UserCmdInfo
52 usercmd.Cmd = int32(utils.IntFromBytes(utils.ReadByteFromFile(file, 4)))
53 usercmd.Size = int32(utils.IntFromBytes(utils.ReadByteFromFile(file, 4)))
54 usercmd.Data = utils.ReadByteFromFile(file, usercmd.Size)
55 //usercmdinfo = classes.UserCmdInfoInit(usercmd.Data, int(usercmd.Size))
56 //fmt.Printf("[%d] UserCmd: %v\n", utils.IntFromBytes(Tick), usercmdinfo)
57 return 5
58 case 0x06: // DataTables
59 var datatables DataTables
60 //var stringtable classes.StringTable
61 datatables.Size = int32(utils.IntFromBytes(utils.ReadByteFromFile(file, 4)))
62 datatables.Data = utils.ReadByteFromFile(file, datatables.Size)
63 // stringtable = classes.StringTableInit(Data)
64 // fmt.Printf("[%d] DataTables: %v\n", utils.IntFromBytes(Size), stringtable)
65 return 6
66 case 0x07: // Stop
67 fmt.Println("Stop")
68 return 7
69 case 0x08: // CustomData
70 Unknown := make([]byte, 4)
71 file.Read(Unknown)
72 Size := make([]byte, 4)
73 file.Read(Size)
74 Data := make([]byte, utils.IntFromBytes(Size))
75 file.Read(Data)
76 return 8
77 case 0x09: // StringTables
78 Size := make([]byte, 4)
79 file.Read(Size)
80 Data := make([]byte, utils.IntFromBytes(Size))
81 file.Read(Data)
82 return 9
83 default:
84 return 0
85 }
86 //fmt.Println(Type[0])
87 //fmt.Println(utils.IntFromBytes(Tick))
88 //fmt.Println(Slot[0])
89}
diff --git a/messages/types.go b/messages/types.go
new file mode 100644
index 0000000..ee42a96
--- /dev/null
+++ b/messages/types.go
@@ -0,0 +1,36 @@
1package messages
2
3type Packet struct {
4 PacketInfo []byte
5 InSequence int32
6 OutSequence int32
7 Size int32
8 Data []byte
9}
10
11type ConsoleCmd struct {
12 Size int32
13 Data string
14}
15
16type UserCmd struct {
17 Cmd int32
18 Size int32
19 Data []byte
20}
21
22type DataTables struct {
23 Size int32
24 Data []byte
25}
26
27type CustomData struct {
28 Unknown int32
29 Size int32
30 Data []byte
31}
32
33type StringTables struct {
34 Size int32
35 Data []byte
36}
diff --git a/utils/header.go b/utils/header.go
new file mode 100644
index 0000000..68def9e
--- /dev/null
+++ b/utils/header.go
@@ -0,0 +1,43 @@
1package utils
2
3import (
4 "fmt"
5 "os"
6)
7
8func HeaderOut(file *os.File) {
9 DemoFileStamp := make([]byte, 8)
10 DemoProtocol := make([]byte, 4)
11 NetworkProtocol := make([]byte, 4)
12 ServerName := make([]byte, 260)
13 ClientName := make([]byte, 260)
14 MapName := make([]byte, 260)
15 GameDirectory := make([]byte, 260)
16 PlaybackTime := make([]byte, 4)
17 PlaybackTicks := make([]byte, 4)
18 PlaybackFrames := make([]byte, 4)
19 SignOnLength := make([]byte, 4)
20 file.Read(DemoFileStamp)
21 file.Read(DemoProtocol)
22 file.Read(NetworkProtocol)
23 file.Read(ServerName)
24 file.Read(ClientName)
25 file.Read(MapName)
26 file.Read(GameDirectory)
27 file.Read(PlaybackTime)
28 file.Read(PlaybackTicks)
29 file.Read(PlaybackFrames)
30 file.Read(SignOnLength)
31
32 fmt.Println(string(DemoFileStamp))
33 fmt.Println(IntFromBytes(DemoProtocol))
34 fmt.Println(IntFromBytes(NetworkProtocol))
35 fmt.Println(string(ServerName))
36 fmt.Println(string(ClientName))
37 fmt.Println(string(MapName))
38 fmt.Println(string(GameDirectory))
39 fmt.Println(FloatFromBytes(PlaybackTime))
40 fmt.Println(IntFromBytes(PlaybackTicks))
41 fmt.Println(IntFromBytes(PlaybackFrames))
42 fmt.Println(IntFromBytes(SignOnLength))
43}
diff --git a/utils/utils.go b/utils/utils.go
new file mode 100644
index 0000000..62924c2
--- /dev/null
+++ b/utils/utils.go
@@ -0,0 +1,57 @@
1package utils
2
3import (
4 "encoding/binary"
5 "log"
6 "math"
7 "os"
8 "unsafe"
9
10 "github.com/potterxu/bitreader"
11)
12
13func ReadByteFromFile(file *os.File, size int32) []byte {
14 tmp := make([]byte, size)
15 file.Read(tmp)
16 return tmp
17}
18
19func CheckError(e error) {
20 if e != nil {
21 log.Panic(e)
22 }
23}
24
25func CheckFirstBit(byteArr []byte) bool {
26 reader := bitreader.BitReader(byteArr)
27 state, err := reader.ReadBit()
28 if err != nil {
29 state = false
30 }
31 return state
32}
33
34func IntFromBytes(byteArr []byte) uint32 {
35 int := binary.LittleEndian.Uint32(byteArr)
36 return int
37}
38
39func FloatFromBytes(byteArr []byte) float32 {
40 bits := binary.LittleEndian.Uint32(byteArr)
41 float := math.Float32frombits(bits)
42 return float
43}
44
45func FloatArrFromBytes(byteArr []byte) []float32 {
46 if len(byteArr) == 0 {
47 return nil
48 }
49
50 l := len(byteArr) / 4
51 ptr := unsafe.Pointer(&byteArr[0])
52 // It is important to keep in mind that the Go garbage collector
53 // will not interact with this data, and that if src if freed,
54 // the behavior of any Go code using the slice is nondeterministic.
55 // Reference: https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices
56 return (*[1 << 26]float32)((*[1 << 26]float32)(ptr))[:l:l]
57}