diff --git a/docs/scarpet/api/Auxiliary.md b/docs/scarpet/api/Auxiliary.md
index 99ee6b53..d5f027a0 100644
--- a/docs/scarpet/api/Auxiliary.md
+++ b/docs/scarpet/api/Auxiliary.md
@@ -552,7 +552,7 @@ Function example:
script run create_datapack('example',{'data/test/functions/talk.mcfunction'->'say 1\nsay 2'})
-### `enable_hidden_dimensions()`
+### `enable_hidden_dimensions()` (1.18.1 and lower)
The function reads current datapack settings detecting new dimensions defined by these datapacks that have not yet been added
to the list of current dimensions and adds them so that they can be used and accessed right away. It doesn't matter how the
@@ -560,7 +560,8 @@ datapacks have been added to the game, either with `create_datapack()` or manual
`/datapack enable` on it. Returns the list of valid dimension names / identifiers that has been added in the process.
Fine print: The function should be
-considered experimental. There 'should not be' (famous last words) any side-effects if no worlds are added. Already connected
+considered experimental. For example: is not supposed to work at all in vanilla, and its doing exactly that in 1.18.2+.
+There 'should not be' (famous last words) any side-effects if no worlds are added. Already connected
clients will not see suggestions for commands that use dimensions `/execute in ` (vanilla client limitation)
but all commands should work just fine with
the new dimensions. Existing worlds that have gotten modified settings by the datapacks will not be reloaded or replaced.
diff --git a/docs/scarpet/resources/editors/idea/2.txt b/docs/scarpet/resources/editors/idea/2.txt
index 5e0a53fa..906c84da 100644
--- a/docs/scarpet/resources/editors/idea/2.txt
+++ b/docs/scarpet/resources/editors/idea/2.txt
@@ -31,7 +31,6 @@ display_title
draw_shape
drop_item
emitted_light
-enable_hidden_dimensions
encode_nbt
entity_area
entity_event
diff --git a/docs/scarpet/resources/editors/npp/scarpet.xml b/docs/scarpet/resources/editors/npp/scarpet.xml
index cdba07d4..9c63c812 100644
--- a/docs/scarpet/resources/editors/npp/scarpet.xml
+++ b/docs/scarpet/resources/editors/npp/scarpet.xml
@@ -60,7 +60,7 @@
place_item set_biome biome loaded_status generation_status sample_noise inhabited_time spawn_potential chunk_tickets
plop harvest destroy create_explosion
structure_eligibility structures structure_references set_structure
- reset_chunk reload_chunk create_datapack enable_hidden_dimensions
+ reset_chunk reload_chunk create_datapack
add_chunk_ticket
convert_date unix_time
diff --git a/src/main/java/carpet/fakes/MinecraftServerInterface.java b/src/main/java/carpet/fakes/MinecraftServerInterface.java
index 91be09f4..f68a18c9 100644
--- a/src/main/java/carpet/fakes/MinecraftServerInterface.java
+++ b/src/main/java/carpet/fakes/MinecraftServerInterface.java
@@ -6,6 +6,7 @@ import java.util.function.BooleanSupplier;
import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.ResourceKey;
//import net.minecraft.server.ServerResources;
+import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.storage.LevelStorageSource;
@@ -16,4 +17,6 @@ public interface MinecraftServerInterface
LevelStorageSource.LevelStorageAccess getCMSession();
Map, ServerLevel> getCMWorlds();
void reloadAfterReload(RegistryAccess newRegs);
+
+ MinecraftServer.ReloadableResources getResourceManager();
}
diff --git a/src/main/java/carpet/mixins/MinecraftServer_scarpetMixin.java b/src/main/java/carpet/mixins/MinecraftServer_scarpetMixin.java
index ac92aae8..ed5a8eb0 100644
--- a/src/main/java/carpet/mixins/MinecraftServer_scarpetMixin.java
+++ b/src/main/java/carpet/mixins/MinecraftServer_scarpetMixin.java
@@ -107,4 +107,10 @@ public abstract class MinecraftServer_scarpetMixin extends ReentrantBlockableEve
functionManager.replaceLibrary(this.resources.managers().getFunctionLibrary());
structureManager.onResourceManagerReload(this.resources.resourceManager());
}
+
+ @Override
+ public MinecraftServer.ReloadableResources getResourceManager()
+ {
+ return resources;
+ }
}
diff --git a/src/main/java/carpet/script/api/Auxiliary.java b/src/main/java/carpet/script/api/Auxiliary.java
index aaa37b33..124d1f90 100644
--- a/src/main/java/carpet/script/api/Auxiliary.java
+++ b/src/main/java/carpet/script/api/Auxiliary.java
@@ -2,7 +2,6 @@ package carpet.script.api;
import carpet.CarpetServer;
import carpet.fakes.MinecraftServerInterface;
-import carpet.fakes.ServerWorldInterface;
import carpet.fakes.ThreadedAnvilChunkStorageInterface;
import carpet.helpers.FeatureGenerator;
import carpet.logging.HUDController;
@@ -33,22 +32,15 @@ import carpet.script.value.LazyListValue;
import carpet.script.value.ListValue;
import carpet.script.value.MapValue;
import carpet.script.value.NBTSerializableValue;
-import carpet.script.value.NullValue;
import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.script.value.ValueConversions;
import carpet.utils.Messenger;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
-import com.mojang.datafixers.util.Pair;
-import com.mojang.serialization.DynamicOps;
import net.minecraft.SharedConstants;
-import net.minecraft.Util;
import net.minecraft.commands.CommandSourceStack;
-import net.minecraft.commands.Commands;
import net.minecraft.core.BlockPos;
-import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.Rotations;
@@ -69,17 +61,12 @@ import net.minecraft.network.protocol.game.ClientboundSetActionBarTextPacket;
import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket;
import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket;
import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket;
-import net.minecraft.resources.RegistryOps;
-import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
-//import net.minecraft.server.WorldLoader;
-import net.minecraft.server.WorldStem;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.packs.repository.Pack;
import net.minecraft.server.packs.repository.PackRepository;
-import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.sounds.SoundSource;
import net.minecraft.stats.Stat;
import net.minecraft.stats.StatType;
@@ -90,20 +77,10 @@ import net.minecraft.world.entity.decoration.ArmorStand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ChunkPos;
-import net.minecraft.world.level.DataPackConfig;
import net.minecraft.world.level.Level;
-import net.minecraft.world.level.biome.BiomeManager;
import net.minecraft.world.level.block.state.BlockState;
-import net.minecraft.world.level.border.BorderChangeListener;
-import net.minecraft.world.level.chunk.ChunkGenerator;
-import net.minecraft.world.level.dimension.DimensionType;
-import net.minecraft.world.level.dimension.LevelStem;
-import net.minecraft.world.level.levelgen.WorldGenSettings;
import net.minecraft.world.level.storage.CommandStorage;
-import net.minecraft.world.level.storage.DerivedLevelData;
import net.minecraft.world.level.storage.LevelResource;
-import net.minecraft.world.level.storage.LevelStorageSource;
-import net.minecraft.world.level.storage.WorldData;
import net.minecraft.world.phys.Vec3;
import org.apache.commons.io.FileUtils;
@@ -1113,49 +1090,8 @@ public class Auxiliary {
expression.addContextFunction("enable_hidden_dimensions", 0, (c, t, lv) -> {
CarpetContext cc = (CarpetContext)c;
- // from minecraft.server.Main.main
- MinecraftServer server = cc.s.getServer();
- LevelStorageSource.LevelStorageAccess session = ((MinecraftServerInterface)server).getCMSession();
- DataPackConfig dataPackSettings = session.getDataPacks();
- PackRepository resourcePackManager = server.getPackRepository();
-
- WorldStem.InitConfig initConfig = new WorldStem.InitConfig(resourcePackManager, Commands.CommandSelection.DEDICATED, 4, false);
-
-
- final WorldStem data = WorldStem.load(initConfig, () -> {
- DataPackConfig dataPackConfig = session.getDataPacks();
- return dataPackConfig == null ? DataPackConfig.DEFAULT : dataPackConfig;
- },
- (resourceManager, dataPackConfigx) -> {
- RegistryAccess.Writable writable = RegistryAccess.builtinCopy();
- DynamicOps dynamicOps = RegistryOps.createAndLoad(NbtOps.INSTANCE, writable, (ResourceManager) resourceManager);
- WorldData worldData = session.getDataTag(dynamicOps, dataPackConfigx, writable.allElementsLifecycle());
- return Pair.of(worldData, writable.freeze());
- }, Util.backgroundExecutor(), Runnable::run).join();
- WorldGenSettings generatorOptions = data.worldData().worldGenSettings();
-
- boolean bl = generatorOptions.isDebug();
- long l = generatorOptions.seed();
- long m = BiomeManager.obfuscateSeed(l);
- Map, ServerLevel> existing_worlds = ((MinecraftServerInterface)server).getCMWorlds();
- List addeds = new ArrayList<>();
- for (Map.Entry, LevelStem> entry : generatorOptions.dimensions().entrySet()) {
- ResourceKey registryKey = entry.getKey();
- if (!existing_worlds.containsKey(registryKey))
- {
- ResourceKey resourceKey2 = ResourceKey.create(Registry.DIMENSION_REGISTRY, registryKey.location());
- DerivedLevelData derivedLevelData = new DerivedLevelData(data.worldData(), ((ServerWorldInterface) server.overworld()).getWorldPropertiesCM());
- ChunkGenerator chunkGenerator2 = ((LevelStem)entry.getValue()).generator();
- Holder holder2 = ((LevelStem)entry.getValue()).typeHolder();
- ServerLevel serverLevel2 = new ServerLevel(server, Util.backgroundExecutor(), session, derivedLevelData, resourceKey2,
- holder2, WorldTools.NOOP_LISTENER,chunkGenerator2, bl, m, ImmutableList.of(), false);
- server.overworld().getWorldBorder().addListener(new BorderChangeListener.DelegateBorderChangeListener(serverLevel2.getWorldBorder()));
- existing_worlds.put(resourceKey2, serverLevel2);
- addeds.add(ValueConversions.of(registryKey.location()));
- }
- }
- ((MinecraftServerInterface)server).reloadAfterReload(data.registryAccess());
- return ListValue.wrap(addeds);
+ cc.host.issueDeprecation("enable_hidden_dimensions in 1.18.2 and 1.19");
+ return Value.NULL;
});
}
diff --git a/src/main/java/carpet/script/utils/Experimental.java b/src/main/java/carpet/script/utils/Experimental.java
new file mode 100644
index 00000000..2bdc958f
--- /dev/null
+++ b/src/main/java/carpet/script/utils/Experimental.java
@@ -0,0 +1,156 @@
+package carpet.script.utils;
+
+import carpet.fakes.MinecraftServerInterface;
+import carpet.fakes.ServerWorldInterface;
+import carpet.script.CarpetScriptServer;
+import carpet.script.value.ListValue;
+import carpet.script.value.Value;
+import carpet.script.value.ValueConversions;
+import com.google.common.collect.ImmutableList;
+import com.mojang.datafixers.util.Pair;
+import com.mojang.serialization.DynamicOps;
+import net.minecraft.Util;
+import net.minecraft.commands.Commands;
+import net.minecraft.core.Holder;
+import net.minecraft.core.Registry;
+import net.minecraft.core.RegistryAccess;
+import net.minecraft.nbt.NbtOps;
+import net.minecraft.nbt.Tag;
+import net.minecraft.resources.RegistryOps;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.WorldStem;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.packs.PackResources;
+import net.minecraft.server.packs.PackType;
+import net.minecraft.server.packs.repository.Pack;
+import net.minecraft.server.packs.repository.PackRepository;
+import net.minecraft.server.packs.resources.CloseableResourceManager;
+import net.minecraft.server.packs.resources.MultiPackResourceManager;
+import net.minecraft.server.packs.resources.ResourceManager;
+import net.minecraft.world.level.DataPackConfig;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.biome.BiomeManager;
+import net.minecraft.world.level.border.BorderChangeListener;
+import net.minecraft.world.level.chunk.ChunkGenerator;
+import net.minecraft.world.level.dimension.DimensionType;
+import net.minecraft.world.level.dimension.LevelStem;
+import net.minecraft.world.level.levelgen.WorldGenSettings;
+import net.minecraft.world.level.storage.DerivedLevelData;
+import net.minecraft.world.level.storage.LevelStorageSource;
+import net.minecraft.world.level.storage.WorldData;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+public class Experimental
+{
+ public static Value reloadOne(MinecraftServer server)
+ {
+ LevelStorageSource.LevelStorageAccess session = ((MinecraftServerInterface) server).getCMSession();
+ DataPackConfig dataPackSettings = session.getDataPacks();
+ PackRepository resourcePackManager = server.getPackRepository();
+ DataPackConfig dataPackSettings2 = MinecraftServer.configurePackRepository(resourcePackManager, dataPackSettings == null ? DataPackConfig.DEFAULT : dataPackSettings, false);
+
+ CarpetScriptServer.LOG.error("datapacks: {}", dataPackSettings2.getEnabled());
+
+ MinecraftServer.ReloadableResources serverRM = ((MinecraftServerInterface) server).getResourceManager();
+ var resourceManager = serverRM.resourceManager();
+
+
+ final RegistryAccess.Frozen currentRegistry = server.registryAccess();
+
+ ImmutableList packsToLoad = resourcePackManager.getAvailableIds().stream().map(server.getPackRepository()::getPack).filter(Objects::nonNull).map(Pack::open).collect(ImmutableList.toImmutableList());
+ final CloseableResourceManager resources = new MultiPackResourceManager(PackType.SERVER_DATA, packsToLoad);
+ //ReloadableServerResources managers = ReloadableServerResources.loadResources(resources, currentRegistry, server.isDedicatedServer() ? Commands.CommandSelection.DEDICATED : Commands.CommandSelection.INTEGRATED, server.getFunctionCompilationLevel(), Util.backgroundExecutor(), Util.backgroundExecutor()).join();
+
+ //believe the other one will fillup based on the datapacks only.
+ //resources.close();
+
+
+ //not sure its needed, but doesn't seem to have a negative effect and might be used in some custom shtuff
+ //serverRM.updateGlobals();
+ DynamicOps dynamicOps = RegistryOps.create(NbtOps.INSTANCE, server.registryAccess());//, (ResourceManager) resourceManager);
+
+ WorldData saveProperties = session.getDataTag(dynamicOps, dataPackSettings2, server.registryAccess().allElementsLifecycle());
+
+ //RegistryReadOps registryOps = RegistryReadOps.create(NbtOps.INSTANCE, serverRM.getResourceManager(), (RegistryAccess.RegistryHolder) server.registryAccess());
+ //WorldData saveProperties = session.getDataTag(registryOps, dataPackSettings2);
+ if (saveProperties == null) return Value.NULL;
+ //session.backupLevelDataFile(server.getRegistryManager(), saveProperties); // no need
+
+ // MinecraftServer.createWorlds
+ // save properties should now contain dimension settings
+ WorldGenSettings generatorOptions = saveProperties.worldGenSettings();
+ boolean bl = generatorOptions.isDebug();
+ long l = generatorOptions.seed();
+ long m = BiomeManager.obfuscateSeed(l);
+ Map, ServerLevel> existing_worlds = ((MinecraftServerInterface) server).getCMWorlds();
+ List addeds = new ArrayList<>();
+ for (Map.Entry, LevelStem> entry : generatorOptions.dimensions().entrySet())
+ {
+ ResourceKey registryKey = entry.getKey();
+ CarpetScriptServer.LOG.error("Analysing workld: {}", registryKey.location());
+ if (!existing_worlds.containsKey(registryKey))
+ {
+ addeds.add(ValueConversions.of(registryKey.location()));
+ ResourceKey registryKey2 = ResourceKey.create(Registry.DIMENSION_REGISTRY, registryKey.location());
+ Holder holder2 = (entry.getValue()).typeHolder();
+ ChunkGenerator chunkGenerator3 = entry.getValue().generator();
+ DerivedLevelData unmodifiableLevelProperties = new DerivedLevelData(saveProperties, ((ServerWorldInterface) server.overworld()).getWorldPropertiesCM());
+ ServerLevel serverWorld2 = new ServerLevel(server, Util.backgroundExecutor(), session, unmodifiableLevelProperties, registryKey2, holder2, WorldTools.NOOP_LISTENER, chunkGenerator3, bl, m, List.of(), false);
+ server.overworld().getWorldBorder().addListener(new BorderChangeListener.DelegateBorderChangeListener(serverWorld2.getWorldBorder()));
+ existing_worlds.put(registryKey2, serverWorld2);
+ }
+ }
+ return ListValue.wrap(addeds);
+ }
+
+ public static Value reloadTwo(MinecraftServer server)
+ {
+ LevelStorageSource.LevelStorageAccess session = ((MinecraftServerInterface)server).getCMSession();
+ DataPackConfig dataPackSettings = session.getDataPacks();
+ PackRepository resourcePackManager = server.getPackRepository();
+
+ WorldStem.InitConfig initConfig = new WorldStem.InitConfig(resourcePackManager, Commands.CommandSelection.DEDICATED, 4, false);
+
+
+ final WorldStem data = WorldStem.load(initConfig, () -> {
+ DataPackConfig dataPackConfig = session.getDataPacks();
+ return dataPackConfig == null ? DataPackConfig.DEFAULT : dataPackConfig;
+ },
+ (resourceManager, dataPackConfigx) -> {
+ RegistryAccess.Writable writable = RegistryAccess.builtinCopy();
+ DynamicOps dynamicOps = RegistryOps.createAndLoad(NbtOps.INSTANCE, writable, (ResourceManager) resourceManager);
+ WorldData worldData = session.getDataTag(dynamicOps, dataPackConfigx, writable.allElementsLifecycle());
+ return Pair.of(worldData, writable.freeze());
+ }, Util.backgroundExecutor(), Runnable::run).join();
+ WorldGenSettings generatorOptions = data.worldData().worldGenSettings();
+
+ boolean bl = generatorOptions.isDebug();
+ long l = generatorOptions.seed();
+ long m = BiomeManager.obfuscateSeed(l);
+ Map, ServerLevel> existing_worlds = ((MinecraftServerInterface)server).getCMWorlds();
+ List addeds = new ArrayList<>();
+ for (Map.Entry, LevelStem> entry : generatorOptions.dimensions().entrySet()) {
+ ResourceKey registryKey = entry.getKey();
+ CarpetScriptServer.LOG.error("Analysing workld: {}", registryKey.location());
+ if (!existing_worlds.containsKey(registryKey))
+ {
+ ResourceKey resourceKey2 = ResourceKey.create(Registry.DIMENSION_REGISTRY, registryKey.location());
+ DerivedLevelData derivedLevelData = new DerivedLevelData(data.worldData(), ((ServerWorldInterface) server.overworld()).getWorldPropertiesCM());
+ ChunkGenerator chunkGenerator2 = ((LevelStem)entry.getValue()).generator();
+ Holder holder2 = ((LevelStem)entry.getValue()).typeHolder();
+ ServerLevel serverLevel2 = new ServerLevel(server, Util.backgroundExecutor(), session, derivedLevelData, resourceKey2,
+ holder2, WorldTools.NOOP_LISTENER,chunkGenerator2, bl, m, ImmutableList.of(), false);
+ server.overworld().getWorldBorder().addListener(new BorderChangeListener.DelegateBorderChangeListener(serverLevel2.getWorldBorder()));
+ existing_worlds.put(resourceKey2, serverLevel2);
+ addeds.add(ValueConversions.of(registryKey.location()));
+ }
+ }
+ ((MinecraftServerInterface)server).reloadAfterReload(data.registryAccess());
+ return ListValue.wrap(addeds);
+ }
+}