mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-11-01 17:00:26 +00:00
Fail-closed review fixes
- Modded logins are refused only when this save's dimension registry lists the primary world - Otherwise Iris warns once and leaves routing idle - An unreadable dimension registry counts as expecting the primary world - A vanilla slot bound to Iris without Iris storage points at the bukkit.yml entry and /iris replace - The refusal consequence comes from whether startup worlds exist instead of the first tick - The first WorldLoadEvent or a hotload marks startup worlds as existing - A failed enable on a hotload says the server keeps running - Reconciler resolution failures report the refusal banner - Operators get a join notice for such failures until the world loads - The fail-closed generator is built even when the cause message cannot be read - Tests drive Iris.onEnable for the lock, the unsupported-server lock and the rethrow - The failed-enable teardown decision lives in FailedEnableLock with a test
This commit is contained in:
1 parent
3a4da2086e
commit
eefcbc40ef
13 files changed
+644
-84
No files matched your search
+33
-3
@@ -40,6 +40,7 @@ public final class ModdedPrimaryWorldRouter {
|
||||
private static final Set<UUID> inFlight = ConcurrentHashMap.newKeySet();
|
||||
private static int tickCounter = 0;
|
||||
private static volatile String loginRefusal;
|
||||
private static volatile String absentPrimary;
|
||||
|
||||
private ModdedPrimaryWorldRouter() {
|
||||
}
|
||||
@@ -48,6 +49,7 @@ public final class ModdedPrimaryWorldRouter {
|
||||
routed.clear();
|
||||
inFlight.clear();
|
||||
loginRefusal = null;
|
||||
absentPrimary = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,7 +101,7 @@ public final class ModdedPrimaryWorldRouter {
|
||||
NativeWorld target = ModdedDimensionManager.level(server, primary);
|
||||
if (target == null) {
|
||||
if (ModdedStartup.dimensionsRestored()) {
|
||||
refuseLogins(server, primary);
|
||||
judgeMissingPrimary(server, primary);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -141,9 +143,37 @@ public final class ModdedPrimaryWorldRouter {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* primaryWorld is instance-wide but the dimension it names belongs to one save. Only a save whose registry lists
|
||||
* it expected it here, so only that save has a primary world that failed to load.
|
||||
*/
|
||||
private static void judgeMissingPrimary(NativeModdedServer server, String primary) {
|
||||
if (loginRefusal == null && primary.equals(absentPrimary)) {
|
||||
return;
|
||||
}
|
||||
if (loginRefusal == null && !expectedInThisSave(server, primary)) {
|
||||
absentPrimary = primary;
|
||||
ModdedIrisLog.warn("Iris primary world '" + primary + "' from config/irisworldgen/modded.json does not"
|
||||
+ " exist in this save, so players are not routed. Create it here with /iris world replace-overworld"
|
||||
+ " <pack> or clear primaryWorld.");
|
||||
return;
|
||||
}
|
||||
refuseLogins(server, primary);
|
||||
}
|
||||
|
||||
private static boolean expectedInThisSave(NativeModdedServer server, String primary) {
|
||||
try {
|
||||
return ModdedDimensionRegistryStore.get(server, primary) != null;
|
||||
} catch (RuntimeException unreadable) {
|
||||
ModdedIrisLog.error("Iris could not read this save's dimension registry to judge primary world '"
|
||||
+ primary + "'", unreadable);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Players left in the overworld would generate the terrain the primary Iris world was configured to replace, so a
|
||||
* primary world that did not load refuses every player instead.
|
||||
* primary world this save expected and did not load refuses every player instead.
|
||||
*/
|
||||
private static void refuseLogins(NativeModdedServer server, String primary) {
|
||||
String refusal = "Iris primary world '" + primary + "' is not loaded, so this server refuses players."
|
||||
@@ -152,7 +182,7 @@ public final class ModdedPrimaryWorldRouter {
|
||||
for (String line : GenerationRefusalNotice.compose(
|
||||
"Iris refused player logins: primary world '" + primary + "' is not loaded",
|
||||
List.of("routePlayersToPrimaryWorld sends players to '" + primary
|
||||
+ "', which did not load at startup."),
|
||||
+ "', which this save's dimension registry expects but did not load at startup."),
|
||||
List.of(
|
||||
"Players are disconnected instead of playing in the overworld, so no chunks are"
|
||||
+ " written there.",
|
||||
|
||||
Reference in new issue
Block a user