2022-04-14 18:39:18 +03:00
|
|
|
package model
|
2022-04-13 15:01:20 +03:00
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/xml"
|
|
|
|
"fmt"
|
2022-04-15 16:27:51 +03:00
|
|
|
"log"
|
2022-04-13 15:01:20 +03:00
|
|
|
"os"
|
2022-04-15 16:27:51 +03:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
2022-04-13 15:01:20 +03:00
|
|
|
|
2022-04-14 18:39:18 +03:00
|
|
|
"github.com/robertjanetzko/LegendsBrowser2/backend/util"
|
|
|
|
)
|
2022-04-14 16:49:09 +03:00
|
|
|
|
|
|
|
func (e *HistoricalEvent) Name() string { return "" }
|
|
|
|
func (e *HistoricalEventCollection) Name() string { return "" }
|
2022-04-13 15:01:20 +03:00
|
|
|
|
|
|
|
func Parse(file string) (*DfWorld, error) {
|
|
|
|
xmlFile, err := os.Open(file)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println("Successfully Opened", file)
|
|
|
|
defer xmlFile.Close()
|
|
|
|
|
|
|
|
converter := util.NewConvertReader(xmlFile)
|
|
|
|
d := xml.NewDecoder(converter)
|
|
|
|
|
2022-04-15 16:27:51 +03:00
|
|
|
var world *DfWorld
|
|
|
|
BaseLoop:
|
2022-04-13 15:01:20 +03:00
|
|
|
for {
|
|
|
|
tok, err := d.Token()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
switch t := tok.(type) {
|
|
|
|
case xml.StartElement:
|
|
|
|
if t.Name.Local == "df_world" {
|
2022-04-15 16:27:51 +03:00
|
|
|
world, err = parseDfWorld(d, &t)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
break BaseLoop
|
2022-04-13 15:01:20 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-04-15 16:27:51 +03:00
|
|
|
|
|
|
|
plus := true
|
|
|
|
|
|
|
|
if plus {
|
|
|
|
file = strings.Replace(file, "-legends.xml", "-legends_plus.xml", 1)
|
|
|
|
xmlFile, err := os.Open(file)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
return world, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println("Successfully Opened", file)
|
|
|
|
defer xmlFile.Close()
|
|
|
|
|
|
|
|
converter := util.NewConvertReader(xmlFile)
|
|
|
|
d := xml.NewDecoder(converter)
|
|
|
|
|
|
|
|
PlusLoop:
|
|
|
|
for {
|
|
|
|
tok, err := d.Token()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
switch t := tok.(type) {
|
|
|
|
case xml.StartElement:
|
|
|
|
if t.Name.Local == "df_world" {
|
|
|
|
world, err = parseDfWorldPlus(d, &t, world)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
break PlusLoop
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return world, nil
|
2022-04-13 15:01:20 +03:00
|
|
|
}
|
|
|
|
|
2022-04-14 16:49:09 +03:00
|
|
|
func parseArray[T any](d *xml.Decoder, dest *[]T, creator func(*xml.Decoder, *xml.StartElement) (T, error)) {
|
2022-04-13 15:01:20 +03:00
|
|
|
for {
|
|
|
|
tok, err := d.Token()
|
|
|
|
if err != nil {
|
|
|
|
return // nil, err
|
|
|
|
}
|
|
|
|
switch t := tok.(type) {
|
|
|
|
case xml.StartElement:
|
2022-04-14 16:49:09 +03:00
|
|
|
x, _ := creator(d, &t)
|
2022-04-13 15:01:20 +03:00
|
|
|
*dest = append(*dest, x)
|
|
|
|
|
|
|
|
case xml.EndElement:
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-14 16:49:09 +03:00
|
|
|
func parseMap[T Identifiable](d *xml.Decoder, dest *map[int]T, creator func(*xml.Decoder, *xml.StartElement) (T, error)) {
|
2022-04-13 15:01:20 +03:00
|
|
|
for {
|
|
|
|
tok, err := d.Token()
|
|
|
|
if err != nil {
|
|
|
|
return // nil, err
|
|
|
|
}
|
|
|
|
switch t := tok.(type) {
|
|
|
|
case xml.StartElement:
|
2022-04-14 16:49:09 +03:00
|
|
|
x, _ := creator(d, &t)
|
2022-04-13 15:01:20 +03:00
|
|
|
(*dest)[x.Id()] = x
|
|
|
|
|
|
|
|
case xml.EndElement:
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-04-15 16:27:51 +03:00
|
|
|
|
|
|
|
func parseMapPlus[T Identifiable](d *xml.Decoder, dest *map[int]T, creator func(*xml.Decoder, *xml.StartElement, T) (T, error)) {
|
|
|
|
for {
|
|
|
|
tok, err := d.Token()
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
switch t := tok.(type) {
|
|
|
|
case xml.StartElement:
|
|
|
|
id, err := parseId(d)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
x, err := creator(d, &t, (*dest)[id])
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
(*dest)[id] = x
|
|
|
|
|
|
|
|
case xml.EndElement:
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
func parseId(d *xml.Decoder) (int, error) {
|
|
|
|
var data []byte
|
|
|
|
for {
|
|
|
|
tok, err := d.Token()
|
|
|
|
if err != nil {
|
|
|
|
return -1, err
|
|
|
|
}
|
|
|
|
switch t := tok.(type) {
|
|
|
|
case xml.StartElement:
|
|
|
|
data = nil
|
|
|
|
if t.Name.Local != "id" {
|
|
|
|
d.Skip()
|
|
|
|
// return -1, fmt.Errorf("expected id at: %d", d.InputOffset())
|
|
|
|
}
|
|
|
|
|
|
|
|
case xml.CharData:
|
|
|
|
data = append(data, t...)
|
|
|
|
|
|
|
|
case xml.EndElement:
|
|
|
|
if t.Name.Local == "id" {
|
|
|
|
return strconv.Atoi(string(data))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|