80 lines
2.5 KiB
Go
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
|
|
}
|