Parse the map guild seed file (maps/<map>.guild)

GuildSeedParser reads the server-owned NPC guild seed (W7): guilds in
static ID order, each with its CZONE city_prop_gm_guild keys, nation key,
name, crest, charter (GuildCharterType name), leadership type, motto and
repledge/teleport limits, plus the known no-guild keys. An unknown charter,
a guild with no keys or a crest without five values fails the file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
MagicBotandClaude Opus 5.5 committed 2026-10-27 21:15:09 -04:00
1 parent 21975e0bed
commit 4839883530
3 files changed
+158

No files matched your search

+103
View File
@@ -0,0 +1,103 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2026
// https://www.magicbane.com
package engine.parsers.map;
import engine.gameManager.ConfigManager;
import engine.mbEnums;
import engine.parsers.cache.CacheParserUtil;
import engine.parsers.objects.GuildSeed;
import engine.parsers.objects.GuildSeedEntry;
import org.json.JSONArray;
import org.json.JSONObject;
import org.pmw.tinylog.Logger;
import java.io.File;
// Loads the NPC guild seed for a map (maps/<map>.guild), in file order. Guild keys are unsigned in the file.
public class GuildSeedParser {
private static final String mapPath = ConfigManager.DEFAULT_DATA_DIR + "maps/";
public static GuildSeed parseGuildSeed(int mapID) {
GuildSeed guildSeed = new GuildSeed();
File seedFile = new File(mapPath + mapID + ".guild");
JSONObject seedJson;
JSONArray guildsJson;
JSONArray noGuildJson;
if (!seedFile.exists()) {
Logger.error("Guild seed not found: " + seedFile.getAbsolutePath());
return null;
}
try {
seedJson = CacheParserUtil.readJsonFile(seedFile);
if (seedJson.getInt("map") != mapID) {
Logger.error(seedFile.getName() + ": map " + seedJson.getInt("map") + " does not match MB_WORLD_MAPID " + mapID);
return null;
}
guildsJson = seedJson.getJSONArray("guilds");
for (int i = 0; i < guildsJson.length(); i++)
guildSeed.guilds.add(parseGuildEntry(guildsJson.getJSONObject(i)));
noGuildJson = seedJson.getJSONArray("noGuildKeys");
for (int i = 0; i < noGuildJson.length(); i++)
guildSeed.noGuildKeys.add((int) noGuildJson.getLong(i));
} catch (Exception e) {
Logger.error(seedFile.getName() + ": " + e);
return null;
}
Logger.info("Loaded " + guildSeed.guilds.size() + " guilds from " + seedFile.getName());
return guildSeed;
}
private static GuildSeedEntry parseGuildEntry(JSONObject guildJson) {
GuildSeedEntry guild = new GuildSeedEntry();
JSONArray keysJson = guildJson.getJSONArray("guildKeys");
JSONArray crestJson = guildJson.getJSONArray("crest");
for (int i = 0; i < keysJson.length(); i++)
guild.guildKeys.add((int) keysJson.getLong(i));
guild.nationKey = (int) guildJson.getLong("nationKey");
guild.name = guildJson.getString("name");
guild.charter = mbEnums.GuildCharterType.valueOf(guildJson.getString("charter"));
guild.leadershipType = guildJson.getString("leadershipType");
guild.motto = guildJson.getString("motto");
guild.repledgeMin = guildJson.getInt("repledgeMin");
guild.repledgeMax = guildJson.getInt("repledgeMax");
guild.repledgeKick = guildJson.getInt("repledgeKick");
guild.teleportMin = guildJson.getInt("teleportMin");
guild.teleportMax = guildJson.getInt("teleportMax");
if (guild.guildKeys.isEmpty())
throw new IllegalStateException("guild " + guild.name + " has no guild keys");
if (crestJson.length() != 5)
throw new IllegalStateException("guild " + guild.name + " crest has " + crestJson.length() + " values");
guild.crest = new int[5];
for (int i = 0; i < 5; i++)
guild.crest[i] = crestJson.getInt(i);
return guild;
}
}
+22
View File
@@ -0,0 +1,22 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2026
// https://www.magicbane.com
package engine.parsers.objects;
import java.util.ArrayList;
import java.util.HashSet;
// A map's server-owned NPC guild seed (maps/<map>.guild). Guilds are in static ID order.
// noGuildKeys are CITY-prop guild keys known to have no guild: placeholders and Ruins.
public class GuildSeed {
public final ArrayList<GuildSeedEntry> guilds = new ArrayList<>();
public final HashSet<Integer> noGuildKeys = new HashSet<>();
}
@@ -0,0 +1,33 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2026
// https://www.magicbane.com
package engine.parsers.objects;
import engine.mbEnums;
import java.util.ArrayList;
// One NPC guild of a <map>.guild seed file. guildKeys and nationKey are CZONE city_prop_gm_guild / _nation values.
// Crest is in obj_guild column order: backgroundColor01, backgroundColor02, symbolColor, backgroundDesign, symbol.
public class GuildSeedEntry {
public final ArrayList<Integer> guildKeys = new ArrayList<>();
public int nationKey;
public String name;
public int[] crest;
public mbEnums.GuildCharterType charter;
public String leadershipType;
public String motto;
public int repledgeMin;
public int repledgeMax;
public int repledgeKick;
public int teleportMin;
public int teleportMax;
}