From b63c76f48c0a76aafefcbb3cab65f7d1358bfd00 Mon Sep 17 00:00:00 2001 From: Robert Janetzko Date: Thu, 5 May 2022 20:18:31 +0000 Subject: [PATCH] hf search --- .gitignore | 3 +- analyze/overwrites.json | 8 ++++ backend/.gitignore | 4 +- backend/conf.json | 5 --- backend/model/context.go | 18 +++++--- backend/model/functions.go | 1 + backend/model/history.go | 55 +++++++++++++++++++++++ backend/model/map.go | 6 +-- backend/model/model.go | 4 ++ backend/model/parse.go | 1 + backend/server/resource.go | 7 ++- backend/server/server.go | 43 ++++++++++++++++++ backend/server/templates.go | 1 + backend/templates/entity.html | 30 ++++++++++++- backend/templates/hf.html | 4 ++ backend/templates/hfs.html | 76 ++++++++++++++++++++++++++++++++ backend/templates/popoverHf.html | 10 ++++- 17 files changed, 255 insertions(+), 21 deletions(-) delete mode 100644 backend/conf.json create mode 100644 backend/model/history.go create mode 100644 backend/templates/hfs.html diff --git a/.gitignore b/.gitignore index 8629f64..4f38d20 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ legendsbrowser /*.json .DS_Store bin -/inputs/* \ No newline at end of file +/inputs/* +/inputs2/* \ No newline at end of file diff --git a/analyze/overwrites.json b/analyze/overwrites.json index 5db4fee..be7ada2 100644 --- a/analyze/overwrites.json +++ b/analyze/overwrites.json @@ -53,6 +53,10 @@ } ], "HistoricalFigure": [ + { + "Name": "Leader", + "Type": "bool" + }, { "Name": "Werebeast", "Type": "bool" @@ -79,6 +83,10 @@ } ], "Entity": [ + { + "Name": "Leaders", + "Type": "[]*EntityLeader" + }, { "Name": "Sites", "Type": "[]int" diff --git a/backend/.gitignore b/backend/.gitignore index f5cd815..63acb66 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -1,2 +1,4 @@ resources/frontend/* -same.json \ No newline at end of file +same.json +conf.json +_conf.json \ No newline at end of file diff --git a/backend/conf.json b/backend/conf.json deleted file mode 100644 index 4615bf9..0000000 --- a/backend/conf.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "LastPath": "/workspaces/legendsbrowser/inputs/legends-Runlance-01510-01-01", - "LastFile": "/workspaces/legendsbrowser/inputs/legends-Runlance-01510-01-01/Runlance-01510-01-01-legends.xml", - "DebugTemplates": true -} \ No newline at end of file diff --git a/backend/model/context.go b/backend/model/context.go index 33266f9..513d2de 100644 --- a/backend/model/context.go +++ b/backend/model/context.go @@ -57,7 +57,7 @@ func (c *Context) hfUnrelated(id int) string { func (c *Context) hfShort(id int) string { if x, ok := c.World.HistoricalFigures[id]; ok { - return fmt.Sprintf(`%s`, x.Id(), util.Title(x.FirstName())) + return fmt.Sprintf(`%s%s`, x.Id(), hfIcon(x), util.Title(x.FirstName())) } return "UNKNOWN HISTORICAL FIGURE" } @@ -73,7 +73,7 @@ func (c *Context) hfRelated(id, to int) string { if x, ok := c.World.HistoricalFigures[id]; ok { if t, ok := c.World.HistoricalFigures[to]; ok { if y, ok := util.Find(t.HfLink, func(l *HfLink) bool { return l.Hfid == id }); ok { - return fmt.Sprintf(`%s %s %s`, t.PossesivePronoun(), y.LinkType, x.Id(), util.Title(x.Name())) + return fmt.Sprintf(`%s %s %s%s`, t.PossesivePronoun(), y.LinkType, x.Id(), hfIcon(x), util.Title(x.Name())) } } return hf(x) @@ -81,6 +81,14 @@ func (c *Context) hfRelated(id, to int) string { return "UNKNOWN HISTORICAL FIGURE" } +func hfIcon(x *HistoricalFigure) string { + switch { + case x.Leader: + return ` ` + } + return "" +} + func hf(x *HistoricalFigure) string { r := x.Race if x.Deity { @@ -98,7 +106,7 @@ func hf(x *HistoricalFigure) string { if x.Vampire { r += " vampire" } - return fmt.Sprintf(`the %s %s`, r, x.Id(), util.Title(x.Name())) + return fmt.Sprintf(`the %s %s%s`, r, x.Id(), hfIcon(x), util.Title(x.Name())) } func (c *Context) hfList(ids []int) string { @@ -152,7 +160,7 @@ func (c *Context) siteStructure(siteId, structureId int, prefix string) string { func (c *Context) site(id int, prefix string) string { if x, ok := c.World.Sites[id]; ok { - return fmt.Sprintf(`%s %s`, prefix, util.If(x.Ruin, " ruin", ""), x.Id(), x.Icon(), util.Title(x.Name())) + return fmt.Sprintf(`%s %s`, prefix, x.Id(), x.Icon(), util.If(x.Ruin, " ruin", ""), util.Title(x.Name())) } return "UNKNOWN SITE" } @@ -160,7 +168,7 @@ func (c *Context) site(id int, prefix string) string { func (c *Context) structure(siteId, structureId int) string { if x, ok := c.World.Sites[siteId]; ok { if y, ok := x.Structures[structureId]; ok { - return fmt.Sprintf(` %s`, util.If(y.Ruin, " ruin", ""), siteId, structureId, y.Icon(), util.Title(y.Name())) + return fmt.Sprintf(` %s`, siteId, structureId, y.Icon(), util.If(y.Ruin, " ruin", ""), util.Title(y.Name())) } } return "UNKNOWN STRUCTURE" diff --git a/backend/model/functions.go b/backend/model/functions.go index 99815b4..db20919 100644 --- a/backend/model/functions.go +++ b/backend/model/functions.go @@ -9,6 +9,7 @@ import ( ) var LinkHf = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).hf(id)) } +var LinkHfShort = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).hfShort(id)) } var LinkHfList = func(w *DfWorld, id []int) template.HTML { return template.HTML((&Context{World: w}).hfList(id)) } var LinkEntity = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).entity(id)) } var LinkSite = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).site(id, "")) } diff --git a/backend/model/history.go b/backend/model/history.go new file mode 100644 index 0000000..d86e8f4 --- /dev/null +++ b/backend/model/history.go @@ -0,0 +1,55 @@ +package model + +import ( + "fmt" + "io/ioutil" + "regexp" + "strconv" + "strings" + + "github.com/robertjanetzko/LegendsBrowser2/backend/util" +) + +type EntityLeader struct { + Hf *HistoricalFigure + StartYear int + EndYear int +} + +func (w *DfWorld) LoadHistory() { + w.LoadDimensions() + + path := strings.ReplaceAll(w.FilePath, "-legends.xml", "-world_history.txt") + data, err := ioutil.ReadFile(path) + if err != nil { + fmt.Println(err) + return + } + + leaderRegEx := regexp.MustCompile(` \[\*\] (.+?) \(.*?Reign Began: (-?\d+)\)`) + results := regexp.MustCompile(`\n([^ ].*?), [^\n]+(?:\n [^\n]+)*`).FindAllStringSubmatch(util.ConvertCp473(data), -1) + for _, result := range results { + if _, civ, ok := util.FindInMap(w.Entities, nameMatches[*Entity](result[1])); ok { + leaders := leaderRegEx.FindAllStringSubmatch(result[0], -1) + var last *EntityLeader + for _, leader := range leaders { + year, _ := strconv.Atoi(leader[2]) + l := &EntityLeader{StartYear: year, EndYear: -1} + if _, hf, ok := util.FindInMap(w.HistoricalFigures, nameMatches[*HistoricalFigure](leader[1])); ok { + hf.Leader = true + l.Hf = hf + civ.Leaders = append(civ.Leaders, l) + } + if last != nil { + last.EndYear = year + } + last = l + } + } + } +} + +func nameMatches[T Named](name string) func(T) bool { + name = strings.ToLower(name) + return func(t T) bool { return t.Name() == name } +} diff --git a/backend/model/map.go b/backend/model/map.go index ea6426b..611ebc7 100644 --- a/backend/model/map.go +++ b/backend/model/map.go @@ -74,17 +74,13 @@ func (w *DfWorld) LoadDimensions() { } fmt.Println("Found Worldgen", path) - content, err := ioutil.ReadFile(path) if err != nil { return } - text := string(content) - fmt.Println(text) - r := regexp.MustCompile(`\[DIM:(\d+):(\d+)\]`) - result := r.FindAllStringSubmatch(text, 1) + result := r.FindAllStringSubmatch(string(content), 1) if result == nil { return } diff --git a/backend/model/model.go b/backend/model/model.go index b05594b..ba59433 100644 --- a/backend/model/model.go +++ b/backend/model/model.go @@ -1990,6 +1990,7 @@ type Entity struct { Type_ EntityType `json:"type" legend:"plus" related:""` // type Weapon []EntityWeapon `json:"weapon" legend:"plus" related:""` // weapon WorshipId []int `json:"worshipId" legend:"plus" related:""` // worship_id + Leaders []*EntityLeader `json:"leaders" legend:"add" related:""` // Leaders Sites []int `json:"sites" legend:"add" related:""` // Sites Wars []*HistoricalEventCollection `json:"wars" legend:"add" related:""` // Wars } @@ -2029,6 +2030,7 @@ func (x *Entity) MarshalJSON() ([]byte, error) { } d["weapon"] = x.Weapon d["worshipId"] = x.WorshipId + d["leaders"] = x.Leaders d["sites"] = x.Sites d["wars"] = x.Wars return json.Marshal(d) @@ -18900,6 +18902,7 @@ type HistoricalFigure struct { Sphere []string `json:"sphere" legend:"base" related:""` // sphere UsedIdentityId []int `json:"usedIdentityId" legend:"base" related:""` // used_identity_id VagueRelationship []*VagueRelationship `json:"vagueRelationship" legend:"base" related:""` // vague_relationship + Leader bool `json:"leader" legend:"add" related:""` // Leader Necromancer bool `json:"necromancer" legend:"add" related:""` // Necromancer NecromancerSince int `json:"necromancerSince" legend:"add" related:""` // NecromancerSince Vampire bool `json:"vampire" legend:"add" related:""` // Vampire @@ -19022,6 +19025,7 @@ func (x *HistoricalFigure) MarshalJSON() ([]byte, error) { d["sphere"] = x.Sphere d["usedIdentityId"] = x.UsedIdentityId d["vagueRelationship"] = x.VagueRelationship + d["leader"] = x.Leader d["necromancer"] = x.Necromancer if x.NecromancerSince != -1 { d["necromancerSince"] = x.NecromancerSince diff --git a/backend/model/parse.go b/backend/model/parse.go index d6964aa..ad60f87 100644 --- a/backend/model/parse.go +++ b/backend/model/parse.go @@ -143,6 +143,7 @@ BaseLoop: // ioutil.WriteFile("same.json", same, 0644) world.LoadMap() + world.LoadHistory() world.process() diff --git a/backend/server/resource.go b/backend/server/resource.go index 62caa58..67ee870 100644 --- a/backend/server/resource.go +++ b/backend/server/resource.go @@ -18,7 +18,12 @@ func (srv *DfServer) RegisterWorldPage(path string, template string, accessor fu return } - data := accessor(mux.Vars(r)) + params := mux.Vars(r) + for k, v := range r.URL.Query() { + params[k] = v[0] + } + + data := accessor(params) if data == nil || (reflect.ValueOf(data).Kind() == reflect.Ptr && reflect.ValueOf(data).IsNil()) { srv.notFound(w) return diff --git a/backend/server/server.go b/backend/server/server.go index 32751cc..78d99ab 100644 --- a/backend/server/server.go +++ b/backend/server/server.go @@ -106,6 +106,7 @@ func StartServer(config *Config, world *model.DfWorld, static embed.FS) error { srv.RegisterWorldResourcePage("/writtencontent/{id}", "writtencontent.html", func(id int) any { return srv.context.world.WrittenContents[id] }) srv.RegisterWorldResourcePage("/popover/writtencontent/{id}", "popoverWrittencontent.html", func(id int) any { return srv.context.world.WrittenContents[id] }) + srv.RegisterWorldPage("/hfs", "hfs.html", srv.searchHf) srv.RegisterWorldResourcePage("/hf/{id}", "hf.html", func(id int) any { return srv.context.world.HistoricalFigures[id] }) srv.RegisterWorldResourcePage("/popover/hf/{id}", "popoverHf.html", func(id int) any { return srv.context.world.HistoricalFigures[id] }) @@ -172,6 +173,48 @@ func (srv *DfServer) findStructure(p Parms) any { return nil } +func (srv *DfServer) searchHf(p Parms) any { + var list []*model.HistoricalFigure + + for _, hf := range srv.context.world.HistoricalFigures { + if p["leader"] == "1" && !hf.Leader { + continue + } + if p["deity"] == "1" && !hf.Deity { + continue + } + if p["force"] == "1" && !hf.Force { + continue + } + if p["vampire"] == "1" && !hf.Vampire { + continue + } + if p["werebeast"] == "1" && !hf.Werebeast { + continue + } + if p["necromancer"] == "1" && !hf.Necromancer { + continue + } + if p["alive"] == "1" && hf.DeathYear != -1 { + continue + } + if p["ghost"] == "1" && false { // TODO ghost + continue + } + if p["adventurer"] == "1" && !hf.Adventurer { + continue + } + list = append(list, hf) + } + + sort.Slice(list, func(i, j int) bool { return list[i].Name_ < list[j].Name_ }) + + return map[string]any{ + "Params": p, + "Hfs": list, + } +} + func (srv *DfServer) notFound(w http.ResponseWriter) { err := srv.templates.Render(w, "notFound.html", nil) if err != nil { diff --git a/backend/server/templates.go b/backend/server/templates.go index 791dd58..26582f4 100644 --- a/backend/server/templates.go +++ b/backend/server/templates.go @@ -30,6 +30,7 @@ func (srv *DfServer) LoadTemplates() { srv.context.world.Width, srv.context.world.Height)) }, "hf": func(id int) template.HTML { return model.LinkHf(srv.context.world, id) }, + "hfShort": func(id int) template.HTML { return model.LinkHfShort(srv.context.world, id) }, "getHf": func(id int) *model.HistoricalFigure { return srv.context.world.HistoricalFigures[id] }, "hfList": func(ids []int) template.HTML { return model.LinkHfList(srv.context.world, ids) }, "entity": func(id int) template.HTML { return model.LinkEntity(srv.context.world, id) }, diff --git a/backend/templates/entity.html b/backend/templates/entity.html index 7e0f00d..e673f09 100644 --- a/backend/templates/entity.html +++ b/backend/templates/entity.html @@ -13,8 +13,11 @@