From eead3c2bd90fa428dca616bc56fcd85f362f4040 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Thu, 6 Jun 2024 22:24:34 +0300 Subject: change project name, decouple main and parsing entrance this will make it more like a library, where another project can create Parser struct and call ParseDemos to get all relevant information, and if anyone wants to use executable from this project, the main function works exactly the same --- cmd/parser.go | 107 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 80 insertions(+), 27 deletions(-) (limited to 'cmd/parser.go') diff --git a/cmd/parser.go b/cmd/parser.go index b4cbba4..f21d91f 100644 --- a/cmd/parser.go +++ b/cmd/parser.go @@ -1,53 +1,106 @@ package main import ( + "errors" "fmt" "os" + "strings" "github.com/pektezol/bitreader" - "github.com/pektezol/demoparser/pkg/packets" - "github.com/pektezol/demoparser/pkg/writer" + "github.com/pektezol/sdp.go/pkg/packets" + "github.com/pektezol/sdp.go/pkg/writer" ) +type Demo struct { + Headers packets.Headers `json:"headers"` + Messages []packets.Message `json:"messages"` +} + +type Parser struct { + DemoPath string + writer strings.Builder +} + +func NewParser(demoPath string) *Parser { + return &Parser{ + DemoPath: demoPath, + } +} + const littleEndian bool = true func main() { if len(os.Args) != 2 { - panic("specify file in command line arguments") + fmt.Println("specify file in command line arguments") + os.Exit(1) } - writer.AppendLine("Generated By: github.com/pektezol/demoparser") - files, err := os.ReadDir(os.Args[1]) - if err != nil { // If it's not a directory - file, err := os.Open(os.Args[1]) - if err != nil { - panic(err) - } - writer.AppendLine("\nFile Name: %s", file.Name()) - reader := bitreader.NewReader(file, littleEndian) - demoParserHandler(reader) - defer file.Close() - fmt.Println(writer.GetString()) - return + parser := NewParser(os.Args[1]) + _, err := parser.ParseDemos() + if err != nil { + fmt.Println(err.Error()) + os.Exit(1) } - for _, fileinfo := range files { // If it is a directory - file, err := os.Open(os.Args[1] + fileinfo.Name()) + fmt.Println(parser.GetOutput()) +} + +func (p *Parser) GetOutput() string { + return p.writer.String() +} + +func (p *Parser) ParseDemos() ([]Demo, error) { + writer.AppendLine("Generated By: github.com/pektezol/sdp.go") + files, err := os.ReadDir(p.DemoPath) + if err != nil { + // not a directory + file, err := os.Open(p.DemoPath) if err != nil { - panic(err) + return []Demo{}, err } - writer.AppendLine("\nFile Name: %s", file.Name()) - reader := bitreader.NewReader(file, littleEndian) - demoParserHandler(reader) defer file.Close() + reader := bitreader.NewReader(file, littleEndian) + demo := demoParserHandler(reader, file.Name()) + p.writer = writer.GetWriter() + return []Demo{demo}, nil + } else { + demos := []Demo{} + // directory + for _, fileinfo := range files { + if len(fileinfo.Name()) > 4 && fileinfo.Name()[len(fileinfo.Name())-4:] == ".dem" { + file, err := os.Open(p.DemoPath + fileinfo.Name()) + if err != nil { + return []Demo{}, err + } + defer file.Close() + reader := bitreader.NewReader(file, littleEndian) + demo := demoParserHandler(reader, file.Name()) + demos = append(demos, demo) + } + } + p.writer = writer.GetWriter() + if len(demos) == 0 { + return demos, errors.New("no demo found in given directory") + } + return demos, nil } - fmt.Println(writer.GetString()) } -func demoParserHandler(reader *bitreader.Reader) { - packets.ParseHeaders(reader) +func demoParserHandler(reader *bitreader.Reader, filename string) Demo { + demo := Demo{} + writer.AppendLine("\nFile Name: %s", filename) + // this is for recovering after a panic inside parse headers and packet. + // this approach was taken since error handling bitreader functions would take a long time. + defer func() { + if err := recover(); err != nil { + writer.AppendLine("failed to parse demo: %v", err) + } + }() + demo.Headers = packets.ParseHeaders(reader) for { - packet := packets.ParsePackets(reader) - if packet.PacketType == 7 { + message := packets.ParseMessage(reader) + demo.Messages = append(demo.Messages, message) + if message.PacketType == 7 { break } } + return demo } -- cgit v1.2.3