mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-11-01 17:00:26 +00:00
Merge origin/master into terrain-first hydrology
Brings master's Sentry removal, bound platform classification, Vision entity toggle, release version and generation context binding onto the rivers rework while keeping the hydrology system master had removed. Hydrology files master deleted are restored from the branch, master's non-hydrology edits are kept, and the modded adapter builds drop the Sentry dependency with master. Also removes the ridge_tunnel find selector: no course publishes ridge bores any more, so it could never return a result.
This commit is contained in:
commit
f6a7ad7472
74 files changed
+869
-726
No files matched your search
+90
-12
@@ -331,34 +331,113 @@ public final class IrisModdedChunkGenerator extends ChunkGenerator {
|
||||
if (server == null) {
|
||||
return null;
|
||||
}
|
||||
// Snapshot, never server.getAllLevels(): this runs off the server thread from data queries.
|
||||
for (ServerLevel level : ModdedServerLevels.levels(server)) {
|
||||
ServerLevel resolved = resolveBoundLevel(server, ModdedServerLevels.levels(server));
|
||||
if (resolved != null) {
|
||||
boundLevel = resolved;
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
ServerLevel resolveBoundLevel(MinecraftServer server, List<ServerLevel> snapshot) {
|
||||
for (ServerLevel level : snapshot) {
|
||||
if (level.getChunkSource().getGenerator() == this) {
|
||||
boundLevel = level;
|
||||
return level;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
ServerLevel overworld = server.getLevel(Level.OVERWORLD);
|
||||
return overworld != null && overworld.getChunkSource().getGenerator() == this ? overworld : null;
|
||||
}
|
||||
|
||||
Engine engine() {
|
||||
requireBindingAllowed();
|
||||
Engine cached = engine;
|
||||
requireCompletedShutdown(cached);
|
||||
if (cached != null && !cached.isClosed()) {
|
||||
Engine cached = readyEngine();
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
ServerLevel level = boundLevel();
|
||||
if (level == null) {
|
||||
throw new IllegalStateException("Iris generator '" + dimensionKey + "' has no bound ServerLevel yet");
|
||||
}
|
||||
return bindEngine(level);
|
||||
return bindGenerationLevel(level);
|
||||
}
|
||||
|
||||
private Engine engine(ResourceKey<Level> levelKey) {
|
||||
Engine cached = readyEngine();
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
ServerLevel level = boundLevel;
|
||||
if (level == null) {
|
||||
level = requirePublishedLevel(ModdedEngineBootstrap.currentServer(), levelKey);
|
||||
} else {
|
||||
requireGeneratorLevel(level, levelKey);
|
||||
}
|
||||
return bindGenerationLevel(level);
|
||||
}
|
||||
|
||||
private Engine engine(ServerLevel generationLevel) {
|
||||
Engine cached = readyEngine();
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
ServerLevel level = boundLevel == null ? generationLevel : boundLevel;
|
||||
requireGeneratorLevel(level, generationLevel.dimension());
|
||||
return bindGenerationLevel(level);
|
||||
}
|
||||
|
||||
private Engine readyEngine() {
|
||||
requireBindingAllowed();
|
||||
Engine cached = engine;
|
||||
requireCompletedShutdown(cached);
|
||||
if (cached != null && !cached.isClosed()) {
|
||||
return cached;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Engine bindGenerationLevel(ServerLevel level) {
|
||||
bindLevel(level);
|
||||
Engine bound = readyEngine();
|
||||
if (bound == null) {
|
||||
throw new IllegalStateException("Iris generator '" + dimensionKey
|
||||
+ "' completed generation binding without a ready engine");
|
||||
}
|
||||
return bound;
|
||||
}
|
||||
|
||||
ServerLevel requirePublishedLevel(MinecraftServer server, ResourceKey<Level> levelKey) {
|
||||
if (server == null) {
|
||||
throw new IllegalStateException("Iris generator '" + dimensionKey
|
||||
+ "' cannot resolve level '" + levelKey.identifier() + "': server is unavailable");
|
||||
}
|
||||
ServerLevel level = server.getLevel(levelKey);
|
||||
if (level == null) {
|
||||
throw new IllegalStateException("Iris generator '" + dimensionKey
|
||||
+ "' has no published ServerLevel for '" + levelKey.identifier() + "'");
|
||||
}
|
||||
requireGeneratorLevel(level, levelKey);
|
||||
return level;
|
||||
}
|
||||
|
||||
private void requireGeneratorLevel(ServerLevel level, ResourceKey<Level> levelKey) {
|
||||
if (!levelKey.equals(level.dimension())) {
|
||||
throw new IllegalStateException("Iris generator '" + dimensionKey + "' resolved level '"
|
||||
+ level.dimension().identifier() + "' while binding '" + levelKey.identifier() + "'");
|
||||
}
|
||||
ChunkGenerator publishedGenerator = level.getChunkSource().getGenerator();
|
||||
if (publishedGenerator != this) {
|
||||
throw new IllegalStateException("Published ServerLevel '" + levelKey.identifier()
|
||||
+ "' does not use Iris generator '" + dimensionKey + "'");
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void bindLevel(ServerLevel level) {
|
||||
if (level.getChunkSource().getGenerator() != this) {
|
||||
throw new IllegalArgumentException("ServerLevel does not use Iris generator '" + dimensionKey + "'");
|
||||
}
|
||||
Engine current = engineIfBound();
|
||||
if (boundLevel == level && current != null && current.getComplex() != null) {
|
||||
return;
|
||||
}
|
||||
requireCompletedShutdown(engine);
|
||||
unloading = false;
|
||||
Engine bound = bindEngine(level);
|
||||
@@ -853,7 +932,6 @@ public final class IrisModdedChunkGenerator extends ChunkGenerator {
|
||||
@Override
|
||||
public void applyBiomeDecoration(WorldGenLevel level, ChunkAccess chunk, StructureManager structureManager) {
|
||||
Engine current = engine();
|
||||
// Self-heal for an engine bound through a data-query path instead of bindLevel; a no-op once prepared.
|
||||
importedFeatures.prepare(current);
|
||||
try (GenerationSessionLease lease = requireGenerationLease(current, "modded_biome_decoration");
|
||||
IrisContext.Scope ignored = IrisContext.open(current, lease.sessionId(), null)) {
|
||||
@@ -867,7 +945,7 @@ public final class IrisModdedChunkGenerator extends ChunkGenerator {
|
||||
|
||||
@Override
|
||||
public void createStructures(RegistryAccess registryAccess, ChunkGeneratorStructureState structureState, StructureManager structureManager, ChunkAccess chunk, StructureTemplateManager templateManager, ResourceKey<Level> levelKey) {
|
||||
Engine current = engine();
|
||||
Engine current = engine(levelKey);
|
||||
try (GenerationSessionLease lease = requireGenerationLease(current, "modded_create_structures");
|
||||
IrisContext.Scope ignored = IrisContext.open(current, lease.sessionId(), null)) {
|
||||
Map<Structure, StructureStart> previousStarts = new HashMap<>(chunk.getAllStarts());
|
||||
@@ -891,7 +969,7 @@ public final class IrisModdedChunkGenerator extends ChunkGenerator {
|
||||
|
||||
@Override
|
||||
public void createReferences(WorldGenLevel level, StructureManager structureManager, ChunkAccess chunk) {
|
||||
Engine current = engine();
|
||||
Engine current = engine(level.getLevel());
|
||||
try (GenerationSessionLease lease = requireGenerationLease(current, "modded_create_references");
|
||||
IrisContext.Scope ignored = IrisContext.open(current, lease.sessionId(), null)) {
|
||||
NativeStructureReferenceRepair.createReferences(
|
||||
|
||||
+1
@@ -590,6 +590,7 @@ public final class ModdedDimensionManager {
|
||||
|
||||
boolean loadEventStarted = false;
|
||||
try {
|
||||
serverAccess.initializeLevelData(server, level);
|
||||
generator.bindLevel(level);
|
||||
Handle handle = new Handle(dimensionId, pack, packDimensionKey, seed, level, generator);
|
||||
ServerLevel previous = serverAccess.putLevelIfAbsent(server, key, level);
|
||||
|
||||
@@ -113,7 +113,6 @@ public final class ModdedEngineBootstrap {
|
||||
bindWorldGenerators(server);
|
||||
services().enableAll();
|
||||
ModdedProtocolHandler.start(server);
|
||||
ModdedSentry.start(loader());
|
||||
}
|
||||
|
||||
private static void bindWorldGenerators(MinecraftServer server) {
|
||||
@@ -194,7 +193,6 @@ public final class ModdedEngineBootstrap {
|
||||
MultiBurst.burst.close();
|
||||
MultiBurst.ioBurst.close();
|
||||
});
|
||||
failure = runStopStage(failure, "sentry", ModdedSentry::flush);
|
||||
failure = runStopStage(failure, "startup state", ModdedStartup::reset);
|
||||
failure = runStopStage(failure, "server state", () -> {
|
||||
currentServer = null;
|
||||
|
||||
@@ -47,7 +47,6 @@ public final class ModdedPlatform implements IrisPlatform {
|
||||
private static final ConcurrentHashMap<String, ErrorThrottle> ERROR_THROTTLES = new ConcurrentHashMap<>();
|
||||
|
||||
private static volatile Consumer<Throwable> ERROR_SINK = null;
|
||||
private static volatile Consumer<Throwable> CAPTURE_SINK = null;
|
||||
|
||||
private final ModdedLoader loader;
|
||||
private final ModdedRegistries registries;
|
||||
@@ -67,10 +66,6 @@ public final class ModdedPlatform implements IrisPlatform {
|
||||
ERROR_SINK = sink;
|
||||
}
|
||||
|
||||
public static void captureSink(Consumer<Throwable> sink) {
|
||||
CAPTURE_SINK = sink;
|
||||
}
|
||||
|
||||
public MinecraftServer server() {
|
||||
return ModdedEngineBootstrap.currentServer();
|
||||
}
|
||||
@@ -230,9 +225,8 @@ public final class ModdedPlatform implements IrisPlatform {
|
||||
}
|
||||
|
||||
/**
|
||||
* Throttled per exception signature. A single broken pack rule can fail on every generated chunk, and this
|
||||
* feeds Sentry, so each distinct signature reports its first few occurrences and then only a periodic
|
||||
* suppressed-count summary.
|
||||
* Throttled per exception signature. A single broken pack rule can fail on every generated chunk, so each
|
||||
* distinct signature reports its first few occurrences and then only a periodic suppressed-count summary.
|
||||
*/
|
||||
@Override
|
||||
public void reportError(Throwable error) {
|
||||
@@ -261,14 +255,6 @@ public final class ModdedPlatform implements IrisPlatform {
|
||||
return;
|
||||
}
|
||||
ModdedIrisLog.error(message, error);
|
||||
Consumer<Throwable> capture = CAPTURE_SINK;
|
||||
if (capture != null) {
|
||||
try {
|
||||
capture.accept(error);
|
||||
} catch (Throwable captureFailure) {
|
||||
ModdedIrisLog.error("Iris error-reporting sink failed", captureFailure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void resetErrorThrottles() {
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Servers
|
||||
* Copyright (c) 2026 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package art.arcane.iris.modded;
|
||||
|
||||
import art.arcane.iris.BuildConstants;
|
||||
import art.arcane.iris.core.IrisSettings;
|
||||
import art.arcane.iris.spi.IrisLogging;
|
||||
import art.arcane.volmlib.util.json.JSONException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import io.sentry.Sentry;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public final class ModdedSentry {
|
||||
private static final String DSN = "http://4cdbb9ac953306529947f4ca1e8e6b26@sentry.volmit.com:8080/2";
|
||||
private static final long FLUSH_TIMEOUT_MS = 2000L;
|
||||
private static final AtomicBoolean STARTED = new AtomicBoolean(false);
|
||||
|
||||
private ModdedSentry() {
|
||||
}
|
||||
|
||||
public static void start(ModdedLoader loader) {
|
||||
IrisSettings.IrisSettingsSentry settings = IrisSettings.get().getSentry();
|
||||
if (settings.disableAutoReporting || Sentry.isEnabled() || Boolean.getBoolean("iris.suppressReporting")) {
|
||||
return;
|
||||
}
|
||||
if (!STARTED.compareAndSet(false, true)) {
|
||||
return;
|
||||
}
|
||||
IrisLogging.info("Enabling Sentry for anonymous error reporting. You can disable this in the settings.");
|
||||
Sentry.init(options -> {
|
||||
options.setDsn(DSN);
|
||||
if (settings.debug) {
|
||||
options.setDebug(true);
|
||||
}
|
||||
options.setAttachServerName(false);
|
||||
options.setEnableUncaughtExceptionHandler(false);
|
||||
options.setRelease(loader.modVersion());
|
||||
options.setEnvironment(BuildConstants.ENVIRONMENT);
|
||||
options.setBeforeSend((event, hint) -> suppress(event.getThrowable()) ? null : event);
|
||||
});
|
||||
Sentry.configureScope(scope -> {
|
||||
scope.setTag("server", loader.platformName());
|
||||
scope.setTag("server.mc", loader.minecraftVersion());
|
||||
scope.setTag("iris.loader", loader.platformName());
|
||||
scope.setTag("iris.commit", BuildConstants.COMMIT);
|
||||
});
|
||||
ModdedPlatform.captureSink(Sentry::captureException);
|
||||
}
|
||||
|
||||
public static void flush() {
|
||||
if (Sentry.isEnabled()) {
|
||||
Sentry.flush(FLUSH_TIMEOUT_MS);
|
||||
Sentry.close();
|
||||
}
|
||||
ModdedPlatform.captureSink(null);
|
||||
STARTED.set(false);
|
||||
}
|
||||
|
||||
private static boolean suppress(Throwable error) {
|
||||
return (error instanceof IllegalStateException state && "zip file closed".equals(state.getMessage()))
|
||||
|| error instanceof JSONException
|
||||
|| error instanceof JsonSyntaxException;
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,8 @@ public interface ModdedServerAccess {
|
||||
|
||||
LevelStorageSource.LevelStorageAccess levelStorage(MinecraftServer server);
|
||||
|
||||
void initializeLevelData(MinecraftServer server, ServerLevel level);
|
||||
|
||||
ServerLevel putLevel(MinecraftServer server, ResourceKey<Level> key, ServerLevel level);
|
||||
|
||||
ServerLevel putLevelIfAbsent(MinecraftServer server, ResourceKey<Level> key, ServerLevel level);
|
||||
|
||||
+150
-2
@@ -23,7 +23,11 @@ import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import net.minecraft.world.level.storage.PrimaryLevelData;
|
||||
import net.minecraft.world.level.storage.WorldData;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@@ -34,6 +38,18 @@ import java.util.function.Consumer;
|
||||
|
||||
public final class ModdedServerLevels implements ModdedServerAccess {
|
||||
private static final int CAPTURE_ATTEMPTS = 16;
|
||||
private static final ClassValue<HostLevelPublication> HOST_LEVEL_PUBLICATIONS = new ClassValue<>() {
|
||||
@Override
|
||||
protected HostLevelPublication computeValue(Class<?> type) {
|
||||
return HostLevelPublication.detect(type, ServerLevel.class);
|
||||
}
|
||||
};
|
||||
private static final ClassValue<HostLevelDataAttachment> HOST_LEVEL_DATA_ATTACHMENTS = new ClassValue<>() {
|
||||
@Override
|
||||
protected HostLevelDataAttachment computeValue(Class<?> type) {
|
||||
return HostLevelDataAttachment.detect(type, PrimaryLevelData.class, ResourceKey.class);
|
||||
}
|
||||
};
|
||||
private static volatile Snapshot snapshot;
|
||||
|
||||
private final Consumer<MinecraftServer> levelCacheInvalidator;
|
||||
@@ -43,8 +59,8 @@ public final class ModdedServerLevels implements ModdedServerAccess {
|
||||
}
|
||||
|
||||
/**
|
||||
* Immutable view of the loaded levels. {@code server.levels} is a plain map mutated on the server
|
||||
* thread, so every off-server-thread reader must iterate this snapshot instead of
|
||||
* Immutable view of the loaded levels. {@code server.levels} is loader-owned and published on the
|
||||
* server thread, so every off-server-thread reader must iterate this snapshot instead of
|
||||
* {@code server.getAllLevels()} to avoid ConcurrentModificationException.
|
||||
*/
|
||||
public static List<ServerLevel> levels(MinecraftServer server) {
|
||||
@@ -137,8 +153,32 @@ public final class ModdedServerLevels implements ModdedServerAccess {
|
||||
return server.storageSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeLevelData(MinecraftServer server, ServerLevel level) {
|
||||
Object levelData = level.getLevelData();
|
||||
HostLevelDataAttachment attachment = HOST_LEVEL_DATA_ATTACHMENTS.get(levelData.getClass());
|
||||
if (!attachment.supported()) {
|
||||
return;
|
||||
}
|
||||
WorldData worldData = server.getWorldData();
|
||||
if (!(worldData instanceof PrimaryLevelData rootData)) {
|
||||
throw new IllegalStateException("Host level data attachment requires PrimaryLevelData, found "
|
||||
+ worldData.getClass().getName());
|
||||
}
|
||||
attachment.attach(levelData, rootData, level.dimension());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerLevel putLevel(MinecraftServer server, ResourceKey<Level> key, ServerLevel level) {
|
||||
HostLevelPublication hostPublication = HOST_LEVEL_PUBLICATIONS.get(server.getClass());
|
||||
if (hostPublication.supported()) {
|
||||
ServerLevel previous = server.levels.get(key);
|
||||
if (previous != level) {
|
||||
hostPublication.add(server, level);
|
||||
capture(server);
|
||||
}
|
||||
return previous;
|
||||
}
|
||||
ServerLevel previous = server.levels.put(key, level);
|
||||
if (previous != level) {
|
||||
capture(server);
|
||||
@@ -149,6 +189,15 @@ public final class ModdedServerLevels implements ModdedServerAccess {
|
||||
|
||||
@Override
|
||||
public ServerLevel putLevelIfAbsent(MinecraftServer server, ResourceKey<Level> key, ServerLevel level) {
|
||||
HostLevelPublication hostPublication = HOST_LEVEL_PUBLICATIONS.get(server.getClass());
|
||||
if (hostPublication.supported()) {
|
||||
ServerLevel previous = server.levels.get(key);
|
||||
if (previous == null) {
|
||||
hostPublication.add(server, level);
|
||||
capture(server);
|
||||
}
|
||||
return previous;
|
||||
}
|
||||
ServerLevel previous = server.levels.putIfAbsent(key, level);
|
||||
if (previous == null) {
|
||||
capture(server);
|
||||
@@ -159,6 +208,15 @@ public final class ModdedServerLevels implements ModdedServerAccess {
|
||||
|
||||
@Override
|
||||
public ServerLevel removeLevel(MinecraftServer server, ResourceKey<Level> key) {
|
||||
HostLevelPublication hostPublication = HOST_LEVEL_PUBLICATIONS.get(server.getClass());
|
||||
if (hostPublication.supported()) {
|
||||
ServerLevel removed = server.levels.get(key);
|
||||
if (removed != null) {
|
||||
hostPublication.remove(server, removed);
|
||||
capture(server);
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
ServerLevel removed = server.levels.remove(key);
|
||||
if (removed != null) {
|
||||
capture(server);
|
||||
@@ -175,4 +233,94 @@ public final class ModdedServerLevels implements ModdedServerAccess {
|
||||
private record Snapshot(MinecraftServer server, List<ServerLevel> levels,
|
||||
Map<ResourceKey<Level>, ServerLevel> byKey) {
|
||||
}
|
||||
|
||||
static final class HostLevelPublication {
|
||||
private final Method addLevel;
|
||||
private final Method removeLevel;
|
||||
|
||||
private HostLevelPublication(Method addLevel, Method removeLevel) {
|
||||
this.addLevel = addLevel;
|
||||
this.removeLevel = removeLevel;
|
||||
}
|
||||
|
||||
static HostLevelPublication detect(Class<?> serverType, Class<?> levelType) {
|
||||
try {
|
||||
Method addLevel = serverType.getMethod("addLevel", levelType);
|
||||
Method removeLevel = serverType.getMethod("removeLevel", levelType);
|
||||
return new HostLevelPublication(addLevel, removeLevel);
|
||||
} catch (NoSuchMethodException e) {
|
||||
return new HostLevelPublication(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
boolean supported() {
|
||||
return addLevel != null && removeLevel != null;
|
||||
}
|
||||
|
||||
void add(Object server, Object level) {
|
||||
invoke(addLevel, server, level);
|
||||
}
|
||||
|
||||
void remove(Object server, Object level) {
|
||||
invoke(removeLevel, server, level);
|
||||
}
|
||||
|
||||
private void invoke(Method method, Object server, Object level) {
|
||||
try {
|
||||
method.invoke(server, level);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException("Iris cannot access host level publication method "
|
||||
+ method.getName(), e);
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof RuntimeException runtimeException) {
|
||||
throw runtimeException;
|
||||
}
|
||||
if (cause instanceof Error fatalError) {
|
||||
throw fatalError;
|
||||
}
|
||||
throw new IllegalStateException("Host level publication method " + method.getName()
|
||||
+ " failed", cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static final class HostLevelDataAttachment {
|
||||
private final Method attach;
|
||||
|
||||
private HostLevelDataAttachment(Method attach) {
|
||||
this.attach = attach;
|
||||
}
|
||||
|
||||
static HostLevelDataAttachment detect(Class<?> levelDataType, Class<?> rootDataType,
|
||||
Class<?> dimensionKeyType) {
|
||||
try {
|
||||
return new HostLevelDataAttachment(levelDataType.getMethod(
|
||||
"attach", rootDataType, dimensionKeyType));
|
||||
} catch (NoSuchMethodException e) {
|
||||
return new HostLevelDataAttachment(null);
|
||||
}
|
||||
}
|
||||
|
||||
boolean supported() {
|
||||
return attach != null;
|
||||
}
|
||||
|
||||
void attach(Object levelData, Object rootData, Object dimensionKey) {
|
||||
try {
|
||||
attach.invoke(levelData, rootData, dimensionKey);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException("Iris cannot access host level data attachment method", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof RuntimeException runtimeException) {
|
||||
throw runtimeException;
|
||||
}
|
||||
if (cause instanceof Error fatalError) {
|
||||
throw fatalError;
|
||||
}
|
||||
throw new IllegalStateException("Host level data attachment failed", cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -87,7 +87,7 @@ final class ModdedCommandHelp {
|
||||
Entry.group("datapack", ModdedHelpMessages.GROUP_DATAPACK_WORLD_DATAPACK_INSTALL_AND_STATUS_HELPERS, "datapacks", "dp"),
|
||||
Entry.group("structure", ModdedHelpMessages.GROUP_STRUCTURE_IRIS_STRUCTURE_INDEX_INFO_AND_PLACEMENT_TOOLS, "struct", "str"),
|
||||
Entry.command("goldenhash", "[radius] [threads] [capture|verify]", ModdedHelpMessages.COMMAND_GOLDENHASH_GENERATE_DETERMINISTIC_BLOCK_HASHES_FOR_PARITY_TESTING, "gold"),
|
||||
Entry.group("developer", ModdedHelpMessages.GROUP_DEVELOPER_DEVELOPER_DIAGNOSTICS_SENTRY_TEST_NETWORK_INTERFACES_REGION_FILE_SCAN, "dev")
|
||||
Entry.group("developer", ModdedHelpMessages.GROUP_DEVELOPER_DEVELOPER_DIAGNOSTICS_NETWORK_INTERFACES_REGION_FILE_SCAN, "dev")
|
||||
));
|
||||
SECTIONS.put("what", List.of(
|
||||
Entry.command("here", "", ModdedHelpMessages.COMMAND_WHAT_HERE_INSPECT_CURRENT_IRIS_CONTEXT),
|
||||
@@ -197,7 +197,6 @@ final class ModdedCommandHelp {
|
||||
SECTIONS.put("struct", SECTIONS.get("structure"));
|
||||
SECTIONS.put("str", SECTIONS.get("structure"));
|
||||
SECTIONS.put("developer", List.of(
|
||||
Entry.command("sentry", "", ModdedHelpMessages.COMMAND_SENTRY_SEND_A_TEST_EXCEPTION_TO_THE_IRIS_ERROR_REPORTER),
|
||||
Entry.command("network", "", ModdedHelpMessages.COMMAND_NETWORK_LIST_NETWORK_INTERFACES_AND_THEIR_ADDRESSES, "ip")
|
||||
));
|
||||
SECTIONS.put("dev", SECTIONS.get("developer"));
|
||||
|
||||
-9
@@ -19,7 +19,6 @@
|
||||
package art.arcane.iris.modded.command;
|
||||
|
||||
import art.arcane.iris.modded.ModdedIrisLog;
|
||||
import art.arcane.iris.spi.IrisPlatforms;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
@@ -44,20 +43,12 @@ final class ModdedDeveloperCommands {
|
||||
static LiteralArgumentBuilder<CommandSourceStack> tree(String name) {
|
||||
return Commands.literal(name).requires(GATE)
|
||||
.executes((CommandContext<CommandSourceStack> context) -> ModdedCommandHelp.send(context.getSource(), "developer"))
|
||||
.then(Commands.literal("sentry")
|
||||
.executes((CommandContext<CommandSourceStack> context) -> sentry(context.getSource())))
|
||||
.then(Commands.literal("network")
|
||||
.executes((CommandContext<CommandSourceStack> context) -> network(context.getSource())))
|
||||
.then(Commands.literal("ip")
|
||||
.executes((CommandContext<CommandSourceStack> context) -> network(context.getSource())));
|
||||
}
|
||||
|
||||
private static int sentry(CommandSourceStack source) {
|
||||
IrisPlatforms.get().reportError(new Exception("This is an Iris Sentry test exception"));
|
||||
ModdedCommandFeedback.ok(source, IrisLanguage.plain(ModdedCommandMessages.MODDED_DEVELOPER_COMMANDS_DISPATCHED_TEST_EXCEPTION_IRIS_ERROR_REPORTER_SENTRY_IF_ENABLED));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int network(CommandSourceStack source) {
|
||||
try {
|
||||
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
|
||||
|
||||
Reference in new issue
Block a user