custom decoder
This commit is contained in:
parent
ef5c2ca337
commit
ed3cb294c9
6 changed files with 441 additions and 91 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
|||
region*.xml
|
||||
*legends.xml
|
||||
*legends_plus.xml
|
||||
legendsbrowser
|
||||
*.pprof
|
||||
*.png
|
35
main.go
35
main.go
|
@ -9,26 +9,40 @@ import (
|
|||
"runtime"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/pkg/profile"
|
||||
)
|
||||
|
||||
var world model.World
|
||||
|
||||
func main() {
|
||||
defer profile.Start(profile.MemProfile).Stop()
|
||||
go func() {
|
||||
http.ListenAndServe(":8081", nil)
|
||||
}()
|
||||
// defer profile.Start(profile.MemProfile).Stop()
|
||||
// go func() {
|
||||
// http.ListenAndServe(":8081", nil)
|
||||
// }()
|
||||
|
||||
fmt.Println("Hallo Welt!")
|
||||
|
||||
// world.Load("region1-00152-01-01-legends.xml")
|
||||
// world.Load("region1-00152-01-01-legends_plus.xml")
|
||||
world.Load("region2-00195-01-01-legends.xml")
|
||||
// world.Load("Agora-00033-01-01-legends_plus.xml")
|
||||
runtime.GC()
|
||||
world.Process()
|
||||
|
||||
model.ListOtherElements(&world.HistoricalEvents)
|
||||
// listOtherElements(&world.HistoricalFigures)
|
||||
// model.ListOtherElements("world", &[]*model.World{&world})
|
||||
// model.ListOtherElements("region", &world.Regions)
|
||||
// model.ListOtherElements("underground regions", &world.UndergroundRegions)
|
||||
// model.ListOtherElements("landmasses", &world.Landmasses)
|
||||
// model.ListOtherElements("sites", &world.Sites)
|
||||
// model.ListOtherElements("world constructions", &world.WorldConstructions)
|
||||
// model.ListOtherElements("artifacts", &world.Artifacts)
|
||||
// model.ListOtherElements("entities", &world.Entities)
|
||||
// model.ListOtherElements("hf", &world.HistoricalFigures)
|
||||
// model.ListOtherElements("events", &world.HistoricalEvents)
|
||||
// model.ListOtherElements("collections", &world.HistoricalEventCollections)
|
||||
// model.ListOtherElements("era", &world.HistoricalEras)
|
||||
// model.ListOtherElements("danceForm", &world.DanceForms)
|
||||
// model.ListOtherElements("musicalForm", &world.MusicalForms)
|
||||
// model.ListOtherElements("poeticForm", &world.PoeticForms)
|
||||
// model.ListOtherElements("written", &world.WrittenContents)
|
||||
|
||||
router := mux.NewRouter().StrictSlash(true)
|
||||
|
||||
|
@ -42,6 +56,11 @@ func main() {
|
|||
server.RegisterResource(router, "collection", world.HistoricalEventCollectionMap)
|
||||
server.RegisterResource(router, "entity", world.EntityMap)
|
||||
server.RegisterResource(router, "event", world.HistoricalEventMap)
|
||||
server.RegisterResource(router, "era", world.HistoricalEraMap)
|
||||
server.RegisterResource(router, "danceForm", world.DanceFormMap)
|
||||
server.RegisterResource(router, "musicalForm", world.MusicalFormMap)
|
||||
server.RegisterResource(router, "poeticForm", world.PoeticFormMap)
|
||||
server.RegisterResource(router, "written", world.WrittenContentMap)
|
||||
|
||||
spa := server.SpaHandler{StaticPath: "frontend/dist/legendsbrowser", IndexPath: "index.html"}
|
||||
router.PathPrefix("/").Handler(spa)
|
||||
|
|
|
@ -10,7 +10,10 @@ import (
|
|||
"github.com/iancoleman/strcase"
|
||||
)
|
||||
|
||||
func ListOtherElements[T TypedOthers](items *[]T) {
|
||||
func ListOtherElements[T Others](name string, items *[]T) {
|
||||
fmt.Println()
|
||||
fmt.Println(name)
|
||||
fmt.Println()
|
||||
m := make(map[string]map[string]bool)
|
||||
cantInt := make(map[string]bool)
|
||||
isObj := make(map[string]bool)
|
||||
|
@ -18,11 +21,12 @@ func ListOtherElements[T TypedOthers](items *[]T) {
|
|||
for _, item := range *items {
|
||||
found := make(map[string]bool)
|
||||
for _, el := range item.Others() {
|
||||
if !m[el.XMLName.Local][item.Type()] {
|
||||
t := name // item.Type()
|
||||
if !m[el.XMLName.Local][t] {
|
||||
if m[el.XMLName.Local] == nil {
|
||||
m[el.XMLName.Local] = map[string]bool{}
|
||||
}
|
||||
m[el.XMLName.Local][item.Type()] = true
|
||||
m[el.XMLName.Local][t] = true
|
||||
}
|
||||
_, err := strconv.Atoi(el.Value)
|
||||
if err != nil {
|
||||
|
|
174
model/model.go
174
model/model.go
|
@ -6,17 +6,24 @@ type Region struct {
|
|||
XMLName xml.Name `xml:"region" json:"-"`
|
||||
NamedObject
|
||||
Type string `xml:"type" json:"type"`
|
||||
OtherElements
|
||||
EventObject
|
||||
}
|
||||
|
||||
type UndergroundRegion struct {
|
||||
XMLName xml.Name `xml:"underground_region" json:"-"`
|
||||
NamedObject
|
||||
Type string `xml:"type" json:"type"`
|
||||
Type string `xml:"type" json:"type"`
|
||||
Depth *int `xml:"depth" json:"depth,omitempty"`
|
||||
OtherElements
|
||||
EventObject
|
||||
}
|
||||
|
||||
type Landmass struct {
|
||||
XMLName xml.Name `xml:"landmass" json:"-"`
|
||||
NamedObject
|
||||
OtherElements
|
||||
EventObject
|
||||
}
|
||||
|
||||
type Site struct {
|
||||
|
@ -27,6 +34,7 @@ type Site struct {
|
|||
Rectangle string `xml:"rectangle" json:"rectangle"`
|
||||
Structures []Structure `xml:"structures>structure" json:"structures"`
|
||||
|
||||
OtherElements
|
||||
EventObject
|
||||
}
|
||||
|
||||
|
@ -38,17 +46,30 @@ type Structure struct {
|
|||
LocalId int `xml:"local_id" json:"localId"`
|
||||
Name string `xml:"name" json:"name"`
|
||||
Type string `xml:"type" json:"type"`
|
||||
OtherElements
|
||||
EventObject
|
||||
}
|
||||
|
||||
type WorldConstruction struct {
|
||||
XMLName xml.Name `xml:"world_construction" json:"-"`
|
||||
NamedObject
|
||||
OtherElements
|
||||
EventObject
|
||||
}
|
||||
|
||||
type Artifact struct {
|
||||
XMLName xml.Name `xml:"artifact" json:"-"`
|
||||
NamedObject
|
||||
SiteId int `xml:"site_id" json:"siteId"`
|
||||
SiteId int `xml:"site_id" json:"siteId"`
|
||||
AbsTileX *int `xml:"abs_tile_x" json:"absTileX,omitempty"`
|
||||
AbsTileY *int `xml:"abs_tile_y" json:"absTileY,omitempty"`
|
||||
AbsTileZ *int `xml:"abs_tile_z" json:"absTileZ,omitempty"`
|
||||
HolderHfid *int `xml:"holder_hfid" json:"holderHfid,omitempty" legend:"hf"`
|
||||
// item object
|
||||
StructureLocalId *int `xml:"structure_local_id" json:"structureLocalId,omitempty"`
|
||||
SubregionId *int `xml:"subregion_id" json:"subregionId,omitempty"`
|
||||
|
||||
OtherElements
|
||||
|
||||
EventObject
|
||||
}
|
||||
|
@ -56,8 +77,44 @@ type Artifact struct {
|
|||
type HistoricalFigure struct {
|
||||
XMLName xml.Name `xml:"historical_figure" json:"-"`
|
||||
NamedObject
|
||||
Race string `xml:"race" json:"race"`
|
||||
Caste string `xml:"caste" json:"caste"`
|
||||
|
||||
Race *string `xml:"race" json:"race"`
|
||||
// Caste *string `xml:"caste" json:"caste"`
|
||||
// ActiveInteraction *[]string `xml:"active_interaction" json:"activeInteraction,omitempty"`
|
||||
// Animated *string `xml:"animated" json:"animated,omitempty"`
|
||||
// AnimatedString *string `xml:"animated_string" json:"animatedString,omitempty"`
|
||||
// Appeared *int `xml:"appeared" json:"appeared,omitempty"`
|
||||
// AssociatedType *string `xml:"associated_type" json:"associatedType,omitempty"`
|
||||
// BirthSeconds72 *int `xml:"birth_seconds72" json:"birthSeconds72,omitempty"`
|
||||
// BirthYear *int `xml:"birth_year" json:"birthYear,omitempty"`
|
||||
// CurrentIdentityId *int `xml:"current_identity_id" json:"currentIdentityId,omitempty" legend:"entity"`
|
||||
// DeathSeconds72 *int `xml:"death_seconds72" json:"deathSeconds72,omitempty"`
|
||||
// DeathYear *int `xml:"death_year" json:"deathYear,omitempty"`
|
||||
// Deity *string `xml:"deity" json:"deity,omitempty"`
|
||||
// EntPopId *int `xml:"ent_pop_id" json:"entPopId,omitempty"`
|
||||
// // entity_former_position_link object
|
||||
// // entity_link object
|
||||
// // entity_position_link object
|
||||
// // entity_reputation object
|
||||
// // entity_squad_link object
|
||||
// Force *string `xml:"force" json:"force,omitempty"`
|
||||
// Goal *[]string `xml:"goal" json:"goal,omitempty"`
|
||||
// // hf_link object
|
||||
// // hf_skill object
|
||||
// HoldsArtifact *[]int `xml:"holds_artifact" json:"holdsArtifact,omitempty"`
|
||||
// // honor_entity object
|
||||
// InteractionKnowledge *[]string `xml:"interaction_knowledge" json:"interactionKnowledge,omitempty"`
|
||||
// // intrigue_actor object
|
||||
// // intrigue_plot object
|
||||
// JourneyPet *[]string `xml:"journey_pet" json:"journeyPet,omitempty"`
|
||||
// // relationship_profile_hf_historical object
|
||||
// // relationship_profile_hf_visual object
|
||||
// // site_link object
|
||||
// // site_property object
|
||||
// Sphere *[]string `xml:"sphere" json:"sphere,omitempty"`
|
||||
// UsedIdentityId *[]int `xml:"used_identity_id" json:"usedIdentityId,omitempty" legend:"entity"`
|
||||
// // vague_relationship object
|
||||
|
||||
OtherElements
|
||||
|
||||
EventObject
|
||||
|
@ -68,16 +125,113 @@ func (r *HistoricalFigure) Type() string { return "hf" }
|
|||
type HistoricalEventCollection struct {
|
||||
XMLName xml.Name `xml:"historical_event_collection" json:"-"`
|
||||
NamedObject
|
||||
StartYear int `xml:"year"`
|
||||
StartSeconds int `xml:"seconds72"`
|
||||
EndYear int `xml:"end_year"`
|
||||
EndSeconds int `xml:"end_seconds72"`
|
||||
Type string `xml:"type" json:"type"`
|
||||
EventIds []int `xml:"event" json:"eventIds"`
|
||||
Year int `xml:"year"`
|
||||
Seconds int `xml:"seconds72"`
|
||||
EndYear int `xml:"end_year"`
|
||||
EndSeconds int `xml:"end_seconds72"`
|
||||
Type string `xml:"type" json:"type"`
|
||||
|
||||
EventIds []int `xml:"event" json:"eventIds"`
|
||||
|
||||
AggressorEntId *int `xml:"aggressor_ent_id" json:"aggressorEntId,omitempty"`
|
||||
AttackingEnid *int `xml:"attacking_enid" json:"attackingEnid,omitempty" legend:"entity"`
|
||||
AttackingHfid *[]int `xml:"attacking_hfid" json:"attackingHfid,omitempty" legend:"hf"`
|
||||
AttackingSquadDeaths *[]int `xml:"attacking_squad_deaths" json:"attackingSquadDeaths,omitempty"`
|
||||
AttackingSquadEntityPop *[]int `xml:"attacking_squad_entity_pop" json:"attackingSquadEntityPop,omitempty"`
|
||||
AttackingSquadNumber *[]int `xml:"attacking_squad_number" json:"attackingSquadNumber,omitempty"`
|
||||
AttackingSquadRace *[]string `xml:"attacking_squad_race" json:"attackingSquadRace,omitempty"`
|
||||
AttackingSquadSite *[]int `xml:"attacking_squad_site" json:"attackingSquadSite,omitempty"`
|
||||
CivId *int `xml:"civ_id" json:"civId,omitempty" legend:"entity"`
|
||||
Coords *string `xml:"coords" json:"coords,omitempty"`
|
||||
DefenderEntId *int `xml:"defender_ent_id" json:"defenderEntId,omitempty"`
|
||||
DefendingEnid *int `xml:"defending_enid" json:"defendingEnid,omitempty" legend:"entity"`
|
||||
DefendingHfid *[]int `xml:"defending_hfid" json:"defendingHfid,omitempty" legend:"hf"`
|
||||
DefendingSquadDeaths *[]int `xml:"defending_squad_deaths" json:"defendingSquadDeaths,omitempty"`
|
||||
DefendingSquadEntityPop *[]int `xml:"defending_squad_entity_pop" json:"defendingSquadEntityPop,omitempty"`
|
||||
DefendingSquadNumber *[]int `xml:"defending_squad_number" json:"defendingSquadNumber,omitempty"`
|
||||
DefendingSquadRace *[]string `xml:"defending_squad_race" json:"defendingSquadRace,omitempty"`
|
||||
DefendingSquadSite *[]int `xml:"defending_squad_site" json:"defendingSquadSite,omitempty"`
|
||||
Eventcol *[]int `xml:"eventcol" json:"eventcol,omitempty"`
|
||||
FeatureLayerId *int `xml:"feature_layer_id" json:"featureLayerId,omitempty"`
|
||||
IndividualMerc *[]string `xml:"individual_merc" json:"individualMerc,omitempty"`
|
||||
NoncomHfid *[]int `xml:"noncom_hfid" json:"noncomHfid,omitempty" legend:"hf"`
|
||||
OccasionId *int `xml:"occasion_id" json:"occasionId,omitempty"`
|
||||
Ordinal *int `xml:"ordinal" json:"ordinal,omitempty"`
|
||||
Outcome *string `xml:"outcome" json:"outcome,omitempty"`
|
||||
ParentEventcol *int `xml:"parent_eventcol" json:"parentEventcol,omitempty"`
|
||||
SiteId *int `xml:"site_id" json:"siteId,omitempty" legend:"site"`
|
||||
StartSeconds72 *int `xml:"start_seconds72" json:"startSeconds72,omitempty"`
|
||||
StartYear *int `xml:"start_year" json:"startYear,omitempty"`
|
||||
SubregionId *int `xml:"subregion_id" json:"subregionId,omitempty"`
|
||||
WarEventcol *int `xml:"war_eventcol" json:"warEventcol,omitempty"`
|
||||
ASupportMercEnid *int `xml:"a_support_merc_enid" json:"aSupportMercEnid,omitempty" legend:"entity"`
|
||||
ASupportMercHfid *[]int `xml:"a_support_merc_hfid" json:"aSupportMercHfid,omitempty" legend:"hf"`
|
||||
AttackingMercEnid *int `xml:"attacking_merc_enid" json:"attackingMercEnid,omitempty" legend:"entity"`
|
||||
AttackingSquadAnimated *[]string `xml:"attacking_squad_animated" json:"attackingSquadAnimated,omitempty"`
|
||||
CompanyMerc *[]string `xml:"company_merc" json:"companyMerc,omitempty"`
|
||||
DSupportMercEnid *int `xml:"d_support_merc_enid" json:"dSupportMercEnid,omitempty" legend:"entity"`
|
||||
DSupportMercHfid *[]int `xml:"d_support_merc_hfid" json:"dSupportMercHfid,omitempty" legend:"hf"`
|
||||
DefendingMercEnid *int `xml:"defending_merc_enid" json:"defendingMercEnid,omitempty" legend:"entity"`
|
||||
DefendingSquadAnimated *[]string `xml:"defending_squad_animated" json:"defendingSquadAnimated,omitempty"`
|
||||
TargetEntityId *int `xml:"target_entity_id" json:"targetEntityId,omitempty" legend:"entity"`
|
||||
|
||||
OtherElements
|
||||
}
|
||||
|
||||
type Entity struct {
|
||||
XMLName xml.Name `xml:"entity" json:"-"`
|
||||
NamedObject
|
||||
OtherElements
|
||||
EventObject
|
||||
}
|
||||
|
||||
type EntityPopulation struct {
|
||||
XMLName xml.Name `xml:"entity_population" json:"-"`
|
||||
OtherElements
|
||||
}
|
||||
|
||||
type HistoricalEra struct {
|
||||
XMLName xml.Name `xml:"historical_era" json:"-"`
|
||||
NamedObject
|
||||
StartYear *int `xml:"start_year" json:"startYear,omitempty"`
|
||||
OtherElements
|
||||
}
|
||||
|
||||
type DanceForm struct {
|
||||
XMLName xml.Name `xml:"dance_form" json:"-"`
|
||||
ArtForm
|
||||
}
|
||||
|
||||
type MusicalForm struct {
|
||||
XMLName xml.Name `xml:"musical_form" json:"-"`
|
||||
ArtForm
|
||||
}
|
||||
|
||||
type PoeticForm struct {
|
||||
XMLName xml.Name `xml:"poetic_form" json:"-"`
|
||||
ArtForm
|
||||
}
|
||||
|
||||
type WrittenContent struct {
|
||||
XMLName xml.Name `xml:"written_content" json:"-"`
|
||||
NamedObject
|
||||
|
||||
AuthorHfid *int `xml:"author_hfid" json:"authorHfid,omitempty" legend:"hf"`
|
||||
AuthorRoll *int `xml:"author_roll" json:"authorRoll,omitempty"`
|
||||
Form *string `xml:"form" json:"form,omitempty"`
|
||||
FormId *int `xml:"form_id" json:"formId,omitempty"`
|
||||
Style *[]string `xml:"style" json:"style,omitempty"`
|
||||
Title *string `xml:"title" json:"title,omitempty"`
|
||||
|
||||
OtherElements
|
||||
EventObject
|
||||
}
|
||||
|
||||
type ArtForm struct {
|
||||
NamedObject
|
||||
|
||||
Description *string `xml:"description" json:"description,omitempty"`
|
||||
|
||||
OtherElements
|
||||
EventObject
|
||||
}
|
||||
|
|
304
model/world.go
304
model/world.go
|
@ -2,10 +2,12 @@ package model
|
|||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type World struct {
|
||||
|
@ -13,33 +15,62 @@ type World struct {
|
|||
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"`
|
||||
// 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"`
|
||||
// HistoricalEras []*HistoricalEra `xml:"historical_eras>historical_era"`
|
||||
// Entities []*Entity `xml:"entities>entity"`
|
||||
// EntityPopulations []*EntityPopulation `xml:"entity_populations>entity_population"`
|
||||
// DanceForms []*DanceForm `xml:"dance_forms>dance_form"`
|
||||
// MusicalForms []*MusicalForm `xml:"musical_forms>musical_form"`
|
||||
// PoeticForms []*PoeticForm `xml:"poetic_forms>poetic_form"`
|
||||
// WrittenContents []*WrittenContent `xml:"written_contents>written_content"`
|
||||
OtherElements
|
||||
|
||||
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
|
||||
RegionMap map[int]*Region `xml:"regions>region"`
|
||||
UndergroundRegionMap map[int]*UndergroundRegion `xml:"underground_regions>underground_region"`
|
||||
LandmassMap map[int]*Landmass `xml:"landmasses>landmass"`
|
||||
SiteMap map[int]*Site `xml:"sites>site"`
|
||||
WorldConstructionMap map[int]*WorldConstruction `xml:"world_constructions>world_construction"`
|
||||
ArtifactMap map[int]*Artifact `xml:"artifacts>artifact"`
|
||||
HistoricalFigureMap map[int]*HistoricalFigure `xml:"historical_figures>historical_figure"`
|
||||
HistoricalEventMap map[int]*HistoricalEvent `xml:"historical_events>historical_event"`
|
||||
HistoricalEventCollectionMap map[int]*HistoricalEventCollection `xml:"historical_event_collections>historical_event_collection"`
|
||||
HistoricalEraMap map[int]*HistoricalEra `xml:"historical_eras>historical_era"`
|
||||
EntityMap map[int]*Entity `xml:"entities>entity"`
|
||||
DanceFormMap map[int]*DanceForm `xml:"dance_forms>dance_form"`
|
||||
MusicalFormMap map[int]*MusicalForm //`xml:"musical_forms>musical_form"`
|
||||
PoeticFormMap map[int]*PoeticForm // `xml:"poetic_forms>poetic_form"`
|
||||
WrittenContentMap map[int]*WrittenContent `xml:"written_contents>written_content"`
|
||||
}
|
||||
|
||||
var cp437 = []byte(" \t\n \r !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ CueaaaaceeeiiiAAEaAooouuyOU faiounN ")
|
||||
|
||||
// var cp437 = []byte(" \t\n \r !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñÑ ")
|
||||
|
||||
type ConvertReader struct {
|
||||
r io.Reader
|
||||
read int
|
||||
}
|
||||
|
||||
func (c *ConvertReader) Read(b []byte) (n int, err error) {
|
||||
n, err = c.r.Read(b)
|
||||
if c.read == 0 && n > 35 {
|
||||
copy(b[30:35], []byte("UTF-8"))
|
||||
}
|
||||
c.read += n
|
||||
for i := range b {
|
||||
b[i] = cp437[b[i]]
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (w *World) Load(file string) {
|
||||
xmlFile, err := os.Open(file)
|
||||
if err != nil {
|
||||
|
@ -49,51 +80,198 @@ func (w *World) Load(file string) {
|
|||
fmt.Println("Successfully Opened users.xml")
|
||||
defer xmlFile.Close()
|
||||
|
||||
byteValue, _ := io.ReadAll(xmlFile)
|
||||
fmt.Println(len(byteValue))
|
||||
converter := &ConvertReader{r: xmlFile}
|
||||
|
||||
copy(byteValue[30:35], []byte("UTF-8"))
|
||||
for i := range byteValue {
|
||||
byteValue[i] = cp437[byteValue[i]]
|
||||
}
|
||||
// byteValue, _ := io.ReadAll(converter)
|
||||
// fmt.Println(len(byteValue))
|
||||
|
||||
err = xml.Unmarshal(byteValue, w)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
fillTypes(reflect.TypeOf(w))
|
||||
fmt.Println(types["Region"])
|
||||
|
||||
d := xml.NewDecoder(converter)
|
||||
parseObject(d, nil, reflect.ValueOf(w))
|
||||
|
||||
// err = xml.Unmarshal(byteValue, w)
|
||||
// if err != nil {
|
||||
// fmt.Println(err)
|
||||
// }
|
||||
fmt.Println("World loaded")
|
||||
}
|
||||
|
||||
var types = make(map[string]map[string]reflect.StructField)
|
||||
|
||||
func fillTypes(t reflect.Type) {
|
||||
if t.Kind() == reflect.Pointer {
|
||||
t = t.Elem()
|
||||
}
|
||||
if t.Kind() != reflect.Struct {
|
||||
return
|
||||
}
|
||||
fmt.Println(t.Name())
|
||||
|
||||
if _, ok := types[t.Name()]; ok {
|
||||
return
|
||||
}
|
||||
|
||||
info := make(map[string]reflect.StructField)
|
||||
DeepFields(t, &info, make([]int, 0))
|
||||
|
||||
types[t.Name()] = info
|
||||
}
|
||||
|
||||
func DeepFields(t reflect.Type, info *map[string]reflect.StructField, index []int) {
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
f.Index = append(index, f.Index[0])
|
||||
if xml, ok := f.Tag.Lookup("xml"); ok {
|
||||
if p := strings.Index(xml, ">"); p >= 0 {
|
||||
(*info)[xml[0:p]] = f
|
||||
} else {
|
||||
for _, s := range strings.Split(xml, "|") {
|
||||
(*info)[s] = f
|
||||
}
|
||||
}
|
||||
if f.Type.Kind() == reflect.Map || f.Type.Kind() == reflect.Slice {
|
||||
fillTypes(f.Type.Elem())
|
||||
}
|
||||
fmt.Println(i, f)
|
||||
}
|
||||
if f.Type.Kind() == reflect.Struct && f.Anonymous {
|
||||
DeepFields(f.Type, info, f.Index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func parseObject(d *xml.Decoder, start *xml.StartElement, val reflect.Value) error {
|
||||
if start == nil {
|
||||
for {
|
||||
tok, err := d.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if t, ok := tok.(xml.StartElement); ok {
|
||||
start = &t
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if val.Kind() == reflect.Pointer {
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
typ, ok := types[val.Type().Name()]
|
||||
if !ok {
|
||||
d.Skip()
|
||||
return nil
|
||||
}
|
||||
|
||||
Loop:
|
||||
for {
|
||||
tok, err := d.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch t := tok.(type) {
|
||||
case xml.StartElement:
|
||||
if ty, ok := typ[t.Name.Local]; ok {
|
||||
if ty.Type.Kind() == reflect.Map {
|
||||
fmt.Println(" ", t.Name.Local, val.Type().Name(), ty)
|
||||
f := val.Field(ty.Index[0])
|
||||
if f.IsNil() {
|
||||
f.Set(reflect.MakeMapWithSize(ty.Type, 0))
|
||||
}
|
||||
parseMap(d, ty, f)
|
||||
val.Field(ty.Index[0]).SetMapIndex(reflect.ValueOf(6), reflect.New(ty.Type.Elem().Elem()))
|
||||
}
|
||||
} else {
|
||||
d.Skip()
|
||||
}
|
||||
// parseObject(d, &t, val)
|
||||
case xml.EndElement:
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseMap(d *xml.Decoder, field reflect.StructField, dest reflect.Value) error {
|
||||
x, ok := field.Tag.Lookup("xml")
|
||||
if !ok {
|
||||
return errors.New("no xml tag")
|
||||
}
|
||||
elementName := strings.Split(x, ">")[1]
|
||||
|
||||
var lastStart *xml.StartElement
|
||||
var id int
|
||||
|
||||
Loop:
|
||||
for {
|
||||
tok, err := d.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch t := tok.(type) {
|
||||
case xml.StartElement:
|
||||
if t.Name.Local == elementName {
|
||||
lastStart = &t
|
||||
id = -1
|
||||
} else if t.Name.Local == "id" {
|
||||
if id != -1 {
|
||||
return errors.New("ID at invalid place")
|
||||
}
|
||||
d.DecodeElement(&id, &t)
|
||||
|
||||
obj := dest.MapIndex(reflect.ValueOf(id))
|
||||
if !obj.IsValid() {
|
||||
obj = reflect.New(field.Type.Elem().Elem())
|
||||
dest.SetMapIndex(reflect.ValueOf(id), obj)
|
||||
obj.Elem().FieldByIndex(types[obj.Type().Elem().Name()]["id"].Index).SetInt(int64(id))
|
||||
}
|
||||
d.DecodeElement(obj.Interface(), lastStart)
|
||||
} else {
|
||||
fmt.Println("SKIP", elementName, t.Name.Local)
|
||||
d.Skip()
|
||||
}
|
||||
case xml.EndElement:
|
||||
if t.Name.Local != elementName {
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *World) Process() {
|
||||
w.RegionMap = make(map[int]*Region)
|
||||
mapObjects(&w.Regions, &w.RegionMap)
|
||||
// w.RegionMap = make(map[int]*Region)
|
||||
// mapObjects(&w.Regions, &w.RegionMap)
|
||||
|
||||
w.UndergroundRegionMap = make(map[int]*UndergroundRegion)
|
||||
mapObjects(&w.UndergroundRegions, &w.UndergroundRegionMap)
|
||||
// w.UndergroundRegionMap = make(map[int]*UndergroundRegion)
|
||||
// mapObjects(&w.UndergroundRegions, &w.UndergroundRegionMap)
|
||||
|
||||
w.LandmassMap = make(map[int]*Landmass)
|
||||
mapObjects(&w.Landmasses, &w.LandmassMap)
|
||||
// w.LandmassMap = make(map[int]*Landmass)
|
||||
// mapObjects(&w.Landmasses, &w.LandmassMap)
|
||||
|
||||
w.SiteMap = make(map[int]*Site)
|
||||
mapObjects(&w.Sites, &w.SiteMap)
|
||||
// w.SiteMap = make(map[int]*Site)
|
||||
// mapObjects(&w.Sites, &w.SiteMap)
|
||||
|
||||
w.WorldConstructionMap = make(map[int]*WorldConstruction)
|
||||
mapObjects(&w.WorldConstructions, &w.WorldConstructionMap)
|
||||
// w.WorldConstructionMap = make(map[int]*WorldConstruction)
|
||||
// mapObjects(&w.WorldConstructions, &w.WorldConstructionMap)
|
||||
|
||||
w.ArtifactMap = make(map[int]*Artifact)
|
||||
mapObjects(&w.Artifacts, &w.ArtifactMap)
|
||||
// w.ArtifactMap = make(map[int]*Artifact)
|
||||
// mapObjects(&w.Artifacts, &w.ArtifactMap)
|
||||
|
||||
w.HistoricalFigureMap = make(map[int]*HistoricalFigure)
|
||||
mapObjects(&w.HistoricalFigures, &w.HistoricalFigureMap)
|
||||
// w.HistoricalFigureMap = make(map[int]*HistoricalFigure)
|
||||
// mapObjects(&w.HistoricalFigures, &w.HistoricalFigureMap)
|
||||
|
||||
w.HistoricalEventMap = make(map[int]*HistoricalEvent)
|
||||
mapObjects(&w.HistoricalEvents, &w.HistoricalEventMap)
|
||||
// w.HistoricalEventMap = make(map[int]*HistoricalEvent)
|
||||
// mapObjects(&w.HistoricalEvents, &w.HistoricalEventMap)
|
||||
|
||||
w.HistoricalEventCollectionMap = make(map[int]*HistoricalEventCollection)
|
||||
mapObjects(&w.HistoricalEventCollections, &w.HistoricalEventCollectionMap)
|
||||
// w.HistoricalEventCollectionMap = make(map[int]*HistoricalEventCollection)
|
||||
// mapObjects(&w.HistoricalEventCollections, &w.HistoricalEventCollectionMap)
|
||||
|
||||
w.EntityMap = make(map[int]*Entity)
|
||||
mapObjects(&w.Entities, &w.EntityMap)
|
||||
// w.EntityMap = make(map[int]*Entity)
|
||||
// mapObjects(&w.Entities, &w.EntityMap)
|
||||
|
||||
w.processEvents()
|
||||
}
|
||||
|
@ -110,16 +288,16 @@ func (w *World) processEvents() {
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
// 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) {
|
||||
|
@ -130,15 +308,13 @@ func processEvent[T HasEvents](event *HistoricalEvent, v *reflect.Value, fields
|
|||
case reflect.Slice:
|
||||
ids := val.Interface().(*[]int)
|
||||
for _, id := range *ids {
|
||||
x, ok := (*objectMap)[id]
|
||||
if ok {
|
||||
if x, ok := (*objectMap)[id]; ok {
|
||||
x.SetEvents(append(x.GetEvents(), event))
|
||||
}
|
||||
}
|
||||
case reflect.Int:
|
||||
id := int(val.Elem().Int())
|
||||
x, ok := (*objectMap)[id]
|
||||
if ok {
|
||||
if x, ok := (*objectMap)[id]; ok {
|
||||
x.SetEvents(append(x.GetEvents(), event))
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -31,11 +31,7 @@ func RegisterResource[T model.Named](router *mux.Router, resourceName string, re
|
|||
fmt.Println(err)
|
||||
}
|
||||
|
||||
for _, item := range resources {
|
||||
if item.Id() == id {
|
||||
json.NewEncoder(w).Encode(item)
|
||||
}
|
||||
}
|
||||
json.NewEncoder(w).Encode(resources[id])
|
||||
}
|
||||
|
||||
router.HandleFunc(fmt.Sprintf("/api/%s", resourceName), list).Methods("GET")
|
||||
|
|
Loading…
Reference in a new issue