package model import ( "encoding/xml" "fmt" "io" "os" "reflect" ) type World struct { XMLName xml.Name `xml:"df_world"` Name string `xml:"name"` AltName string `xml:"altname"` Regions []*Region `xml:"regions>region"` UndergroundRegions []*UndergroundRegion `xml:"underground_regions>underground_region"` Landmasses []*Landmass `xml:"landmasses>landmass"` Sites []*Site `xml:"sites>site"` WorldConstructions []*WorldConstruction `xml:"world_constructions>world_construction"` Artifacts []*Artifact `xml:"artifacts>artifact"` HistoricalFigures []*HistoricalFigure `xml:"historical_figures>historical_figure"` HistoricalEvents []*HistoricalEvent `xml:"historical_events>historical_event"` HistoricalEventCollections []*HistoricalEventCollection `xml:"historical_event_collections>historical_event_collection"` Entities []*Entity `xml:"entities>entity"` RegionMap map[int]*Region UndergroundRegionMap map[int]*UndergroundRegion LandmassMap map[int]*Landmass SiteMap map[int]*Site WorldConstructionMap map[int]*WorldConstruction ArtifactMap map[int]*Artifact HistoricalFigureMap map[int]*HistoricalFigure HistoricalEventMap map[int]*HistoricalEvent HistoricalEventCollectionMap map[int]*HistoricalEventCollection EntityMap map[int]*Entity } var cp437 = []byte(" \t\n \r !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ CueaaaaceeeiiiAAEaAooouuyOU faiounN ") // var cp437 = []byte(" \t\n \r !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñÑ ") func (w *World) Load(file string) { xmlFile, err := os.Open(file) if err != nil { fmt.Println(err) } fmt.Println("Successfully Opened users.xml") defer xmlFile.Close() byteValue, _ := io.ReadAll(xmlFile) fmt.Println(len(byteValue)) copy(byteValue[30:35], []byte("UTF-8")) for i := range byteValue { byteValue[i] = cp437[byteValue[i]] } err = xml.Unmarshal(byteValue, w) if err != nil { fmt.Println(err) } fmt.Println("World loaded") } func (w *World) Process() { w.RegionMap = make(map[int]*Region) mapObjects(&w.Regions, &w.RegionMap) w.UndergroundRegionMap = make(map[int]*UndergroundRegion) mapObjects(&w.UndergroundRegions, &w.UndergroundRegionMap) w.LandmassMap = make(map[int]*Landmass) mapObjects(&w.Landmasses, &w.LandmassMap) w.SiteMap = make(map[int]*Site) mapObjects(&w.Sites, &w.SiteMap) w.WorldConstructionMap = make(map[int]*WorldConstruction) mapObjects(&w.WorldConstructions, &w.WorldConstructionMap) w.ArtifactMap = make(map[int]*Artifact) mapObjects(&w.Artifacts, &w.ArtifactMap) w.HistoricalFigureMap = make(map[int]*HistoricalFigure) mapObjects(&w.HistoricalFigures, &w.HistoricalFigureMap) w.HistoricalEventMap = make(map[int]*HistoricalEvent) mapObjects(&w.HistoricalEvents, &w.HistoricalEventMap) w.HistoricalEventCollectionMap = make(map[int]*HistoricalEventCollection) mapObjects(&w.HistoricalEventCollections, &w.HistoricalEventCollectionMap) w.EntityMap = make(map[int]*Entity) mapObjects(&w.Entities, &w.EntityMap) w.processEvents() } func (w *World) processEvents() { legendFields := make(map[string][]int) t := reflect.TypeOf(HistoricalEvent{}) for i := 0; i < t.NumField(); i++ { f := t.Field(i) l, ok := f.Tag.Lookup("legend") if ok { legendFields[l] = append(legendFields[l], i) } } for eventIndex := 0; eventIndex < len(w.HistoricalEvents); eventIndex++ { e := w.HistoricalEvents[eventIndex] v := reflect.ValueOf(*e) processEvent(e, &v, legendFields["entity"], &w.EntityMap) processEvent(e, &v, legendFields["site"], &w.SiteMap) processEvent(e, &v, legendFields["hf"], &w.HistoricalFigureMap) processEvent(e, &v, legendFields["artifact"], &w.ArtifactMap) // processEvent(e, &v, legendFields["wc"], &w.WorldConstructionMap) // processEvent(e, &v, legendFields["structure"], &w.St) } } func processEvent[T HasEvents](event *HistoricalEvent, v *reflect.Value, fields []int, objectMap *map[int]T) { for _, i := range fields { val := v.Field(i) if !val.IsZero() { switch val.Elem().Kind() { case reflect.Slice: ids := val.Interface().(*[]int) for _, id := range *ids { x, ok := (*objectMap)[id] if ok { x.SetEvents(append(x.GetEvents(), event)) } } case reflect.Int: id := int(val.Elem().Int()) x, ok := (*objectMap)[id] if ok { x.SetEvents(append(x.GetEvents(), event)) } default: fmt.Println("unknown", val.Elem().Kind()) } } } } func mapObjects[T Identifiable](objects *[]T, objectMap *map[int]T) { for i, obj := range *objects { (*objectMap)[obj.Id()] = (*objects)[i] } }