Files
GaCy-GO/internal/gameserver/navigation_profiles.go
T

80 lines
2.5 KiB
Go

package gameserver
import (
"encoding/json"
"fmt"
"strings"
"sync"
"gac-hkrpg-go/internal/common"
)
var navigationProfilesOnce sync.Once
var navigationProfilesData []byte
var navigationProfilesError error
// Quote Lua text without interpreting either Lua escapes or localized labels.
func luaNavigationString(value string) string {
separator := ""
for strings.Contains(value, "]"+separator+"]") {
separator += "="
}
return "[" + separator + "[" + value + "]" + separator + "]"
}
func loadNavigationProfiles() ([]byte, error) {
navigationProfilesOnce.Do(func() {
var data struct {
ClientVersion string `json:"client_version"`
Profiles []struct {
FloorID uint32 `json:"floor_id"`
TownEntryID uint32 `json:"town_entry_id"`
StoryEntryID uint32 `json:"story_entry_id"`
StoryLabel string `json:"story_label"`
} `json:"profiles"`
}
raw, err := common.ReadResourceFile("resources/NavigationProfiles.json")
if err != nil {
navigationProfilesError = err
return
}
if err = json.Unmarshal(raw, &data); err != nil {
navigationProfilesError = err
return
}
cfg, err := common.LoadRuntimeConfig()
if err != nil {
navigationProfilesError = err
return
}
if data.ClientVersion != cfg.ClientVersion {
navigationProfilesError = fmt.Errorf("navigation profiles Client revision mismatch")
return
}
res, err := common.GameRes()
if err != nil {
navigationProfilesError = err
return
}
var script strings.Builder
script.WriteString("\n_G.__GAC_NAVIGATION_PROFILES = {\n")
seen := map[uint32]bool{}
for _, p := range data.Profiles {
town, townOK := res.MapEntrances[p.TownEntryID]
story, storyOK := res.MapEntrances[p.StoryEntryID]
if !townOK || !storyOK || p.FloorID == 0 || town.FloorID != p.FloorID || story.FloorID != p.FloorID ||
town.PlaneID != story.PlaneID || town.EntranceType != "Town" || story.EntranceType != "Mission" ||
p.TownEntryID == p.StoryEntryID || strings.TrimSpace(p.StoryLabel) == "" || seen[p.FloorID] ||
len(res.LevelOutputConfigs[p.TownEntryID]) == 0 || len(res.LevelOutputConfigs[p.StoryEntryID]) == 0 {
navigationProfilesError = fmt.Errorf("invalid navigation profile for floor %d", p.FloorID)
return
}
seen[p.FloorID] = true
fmt.Fprintf(&script, "{floor_id=%d,town_entry_id=%d,story_entry_id=%d,story_label=%s},\n", p.FloorID, p.TownEntryID, p.StoryEntryID, luaNavigationString(p.StoryLabel))
}
script.WriteString("}\n")
navigationProfilesData = []byte(script.String())
})
return navigationProfilesData, navigationProfilesError
}