Don't inject world load context for main worlds to prevent incompatibilities

This commit is contained in:
Julian Krings 2025-04-08 21:15:19 +02:00
parent 74e2576ca2
commit 71078a20a9
No known key found for this signature in database
GPG Key ID: 208C6E08C3B718D2
11 changed files with 192 additions and 335 deletions

View File

@ -132,7 +132,9 @@ public interface INMSBinding {
AutoClosing injectLevelStems();
Pair<Integer, AutoClosing> injectUncached(boolean overworld, boolean nether, boolean end);
default AutoClosing injectUncached(boolean overworld, boolean nether, boolean end) {
return null;
}
boolean missingDimensionTypes(boolean overworld, boolean nether, boolean end);

View File

@ -126,8 +126,8 @@ public class NMSBinding1X implements INMSBinding {
}
@Override
public Pair<Integer, AutoClosing> injectUncached(boolean overworld, boolean nether, boolean end) {
return new Pair<>(0, new AutoClosing(() -> {}));
public AutoClosing injectUncached(boolean overworld, boolean nether, boolean end) {
return injectLevelStems();
}
@Override

View File

@ -2,12 +2,15 @@ package com.volmit.iris.engine.object;
import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.core.nms.container.AutoClosing;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.misc.ServerProperties;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldInitEvent;
@ -19,14 +22,9 @@ public class IrisContextInjector implements Listener {
@Getter
private static boolean missingDimensionTypes = false;
private AutoClosing autoClosing = null;
private final int totalWorlds;
private int worldCounter = 0;
public IrisContextInjector() {
if (!Bukkit.getWorlds().isEmpty()) {
totalWorlds = 0;
return;
}
if (!Bukkit.getWorlds().isEmpty()) return;
String levelName = ServerProperties.LEVEL_NAME;
List<String> irisWorlds = irisWorlds();
@ -34,29 +32,20 @@ public class IrisContextInjector implements Listener {
boolean nether = irisWorlds.contains(levelName + "_nether");
boolean end = irisWorlds.contains(levelName + "_end");
int i = 1;
if (Bukkit.getAllowNether()) i++;
if (Bukkit.getAllowEnd()) i++;
if (INMS.get().missingDimensionTypes(overworld, nether, end)) {
missingDimensionTypes = true;
totalWorlds = 0;
return;
}
if (overworld || nether || end) {
var pair = INMS.get().injectUncached(overworld, nether, end);
i += pair.getA() - 3;
autoClosing = pair.getB();
autoClosing = INMS.get().injectUncached(overworld, nether, end);
}
totalWorlds = i;
instance.registerListener(this);
}
@EventHandler
@EventHandler(priority = EventPriority.LOWEST)
public void on(WorldInitEvent event) {
if (++worldCounter < totalWorlds) return;
if (autoClosing != null) {
autoClosing.close();
autoClosing = null;

View File

@ -26,6 +26,8 @@ import com.volmit.iris.util.math.RNG;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collector;
import java.util.stream.Collectors;
@SuppressWarnings("ALL")
public class KList<T> extends ArrayList<T> implements List<T> {
@ -65,6 +67,10 @@ public class KList<T> extends ArrayList<T> implements List<T> {
return s;
}
public static <T> Collector<T, ?, KList<T>> collector() {
return Collectors.toCollection(KList::new);
}
public static KList<String> asStringList(List<?> oo) {
KList<String> s = new KList<String>();

View File

@ -645,37 +645,44 @@ public class NMSBinding implements INMSBinding {
}
@Override
@SneakyThrows
public AutoClosing injectLevelStems() {
return inject(this::supplier);
if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!");
var server = ((CraftServer) Bukkit.getServer());
var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class);
var nmsServer = server.getServer();
var old = nmsServer.worldLoader;
field.setAccessible(true);
field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), false, true, true, true)
)));
return new AutoClosing(() -> {
field.set(nmsServer, old);
dataContextLock.unlock();
});
}
@Override
@SneakyThrows
public com.volmit.iris.core.nms.container.Pair<Integer, AutoClosing> injectUncached(boolean overworld, boolean nether, boolean end) {
public AutoClosing injectUncached(boolean overworld, boolean nether, boolean end) {
var reg = registry();
var field = getField(RegistryAccess.ImmutableRegistryAccess.class, Map.class);
field.setAccessible(true);
AutoClosing closing = inject(old -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), true, overworld, nether, end)
)
);
var injected = ((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions().registryOrThrow(Registries.LEVEL_STEM);
var access = createRegistryAccess(((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions(), true, overworld, nether, end);
var injected = access.registryOrThrow(Registries.LEVEL_STEM);
var old = (Map<ResourceKey<? extends Registry<?>>, Registry<?>>) field.get(reg);
var fake = new HashMap<>(old);
fake.put(Registries.LEVEL_STEM, injected);
field.set(reg, fake);
return new com.volmit.iris.core.nms.container.Pair<>(
injected.size(),
new AutoClosing(() -> {
closing.close();
field.set(reg, old);
}));
return new AutoClosing(() -> field.set(reg, old));
}
@Override
@ -692,33 +699,6 @@ public class NMSBinding implements INMSBinding {
((CraftWorld) world).getHandle().K.customDimensions = null;
}
private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) {
return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), false, true, true, true)
));
}
@SneakyThrows
private AutoClosing inject(Function<WorldLoader.DataLoadContext, WorldLoader.DataLoadContext> transformer) {
if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!");
var server = ((CraftServer) Bukkit.getServer());
var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class);
var nmsServer = server.getServer();
var old = nmsServer.worldLoader;
field.setAccessible(true);
field.set(nmsServer, transformer.apply(old));
return new AutoClosing(() -> {
field.set(nmsServer, old);
dataContextLock.unlock();
});
}
private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) {
var access = registry();
var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE);
@ -740,7 +720,7 @@ public class NMSBinding implements INMSBinding {
if (copy) copy(fake, access.registryOrThrow(Registries.LEVEL_STEM));
return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze();
return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake)).freeze();
}
private void register(MappedRegistry<LevelStem> target, Registry<DimensionType> dimensions, FlatLevelSource source, ResourceKey<LevelStem> key) {

View File

@ -646,37 +646,44 @@ public class NMSBinding implements INMSBinding {
}
@Override
@SneakyThrows
public AutoClosing injectLevelStems() {
return inject(this::supplier);
if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!");
var server = ((CraftServer) Bukkit.getServer());
var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class);
var nmsServer = server.getServer();
var old = nmsServer.worldLoader;
field.setAccessible(true);
field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), false, true, true, true)
)));
return new AutoClosing(() -> {
field.set(nmsServer, old);
dataContextLock.unlock();
});
}
@Override
@SneakyThrows
public com.volmit.iris.core.nms.container.Pair<Integer, AutoClosing> injectUncached(boolean overworld, boolean nether, boolean end) {
public AutoClosing injectUncached(boolean overworld, boolean nether, boolean end) {
var reg = registry();
var field = getField(RegistryAccess.ImmutableRegistryAccess.class, Map.class);
field.setAccessible(true);
AutoClosing closing = inject(old -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), true, overworld, nether, end)
)
);
var injected = ((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions().registryOrThrow(Registries.LEVEL_STEM);
var access = createRegistryAccess(((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions(), true, overworld, nether, end);
var injected = access.registryOrThrow(Registries.LEVEL_STEM);
var old = (Map<ResourceKey<? extends Registry<?>>, Registry<?>>) field.get(reg);
var fake = new HashMap<>(old);
fake.put(Registries.LEVEL_STEM, injected);
field.set(reg, fake);
return new com.volmit.iris.core.nms.container.Pair<>(
injected.size(),
new AutoClosing(() -> {
closing.close();
field.set(reg, old);
}));
return new AutoClosing(() -> field.set(reg, old));
}
@Override
@ -693,33 +700,6 @@ public class NMSBinding implements INMSBinding {
((CraftWorld) world).getHandle().K.customDimensions = null;
}
private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) {
return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), false, true, true, true)
));
}
@SneakyThrows
private AutoClosing inject(Function<WorldLoader.DataLoadContext, WorldLoader.DataLoadContext> transformer) {
if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!");
var server = ((CraftServer) Bukkit.getServer());
var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class);
var nmsServer = server.getServer();
var old = nmsServer.worldLoader;
field.setAccessible(true);
field.set(nmsServer, transformer.apply(old));
return new AutoClosing(() -> {
field.set(nmsServer, old);
dataContextLock.unlock();
});
}
private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) {
var access = registry();
var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE);
@ -741,7 +721,7 @@ public class NMSBinding implements INMSBinding {
if (copy) copy(fake, access.registryOrThrow(Registries.LEVEL_STEM));
return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze();
return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake)).freeze();
}
private void register(MappedRegistry<LevelStem> target, Registry<DimensionType> dimensions, FlatLevelSource source, ResourceKey<LevelStem> key) {

View File

@ -647,37 +647,44 @@ public class NMSBinding implements INMSBinding {
}
@Override
@SneakyThrows
public AutoClosing injectLevelStems() {
return inject(this::supplier);
if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!");
var server = ((CraftServer) Bukkit.getServer());
var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class);
var nmsServer = server.getServer();
var old = nmsServer.worldLoader;
field.setAccessible(true);
field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), false, true, true, true)
)));
return new AutoClosing(() -> {
field.set(nmsServer, old);
dataContextLock.unlock();
});
}
@Override
@SneakyThrows
public com.volmit.iris.core.nms.container.Pair<Integer, AutoClosing> injectUncached(boolean overworld, boolean nether, boolean end) {
public AutoClosing injectUncached(boolean overworld, boolean nether, boolean end) {
var reg = registry();
var field = getField(RegistryAccess.ImmutableRegistryAccess.class, Map.class);
field.setAccessible(true);
AutoClosing closing = inject(old -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), true, overworld, nether, end)
)
);
var injected = ((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions().registryOrThrow(Registries.LEVEL_STEM);
var access = createRegistryAccess(((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions(), true, overworld, nether, end);
var injected = access.registryOrThrow(Registries.LEVEL_STEM);
var old = (Map<ResourceKey<? extends Registry<?>>, Registry<?>>) field.get(reg);
var fake = new HashMap<>(old);
fake.put(Registries.LEVEL_STEM, injected);
field.set(reg, fake);
return new com.volmit.iris.core.nms.container.Pair<>(
injected.size(),
new AutoClosing(() -> {
closing.close();
field.set(reg, old);
}));
return new AutoClosing(() -> field.set(reg, old));
}
@Override
@ -694,33 +701,6 @@ public class NMSBinding implements INMSBinding {
((CraftWorld) world).getHandle().K.customDimensions = null;
}
private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) {
return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), false, true, true, true)
));
}
@SneakyThrows
private AutoClosing inject(Function<WorldLoader.DataLoadContext, WorldLoader.DataLoadContext> transformer) {
if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!");
var server = ((CraftServer) Bukkit.getServer());
var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class);
var nmsServer = server.getServer();
var old = nmsServer.worldLoader;
field.setAccessible(true);
field.set(nmsServer, transformer.apply(old));
return new AutoClosing(() -> {
field.set(nmsServer, old);
dataContextLock.unlock();
});
}
private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) {
var access = registry();
var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE);
@ -742,7 +722,7 @@ public class NMSBinding implements INMSBinding {
if (copy) copy(fake, access.registryOrThrow(Registries.LEVEL_STEM));
return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze();
return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake)).freeze();
}
private void register(MappedRegistry<LevelStem> target, Registry<DimensionType> dimensions, FlatLevelSource source, ResourceKey<LevelStem> key) {

View File

@ -672,37 +672,44 @@ public class NMSBinding implements INMSBinding {
}
@Override
@SneakyThrows
public AutoClosing injectLevelStems() {
return inject(this::supplier);
if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!");
var server = ((CraftServer) Bukkit.getServer());
var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class);
var nmsServer = server.getServer();
var old = nmsServer.worldLoader;
field.setAccessible(true);
field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), false, true, true, true)
)));
return new AutoClosing(() -> {
field.set(nmsServer, old);
dataContextLock.unlock();
});
}
@Override
@SneakyThrows
public com.volmit.iris.core.nms.container.Pair<Integer, AutoClosing> injectUncached(boolean overworld, boolean nether, boolean end) {
public AutoClosing injectUncached(boolean overworld, boolean nether, boolean end) {
var reg = registry();
var field = getField(RegistryAccess.ImmutableRegistryAccess.class, Map.class);
field.setAccessible(true);
AutoClosing closing = inject(old -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), true, overworld, nether, end)
)
);
var injected = ((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions().registryOrThrow(Registries.LEVEL_STEM);
var access = createRegistryAccess(((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions(), true, overworld, nether, end);
var injected = access.registryOrThrow(Registries.LEVEL_STEM);
var old = (Map<ResourceKey<? extends Registry<?>>, Registry<?>>) field.get(reg);
var fake = new HashMap<>(old);
fake.put(Registries.LEVEL_STEM, injected);
field.set(reg, fake);
return new com.volmit.iris.core.nms.container.Pair<>(
injected.size(),
new AutoClosing(() -> {
closing.close();
field.set(reg, old);
}));
return new AutoClosing(() -> field.set(reg, old));
}
@Override
@ -719,33 +726,6 @@ public class NMSBinding implements INMSBinding {
((CraftWorld) world).getHandle().K.customDimensions = null;
}
private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) {
return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), false, true, true, true)
));
}
@SneakyThrows
private AutoClosing inject(Function<WorldLoader.DataLoadContext, WorldLoader.DataLoadContext> transformer) {
if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!");
var server = ((CraftServer) Bukkit.getServer());
var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class);
var nmsServer = server.getServer();
var old = nmsServer.worldLoader;
field.setAccessible(true);
field.set(nmsServer, transformer.apply(old));
return new AutoClosing(() -> {
field.set(nmsServer, old);
dataContextLock.unlock();
});
}
private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) {
var access = registry();
var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE);
@ -767,7 +747,7 @@ public class NMSBinding implements INMSBinding {
if (copy) copy(fake, access.registryOrThrow(Registries.LEVEL_STEM));
return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze();
return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake)).freeze();
}
private void register(MappedRegistry<LevelStem> target, Registry<DimensionType> dimensions, FlatLevelSource source, ResourceKey<LevelStem> key) {

View File

@ -676,37 +676,44 @@ public class NMSBinding implements INMSBinding {
}
@Override
@SneakyThrows
public AutoClosing injectLevelStems() {
return inject(this::supplier);
if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!");
var server = ((CraftServer) Bukkit.getServer());
var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class);
var nmsServer = server.getServer();
var old = nmsServer.worldLoader;
field.setAccessible(true);
field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), false, true, true, true)
)));
return new AutoClosing(() -> {
field.set(nmsServer, old);
dataContextLock.unlock();
});
}
@Override
@SneakyThrows
public com.volmit.iris.core.nms.container.Pair<Integer, AutoClosing> injectUncached(boolean overworld, boolean nether, boolean end) {
public AutoClosing injectUncached(boolean overworld, boolean nether, boolean end) {
var reg = registry();
var field = getField(RegistryAccess.ImmutableRegistryAccess.class, Map.class);
field.setAccessible(true);
AutoClosing closing = inject(old -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), true, overworld, nether, end)
)
);
var injected = ((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions().registryOrThrow(Registries.LEVEL_STEM);
var access = createRegistryAccess(((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions(), true, overworld, nether, end);
var injected = access.registryOrThrow(Registries.LEVEL_STEM);
var old = (Map<ResourceKey<? extends Registry<?>>, Registry<?>>) field.get(reg);
var fake = new HashMap<>(old);
fake.put(Registries.LEVEL_STEM, injected);
field.set(reg, fake);
return new com.volmit.iris.core.nms.container.Pair<>(
injected.size(),
new AutoClosing(() -> {
closing.close();
field.set(reg, old);
}));
return new AutoClosing(() -> field.set(reg, old));
}
@Override
@ -723,33 +730,6 @@ public class NMSBinding implements INMSBinding {
((CraftWorld) world).getHandle().K.customDimensions = null;
}
private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) {
return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), false, true, true, true)
));
}
@SneakyThrows
private AutoClosing inject(Function<WorldLoader.DataLoadContext, WorldLoader.DataLoadContext> transformer) {
if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!");
var server = ((CraftServer) Bukkit.getServer());
var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class);
var nmsServer = server.getServer();
var old = nmsServer.worldLoader;
field.setAccessible(true);
field.set(nmsServer, transformer.apply(old));
return new AutoClosing(() -> {
field.set(nmsServer, old);
dataContextLock.unlock();
});
}
private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) {
var access = registry();
var dimensions = access.registryOrThrow(Registries.DIMENSION_TYPE);
@ -771,7 +751,7 @@ public class NMSBinding implements INMSBinding {
if (copy) copy(fake, access.registryOrThrow(Registries.LEVEL_STEM));
return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze();
return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake)).freeze();
}
private void register(MappedRegistry<LevelStem> target, Registry<DimensionType> dimensions, FlatLevelSource source, ResourceKey<LevelStem> key) {

View File

@ -666,37 +666,44 @@ public class NMSBinding implements INMSBinding {
}
@Override
@SneakyThrows
public AutoClosing injectLevelStems() {
return inject(this::supplier);
if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!");
var server = ((CraftServer) Bukkit.getServer());
var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class);
var nmsServer = server.getServer();
var old = nmsServer.worldLoader;
field.setAccessible(true);
field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), false, true, true, true)
)));
return new AutoClosing(() -> {
field.set(nmsServer, old);
dataContextLock.unlock();
});
}
@Override
@SneakyThrows
public Pair<Integer, AutoClosing> injectUncached(boolean overworld, boolean nether, boolean end) {
public AutoClosing injectUncached(boolean overworld, boolean nether, boolean end) {
var reg = registry();
var field = getField(RegistryAccess.ImmutableRegistryAccess.class, Map.class);
field.setAccessible(true);
AutoClosing closing = inject(old -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), true, overworld, nether, end)
)
);
var injected = ((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions().lookupOrThrow(Registries.LEVEL_STEM);
var access = createRegistryAccess(((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions(), true, overworld, nether, end);
var injected = access.lookupOrThrow(Registries.LEVEL_STEM);
var old = (Map<ResourceKey<? extends Registry<?>>, Registry<?>>) field.get(reg);
var fake = new HashMap<>(old);
fake.put(Registries.LEVEL_STEM, injected);
field.set(reg, fake);
return new Pair<>(
injected.size(),
new AutoClosing(() -> {
closing.close();
field.set(reg, old);
}));
return new AutoClosing(() -> field.set(reg, old));
}
@Override
@ -713,33 +720,6 @@ public class NMSBinding implements INMSBinding {
((CraftWorld) world).getHandle().L.customDimensions = null;
}
private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) {
return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), false, true, true, true)
));
}
@SneakyThrows
private AutoClosing inject(Function<WorldLoader.DataLoadContext, WorldLoader.DataLoadContext> transformer) {
if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!");
var server = ((CraftServer) Bukkit.getServer());
var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class);
var nmsServer = server.getServer();
var old = nmsServer.worldLoader;
field.setAccessible(true);
field.set(nmsServer, transformer.apply(old));
return new AutoClosing(() -> {
field.set(nmsServer, old);
dataContextLock.unlock();
});
}
private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) {
var access = registry();
var dimensions = access.lookupOrThrow(Registries.DIMENSION_TYPE);
@ -761,7 +741,7 @@ public class NMSBinding implements INMSBinding {
if (copy) copy(fake, access.lookupOrThrow(Registries.LEVEL_STEM));
return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze();
return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake)).freeze();
}
private void register(MappedRegistry<LevelStem> target, Registry<DimensionType> dimensions, FlatLevelSource source, ResourceKey<LevelStem> key) {

View File

@ -665,37 +665,44 @@ public class NMSBinding implements INMSBinding {
}
@Override
@SneakyThrows
public AutoClosing injectLevelStems() {
return inject(this::supplier);
if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!");
var server = ((CraftServer) Bukkit.getServer());
var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class);
var nmsServer = server.getServer();
var old = nmsServer.worldLoader;
field.setAccessible(true);
field.set(nmsServer, dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), false, true, true, true)
)));
return new AutoClosing(() -> {
field.set(nmsServer, old);
dataContextLock.unlock();
});
}
@Override
@SneakyThrows
public Pair<Integer, AutoClosing> injectUncached(boolean overworld, boolean nether, boolean end) {
public AutoClosing injectUncached(boolean overworld, boolean nether, boolean end) {
var reg = registry();
var field = getField(RegistryAccess.ImmutableRegistryAccess.class, Map.class);
field.setAccessible(true);
AutoClosing closing = inject(old -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), true, overworld, nether, end)
)
);
var injected = ((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions().lookupOrThrow(Registries.LEVEL_STEM);
var access = createRegistryAccess(((CraftServer) Bukkit.getServer()).getServer().worldLoader.datapackDimensions(), true, overworld, nether, end);
var injected = access.lookupOrThrow(Registries.LEVEL_STEM);
var old = (Map<ResourceKey<? extends Registry<?>>, Registry<?>>) field.get(reg);
var fake = new HashMap<>(old);
fake.put(Registries.LEVEL_STEM, injected);
field.set(reg, fake);
return new Pair<>(
injected.size(),
new AutoClosing(() -> {
closing.close();
field.set(reg, old);
}));
return new AutoClosing(() -> field.set(reg, old));
}
@Override
@ -712,33 +719,6 @@ public class NMSBinding implements INMSBinding {
((CraftWorld) world).getHandle().L.customDimensions = null;
}
private WorldLoader.DataLoadContext supplier(WorldLoader.DataLoadContext old) {
return dataLoadContext.aquire(() -> new WorldLoader.DataLoadContext(
old.resources(),
old.dataConfiguration(),
old.datapackWorldgen(),
createRegistryAccess(old.datapackDimensions(), false, true, true, true)
));
}
@SneakyThrows
private AutoClosing inject(Function<WorldLoader.DataLoadContext, WorldLoader.DataLoadContext> transformer) {
if (!dataContextLock.tryLock()) throw new IllegalStateException("Failed to inject data context!");
var server = ((CraftServer) Bukkit.getServer());
var field = getField(MinecraftServer.class, WorldLoader.DataLoadContext.class);
var nmsServer = server.getServer();
var old = nmsServer.worldLoader;
field.setAccessible(true);
field.set(nmsServer, transformer.apply(old));
return new AutoClosing(() -> {
field.set(nmsServer, old);
dataContextLock.unlock();
});
}
private RegistryAccess.Frozen createRegistryAccess(RegistryAccess.Frozen datapack, boolean copy, boolean overworld, boolean nether, boolean end) {
var access = registry();
var dimensions = access.lookupOrThrow(Registries.DIMENSION_TYPE);
@ -760,7 +740,7 @@ public class NMSBinding implements INMSBinding {
if (copy) copy(fake, access.lookupOrThrow(Registries.LEVEL_STEM));
return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake.freeze())).freeze();
return new RegistryAccess.Frozen.ImmutableRegistryAccess(List.of(fake)).freeze();
}
private void register(MappedRegistry<LevelStem> target, Registry<DimensionType> dimensions, FlatLevelSource source, ResourceKey<LevelStem> key) {