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;
|
ZONEMANAGER;
|
||||||
|
|
||||||
public static HashMap<Integer, CZoneTemplate> _zone_templates = new HashMap<>();
|
public static HashMap<Integer, CZoneTemplate> _zone_templates = new HashMap<>();
|
||||||
|
public static ArrayList<ZoneTreeEntry> zoneTree;
|
||||||
|
|
||||||
public static final Set<Zone> macroZones = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
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);
|
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());
|
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) {
|
public static boolean loadZoneTree(int mapID) {
|
||||||
|
|
||||||
ArrayList<ZoneTreeEntry> zoneTree;
|
|
||||||
ArrayList<Zone> cityZones;
|
|
||||||
Zone zone;
|
|
||||||
int staticCount = 0;
|
|
||||||
boolean templatesMissing = false;
|
|
||||||
|
|
||||||
zoneTree = ZoneTreeParser.parseZoneTree(mapID);
|
zoneTree = ZoneTreeParser.parseZoneTree(mapID);
|
||||||
|
|
||||||
if (zoneTree == null)
|
return zoneTree != null;
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
public static TreeSet<Integer> getZoneTreeTemplateIDs() {
|
||||||
|
|
||||||
|
TreeSet<Integer> templateIDs = new TreeSet<>();
|
||||||
|
|
||||||
for (ZoneTreeEntry treeEntry : zoneTree)
|
for (ZoneTreeEntry treeEntry : zoneTree)
|
||||||
if (!treeEntry.isPlayerCity && !_zone_templates.containsKey(treeEntry.template)) {
|
templateIDs.add(treeEntry.template);
|
||||||
Logger.error("Zone " + treeEntry.uid + " (" + treeEntry.name + ") has no CZONE template " + treeEntry.template);
|
|
||||||
templatesMissing = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (templatesMissing)
|
return templateIDs;
|
||||||
return false;
|
}
|
||||||
|
|
||||||
// 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) {
|
for (ZoneTreeEntry treeEntry : zoneTree) {
|
||||||
|
|
||||||
if (treeEntry.isPlayerCity)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (treeEntry.parent != 0 && getZoneByUUID(treeEntry.parent) == null) {
|
if (treeEntry.parent != 0 && getZoneByUUID(treeEntry.parent) == null) {
|
||||||
Logger.error("Zone " + treeEntry.uid + " (" + treeEntry.name + ") has no parent zone " + treeEntry.parent);
|
Logger.error("Zone " + treeEntry.uid + " (" + treeEntry.name + ") has no parent zone " + treeEntry.parent);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
+15
-7
@@ -21,25 +21,33 @@ import org.json.JSONObject;
|
|||||||
import org.pmw.tinylog.Logger;
|
import org.pmw.tinylog.Logger;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
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 {
|
public class ZoneParser {
|
||||||
|
|
||||||
private static final String zonePath = ConfigManager.DEFAULT_DATA_DIR + "CZONE/";
|
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<>();
|
HashMap<Integer, CZoneTemplate> zoneTemplates = new HashMap<>();
|
||||||
File[] zoneFiles = CacheParserUtil.listJsonFiles(zonePath);
|
File zoneFile;
|
||||||
int templateId;
|
|
||||||
JSONObject zoneJson;
|
JSONObject zoneJson;
|
||||||
int failedCount = 0;
|
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 {
|
try {
|
||||||
templateId = CacheParserUtil.templateIdFromFile(zoneFile);
|
|
||||||
zoneJson = CacheParserUtil.readJsonFile(zoneFile);
|
zoneJson = CacheParserUtil.readJsonFile(zoneFile);
|
||||||
zoneTemplates.put(templateId, parseZoneEntry(templateId, zoneJson));
|
zoneTemplates.put(templateId, parseZoneEntry(templateId, zoneJson));
|
||||||
} catch (Exception e) {
|
} 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);
|
logCounts(zoneTemplates);
|
||||||
|
|
||||||
// Partial zone data is never usable; null tells the caller to abort
|
// 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.parent = zoneJson.getInt("parent");
|
||||||
zone.template = zoneJson.getInt("template");
|
zone.template = zoneJson.getInt("template");
|
||||||
zone.name = zoneJson.getString("name");
|
zone.name = zoneJson.getString("name");
|
||||||
zone.isPlayerCity = zoneJson.getBoolean("isPlayerCity");
|
|
||||||
zone.offset = CacheParserUtil.readVector3(zoneJson.getJSONArray("offset"));
|
zone.offset = CacheParserUtil.readVector3(zoneJson.getJSONArray("offset"));
|
||||||
zone.peaceZone = zoneJson.getBoolean("peaceZone");
|
zone.peaceZone = zoneJson.getBoolean("peaceZone");
|
||||||
zone.terrain = zoneJson.getString("terrain");
|
zone.terrain = zoneJson.getString("terrain");
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ public class ZoneTreeEntry {
|
|||||||
public int parent;
|
public int parent;
|
||||||
public int template;
|
public int template;
|
||||||
public String name;
|
public String name;
|
||||||
public boolean isPlayerCity;
|
|
||||||
public Vector3fImmutable offset;
|
public Vector3fImmutable offset;
|
||||||
public boolean peaceZone;
|
public boolean peaceZone;
|
||||||
public String terrain;
|
public String terrain;
|
||||||
|
|||||||
@@ -435,8 +435,15 @@ public class WorldServer {
|
|||||||
Logger.info("Indexing Cache Templates");
|
Logger.info("Indexing Cache Templates");
|
||||||
CObjectIndex.build();
|
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");
|
Logger.info("Loading Cache Zone Templates");
|
||||||
CZoneTemplate._zones = ZoneParser.parseZoneFolder();
|
CZoneTemplate._zones = ZoneParser.parseZoneTemplates(ZoneManager.getZoneTreeTemplateIDs());
|
||||||
|
|
||||||
if (CZoneTemplate._zones == null || CZoneTemplate._zones.isEmpty()) {
|
if (CZoneTemplate._zones == null || CZoneTemplate._zones.isEmpty()) {
|
||||||
Logger.error("ABORT! Cache zone templates failed to load!");
|
Logger.error("ABORT! Cache zone templates failed to load!");
|
||||||
@@ -550,8 +557,8 @@ public class WorldServer {
|
|||||||
|
|
||||||
Logger.info("Loading all Zones");
|
Logger.info("Loading all Zones");
|
||||||
|
|
||||||
if (!ZoneManager.loadZones(worldMapID)) {
|
if (!ZoneManager.loadZones()) {
|
||||||
Logger.error("ABORT! Zone tree failed to load!");
|
Logger.error("ABORT! Zones failed to load!");
|
||||||
exitServer(1);
|
exitServer(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user