mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-27 06:20:02 +00:00
Merge branch 'fail-closed' into review
This commit is contained in:
commit
a9f07ce5c6
25 files changed
+1670
-161
No files matched your search
@@ -372,8 +372,7 @@ public final class BukkitWorldConfiguration {
|
||||
+ "\" is not a string.");
|
||||
}
|
||||
String configuredGenerator = generator.trim();
|
||||
if (!configuredGenerator.equalsIgnoreCase("Iris")
|
||||
&& !configuredGenerator.regionMatches(true, 0, "Iris:", 0, 5)) {
|
||||
if (!isIrisGenerator(configuredGenerator)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -395,6 +394,35 @@ public final class BukkitWorldConfiguration {
|
||||
return candidates;
|
||||
}
|
||||
|
||||
/**
|
||||
* True when any bukkit.yml world names Iris as its generator, vanilla slots included. CraftServer asks a plugin
|
||||
* for a generator only for these worlds, so they are the ones a disabled Iris would hand to vanilla.
|
||||
*/
|
||||
public static boolean configuresIrisGenerator(File configurationFile) throws IOException {
|
||||
Path configurationPath = Objects.requireNonNull(configurationFile, "configurationFile").toPath();
|
||||
if (!Files.exists(configurationPath, LinkOption.NOFOLLOW_LINKS)) {
|
||||
return false;
|
||||
}
|
||||
synchronized (MUTATION_LOCK) {
|
||||
ConfigurationSection worlds = load(configurationFile).getConfigurationSection("worlds");
|
||||
if (worlds == null) {
|
||||
return false;
|
||||
}
|
||||
for (String worldName : worlds.getKeys(false)) {
|
||||
if (worlds.get(worldName + ".generator") instanceof String generator
|
||||
&& isIrisGenerator(generator.trim())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isIrisGenerator(String configuredGenerator) {
|
||||
return configuredGenerator.equalsIgnoreCase("Iris")
|
||||
|| configuredGenerator.regionMatches(true, 0, "Iris:", 0, 5);
|
||||
}
|
||||
|
||||
public static GeneratorReplacement replaceIfMatching(
|
||||
File configurationFile,
|
||||
String worldName,
|
||||
|
||||
@@ -61,7 +61,7 @@ public final class MissingWorldStorageLog {
|
||||
}
|
||||
emit(new String[]{
|
||||
IrisLogging.format("Iris world %s has an empty world folder at %s: no pack snapshot, no region"
|
||||
+ " data; it will generate as vanilla terrain.", worldName, worldStorage),
|
||||
+ " data; Iris refuses to generate it and no other generator gets it.", worldName, worldStorage),
|
||||
IrisLogging.format("Delete that folder, or drop the world with /iris remove world=%s delete=true.",
|
||||
worldName)
|
||||
});
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package art.arcane.iris.world.safeguard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The framed console block Iris prints when it refuses to generate a world. Every platform prints the same shape
|
||||
* so a refusal is found the same way in any server log.
|
||||
*/
|
||||
public final class GenerationRefusalNotice {
|
||||
private static final String RULE = "=".repeat(78);
|
||||
|
||||
private GenerationRefusalNotice() {
|
||||
}
|
||||
|
||||
public static List<String> compose(String headline, List<String> causes, List<String> consequences) {
|
||||
List<String> lines = new ArrayList<>(causes.size() + consequences.size() + 3);
|
||||
lines.add(RULE);
|
||||
lines.add(Objects.requireNonNull(headline, "headline"));
|
||||
for (int index = 0; index < causes.size(); index++) {
|
||||
lines.add((index == 0 ? "Cause: " : "Caused by: ") + causes.get(index));
|
||||
}
|
||||
lines.addAll(consequences);
|
||||
lines.add(RULE);
|
||||
return List.copyOf(lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Every distinct message in the cause chain, outermost first. A wrapper whose message only repeats its cause
|
||||
* (CompletionException, a rethrow with the same text) adds nothing and is skipped.
|
||||
*/
|
||||
public static List<String> causes(Throwable failure) {
|
||||
List<String> causes = new ArrayList<>();
|
||||
Set<Throwable> seen = Collections.newSetFromMap(new IdentityHashMap<>());
|
||||
Throwable current = failure;
|
||||
while (current != null && seen.add(current)) {
|
||||
Throwable cause = current.getCause();
|
||||
String message = current.getMessage();
|
||||
boolean repeatsCause = cause != null && cause.toString().equals(message);
|
||||
if (!repeatsCause) {
|
||||
String text = message == null || message.isBlank() ? current.getClass().getSimpleName() : message.trim();
|
||||
if (causes.isEmpty() || !causes.getLast().equals(text)) {
|
||||
causes.add(text);
|
||||
}
|
||||
}
|
||||
current = cause;
|
||||
}
|
||||
return List.copyOf(causes);
|
||||
}
|
||||
|
||||
public static String summary(Throwable failure) {
|
||||
return String.join("; ", causes(failure));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user