Parse only the zone templates the map's zone tree uses
The world server read all 861 CZONE files; map 108 uses 633. The zone tree is now read first and the parser loads only the templates it names. A template with no CZONE file aborts boot from the parser, replacing the check in loadZones. The tree no longer carries player-city zones (mbScryer drops them at export), so isPlayerCity and its skip are gone. An old tree still holding them aborts boot: template 0 has no CZONE file. Value changes: none; 228 unused templates are no longer in memory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
807a806a0d
commit
3b4a60c739
5 files changed
+44
-32
No files matched your search
@@ -39,6 +39,7 @@ public enum ZoneManager {
|
||||
ZONEMANAGER;
|
||||
|
||||
public static HashMap<Integer, CZoneTemplate> _zone_templates = new HashMap<>();
|
||||
public static ArrayList<ZoneTreeEntry> zoneTree;
|
||||
|
||||
public static final Set<Zone> macroZones = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||
private static final ConcurrentHashMap<Integer, Zone> zonesByID = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD);
|
||||
@@ -76,37 +77,35 @@ public enum ZoneManager {
|
||||
Logger.info("Zone templates: " + _zone_templates.size());
|
||||
}
|
||||
|
||||
// Static zones from the map's zone tree, then player-city zones from the DB. False aborts boot.
|
||||
// Read before the zone templates, so only the templates this map uses are parsed. False aborts boot.
|
||||
|
||||
public static boolean loadZones(int mapID) {
|
||||
|
||||
ArrayList<ZoneTreeEntry> zoneTree;
|
||||
ArrayList<Zone> cityZones;
|
||||
Zone zone;
|
||||
int staticCount = 0;
|
||||
boolean templatesMissing = false;
|
||||
public static boolean loadZoneTree(int mapID) {
|
||||
|
||||
zoneTree = ZoneTreeParser.parseZoneTree(mapID);
|
||||
|
||||
if (zoneTree == null)
|
||||
return false;
|
||||
return zoneTree != null;
|
||||
}
|
||||
|
||||
public static TreeSet<Integer> getZoneTreeTemplateIDs() {
|
||||
|
||||
TreeSet<Integer> templateIDs = new TreeSet<>();
|
||||
|
||||
for (ZoneTreeEntry treeEntry : zoneTree)
|
||||
if (!treeEntry.isPlayerCity && !_zone_templates.containsKey(treeEntry.template)) {
|
||||
Logger.error("Zone " + treeEntry.uid + " (" + treeEntry.name + ") has no CZONE template " + treeEntry.template);
|
||||
templatesMissing = true;
|
||||
}
|
||||
templateIDs.add(treeEntry.template);
|
||||
|
||||
if (templatesMissing)
|
||||
return false;
|
||||
return templateIDs;
|
||||
}
|
||||
|
||||
// Player-city zones in the tree are a recording's cities; the live ones come from the DB
|
||||
// Static zones from the map's zone tree, then player-city zones from the DB. False aborts boot.
|
||||
|
||||
public static boolean loadZones() {
|
||||
|
||||
ArrayList<Zone> cityZones;
|
||||
Zone zone;
|
||||
int staticCount = 0;
|
||||
|
||||
for (ZoneTreeEntry treeEntry : zoneTree) {
|
||||
|
||||
if (treeEntry.isPlayerCity)
|
||||
continue;
|
||||
|
||||
if (treeEntry.parent != 0 && getZoneByUUID(treeEntry.parent) == null) {
|
||||
Logger.error("Zone " + treeEntry.uid + " (" + treeEntry.name + ") has no parent zone " + treeEntry.parent);
|
||||
return false;
|
||||
|
||||
+15
-7
@@ -21,25 +21,33 @@ import org.json.JSONObject;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
|
||||
// Loads zone templates from the client cache JSON (CZONE/<id>.json).
|
||||
// Loads zone templates from the client cache JSON (CZONE/<id>.json), only those the map's zone tree uses.
|
||||
|
||||
public class ZoneParser {
|
||||
|
||||
private static final String zonePath = ConfigManager.DEFAULT_DATA_DIR + "CZONE/";
|
||||
|
||||
public static HashMap<Integer, CZoneTemplate> parseZoneFolder() {
|
||||
public static HashMap<Integer, CZoneTemplate> parseZoneTemplates(Collection<Integer> templateIds) {
|
||||
|
||||
HashMap<Integer, CZoneTemplate> zoneTemplates = new HashMap<>();
|
||||
File[] zoneFiles = CacheParserUtil.listJsonFiles(zonePath);
|
||||
int templateId;
|
||||
File zoneFile;
|
||||
JSONObject zoneJson;
|
||||
int failedCount = 0;
|
||||
|
||||
for (File zoneFile : zoneFiles) {
|
||||
for (int templateId : templateIds) {
|
||||
|
||||
zoneFile = new File(zonePath + templateId + ".json");
|
||||
|
||||
if (!zoneFile.exists()) {
|
||||
Logger.error("Zone template " + templateId + " has no CZONE file: " + zoneFile.getAbsolutePath());
|
||||
failedCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
templateId = CacheParserUtil.templateIdFromFile(zoneFile);
|
||||
zoneJson = CacheParserUtil.readJsonFile(zoneFile);
|
||||
zoneTemplates.put(templateId, parseZoneEntry(templateId, zoneJson));
|
||||
} catch (Exception e) {
|
||||
@@ -48,7 +56,7 @@ public class ZoneParser {
|
||||
}
|
||||
}
|
||||
|
||||
Logger.info("Loaded " + zoneTemplates.size() + " of " + zoneFiles.length + " zone templates");
|
||||
Logger.info("Loaded " + zoneTemplates.size() + " of " + templateIds.size() + " zone templates");
|
||||
logCounts(zoneTemplates);
|
||||
|
||||
// Partial zone data is never usable; null tells the caller to abort
|
||||
|
||||
@@ -67,7 +67,6 @@ public class ZoneTreeParser {
|
||||
zone.parent = zoneJson.getInt("parent");
|
||||
zone.template = zoneJson.getInt("template");
|
||||
zone.name = zoneJson.getString("name");
|
||||
zone.isPlayerCity = zoneJson.getBoolean("isPlayerCity");
|
||||
zone.offset = CacheParserUtil.readVector3(zoneJson.getJSONArray("offset"));
|
||||
zone.peaceZone = zoneJson.getBoolean("peaceZone");
|
||||
zone.terrain = zoneJson.getString("terrain");
|
||||
|
||||
@@ -19,7 +19,6 @@ public class ZoneTreeEntry {
|
||||
public int parent;
|
||||
public int template;
|
||||
public String name;
|
||||
public boolean isPlayerCity;
|
||||
public Vector3fImmutable offset;
|
||||
public boolean peaceZone;
|
||||
public String terrain;
|
||||
|
||||
@@ -435,8 +435,15 @@ public class WorldServer {
|
||||
Logger.info("Indexing Cache Templates");
|
||||
CObjectIndex.build();
|
||||
|
||||
Logger.info("Loading Zone Tree");
|
||||
|
||||
if (!ZoneManager.loadZoneTree(worldMapID)) {
|
||||
Logger.error("ABORT! Zone tree failed to load!");
|
||||
exitServer(1);
|
||||
}
|
||||
|
||||
Logger.info("Loading Cache Zone Templates");
|
||||
CZoneTemplate._zones = ZoneParser.parseZoneFolder();
|
||||
CZoneTemplate._zones = ZoneParser.parseZoneTemplates(ZoneManager.getZoneTreeTemplateIDs());
|
||||
|
||||
if (CZoneTemplate._zones == null || CZoneTemplate._zones.isEmpty()) {
|
||||
Logger.error("ABORT! Cache zone templates failed to load!");
|
||||
@@ -550,8 +557,8 @@ public class WorldServer {
|
||||
|
||||
Logger.info("Loading all Zones");
|
||||
|
||||
if (!ZoneManager.loadZones(worldMapID)) {
|
||||
Logger.error("ABORT! Zone tree failed to load!");
|
||||
if (!ZoneManager.loadZones()) {
|
||||
Logger.error("ABORT! Zones failed to load!");
|
||||
exitServer(1);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user