Pick the realm map from the zone tree's world

mbEnums.WorldMap maps the world name to its realm map: Aerynth 3000000,
Dalgoth 3000001, Vorringia 3000002 (live REALMDATA sent 3000000 on
Aerynth and 3000002 on Vorringia; Dalgoth confirmed from the image).
The world comes from the "world" field mbScryer writes into
maps/<map>.tree, so it is user-editable; an unknown world aborts boot.

MB_WORLD_REALMMAP is removed: REALMDATA and realmmaps/<id>.png both take
the realm map from the world.

Value changes: none while MB_WORLD_REALMMAP matched the map's world.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
MagicBotandClaude Opus 5.5 committed 2026-10-28 07:01:13 -04:00
1 parent 28b374c5c9
commit 173b97ffff
9 files changed
+80 -13

No files matched your search

+1 -1
View File
@@ -30,7 +30,7 @@ public enum RealmMap {
// MB Dev Notes:
// This class loads and caches realm maps used by each
// map set for its realm overlay. The RealmMap loaded is
// controlled by config entry MB_WORLD_REALMMAP
// picked by the world of the map's zone tree (mbEnums.WorldMap)
//
// Unlike a Heightmap this is a just color lookup; identical to
// the old image maps used in 90s web technology.
@@ -61,7 +61,6 @@ public enum ConfigManager {
MB_WORLD_NAME,
MB_WORLD_MAPID,
MB_WORLD_REALMMAP,
MB_WORLD_PORT,
MB_WORLD_ACCESS_LVL,
+12 -2
View File
@@ -20,6 +20,7 @@ import engine.objects.Zone;
import engine.parsers.map.ZoneTreeParser;
import engine.parsers.objects.CZoneProp;
import engine.parsers.objects.CZoneTemplate;
import engine.parsers.objects.ZoneTree;
import engine.parsers.objects.ZoneTreeEntry;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
@@ -41,6 +42,7 @@ public enum ZoneManager {
public static HashMap<Integer, CZoneTemplate> _zone_templates = new HashMap<>();
public static ArrayList<ZoneTreeEntry> zoneTree;
public static mbEnums.WorldMap worldMap;
public static final HashMap<Integer, Zone> staticZonesByTreeUID = new HashMap<>();
public static final HashMap<Integer, Integer> staticIDsByTreeUID = new HashMap<>();
public static final ArrayList<Zone> ruinZones = new ArrayList<>();
@@ -85,9 +87,17 @@ public enum ZoneManager {
public static boolean loadZoneTree(int mapID) {
zoneTree = ZoneTreeParser.parseZoneTree(mapID);
ZoneTree tree;
return zoneTree != null;
tree = ZoneTreeParser.parseZoneTree(mapID);
if (tree == null)
return false;
zoneTree = tree.zones;
worldMap = tree.worldMap;
return true;
}
public static TreeSet<Integer> getZoneTreeTemplateIDs() {
+25
View File
@@ -3139,6 +3139,31 @@ public class mbEnums {
}
}
// The "world" of maps/<map>.tree (NEWWORLD world_name). realmMapID is the ID live sent at the end of REALMDATA
// and names mb.data/realmmaps/<id>.png. Null when unknown, and boot aborts.
public enum WorldMap {
AERYNTH("Aerynth", 3000000),
DALGOTH("Dalgoth", 3000001),
VORRINGIA("Vorringia", 3000002);
public final String worldName;
public final int realmMapID;
WorldMap(String worldName, int realmMapID) {
this.worldName = worldName;
this.realmMapID = realmMapID;
}
public static WorldMap fromWorldName(String worldName) {
for (WorldMap worldMap : values())
if (worldMap.worldName.equals(worldName))
return worldMap;
return null;
}
}
// MB_STATIC_RUNEGATES (World Boot Plan 2.7). DB: static_runegate_portals. JSON: registry props and maps/<map>.gates,
// which needs MB_STATIC_BUILDINGS=JSON. Required; null when missing or unknown, and boot aborts.
public enum StaticRunegateMode {
+2 -2
View File
@@ -9,12 +9,12 @@
package engine.net.client.msg;
import engine.gameManager.ZoneManager;
import engine.net.AbstractConnection;
import engine.net.ByteBufferReader;
import engine.net.ByteBufferWriter;
import engine.net.Protocol;
import engine.objects.Realm;
import engine.server.world.WorldServer;
public class WorldRealmMsg extends ClientNetMsg {
@@ -62,7 +62,7 @@ public class WorldRealmMsg extends ClientNetMsg {
realm.serializeForClientMsg(writer);
writer.putInt(0x0);
writer.putInt(WorldServer.worldRealmMap);
writer.putInt(ZoneManager.worldMap.realmMapID);
}
+16 -5
View File
@@ -9,27 +9,30 @@
package engine.parsers.map;
import engine.gameManager.ConfigManager;
import engine.mbEnums;
import engine.parsers.cache.CacheParserUtil;
import engine.parsers.objects.ZoneTree;
import engine.parsers.objects.ZoneTreeEntry;
import org.json.JSONArray;
import org.json.JSONObject;
import org.pmw.tinylog.Logger;
import java.io.File;
import java.util.ArrayList;
// Loads the zone tree for a map (maps/<map>.tree), in file order: parents always precede their children.
// The tree's "world" picks the map's WorldMap; it is user-editable.
public class ZoneTreeParser {
private static final String mapPath = ConfigManager.DEFAULT_DATA_DIR + "maps/";
public static ArrayList<ZoneTreeEntry> parseZoneTree(int mapID) {
public static ZoneTree parseZoneTree(int mapID) {
ArrayList<ZoneTreeEntry> zoneTree = new ArrayList<>();
ZoneTree zoneTree = new ZoneTree();
File treeFile = new File(mapPath + mapID + ".tree");
JSONObject treeJson;
JSONArray zonesJson;
String worldName;
if (!treeFile.exists()) {
Logger.error("Zone tree not found: " + treeFile.getAbsolutePath());
@@ -44,17 +47,25 @@ public class ZoneTreeParser {
return null;
}
worldName = treeJson.getString("world");
zoneTree.worldMap = mbEnums.WorldMap.fromWorldName(worldName);
if (zoneTree.worldMap == null) {
Logger.error(treeFile.getName() + ": unknown world '" + worldName + "'");
return null;
}
zonesJson = treeJson.getJSONArray("zones");
for (int i = 0; i < zonesJson.length(); i++)
zoneTree.add(parseZoneEntry(zonesJson.getJSONObject(i)));
zoneTree.zones.add(parseZoneEntry(zonesJson.getJSONObject(i)));
} catch (Exception e) {
Logger.error(treeFile.getName() + ": " + e);
return null;
}
Logger.info("Loaded " + zoneTree.size() + " zones from " + treeFile.getName());
Logger.info("Loaded " + zoneTree.zones.size() + " zones from " + treeFile.getName() + " (" + zoneTree.worldMap.worldName + ")");
return zoneTree;
}
+22
View File
@@ -0,0 +1,22 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2026
// https://www.magicbane.com
package engine.parsers.objects;
import engine.mbEnums;
import java.util.ArrayList;
// A map's zone tree (maps/<map>.tree): its world and the static zones in file order.
public class ZoneTree {
public mbEnums.WorldMap worldMap;
public final ArrayList<ZoneTreeEntry> zones = new ArrayList<>();
}
-1
View File
@@ -94,7 +94,6 @@ import static java.lang.System.exit;
public class WorldServer {
public static int worldMapID = Integer.parseInt(ConfigManager.MB_WORLD_MAPID.getValue());
public static int worldRealmMap = Integer.parseInt(ConfigManager.MB_WORLD_REALMMAP.getValue());
public static int worldUUID = 1; // Root object in database
public static mbEnums.AccountStatus worldAccessLevel = mbEnums.AccountStatus.valueOf(ConfigManager.MB_WORLD_ACCESS_LVL.getValue());
+2 -1
View File
@@ -7,6 +7,7 @@ package engine.util;
import engine.InterestManagement.RealmMap;
import engine.InterestManagement.Terrain;
import engine.gameManager.ConfigManager;
import engine.gameManager.ZoneManager;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
@@ -37,7 +38,7 @@ public enum MapLoader {
// Load image from disk
try {
mapPath = ConfigManager.DEFAULT_DATA_DIR + "realmmaps/" + ConfigManager.MB_WORLD_REALMMAP.getValue() + ".png";
mapPath = ConfigManager.DEFAULT_DATA_DIR + "realmmaps/" + ZoneManager.worldMap.realmMapID + ".png";
image = ImageIO.read(new File(mapPath));
// Array size determined by image size