custom decoder
This commit is contained in:
parent
ef5c2ca337
commit
ed3cb294c9
|
@ -1,4 +1,5 @@
|
||||||
region*.xml
|
*legends.xml
|
||||||
|
*legends_plus.xml
|
||||||
legendsbrowser
|
legendsbrowser
|
||||||
*.pprof
|
*.pprof
|
||||||
*.png
|
*.png
|
35
main.go
35
main.go
|
@ -9,26 +9,40 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/pkg/profile"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var world model.World
|
var world model.World
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
defer profile.Start(profile.MemProfile).Stop()
|
// defer profile.Start(profile.MemProfile).Stop()
|
||||||
go func() {
|
// go func() {
|
||||||
http.ListenAndServe(":8081", nil)
|
// http.ListenAndServe(":8081", nil)
|
||||||
}()
|
// }()
|
||||||
|
|
||||||
fmt.Println("Hallo Welt!")
|
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("region2-00195-01-01-legends.xml")
|
||||||
|
// world.Load("Agora-00033-01-01-legends_plus.xml")
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
world.Process()
|
world.Process()
|
||||||
|
|
||||||
model.ListOtherElements(&world.HistoricalEvents)
|
// model.ListOtherElements("world", &[]*model.World{&world})
|
||||||
// listOtherElements(&world.HistoricalFigures)
|
// 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)
|
router := mux.NewRouter().StrictSlash(true)
|
||||||
|
|
||||||
|
@ -42,6 +56,11 @@ func main() {
|
||||||
server.RegisterResource(router, "collection", world.HistoricalEventCollectionMap)
|
server.RegisterResource(router, "collection", world.HistoricalEventCollectionMap)
|
||||||
server.RegisterResource(router, "entity", world.EntityMap)
|
server.RegisterResource(router, "entity", world.EntityMap)
|
||||||
server.RegisterResource(router, "event", world.HistoricalEventMap)
|
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"}
|
spa := server.SpaHandler{StaticPath: "frontend/dist/legendsbrowser", IndexPath: "index.html"}
|
||||||
router.PathPrefix("/").Handler(spa)
|
router.PathPrefix("/").Handler(spa)
|
||||||
|
|
|
@ -10,7 +10,10 @@ import (
|
||||||
"github.com/iancoleman/strcase"
|
"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)
|
m := make(map[string]map[string]bool)
|
||||||
cantInt := make(map[string]bool)
|
cantInt := make(map[string]bool)
|
||||||
isObj := make(map[string]bool)
|
isObj := make(map[string]bool)
|
||||||
|
@ -18,11 +21,12 @@ func ListOtherElements[T TypedOthers](items *[]T) {
|
||||||
for _, item := range *items {
|
for _, item := range *items {
|
||||||
found := make(map[string]bool)
|
found := make(map[string]bool)
|
||||||
for _, el := range item.Others() {
|
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 {
|
if m[el.XMLName.Local] == nil {
|
||||||
m[el.XMLName.Local] = map[string]bool{}
|
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)
|
_, err := strconv.Atoi(el.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
162
model/model.go
162
model/model.go
|
@ -6,17 +6,24 @@ type Region struct {
|
||||||
XMLName xml.Name `xml:"region" json:"-"`
|
XMLName xml.Name `xml:"region" json:"-"`
|
||||||
NamedObject
|
NamedObject
|
||||||
Type string `xml:"type" json:"type"`
|
Type string `xml:"type" json:"type"`
|
||||||
|
OtherElements
|
||||||
|
EventObject
|
||||||
}
|
}
|
||||||
|
|
||||||
type UndergroundRegion struct {
|
type UndergroundRegion struct {
|
||||||
XMLName xml.Name `xml:"underground_region" json:"-"`
|
XMLName xml.Name `xml:"underground_region" json:"-"`
|
||||||
NamedObject
|
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 {
|
type Landmass struct {
|
||||||
XMLName xml.Name `xml:"landmass" json:"-"`
|
XMLName xml.Name `xml:"landmass" json:"-"`
|
||||||
NamedObject
|
NamedObject
|
||||||
|
OtherElements
|
||||||
|
EventObject
|
||||||
}
|
}
|
||||||
|
|
||||||
type Site struct {
|
type Site struct {
|
||||||
|
@ -27,6 +34,7 @@ type Site struct {
|
||||||
Rectangle string `xml:"rectangle" json:"rectangle"`
|
Rectangle string `xml:"rectangle" json:"rectangle"`
|
||||||
Structures []Structure `xml:"structures>structure" json:"structures"`
|
Structures []Structure `xml:"structures>structure" json:"structures"`
|
||||||
|
|
||||||
|
OtherElements
|
||||||
EventObject
|
EventObject
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,17 +46,30 @@ type Structure struct {
|
||||||
LocalId int `xml:"local_id" json:"localId"`
|
LocalId int `xml:"local_id" json:"localId"`
|
||||||
Name string `xml:"name" json:"name"`
|
Name string `xml:"name" json:"name"`
|
||||||
Type string `xml:"type" json:"type"`
|
Type string `xml:"type" json:"type"`
|
||||||
|
OtherElements
|
||||||
|
EventObject
|
||||||
}
|
}
|
||||||
|
|
||||||
type WorldConstruction struct {
|
type WorldConstruction struct {
|
||||||
XMLName xml.Name `xml:"world_construction" json:"-"`
|
XMLName xml.Name `xml:"world_construction" json:"-"`
|
||||||
NamedObject
|
NamedObject
|
||||||
|
OtherElements
|
||||||
|
EventObject
|
||||||
}
|
}
|
||||||
|
|
||||||
type Artifact struct {
|
type Artifact struct {
|
||||||
XMLName xml.Name `xml:"artifact" json:"-"`
|
XMLName xml.Name `xml:"artifact" json:"-"`
|
||||||
NamedObject
|
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
|
EventObject
|
||||||
}
|
}
|
||||||
|
@ -56,8 +77,44 @@ type Artifact struct {
|
||||||
type HistoricalFigure struct {
|
type HistoricalFigure struct {
|
||||||
XMLName xml.Name `xml:"historical_figure" json:"-"`
|
XMLName xml.Name `xml:"historical_figure" json:"-"`
|
||||||
NamedObject
|
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
|
OtherElements
|
||||||
|
|
||||||
EventObject
|
EventObject
|
||||||
|
@ -68,16 +125,113 @@ func (r *HistoricalFigure) Type() string { return "hf" }
|
||||||
type HistoricalEventCollection struct {
|
type HistoricalEventCollection struct {
|
||||||
XMLName xml.Name `xml:"historical_event_collection" json:"-"`
|
XMLName xml.Name `xml:"historical_event_collection" json:"-"`
|
||||||
NamedObject
|
NamedObject
|
||||||
StartYear int `xml:"year"`
|
Year int `xml:"year"`
|
||||||
StartSeconds int `xml:"seconds72"`
|
Seconds int `xml:"seconds72"`
|
||||||
EndYear int `xml:"end_year"`
|
EndYear int `xml:"end_year"`
|
||||||
EndSeconds int `xml:"end_seconds72"`
|
EndSeconds int `xml:"end_seconds72"`
|
||||||
Type string `xml:"type" json:"type"`
|
Type string `xml:"type" json:"type"`
|
||||||
|
|
||||||
EventIds []int `xml:"event" json:"eventIds"`
|
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 {
|
type Entity struct {
|
||||||
XMLName xml.Name `xml:"entity" json:"-"`
|
XMLName xml.Name `xml:"entity" json:"-"`
|
||||||
NamedObject
|
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
|
EventObject
|
||||||
}
|
}
|
||||||
|
|
304
model/world.go
304
model/world.go
|
@ -2,10 +2,12 @@ package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type World struct {
|
type World struct {
|
||||||
|
@ -13,33 +15,62 @@ type World struct {
|
||||||
Name string `xml:"name"`
|
Name string `xml:"name"`
|
||||||
AltName string `xml:"altname"`
|
AltName string `xml:"altname"`
|
||||||
|
|
||||||
Regions []*Region `xml:"regions>region"`
|
// Regions []*Region `xml:"regions>region"`
|
||||||
UndergroundRegions []*UndergroundRegion `xml:"underground_regions>underground_region"`
|
// UndergroundRegions []*UndergroundRegion `xml:"underground_regions>underground_region"`
|
||||||
Landmasses []*Landmass `xml:"landmasses>landmass"`
|
// Landmasses []*Landmass `xml:"landmasses>landmass"`
|
||||||
Sites []*Site `xml:"sites>site"`
|
// Sites []*Site `xml:"sites>site"`
|
||||||
WorldConstructions []*WorldConstruction `xml:"world_constructions>world_construction"`
|
// WorldConstructions []*WorldConstruction `xml:"world_constructions>world_construction"`
|
||||||
Artifacts []*Artifact `xml:"artifacts>artifact"`
|
// Artifacts []*Artifact `xml:"artifacts>artifact"`
|
||||||
HistoricalFigures []*HistoricalFigure `xml:"historical_figures>historical_figure"`
|
// HistoricalFigures []*HistoricalFigure //`xml:"historical_figures>historical_figure"`
|
||||||
HistoricalEvents []*HistoricalEvent `xml:"historical_events>historical_event"`
|
// HistoricalEvents []*HistoricalEvent //`xml:"historical_events>historical_event"`
|
||||||
HistoricalEventCollections []*HistoricalEventCollection `xml:"historical_event_collections>historical_event_collection"`
|
// HistoricalEventCollections []*HistoricalEventCollection `xml:"historical_event_collections>historical_event_collection"`
|
||||||
Entities []*Entity `xml:"entities>entity"`
|
// 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
|
RegionMap map[int]*Region `xml:"regions>region"`
|
||||||
UndergroundRegionMap map[int]*UndergroundRegion
|
UndergroundRegionMap map[int]*UndergroundRegion `xml:"underground_regions>underground_region"`
|
||||||
LandmassMap map[int]*Landmass
|
LandmassMap map[int]*Landmass `xml:"landmasses>landmass"`
|
||||||
SiteMap map[int]*Site
|
SiteMap map[int]*Site `xml:"sites>site"`
|
||||||
WorldConstructionMap map[int]*WorldConstruction
|
WorldConstructionMap map[int]*WorldConstruction `xml:"world_constructions>world_construction"`
|
||||||
ArtifactMap map[int]*Artifact
|
ArtifactMap map[int]*Artifact `xml:"artifacts>artifact"`
|
||||||
HistoricalFigureMap map[int]*HistoricalFigure
|
HistoricalFigureMap map[int]*HistoricalFigure `xml:"historical_figures>historical_figure"`
|
||||||
HistoricalEventMap map[int]*HistoricalEvent
|
HistoricalEventMap map[int]*HistoricalEvent `xml:"historical_events>historical_event"`
|
||||||
HistoricalEventCollectionMap map[int]*HistoricalEventCollection
|
HistoricalEventCollectionMap map[int]*HistoricalEventCollection `xml:"historical_event_collections>historical_event_collection"`
|
||||||
EntityMap map[int]*Entity
|
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{|}~ CueaaaaceeeiiiAAEaAooouuyOU faiounN ")
|
||||||
|
|
||||||
// var cp437 = []byte(" \t\n \r !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñÑ ")
|
// 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) {
|
func (w *World) Load(file string) {
|
||||||
xmlFile, err := os.Open(file)
|
xmlFile, err := os.Open(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -49,51 +80,198 @@ func (w *World) Load(file string) {
|
||||||
fmt.Println("Successfully Opened users.xml")
|
fmt.Println("Successfully Opened users.xml")
|
||||||
defer xmlFile.Close()
|
defer xmlFile.Close()
|
||||||
|
|
||||||
byteValue, _ := io.ReadAll(xmlFile)
|
converter := &ConvertReader{r: xmlFile}
|
||||||
fmt.Println(len(byteValue))
|
|
||||||
|
|
||||||
copy(byteValue[30:35], []byte("UTF-8"))
|
// byteValue, _ := io.ReadAll(converter)
|
||||||
for i := range byteValue {
|
// fmt.Println(len(byteValue))
|
||||||
byteValue[i] = cp437[byteValue[i]]
|
|
||||||
}
|
|
||||||
|
|
||||||
err = xml.Unmarshal(byteValue, w)
|
fillTypes(reflect.TypeOf(w))
|
||||||
if err != nil {
|
fmt.Println(types["Region"])
|
||||||
fmt.Println(err)
|
|
||||||
}
|
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")
|
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() {
|
func (w *World) Process() {
|
||||||
w.RegionMap = make(map[int]*Region)
|
// w.RegionMap = make(map[int]*Region)
|
||||||
mapObjects(&w.Regions, &w.RegionMap)
|
// mapObjects(&w.Regions, &w.RegionMap)
|
||||||
|
|
||||||
w.UndergroundRegionMap = make(map[int]*UndergroundRegion)
|
// w.UndergroundRegionMap = make(map[int]*UndergroundRegion)
|
||||||
mapObjects(&w.UndergroundRegions, &w.UndergroundRegionMap)
|
// mapObjects(&w.UndergroundRegions, &w.UndergroundRegionMap)
|
||||||
|
|
||||||
w.LandmassMap = make(map[int]*Landmass)
|
// w.LandmassMap = make(map[int]*Landmass)
|
||||||
mapObjects(&w.Landmasses, &w.LandmassMap)
|
// mapObjects(&w.Landmasses, &w.LandmassMap)
|
||||||
|
|
||||||
w.SiteMap = make(map[int]*Site)
|
// w.SiteMap = make(map[int]*Site)
|
||||||
mapObjects(&w.Sites, &w.SiteMap)
|
// mapObjects(&w.Sites, &w.SiteMap)
|
||||||
|
|
||||||
w.WorldConstructionMap = make(map[int]*WorldConstruction)
|
// w.WorldConstructionMap = make(map[int]*WorldConstruction)
|
||||||
mapObjects(&w.WorldConstructions, &w.WorldConstructionMap)
|
// mapObjects(&w.WorldConstructions, &w.WorldConstructionMap)
|
||||||
|
|
||||||
w.ArtifactMap = make(map[int]*Artifact)
|
// w.ArtifactMap = make(map[int]*Artifact)
|
||||||
mapObjects(&w.Artifacts, &w.ArtifactMap)
|
// mapObjects(&w.Artifacts, &w.ArtifactMap)
|
||||||
|
|
||||||
w.HistoricalFigureMap = make(map[int]*HistoricalFigure)
|
// w.HistoricalFigureMap = make(map[int]*HistoricalFigure)
|
||||||
mapObjects(&w.HistoricalFigures, &w.HistoricalFigureMap)
|
// mapObjects(&w.HistoricalFigures, &w.HistoricalFigureMap)
|
||||||
|
|
||||||
w.HistoricalEventMap = make(map[int]*HistoricalEvent)
|
// w.HistoricalEventMap = make(map[int]*HistoricalEvent)
|
||||||
mapObjects(&w.HistoricalEvents, &w.HistoricalEventMap)
|
// mapObjects(&w.HistoricalEvents, &w.HistoricalEventMap)
|
||||||
|
|
||||||
w.HistoricalEventCollectionMap = make(map[int]*HistoricalEventCollection)
|
// w.HistoricalEventCollectionMap = make(map[int]*HistoricalEventCollection)
|
||||||
mapObjects(&w.HistoricalEventCollections, &w.HistoricalEventCollectionMap)
|
// mapObjects(&w.HistoricalEventCollections, &w.HistoricalEventCollectionMap)
|
||||||
|
|
||||||
w.EntityMap = make(map[int]*Entity)
|
// w.EntityMap = make(map[int]*Entity)
|
||||||
mapObjects(&w.Entities, &w.EntityMap)
|
// mapObjects(&w.Entities, &w.EntityMap)
|
||||||
|
|
||||||
w.processEvents()
|
w.processEvents()
|
||||||
}
|
}
|
||||||
|
@ -110,16 +288,16 @@ func (w *World) processEvents() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for eventIndex := 0; eventIndex < len(w.HistoricalEvents); eventIndex++ {
|
// for eventIndex := 0; eventIndex < len(w.HistoricalEvents); eventIndex++ {
|
||||||
e := w.HistoricalEvents[eventIndex]
|
// e := w.HistoricalEvents[eventIndex]
|
||||||
v := reflect.ValueOf(*e)
|
// v := reflect.ValueOf(*e)
|
||||||
processEvent(e, &v, legendFields["entity"], &w.EntityMap)
|
// processEvent(e, &v, legendFields["entity"], &w.EntityMap)
|
||||||
processEvent(e, &v, legendFields["site"], &w.SiteMap)
|
// processEvent(e, &v, legendFields["site"], &w.SiteMap)
|
||||||
processEvent(e, &v, legendFields["hf"], &w.HistoricalFigureMap)
|
// processEvent(e, &v, legendFields["hf"], &w.HistoricalFigureMap)
|
||||||
processEvent(e, &v, legendFields["artifact"], &w.ArtifactMap)
|
// processEvent(e, &v, legendFields["artifact"], &w.ArtifactMap)
|
||||||
// processEvent(e, &v, legendFields["wc"], &w.WorldConstructionMap)
|
// // processEvent(e, &v, legendFields["wc"], &w.WorldConstructionMap)
|
||||||
// processEvent(e, &v, legendFields["structure"], &w.St)
|
// // processEvent(e, &v, legendFields["structure"], &w.St)
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
func processEvent[T HasEvents](event *HistoricalEvent, v *reflect.Value, fields []int, objectMap *map[int]T) {
|
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:
|
case reflect.Slice:
|
||||||
ids := val.Interface().(*[]int)
|
ids := val.Interface().(*[]int)
|
||||||
for _, id := range *ids {
|
for _, id := range *ids {
|
||||||
x, ok := (*objectMap)[id]
|
if x, ok := (*objectMap)[id]; ok {
|
||||||
if ok {
|
|
||||||
x.SetEvents(append(x.GetEvents(), event))
|
x.SetEvents(append(x.GetEvents(), event))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case reflect.Int:
|
case reflect.Int:
|
||||||
id := int(val.Elem().Int())
|
id := int(val.Elem().Int())
|
||||||
x, ok := (*objectMap)[id]
|
if x, ok := (*objectMap)[id]; ok {
|
||||||
if ok {
|
|
||||||
x.SetEvents(append(x.GetEvents(), event))
|
x.SetEvents(append(x.GetEvents(), event))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -31,11 +31,7 @@ func RegisterResource[T model.Named](router *mux.Router, resourceName string, re
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range resources {
|
json.NewEncoder(w).Encode(resources[id])
|
||||||
if item.Id() == id {
|
|
||||||
json.NewEncoder(w).Encode(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
router.HandleFunc(fmt.Sprintf("/api/%s", resourceName), list).Methods("GET")
|
router.HandleFunc(fmt.Sprintf("/api/%s", resourceName), list).Methods("GET")
|
||||||
|
|
Loading…
Reference in New Issue