diff --git a/internal/packets/login/BadLanguageFilter.xml b/internal/packets/login/BadLanguageFilter.xml index 660c7e6..0163c29 100644 --- a/internal/packets/login/BadLanguageFilter.xml +++ b/internal/packets/login/BadLanguageFilter.xml @@ -2,9 +2,7 @@ - - - + \ No newline at end of file diff --git a/internal/packets/parser/parser.go b/internal/packets/parser/parser.go index 3c0efde..ca4ab1a 100644 --- a/internal/packets/parser/parser.go +++ b/internal/packets/parser/parser.go @@ -8,7 +8,6 @@ import ( "sync" ) -// Object pools for reducing allocations var ( fieldOrderPool = sync.Pool{ New: func() any { @@ -29,7 +28,6 @@ var ( } ) -// String builder for efficient concatenation type stringBuilder struct { buf []byte } @@ -52,6 +50,7 @@ type Parser struct { current *Token input string substructs map[string]*PacketDef + templates map[string]*PacketDef tagStack []string fieldNames []string } @@ -68,7 +67,7 @@ var typeMap = map[string]common.EQ2DataType{ "si64": common.TypeSInt64, "f32": common.TypeFloat, "f64": common.TypeDouble, - "double": common.TypeDouble, // XML compatibility + "double": common.TypeDouble, "str8": common.TypeString8, "str16": common.TypeString16, "str32": common.TypeString32, @@ -84,6 +83,7 @@ func NewParser(input string) *Parser { lexer: NewLexer(input), input: input, substructs: make(map[string]*PacketDef), + templates: make(map[string]*PacketDef), tagStack: make([]string, 0, 16), fieldNames: make([]string, 0, 8), } @@ -285,14 +285,6 @@ func combineConditions(cond1, cond2 string) string { return string(buf) } -// Creates packet definition with estimated capacity -func NewPacketDef(estimatedFields int) *PacketDef { - return &PacketDef{ - Fields: make(map[string]FieldDesc, estimatedFields), - Orders: make(map[uint32][]string, 4), - } -} - // Parses the entire PML document func (p *Parser) Parse() (map[string]*PacketDef, error) { packets := make(map[string]*PacketDef) @@ -322,6 +314,16 @@ func (p *Parser) Parse() (map[string]*PacketDef, error) { if name != "" { p.substructs[name] = substruct } + case "template": + name := p.current.Attributes["name"] + if name != "" { + err := p.parseTemplateDefinition(name) + if err != nil { + return nil, err + } + } else { + p.advance() + } default: p.advance() } @@ -468,6 +470,11 @@ func (p *Parser) parseElements(packetDef *PacketDef, fieldOrder *[]string, prefi if err != nil { return err } + case "template": + err := p.parseTemplate(packetDef, fieldOrder, prefix) + if err != nil { + return err + } default: err := p.parseField(packetDef, fieldOrder, prefix) if err != nil { @@ -483,6 +490,90 @@ func (p *Parser) parseElements(packetDef *PacketDef, fieldOrder *[]string, prefi return nil } +// Handles template definition and usage +func (p *Parser) parseTemplate(packetDef *PacketDef, fieldOrder *[]string, prefix string) error { + attrs := p.current.Attributes + + // Template definition: