From 54c9024615910eb54a5b000ac147b70f9045a719 Mon Sep 17 00:00:00 2001 From: candle Date: Sun, 6 Jul 2025 17:14:37 -0400 Subject: [PATCH] almost 1.2.7 parity, no updates in initial dimension currently --- gradle.properties | 2 +- .../io/lampnet/travelerssuitcase/Config.java | 2 +- .../SuitcaseRegistryState.java | 122 +++-- .../travelerssuitcase/TravelersSuitcase.java | 503 ++++++++++++++++-- .../travelerssuitcase/block/ModBlocks.java | 2 +- .../block/PocketPortalBlock.java | 29 +- .../block/SuitcaseBlock.java | 34 +- .../block/entity/SuitcaseBlockEntity.java | 21 +- .../EnterPocketDimensionCriterion.java | 37 ++ .../travelerssuitcase/data/MobEntryData.java | 55 ++ .../data/PlayerEntryData.java | 57 ++ .../travelerssuitcase/item/KeystoneItem.java | 292 ++++++---- .../mixin/LevelStemMixin.java | 34 ++ .../mixin/MappedRegistryMixin.java | 46 ++ .../mixin/MinecraftServerAccess.java | 20 + .../mixin/ServerChunkManagerMixin.java | 30 ++ .../mixin/ServerWorldMixin.java | 58 ++ .../util/FilteredRegistry.java | 144 +++++ .../travelerssuitcase/util/GameRuleStore.java | 37 ++ .../travelerssuitcase/util/SafeIterator.java | 23 + .../util/VoidChunkGenerator.java | 90 ++++ .../util/VoidWorldProgressListener.java | 33 ++ .../travelerssuitcase/world/Fantasy.java | 198 +++++++ .../world/FantasyDimensionOptions.java | 17 + .../world/FantasyInitializer.java | 15 + .../world/FantasyWorldAccess.java | 10 + .../world/PortalChunkGenerator.java | 105 ++++ .../world/RemoveFromRegistry.java | 26 + .../travelerssuitcase/world/RuntimeWorld.java | 68 +++ .../world/RuntimeWorldConfig.java | 199 +++++++ .../world/RuntimeWorldHandle.java | 37 ++ .../world/RuntimeWorldManager.java | 115 ++++ .../world/RuntimeWorldProperties.java | 222 ++++++++ .../advancements/smaller_on_the_outside.json | 28 + .../dimension/pocket_dimension_.json | 16 - .../structures/pocket_island_01.nbt | Bin 317371 -> 317408 bytes .../resources/travelerssuitcase.mixins.json | 5 + 37 files changed, 2492 insertions(+), 240 deletions(-) create mode 100644 src/main/java/io/lampnet/travelerssuitcase/criterion/EnterPocketDimensionCriterion.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/data/MobEntryData.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/data/PlayerEntryData.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/mixin/LevelStemMixin.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/mixin/MappedRegistryMixin.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/mixin/MinecraftServerAccess.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/mixin/ServerChunkManagerMixin.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/mixin/ServerWorldMixin.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/util/FilteredRegistry.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/util/GameRuleStore.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/util/SafeIterator.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/util/VoidChunkGenerator.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/util/VoidWorldProgressListener.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/world/Fantasy.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/world/FantasyDimensionOptions.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/world/FantasyInitializer.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/world/FantasyWorldAccess.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/world/PortalChunkGenerator.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/world/RemoveFromRegistry.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorld.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorldConfig.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorldHandle.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorldManager.java create mode 100644 src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorldProperties.java create mode 100644 src/main/resources/data/travelerssuitcase/advancements/smaller_on_the_outside.json delete mode 100644 src/main/resources/data/travelerssuitcase/dimension/pocket_dimension_.json diff --git a/gradle.properties b/gradle.properties index d011161..4d0cb72 100644 --- a/gradle.properties +++ b/gradle.properties @@ -38,7 +38,7 @@ mod_name=TravelersSuitcase # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=MIT # The mod version. See https://semver.org/ -mod_version=1.0-SNAPSHOT +mod_version=1.2.7-SNAPSHOT # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/src/main/java/io/lampnet/travelerssuitcase/Config.java b/src/main/java/io/lampnet/travelerssuitcase/Config.java index 490a2a6..245305a 100644 --- a/src/main/java/io/lampnet/travelerssuitcase/Config.java +++ b/src/main/java/io/lampnet/travelerssuitcase/Config.java @@ -19,7 +19,7 @@ public class Config { static final ForgeConfigSpec SPEC = BUILDER.build(); private static boolean validateItemName(final Object obj) { - return obj instanceof final String itemName && ForgeRegistries.ITEMS.containsKey(new ResourceLocation(itemName)); + return obj instanceof final String itemName && ForgeRegistries.ITEMS.containsKey(ResourceLocation.parse(itemName)); } @SubscribeEvent diff --git a/src/main/java/io/lampnet/travelerssuitcase/SuitcaseRegistryState.java b/src/main/java/io/lampnet/travelerssuitcase/SuitcaseRegistryState.java index e5ca29f..63f073b 100644 --- a/src/main/java/io/lampnet/travelerssuitcase/SuitcaseRegistryState.java +++ b/src/main/java/io/lampnet/travelerssuitcase/SuitcaseRegistryState.java @@ -1,21 +1,21 @@ package io.lampnet.travelerssuitcase; import io.lampnet.travelerssuitcase.block.entity.SuitcaseBlockEntity; +import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; import net.minecraft.server.MinecraftServer; -import net.minecraft.world.level.saveddata.SavedData; -import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; -import org.jetbrains.annotations.NotNull; +import net.minecraft.world.level.saveddata.SavedData; import java.util.HashMap; import java.util.Map; import java.util.Objects; public class SuitcaseRegistryState extends SavedData { - private static final String REGISTRY_KEY = "travelers_suitcase_registry"; + public static final String DATA_NAME = "travelers_suitcase_registry"; private final Map> registry = new HashMap<>(); public SuitcaseRegistryState() { @@ -23,62 +23,86 @@ public class SuitcaseRegistryState extends SavedData { } @Override - public @NotNull CompoundTag save(@NotNull CompoundTag nbt) { - ListTag keystonesList = new ListTag(); - for (Map.Entry> keystoneEntry : registry.entrySet()) { - CompoundTag keystoneNbt = new CompoundTag(); - keystoneNbt.putString("KeystoneName", keystoneEntry.getKey()); - ListTag playersList = getPlayersList(keystoneEntry); - keystoneNbt.put("Players", playersList); - keystonesList.add(keystoneNbt); + public CompoundTag save(CompoundTag nbt) { + CompoundTag top = new CompoundTag(); + for (Map.Entry> entry : registry.entrySet()) { + String keystone = entry.getKey(); + Map playerMap = entry.getValue(); + + ListTag playerList = new ListTag(); + for (Map.Entry e2 : playerMap.entrySet()) { + CompoundTag record = new CompoundTag(); + record.putString("UUID", e2.getKey()); + BlockPos pos = e2.getValue(); + record.putInt("X", pos.getX()); + record.putInt("Y", pos.getY()); + record.putInt("Z", pos.getZ()); + playerList.add(record); + } + top.put(keystone, playerList); } - nbt.put("SuitcaseRegistry", keystonesList); + nbt.put("RegistryEntries", top); return nbt; } - private static @NotNull ListTag getPlayersList(Map.Entry> keystoneEntry) { - ListTag playersList = new ListTag(); - for (Map.Entry playerEntry : keystoneEntry.getValue().entrySet()) { - CompoundTag playerNbt = new CompoundTag(); - playerNbt.putString("UUID", playerEntry.getKey()); - BlockPos pos = playerEntry.getValue(); - playerNbt.putInt("X", pos.getX()); - playerNbt.putInt("Y", pos.getY()); - playerNbt.putInt("Z", pos.getZ()); - - playersList.add(playerNbt); - } - return playersList; - } - public static SuitcaseRegistryState load(CompoundTag nbt) { - SuitcaseRegistryState state = new SuitcaseRegistryState(); - if (nbt.contains("SuitcaseRegistry")) { - ListTag keystonesList = nbt.getList("SuitcaseRegistry", Tag.TAG_COMPOUND); - for (int i = 0; i < keystonesList.size(); i++) { - CompoundTag keystoneNbt = keystonesList.getCompound(i); - String keystoneName = keystoneNbt.getString("KeystoneName"); - Map playersMap = new HashMap<>(); - ListTag playersList = keystoneNbt.getList("Players", Tag.TAG_COMPOUND); - for (int j = 0; j < playersList.size(); j++) { - CompoundTag playerNbt = playersList.getCompound(j); - String uuid = playerNbt.getString("UUID"); - BlockPos pos = new BlockPos( - playerNbt.getInt("X"), - playerNbt.getInt("Y"), - playerNbt.getInt("Z") - ); - playersMap.put(uuid, pos); + SuitcaseRegistryState data = new SuitcaseRegistryState(); + if (nbt.contains("RegistryEntries", Tag.TAG_COMPOUND)) { + CompoundTag top = nbt.getCompound("RegistryEntries"); + for (String keystone : top.getAllKeys()) { + ListTag playerList = top.getList(keystone, Tag.TAG_COMPOUND); + Map playerMap = new HashMap<>(); + for (int i = 0; i < playerList.size(); i++) { + CompoundTag rec = playerList.getCompound(i); + String uuid = rec.getString("UUID"); + int x = rec.getInt("X"); + int y = rec.getInt("Y"); + int z = rec.getInt("Z"); + playerMap.put(uuid, new BlockPos(x, y, z)); } - state.registry.put(keystoneName, playersMap); + data.registry.put(keystone, playerMap); } } - return state; + return data; + } + + public void syncFromStaticRegistry() { + registry.clear(); + SuitcaseBlockEntity.saveSuitcaseRegistryTo(registry); + setDirty(); + } + + public void syncToStaticRegistry() { + SuitcaseBlockEntity.initializeSuitcaseRegistry(registry); + } + + public static void onServerStart(MinecraftServer server) { + Level overworld = server.getLevel(Level.OVERWORLD); + if (overworld == null) return; + + SuitcaseRegistryState data = Objects.requireNonNull(((ServerLevel) overworld).getDataStorage()).computeIfAbsent( + SuitcaseRegistryState::load, + SuitcaseRegistryState::new, + DATA_NAME + ); + data.syncToStaticRegistry(); + } + + public static void onRegistryChanged(MinecraftServer server) { + Level overworld = server.getLevel(Level.OVERWORLD); + if (overworld == null) return; + + SuitcaseRegistryState data = Objects.requireNonNull(((ServerLevel) overworld).getDataStorage()).computeIfAbsent( + SuitcaseRegistryState::load, + SuitcaseRegistryState::new, + DATA_NAME + ); + data.syncFromStaticRegistry(); } public static SuitcaseRegistryState getState(MinecraftServer server) { - return Objects.requireNonNull(server.getLevel(Level.OVERWORLD)).getDataStorage() - .computeIfAbsent(SuitcaseRegistryState::load, SuitcaseRegistryState::new, REGISTRY_KEY); + return Objects.requireNonNull(((ServerLevel) server.getLevel(Level.OVERWORLD)).getDataStorage()) + .computeIfAbsent(SuitcaseRegistryState::load, SuitcaseRegistryState::new, DATA_NAME); } public Map> getRegistry() { diff --git a/src/main/java/io/lampnet/travelerssuitcase/TravelersSuitcase.java b/src/main/java/io/lampnet/travelerssuitcase/TravelersSuitcase.java index f15586e..41b1faa 100644 --- a/src/main/java/io/lampnet/travelerssuitcase/TravelersSuitcase.java +++ b/src/main/java/io/lampnet/travelerssuitcase/TravelersSuitcase.java @@ -1,22 +1,102 @@ package io.lampnet.travelerssuitcase; +import com.mojang.brigadier.arguments.BoolArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; import io.lampnet.travelerssuitcase.block.ModBlocks; +import io.lampnet.travelerssuitcase.block.SuitcaseBlock; import io.lampnet.travelerssuitcase.block.entity.ModBlockEntities; +import io.lampnet.travelerssuitcase.block.entity.SuitcaseBlockEntity; +import io.lampnet.travelerssuitcase.criterion.EnterPocketDimensionCriterion; +import io.lampnet.travelerssuitcase.data.MobEntryData; +import io.lampnet.travelerssuitcase.data.PlayerEntryData; +import io.lampnet.travelerssuitcase.item.KeystoneItem; import io.lampnet.travelerssuitcase.item.ModItemGroups; import io.lampnet.travelerssuitcase.item.ModItems; -import io.lampnet.travelerssuitcase.block.entity.SuitcaseBlockEntity; -import io.lampnet.travelerssuitcase.SuitcaseRegistryState; +import io.lampnet.travelerssuitcase.world.Fantasy; +import io.lampnet.travelerssuitcase.world.FantasyInitializer; +import io.lampnet.travelerssuitcase.world.PortalChunkGenerator; +import io.lampnet.travelerssuitcase.world.RuntimeWorldConfig; +import net.minecraft.advancements.CriteriaTriggers; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.monster.Enemy; +import net.minecraft.world.entity.animal.Wolf; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.RegisterCommandsEvent; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.event.server.ServerStartingEvent; import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashSet; +import java.util.Set; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.entity.Entity; + +import io.lampnet.travelerssuitcase.world.RuntimeWorldHandle; @Mod(TravelersSuitcase.MODID) public class TravelersSuitcase { public static final String MODID = "travelerssuitcase"; public static final Logger LOGGER = LogManager.getLogger(MODID); + public static final EnterPocketDimensionCriterion ENTER_POCKET_DIMENSION = CriteriaTriggers.register(new EnterPocketDimensionCriterion()); + + private static boolean canCaptureHostile = false; + private static final Set> entityBlacklist = new HashSet<>(); + + // Public accessor methods for the configuration + public static boolean getCanCaptureHostile() { + return canCaptureHostile; + } + + public static void setCanCaptureHostile(boolean value) { + canCaptureHostile = value; + } + + public static Set> getEntityBlacklist() { + return new HashSet<>(entityBlacklist); + } + + public static void addToBlacklist(EntityType entityType) { + entityBlacklist.add(entityType); + } + + public static boolean removeFromBlacklist(EntityType entityType) { + return entityBlacklist.remove(entityType); + } + + public static boolean isBlacklisted(EntityType entityType) { + return entityBlacklist.contains(entityType); + } + + public static void clearBlacklist() { + entityBlacklist.clear(); + } public TravelersSuitcase() { IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); @@ -26,55 +106,392 @@ public class TravelersSuitcase { ModItemGroups.register(modEventBus); ModBlockEntities.register(modEventBus); - MinecraftForge.EVENT_BUS.addListener(this::onWorldLoad); - MinecraftForge.EVENT_BUS.addListener(this::onServerStarting); - MinecraftForge.EVENT_BUS.addListener(this::onServerStopping); + modEventBus.addListener(this::commonSetup); - LOGGER.info("Initializing " + MODID); + MinecraftForge.EVENT_BUS.register(this); + MinecraftForge.EVENT_BUS.register(TravelersSuitcase.class); // Register static methods } - private void onWorldLoad(net.minecraftforge.event.level.LevelEvent.Load event) { - if (event.getLevel() instanceof net.minecraft.server.level.ServerLevel world) { - if (world.dimension().location().getNamespace().equals(MODID)) { - String dimensionName = world.dimension().location().getPath(); - java.nio.file.Path structureMarkerPath = world.getServer().getWorldPath(net.minecraft.world.level.storage.LevelResource.ROOT) - .resolve("data") - .resolve(MODID) - .resolve("pending_structures") - .resolve(dimensionName + ".txt"); - if (java.nio.file.Files.exists(structureMarkerPath)) { - try { - net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate template = world.getServer().getStructureManager() - .get(new net.minecraft.resources.ResourceLocation(MODID, "pocket_island_01")) - .orElse(null); - if (template != null) { - net.minecraft.core.BlockPos pos = new net.minecraft.core.BlockPos(0, 64, 0); - template.placeInWorld( - world, - pos, - pos, - new net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings(), - world.getRandom(), - net.minecraft.world.level.block.Block.UPDATE_ALL - ); - java.nio.file.Files.delete(structureMarkerPath); - } - } catch (java.io.IOException e) { - LOGGER.error("Failed to place structure", e); - } - } + private void commonSetup(final FMLCommonSetupEvent event) { + // Register chunk generators during setup phase + new FantasyInitializer().onInitialize(); + } + + @SubscribeEvent + public static void onServerStarting(ServerStartingEvent event) { + SuitcaseRegistryState.onServerStart(event.getServer()); + + Path registryFile = event.getServer().getWorldPath(net.minecraft.world.level.storage.LevelResource.ROOT) + .resolve("data") + .resolve(MODID) + .resolve("dimension_registry") + .resolve("registry.txt"); + + if (!Files.exists(registryFile)) { + return; + } + var biomeRegistry = event.getServer().registryAccess().registryOrThrow(Registries.BIOME); + + long seed = event.getServer().overworld().getSeed(); + try { + for (String dimName : Files.readAllLines(registryFile)) { + ResourceLocation worldId = ResourceLocation.fromNamespaceAndPath(MODID, dimName); + + var voidGen = new PortalChunkGenerator(biomeRegistry); + + var cfg = new RuntimeWorldConfig() + .setGenerator(voidGen) + .setSeed(seed); + RuntimeWorldHandle handle = Fantasy.get(event.getServer()).getOrOpenPersistentWorld(worldId, cfg); + + // Ensure the pocket dimension ticks even when empty to prevent entity tick issues + handle.setTickWhenEmpty(true); } + } catch (IOException e) { + TravelersSuitcase.LOGGER.error("Failed to reload pocket dimensions", e); } } - private void onServerStarting(net.minecraftforge.event.server.ServerStartingEvent event) { - SuitcaseRegistryState state = SuitcaseRegistryState.getState(event.getServer()); - SuitcaseBlockEntity.initializeSuitcaseRegistry(state.getRegistry()); + @SubscribeEvent + public static void onRegisterCommands(RegisterCommandsEvent event) { + LiteralArgumentBuilder builder = Commands.literal("travelerssuitcase") + .then(Commands.literal("setMobEntry") + .executes(ctx -> { + var src = ctx.getSource(); + var world = src.getLevel(); + var id = world.dimension().location(); + if (!id.getNamespace().equals(MODID) + || !id.getPath().startsWith("pocket_dimension_")) { + src.sendFailure(Component.literal("§cNot in a pocket dimension")); + return 0; + } + var pos = src.getPosition(); + var yaw = src.getEntity().getYRot(); + var pitch = src.getEntity().getXRot(); + + MobEntryData.get(world).setEntry(pos, yaw, pitch); + src.sendSuccess(() -> Component.literal( + String.format("§aMob entry set to %.2f, %.2f, %.2f", pos.x(), pos.y(), pos.z()) + ), false); + return 1; + }) + ) + .then(Commands.literal("setPlayerEntry") + .executes(ctx -> { + var src = ctx.getSource(); + var world = src.getLevel(); + var id = world.dimension().location(); + if (!id.getNamespace().equals(MODID) + || !id.getPath().startsWith("pocket_dimension_")) { + src.sendFailure(Component.literal("§cNot in a pocket dimension")); + return 0; + } + var pos = src.getPosition(); + var yaw = src.getEntity().getYRot(); + var pitch = src.getEntity().getXRot(); + + PlayerEntryData.get(world).setEntry(pos, yaw, pitch); + src.sendSuccess(() -> Component.literal( + String.format("§aPlayer entry set to %.2f, %.2f, %.2f", pos.x(), pos.y(), pos.z()) + ), false); + return 1; + })) + .then(Commands.literal("resetPlayerEntry") + .then(Commands.argument("dimension", StringArgumentType.word()) + .executes(ctx -> { + var src = ctx.getSource(); + String dimSuffix = StringArgumentType.getString(ctx, "dimension"); + + ResourceLocation dimId = ResourceLocation.fromNamespaceAndPath(MODID, "pocket_dimension_" + dimSuffix); + ResourceKey worldKey = ResourceKey.create(Registries.DIMENSION, dimId); + ServerLevel targetWorld = src.getServer().getLevel(worldKey); + + if (targetWorld == null) { + src.sendFailure(Component.literal("§cPocket dimension '" + dimSuffix + "' not found")); + return 0; + } + + // Reset player entry to default position + PlayerEntryData playerData = PlayerEntryData.get(targetWorld); + playerData.setEntry(new Vec3(17.5, 97.0, 9.5), 0f, 0f); + + src.sendSuccess(() -> Component.literal( + "§aPlayer entry reset for pocket dimension '" + dimSuffix + "'" + ), false); + return 1; + }) + ) + ) + .then(Commands.literal("listDimensions") + .requires(src -> src.hasPermission(2)) + .executes(ctx -> { + var src = ctx.getSource(); + src.sendSuccess(() -> Component.literal("§aPocket Dimensions Loaded:"), false); + boolean foundAny = false; + for (ServerLevel world : src.getServer().getAllLevels()) { + var id = world.dimension().location(); + String namespace = id.getNamespace(); + String path = id.getPath(); + String prefix = "pocket_dimension_"; + + if (MODID.equals(namespace) && path.startsWith(prefix)) { + String suffix = path.substring(prefix.length()); + src.sendSuccess(() -> Component.literal(" " + suffix), false); + foundAny = true; + } + } + if (!foundAny) { + src.sendSuccess(() -> Component.literal("§cNo pocket dimensions found."), false); + } + return 1; + }) + ) + .then(Commands.literal("canCaptureHostile") + .requires(src -> src.hasPermission(2)) + .then(Commands.argument("value", BoolArgumentType.bool()) + .executes(ctx -> { + boolean value = BoolArgumentType.getBool(ctx, "value"); + canCaptureHostile = value; + ctx.getSource().sendSuccess(() -> Component.literal( + value ? "§aHostile mob capture enabled" : "§cHostile mob capture disabled" + ), false); + return 1; + }) + ) + .executes(ctx -> { + ctx.getSource().sendSuccess(() -> Component.literal( + "§7Hostile mob capture is currently: " + (canCaptureHostile ? "§aEnabled" : "§cDisabled") + ), false); + return 1; + }) + ) + .then(Commands.literal("mobBlacklist") + .requires(src -> src.hasPermission(2)) + .then(Commands.literal("add") + .then(Commands.argument("entity", StringArgumentType.string()) + .executes(ctx -> { + var src = ctx.getSource(); + String entityString = StringArgumentType.getString(ctx, "entity"); + try { + ResourceLocation entityId = ResourceLocation.parse(entityString); + EntityType entityType = BuiltInRegistries.ENTITY_TYPE.get(entityId); + if (entityType == EntityType.PIG && !entityString.equals("minecraft:pig")) { // Default fallback + src.sendFailure(Component.literal("§cUnknown entity type: " + entityString)); + return 0; + } + if (entityType == EntityType.PLAYER) { + src.sendFailure(Component.literal("§cCannot blacklist players")); + return 0; + } + entityBlacklist.add(entityType); + src.sendSuccess(() -> Component.literal("§aAdded " + entityId + " to blacklist"), false); + return 1; + } catch (Exception e) { + src.sendFailure(Component.literal("§cInvalid entity identifier: " + entityString)); + return 0; + } + }) + ) + ) + .then(Commands.literal("remove") + .then(Commands.argument("entity", StringArgumentType.string()) + .executes(ctx -> { + var src = ctx.getSource(); + String entityString = StringArgumentType.getString(ctx, "entity"); + try { + var entityId = ResourceLocation.parse(entityString); + var entityType = BuiltInRegistries.ENTITY_TYPE.get(entityId); + if (entityType == EntityType.PIG && !entityString.equals("minecraft:pig")) { + src.sendFailure(Component.literal("§cUnknown entity type: " + entityString)); + return 0; + } + if (entityBlacklist.remove(entityType)) { + src.sendSuccess(() -> Component.literal("§aRemoved " + entityId + " from blacklist"), false); + } else { + src.sendSuccess(() -> Component.literal("§7" + entityId + " was not in blacklist"), false); + } + return 1; + } catch (Exception e) { + src.sendFailure(Component.literal("§cInvalid entity identifier: " + entityString)); + return 0; + } + }) + ) + ) + .then(Commands.literal("list") + .executes(ctx -> { + var src = ctx.getSource(); + if (entityBlacklist.isEmpty()) { + src.sendSuccess(() -> Component.literal("§7No entities are blacklisted"), false); + } else { + src.sendSuccess(() -> Component.literal("§aBlacklisted entities:"), false); + entityBlacklist.forEach(entityType -> { + var id = BuiltInRegistries.ENTITY_TYPE.getKey(entityType); + src.sendSuccess(() -> Component.literal(" " + id), false); + }); + } + return 1; + }) + ) + .then(Commands.literal("clear") + .executes(ctx -> { + var src = ctx.getSource(); + int count = entityBlacklist.size(); + entityBlacklist.clear(); + src.sendSuccess(() -> Component.literal("§aCleared blacklist (removed " + count + " entities)"), false); + return 1; + }) + ) + ); + event.getDispatcher().register(builder); } - private void onServerStopping(net.minecraftforge.event.server.ServerStoppingEvent event) { - SuitcaseRegistryState state = SuitcaseRegistryState.getState(event.getServer()); - SuitcaseBlockEntity.saveSuitcaseRegistryTo(state.getRegistry()); - state.setDirty(); + @SubscribeEvent + public void onUseEntity(PlayerInteractEvent.EntityInteract event) { + Level world = event.getLevel(); + if (world.isClientSide) return; + var player = event.getEntity(); + var hand = event.getHand(); + var entity = event.getTarget(); + var stack = player.getItemInHand(hand); + + // Suitcase mob teleport + if (stack.getItem() instanceof BlockItem bi && bi.getBlock() instanceof SuitcaseBlock) { + CompoundTag beNbt = BlockItem.getBlockEntityData(stack); + if (beNbt == null || !beNbt.contains("BoundKeystone")) { + player.displayClientMessage(Component.literal("§c☒"), true); + world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.ZOMBIE_ATTACK_WOODEN_DOOR, SoundSource.PLAYERS, 0.3f, 1.5f); + event.setCancellationResult(InteractionResult.FAIL); + event.setCanceled(true); + return; + } + if (beNbt.getBoolean("Locked")) { + player.displayClientMessage(Component.literal("§c☒"), true); + world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.ZOMBIE_ATTACK_WOODEN_DOOR, SoundSource.PLAYERS, 0.3f, 1.5f); + event.setCancellationResult(InteractionResult.FAIL); + event.setCanceled(true); + return; + } + String keystone = beNbt.getString("BoundKeystone"); + ResourceLocation dimId = ResourceLocation.fromNamespaceAndPath(MODID, "pocket_dimension_" + keystone); + ResourceKey dimKey = ResourceKey.create(Registries.DIMENSION, dimId); + ServerLevel targetWorld = world.getServer().getLevel(dimKey); + if (targetWorld == null) { + player.displayClientMessage(Component.literal("§cPocket dimension not found"), true); + event.setCancellationResult(InteractionResult.FAIL); + event.setCanceled(true); + return; + } + if (!(entity instanceof LivingEntity mob)) { + return; + } + if (entityBlacklist.contains(mob.getType())) { + player.displayClientMessage(Component.literal("§c☒"), true); + world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.ZOMBIE_ATTACK_WOODEN_DOOR, SoundSource.PLAYERS, 0.3f, 1.5f); + event.setCancellationResult(InteractionResult.FAIL); + event.setCanceled(true); + return; + } + boolean isHostile = mob instanceof Enemy || (mob instanceof Wolf wolf && wolf.isAngryAtAllPlayers(world)); + if (!canCaptureHostile && isHostile) { + player.displayClientMessage(Component.literal("§c☒"), true); + world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.ZOMBIE_ATTACK_WOODEN_DOOR, SoundSource.PLAYERS, 0.3f, 1.5f); + event.setCancellationResult(InteractionResult.FAIL); + event.setCanceled(true); + return; + } + MobEntryData data = MobEntryData.get(targetWorld); + Vec3 dest = data.getEntryPos(); + float yaw = data.getEntryYaw(); + float pitch = data.getEntryPitch(); + mob.changeDimension(targetWorld, new net.minecraftforge.common.util.ITeleporter() { + @Override + public Entity placeEntity(Entity entity, ServerLevel currentWorld, ServerLevel destWorld, float yaw, java.util.function.Function repositionEntity) { + Entity e = repositionEntity.apply(false); + e.teleportTo(dest.x, dest.y, dest.z); + return e; + } + }); + world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.BUNDLE_DROP_CONTENTS, SoundSource.PLAYERS, 2.0f, 1.0f); + world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.ITEM_PICKUP, SoundSource.PLAYERS, 0.5f, 1.0f); + event.setCancellationResult(InteractionResult.SUCCESS); + event.setCanceled(true); + return; + } + + // Key rescue mob + if (stack.getItem() instanceof KeystoneItem) { + ResourceLocation dimId = world.dimension().location(); + String namespace = dimId.getNamespace(); + String path = dimId.getPath(); + String prefix = "pocket_dimension_"; + if (!namespace.equals(MODID) || !path.startsWith(prefix)) { + return; + } + String keystoneName = path.substring(prefix.length()); + if (!(entity instanceof LivingEntity mob)) { + return; + } + String playerUuid = player.getUUID().toString(); + BlockPos suitcasePos = SuitcaseBlockEntity.findSuitcasePosition(keystoneName, playerUuid); + if (suitcasePos == null) { + player.displayClientMessage(Component.literal("§cNo suitcase found"), true); + event.setCancellationResult(InteractionResult.FAIL); + event.setCanceled(true); + return; + } + ServerLevel overworld = world.getServer().getLevel(Level.OVERWORLD); + if (overworld == null) { + player.displayClientMessage(Component.literal("§cOverworld is not loaded"), true); + event.setCancellationResult(InteractionResult.FAIL); + event.setCanceled(true); + return; + } + Vec3 exitPos = new Vec3(suitcasePos.getX() + 0.5, suitcasePos.getY() + 0.5, suitcasePos.getZ() + 0.5); + mob.changeDimension(overworld, new net.minecraftforge.common.util.ITeleporter() { + @Override + public Entity placeEntity(Entity entity, ServerLevel currentWorld, ServerLevel destWorld, float yaw, java.util.function.Function repositionEntity) { + Entity e = repositionEntity.apply(false); + e.teleportTo(exitPos.x, exitPos.y, exitPos.z); + return e; + } + }); + overworld.playSound(null, exitPos.x, exitPos.y, exitPos.z, SoundEvents.BUNDLE_DROP_CONTENTS, SoundSource.PLAYERS, 2.0f, 1.0f); + world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.BUNDLE_DROP_CONTENTS, SoundSource.PLAYERS, 2.0f, 1.0f); + event.setCancellationResult(InteractionResult.SUCCESS); + event.setCanceled(true); + } + } + + @SubscribeEvent + public void onUseItem(PlayerInteractEvent.RightClickItem event) { + Level world = event.getLevel(); + var player = event.getEntity(); + var hand = event.getHand(); + var stack = player.getItemInHand(hand); + + if (world.isClientSide || hand != InteractionHand.MAIN_HAND) return; + + if (!(world instanceof ServerLevel sw)) return; + var id = sw.dimension().location(); + if (!id.getNamespace().equals(MODID) || !id.getPath().startsWith("pocket_dimension_")) return; + + if (stack.getItem() == Items.BONE) { + Vec3 pos = player.position(); + float yaw = player.getYRot(); + float pitch = player.getXRot(); + PlayerEntryData.get(sw).setEntry(pos, yaw, pitch); + player.sendSystemMessage(Component.literal(String.format("§aPlayer entry location set to %.1f, %.1f, %.1f", pos.x, pos.y, pos.z))); + event.setCancellationResult(InteractionResult.SUCCESS); + event.setCanceled(true); + } else if (stack.getItem() == Items.LEAD) { + Vec3 pos = player.position(); + float yaw = player.getYRot(); + float pitch = player.getXRot(); + MobEntryData.get(sw).setEntry(pos, yaw, pitch); + player.sendSystemMessage(Component.literal(String.format("§aMob entry location set to %.1f, %.1f, %.1f", pos.x, pos.y, pos.z))); + event.setCancellationResult(InteractionResult.SUCCESS); + event.setCanceled(true); + } } } \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/block/ModBlocks.java b/src/main/java/io/lampnet/travelerssuitcase/block/ModBlocks.java index 223797a..2cd9c09 100644 --- a/src/main/java/io/lampnet/travelerssuitcase/block/ModBlocks.java +++ b/src/main/java/io/lampnet/travelerssuitcase/block/ModBlocks.java @@ -70,7 +70,7 @@ public class ModBlocks { .sound(SoundType.LODESTONE) .noOcclusion() .lightLevel(getPortalLuminance()) - .strength(-1f))); + .strength(5.0f))); private static RegistryObject registerBlock(String name, Supplier blockSupplier) { RegistryObject block = BLOCKS.register(name, blockSupplier); diff --git a/src/main/java/io/lampnet/travelerssuitcase/block/PocketPortalBlock.java b/src/main/java/io/lampnet/travelerssuitcase/block/PocketPortalBlock.java index b0b0417..08b540b 100644 --- a/src/main/java/io/lampnet/travelerssuitcase/block/PocketPortalBlock.java +++ b/src/main/java/io/lampnet/travelerssuitcase/block/PocketPortalBlock.java @@ -28,10 +28,12 @@ import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.nbt.Tag; import org.jetbrains.annotations.NotNull; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import net.minecraft.world.level.storage.loot.LootParams; public class PocketPortalBlock extends Block { private static final Map LAST_KNOWN_POSITIONS = new HashMap<>(); @@ -57,6 +59,12 @@ public class PocketPortalBlock extends Block { super(properties); } + @Override + public List getDrops(BlockState state, LootParams.Builder builder) { + return Collections.singletonList(new ItemStack(this)); + } + + public static void storePlayerPosition(ServerPlayer player) { LAST_KNOWN_POSITIONS.put( player.getUUID().toString(), @@ -125,7 +133,7 @@ public class PocketPortalBlock extends Block { updateItemLore(stack, remainingPlayers); } } - SuitcaseBlockEntity.removeSuitcaseEntry(keystoneName, player.getUUID().toString()); + SuitcaseBlockEntity.removeSuitcaseEntry(keystoneName, player.getUUID().toString(), player.getServer()); } @Override @@ -162,13 +170,13 @@ public class PocketPortalBlock extends Block { // Fallback: Take them to spawn if (!teleported) { - player.displayClientMessage(Component.literal("§cCouldn't find your return point. Taking you to spawn.").withStyle(ChatFormatting.RED), false); + player.displayClientMessage(Component.literal("§c...").withStyle(ChatFormatting.RED), false); teleportToPosition(world, player, overworld, overworld.getSharedSpawnPos().getX() + 0.5, overworld.getSharedSpawnPos().getY() + 1.0, overworld.getSharedSpawnPos().getZ() + 0.5, 0, 0); } - SuitcaseBlockEntity.removeSuitcaseEntry(keystoneName, player.getUUID().toString()); + SuitcaseBlockEntity.removeSuitcaseEntry(keystoneName, player.getUUID().toString(), world.getServer()); LAST_KNOWN_POSITIONS.remove(player.getUUID().toString()); } } @@ -278,7 +286,9 @@ public class PocketPortalBlock extends Block { private void teleportToPosition(Level world, ServerPlayer player, ServerLevel targetWorld, double x, double y, double z, float yaw, float pitch) { - player.teleportTo(targetWorld, x, y, z, yaw, pitch); + if (!world.isClientSide) { + player.teleportTo(targetWorld, x, y, z, yaw, pitch); + } } private void updateItemLore(ItemStack stack, int playerCount) { @@ -304,5 +314,16 @@ public class PocketPortalBlock extends Block { } } } + if (playerCount > 0) { + Component lore = Component.literal(playerCount + " player" + (playerCount > 1 ? "s" : "") + " inside").withStyle(ChatFormatting.GRAY); + CompoundTag displayTag = stack.getOrCreateTagElement("display"); + ListTag loreList = new ListTag(); + loreList.add(StringTag.valueOf(Component.Serializer.toJson(lore))); + displayTag.put("Lore", loreList); + } else { + if (stack.hasTag() && stack.getTag().contains("display")) { + stack.getTag().getCompound("display").remove("Lore"); + } + } } } \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/block/SuitcaseBlock.java b/src/main/java/io/lampnet/travelerssuitcase/block/SuitcaseBlock.java index b9b74b3..b66ff49 100644 --- a/src/main/java/io/lampnet/travelerssuitcase/block/SuitcaseBlock.java +++ b/src/main/java/io/lampnet/travelerssuitcase/block/SuitcaseBlock.java @@ -3,6 +3,7 @@ package io.lampnet.travelerssuitcase.block; import io.lampnet.travelerssuitcase.TravelersSuitcase; import io.lampnet.travelerssuitcase.block.entity.ModBlockEntities; import io.lampnet.travelerssuitcase.block.entity.SuitcaseBlockEntity; +import io.lampnet.travelerssuitcase.data.PlayerEntryData; import io.lampnet.travelerssuitcase.item.KeystoneItem; import net.minecraft.world.level.block.BaseEntityBlock; import net.minecraft.world.level.block.Block; @@ -48,6 +49,10 @@ import net.minecraft.world.level.Level; import net.minecraft.world.Containers; import net.minecraft.world.item.DyeColor; +import net.minecraft.network.protocol.game.ClientboundStopSoundPacket; +import net.minecraft.sounds.SoundSource; +import net.minecraft.sounds.SoundEvents; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -243,20 +248,37 @@ public class SuitcaseBlock extends BaseEntityBlock { return; } String dimensionName = "pocket_dimension_" + keystoneName; - ResourceLocation dimensionRL = new ResourceLocation(TravelersSuitcase.MODID, dimensionName); + ResourceLocation dimensionRL = ResourceLocation.fromNamespaceAndPath(TravelersSuitcase.MODID, dimensionName); ResourceKey dimensionKey = ResourceKey.create(Registries.DIMENSION, dimensionRL); ServerLevel targetWorld = Objects.requireNonNull(world.getServer()).getLevel(dimensionKey); if (targetWorld != null) { + boolean wasFirstTime = suitcase.isFirstTimeEntering(player); suitcase.playerEntered(player); + if (wasFirstTime) { + TravelersSuitcase.ENTER_POCKET_DIMENSION.trigger(player); + } + player.stopRiding(); player.setDeltaMovement(Vec3.ZERO); player.fallDistance = 0f; - player.teleportTo(targetWorld, 17.5, 97, 9.5, player.getYRot(), player.getXRot()); - world.playSound(null, pos, + + PlayerEntryData ped = PlayerEntryData.get(targetWorld); + Vec3 dest = ped.getEntryPos(); + + float yaw = ped.getEntryYaw(); + float pitch = player.getXRot(); + + player.teleportTo(targetWorld, dest.x, dest.y, dest.z, yaw, pitch); + + player.connection.send(new ClientboundStopSoundPacket(null, null)); + + world.playSound( + null, + pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, SoundEvents.BUNDLE_DROP_CONTENTS, - SoundSource.PLAYERS, 2.0f, 1.0f); - } else { - TravelersSuitcase.LOGGER.warn("Target dimension {} not found for keystone {}", dimensionRL, keystoneName); + SoundSource.PLAYERS, + 2.0f, 1.0f + ); } } } diff --git a/src/main/java/io/lampnet/travelerssuitcase/block/entity/SuitcaseBlockEntity.java b/src/main/java/io/lampnet/travelerssuitcase/block/entity/SuitcaseBlockEntity.java index ae1026b..3168bab 100644 --- a/src/main/java/io/lampnet/travelerssuitcase/block/entity/SuitcaseBlockEntity.java +++ b/src/main/java/io/lampnet/travelerssuitcase/block/entity/SuitcaseBlockEntity.java @@ -16,6 +16,9 @@ import org.jetbrains.annotations.Nullable; import java.util.*; +import io.lampnet.travelerssuitcase.SuitcaseRegistryState; +import net.minecraft.server.MinecraftServer; + public class SuitcaseBlockEntity extends BlockEntity { private String boundKeystoneName; private boolean isLocked = false; @@ -70,6 +73,11 @@ public class SuitcaseBlockEntity extends BlockEntity { return dimensionLocked; } + private static final java.util.Set PLAYERS_WHO_ENTERED = new java.util.HashSet<>(); + public boolean isFirstTimeEntering(ServerPlayer player) { + return !PLAYERS_WHO_ENTERED.contains(player.getUUID()); + } + public void playerEntered(ServerPlayer player) { enteredPlayers.removeIf(data -> data.uuid.equals(player.getUUID().toString())); EnteredPlayerData data = new EnteredPlayerData( @@ -79,6 +87,9 @@ public class SuitcaseBlockEntity extends BlockEntity { this.worldPosition ); enteredPlayers.add(data); + + PLAYERS_WHO_ENTERED.add(player.getUUID()); + if (boundKeystoneName != null) { Map suitcases = SUITCASE_REGISTRY.computeIfAbsent( boundKeystoneName, k -> new HashMap<>() @@ -87,6 +98,11 @@ public class SuitcaseBlockEntity extends BlockEntity { } PocketPortalBlock.storePlayerPosition(player); setChangedAndNotify(); + + MinecraftServer server = player.getServer(); + if (server != null) { + SuitcaseRegistryState.onRegistryChanged(server); + } } public EnteredPlayerData getExitPosition(String playerUuid) { @@ -182,13 +198,16 @@ public class SuitcaseBlockEntity extends BlockEntity { return (suitcases != null) ? suitcases.get(playerUuid) : null; } - public static void removeSuitcaseEntry(String keystoneName, String playerUuid) { + public static void removeSuitcaseEntry(String keystoneName, String playerUuid, MinecraftServer server) { Map suitcases = SUITCASE_REGISTRY.get(keystoneName); if (suitcases != null) { suitcases.remove(playerUuid); if (suitcases.isEmpty()) { SUITCASE_REGISTRY.remove(keystoneName); } + if (server != null) { + SuitcaseRegistryState.onRegistryChanged(server); + } } } diff --git a/src/main/java/io/lampnet/travelerssuitcase/criterion/EnterPocketDimensionCriterion.java b/src/main/java/io/lampnet/travelerssuitcase/criterion/EnterPocketDimensionCriterion.java new file mode 100644 index 0000000..abe37ab --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/criterion/EnterPocketDimensionCriterion.java @@ -0,0 +1,37 @@ +package io.lampnet.travelerssuitcase.criterion; + +import com.google.gson.JsonObject; +import io.lampnet.travelerssuitcase.TravelersSuitcase; +import net.minecraft.advancements.critereon.AbstractCriterionTriggerInstance; +import net.minecraft.advancements.critereon.ContextAwarePredicate; +import net.minecraft.advancements.critereon.SimpleCriterionTrigger; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; + +public class EnterPocketDimensionCriterion extends SimpleCriterionTrigger { + static final ResourceLocation ID = ResourceLocation.fromNamespaceAndPath(TravelersSuitcase.MODID, "enter_pocket_dimension"); + + @Override + public ResourceLocation getId() { + return ID; + } + + @Override + public TriggerInstance createInstance(JsonObject jsonObject, ContextAwarePredicate contextAwarePredicate, net.minecraft.advancements.critereon.DeserializationContext deserializationContext) { + return new TriggerInstance(contextAwarePredicate); + } + + public void trigger(ServerPlayer player) { + this.trigger(player, (triggerInstance) -> true); + } + + public static class TriggerInstance extends AbstractCriterionTriggerInstance { + public TriggerInstance(ContextAwarePredicate player) { + super(EnterPocketDimensionCriterion.ID, player); + } + + public JsonObject serializeToJson(net.minecraft.advancements.critereon.SerializationContext serializationContext) { + return super.serializeToJson(serializationContext); + } + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/data/MobEntryData.java b/src/main/java/io/lampnet/travelerssuitcase/data/MobEntryData.java new file mode 100644 index 0000000..97c1a1a --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/data/MobEntryData.java @@ -0,0 +1,55 @@ +package io.lampnet.travelerssuitcase.data; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.saveddata.SavedData; +import net.minecraft.world.phys.Vec3; + +public class MobEntryData extends SavedData { + private static final String DATA_KEY = "pocket_entry_data"; + private Vec3 entryPos = Vec3.ZERO; + private float entryYaw = 0f, entryPitch = 0f; + + public MobEntryData() { + super(); + this.entryPos = new Vec3(35.5, 85, 16.5); + this.entryYaw = 0f; + this.entryPitch = 0f; + } + + public static MobEntryData load(CompoundTag nbt) { + MobEntryData data = new MobEntryData(); + double x = nbt.getDouble("entryX"); + double y = nbt.getDouble("entryY"); + double z = nbt.getDouble("entryZ"); + data.entryPos = new Vec3(x, y, z); + data.entryYaw = nbt.getFloat("entryYaw"); + data.entryPitch = nbt.getFloat("entryPitch"); + return data; + } + + public static MobEntryData get(ServerLevel world) { + return world.getDataStorage().computeIfAbsent(MobEntryData::load, MobEntryData::new, DATA_KEY); + } + + @Override + public CompoundTag save(CompoundTag nbt) { + nbt.putDouble("entryX", entryPos.x); + nbt.putDouble("entryY", entryPos.y); + nbt.putDouble("entryZ", entryPos.z); + nbt.putFloat( "entryYaw", entryYaw); + nbt.putFloat( "entryPitch", entryPitch); + return nbt; + } + + public void setEntry(Vec3 pos, float yaw, float pitch) { + this.entryPos = pos; + this.entryYaw = yaw; + this.entryPitch = pitch; + this.setDirty(); + } + + public Vec3 getEntryPos() { return entryPos; } + public float getEntryYaw() { return entryYaw; } + public float getEntryPitch() { return entryPitch; } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/data/PlayerEntryData.java b/src/main/java/io/lampnet/travelerssuitcase/data/PlayerEntryData.java new file mode 100644 index 0000000..d2057f2 --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/data/PlayerEntryData.java @@ -0,0 +1,57 @@ +package io.lampnet.travelerssuitcase.data; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.saveddata.SavedData; +import net.minecraft.world.phys.Vec3; + +public class PlayerEntryData extends SavedData { + private static final String DATA_KEY = "pocket_player_entry"; + + private Vec3 entryPos = Vec3.ZERO; + private float entryYaw = 0f, entryPitch = 0f; + + public PlayerEntryData() { + super(); + this.entryPos = new Vec3(17.5, 97, 9.5); + this.entryYaw = 0f; + this.entryPitch = 0f; + } + + public static PlayerEntryData load(CompoundTag nbt) { + PlayerEntryData data = new PlayerEntryData(); + data.entryPos = new Vec3( + nbt.getDouble("px"), + nbt.getDouble("py"), + nbt.getDouble("pz") + ); + data.entryYaw = nbt.getFloat("pyaw"); + data.entryPitch = nbt.getFloat("ppitch"); + return data; + } + + public static PlayerEntryData get(ServerLevel world) { + return world.getDataStorage().computeIfAbsent(PlayerEntryData::load, PlayerEntryData::new, DATA_KEY); + } + + @Override + public CompoundTag save(CompoundTag nbt) { + nbt.putDouble("px", entryPos.x); + nbt.putDouble("py", entryPos.y); + nbt.putDouble("pz", entryPos.z); + nbt.putFloat( "pyaw", entryYaw); + nbt.putFloat( "ppitch", entryPitch); + return nbt; + } + + public void setEntry(Vec3 pos, float yaw, float pitch) { + this.entryPos = pos; + this.entryYaw = yaw; + this.entryPitch = pitch; + this.setDirty(); + } + + public Vec3 getEntryPos() { return entryPos; } + public float getEntryYaw() { return entryYaw; } + public float getEntryPitch() { return entryPitch; } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/item/KeystoneItem.java b/src/main/java/io/lampnet/travelerssuitcase/item/KeystoneItem.java index f47afc8..e821e54 100644 --- a/src/main/java/io/lampnet/travelerssuitcase/item/KeystoneItem.java +++ b/src/main/java/io/lampnet/travelerssuitcase/item/KeystoneItem.java @@ -1,26 +1,42 @@ package io.lampnet.travelerssuitcase.item; import io.lampnet.travelerssuitcase.TravelersSuitcase; +import io.lampnet.travelerssuitcase.world.Fantasy; + +import io.lampnet.travelerssuitcase.world.FantasyWorldAccess; +import io.lampnet.travelerssuitcase.world.PortalChunkGenerator; +import io.lampnet.travelerssuitcase.world.RuntimeWorldConfig; +import io.lampnet.travelerssuitcase.world.RuntimeWorldHandle; import net.minecraft.ChatFormatting; -import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.MinecraftServer; -import net.minecraft.sounds.SoundSource; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.network.chat.Component; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.chunk.ChunkStatus; +import net.minecraft.server.level.TicketType; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; import net.minecraft.world.level.storage.LevelResource; -import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import net.minecraft.world.item.ItemStack.TooltipPart; import java.io.IOException; import java.nio.file.Files; @@ -39,35 +55,143 @@ public class KeystoneItem extends Item { @Override public @NotNull InteractionResultHolder use(@NotNull Level world, Player player, @NotNull InteractionHand hand) { ItemStack stack = player.getItemInHand(hand); - String keystoneName = stack.hasCustomHoverName() ? stack.getHoverName().getString().toLowerCase() : ""; - String defaultName = "item.travelerssuitcase.keystone"; - if (!stack.hasCustomHoverName() || keystoneName.isEmpty() || keystoneName.equals(Component.translatable(defaultName).getString().toLowerCase())) { - return InteractionResultHolder.pass(stack); - } - if (world.isClientSide) { - return InteractionResultHolder.success(stack); - } + + // If already enchanted, do nothing if (stack.isEnchanted()) { return InteractionResultHolder.pass(stack); } - String dimensionName = "pocket_dimension_" + keystoneName.replaceAll("[^a-z0-9_]", ""); - createDimension(world.getServer(), dimensionName); - stack.enchant(Enchantments.BINDING_CURSE, 1); - stack.hideTooltipPart(TooltipPart.ENCHANTMENTS); - stack.hideTooltipPart(TooltipPart.MODIFIERS); - CompoundTag nbt = stack.getOrCreateTag(); - nbt.putInt("RepairCost", 32767); - world.playSound(null, player.getX(), player.getY(), player.getZ(), - SoundEvents.AMETHYST_CLUSTER_FALL, SoundSource.PLAYERS, 2.0F, 2.0F); + + // If no valid custom name, do nothing + if (!isValidKeystone(stack)) { + return InteractionResultHolder.pass(stack); + } + + // On client side, just return success + if (world.isClientSide) { + return InteractionResultHolder.success(stack); + } + + // The actual enchantment and dimension creation now happens in inventoryTick return InteractionResultHolder.success(stack); } + private void createOrLoadPersistentDimension(MinecraftServer server, String dimensionName) { + ResourceLocation worldId = ResourceLocation.fromNamespaceAndPath(TravelersSuitcase.MODID, dimensionName); + + Path worldSavePath = server.getWorldPath(LevelResource.ROOT) + .resolve("dimensions") + .resolve(TravelersSuitcase.MODID) + .resolve(dimensionName); + boolean dimensionExists = Files.exists(worldSavePath); + + // Get biome registry - if this fails, the server isn't ready yet + var biomeRegistry = server.registryAccess().registryOrThrow(Registries.BIOME); + + RuntimeWorldConfig config = new RuntimeWorldConfig() + .setGenerator(new PortalChunkGenerator(biomeRegistry)) + .setSeed(server.overworld().getSeed()) + .setShouldTickTime(true); + + RuntimeWorldHandle handle = Fantasy.get(server) + .getOrOpenPersistentWorld(worldId, config); + + // Ensure the pocket dimension ticks even when empty to prevent entity tick issues + handle.setTickWhenEmpty(true); + + TravelersSuitcase.LOGGER.info("Created/loaded pocket dimension '{}', ticking enabled: {}", + dimensionName, ((FantasyWorldAccess) handle.asWorld()).fantasy$shouldTick()); + + registerDimension(server, dimensionName); + + if (!dimensionExists) { + ServerLevel world = handle.asWorld(); + // Schedule structure placement for next tick to ensure world is fully initialized + server.execute(() -> placeStructureDelayed(server, world, dimensionName)); + } + } + + private void placeStructureDelayed(MinecraftServer server, ServerLevel world, String dimensionName) { + try { + StructureTemplate template = server.getStructureManager() + .get(ResourceLocation.fromNamespaceAndPath(TravelersSuitcase.MODID, "pocket_island_01")) + .orElse(null); + + if (template != null) { + BlockPos pos = new BlockPos(0, 64, 0); + + // Ensure the chunk is fully loaded and ready + ChunkPos chunkPos = new ChunkPos(pos); + world.getChunkSource().addRegionTicket(TicketType.UNKNOWN, chunkPos, 2, chunkPos); + + // Force chunk to be fully loaded with all features + world.getChunk(pos.getX() >> 4, pos.getZ() >> 4, ChunkStatus.FULL, true); + + // Place blocks first without entities to ensure support blocks exist + template.placeInWorld( + world, + pos, + pos, + new StructurePlaceSettings() + .setMirror(Mirror.NONE) + .setRotation(Rotation.NONE) + .setIgnoreEntities(true), // Skip entities first + world.getRandom(), + Block.UPDATE_ALL + ); + + world.setChunkForced(pos.getX() >> 4, pos.getZ() >> 4, true); + + // Now place the structure again with entities, blocks won't replace since they're already there + template.placeInWorld( + world, + pos, + pos, + new StructurePlaceSettings() + .setMirror(Mirror.NONE) + .setRotation(Rotation.NONE) + .setIgnoreEntities(false), + world.getRandom(), + Block.UPDATE_NEIGHBORS // Only update neighbors, don't replace existing blocks + ); + + // Force a save to ensure the forced chunk data is properly loaded for ticking + world.save(null, true, false); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void registerDimension(MinecraftServer server, String dimensionName) { + Path registryDir = server.getWorldPath(LevelResource.ROOT) + .resolve("data") + .resolve(TravelersSuitcase.MODID) + .resolve("dimension_registry"); + + try { + Files.createDirectories(registryDir); + Path registryFile = registryDir.resolve("registry.txt"); + + // load existing lines + Set dims = new HashSet<>(); + if (Files.exists(registryFile)) { + dims.addAll(Files.readAllLines(registryFile)); + } + + // add + save only if new + if (dims.add(dimensionName)) { + Files.write(registryFile, dims); + } + } catch (IOException e) { + TravelersSuitcase.LOGGER.error("Failed to write dimension registry", e); + } + } + public static boolean isValidKeystone(ItemStack stack) { String keystoneName = stack.hasCustomHoverName() ? stack.getHoverName().getString().toLowerCase() : ""; String defaultNameKey = "item.travelerssuitcase.keystone"; return stack.hasCustomHoverName() && !keystoneName.isEmpty() && - !keystoneName.equals(Component.translatable(defaultNameKey).getString().toLowerCase()) && - stack.isEnchanted(); + !keystoneName.equals(Component.translatable(defaultNameKey).getString().toLowerCase()); } @Override @@ -84,104 +208,36 @@ public class KeystoneItem extends Item { public void inventoryTick(ItemStack stack, @NotNull Level world, @NotNull Entity entity, int slot, boolean selected) { String keystoneName = stack.hasCustomHoverName() ? stack.getHoverName().getString().toLowerCase() : ""; String defaultNameKey = "item.travelerssuitcase.keystone"; - if (!stack.hasCustomHoverName() || keystoneName.isEmpty() || - keystoneName.equals(Component.translatable(defaultNameKey).getString().toLowerCase())) { + boolean hasValidName = isValidKeystone(stack); + + if (!hasValidName) { CompoundTag nbt = stack.getOrCreateTag(); nbt.putInt("CustomModelData", 1); } else if (stack.getTag() != null && stack.getTag().contains("CustomModelData")) { stack.getTag().remove("CustomModelData"); } - } - private boolean createDimension(MinecraftServer server, String dimensionName) { - if (server == null) { - TravelersSuitcase.LOGGER.error("Failed to create dimension: " + dimensionName + " (MinecraftServer instance is null)"); - return false; - } - try { - Path datapackPath = server.getWorldPath(LevelResource.ROOT) - .resolve("datapacks") - .resolve("travelerssuitcase"); - Path dimensionPath = datapackPath - .resolve("data") - .resolve("travelerssuitcase") - .resolve("dimension"); - Files.createDirectories(dimensionPath); - createPackMcmeta(datapackPath); - Path dimensionFile = dimensionPath.resolve(dimensionName + ".json"); - boolean dimensionExists = Files.exists(dimensionFile); + // Auto-enchant and create dimension when item gets a valid custom name + if (!world.isClientSide() && hasValidName && !stack.isEnchanted()) { + String dimensionName = "pocket_dimension_" + keystoneName.replaceAll("[^a-z0-9_]", ""); + createOrLoadPersistentDimension(world.getServer(), dimensionName); - ResourceLocation dimensionKeyLocation = new ResourceLocation("travelerssuitcase", dimensionName); - boolean isDimensionRegistered = server.levelKeys().stream() - .anyMatch(key -> key.location().equals(dimensionKeyLocation)); - - Path dimensionRegistryPath = server.getWorldPath(LevelResource.ROOT) - .resolve("data") - .resolve("travelerssuitcase") - .resolve("dimension_registry"); - Files.createDirectories(dimensionRegistryPath); - Path dimensionRegistryFile = dimensionRegistryPath.resolve("registry.txt"); - Set registeredDimensionsInFile; - if (Files.exists(dimensionRegistryFile)) { - registeredDimensionsInFile = new HashSet<>(Files.readAllLines(dimensionRegistryFile)); - } else { - registeredDimensionsInFile = new HashSet<>(); + stack.enchant(Enchantments.BINDING_CURSE, 1); + CompoundTag nbt = stack.getOrCreateTag(); + nbt.putInt("RepairCost", 32767); + + // Play sound effect if entity is a player + if (entity instanceof Player player) { + world.playSound(null, player.getX(), player.getY(), player.getZ(), + SoundEvents.AMETHYST_CLUSTER_FALL, SoundSource.PLAYERS, 2.0F, 2.0F); } - boolean isDimensionInRegistryFile = registeredDimensionsInFile.contains(dimensionName); - - if (!dimensionExists) { - String dimensionJson = """ - { - "type": "travelerssuitcase:pocket_dimension_type", - "generator": { - "type": "minecraft:flat", - "settings": { - "biome": "travelerssuitcase:pocket_islands", - "layers": [ - { - "block": "travelerssuitcase:portal", - "height": 1 - } - ] - } - } - } - """; - Files.writeString(dimensionFile, dimensionJson); - if (!isDimensionInRegistryFile) { - registeredDimensionsInFile.add(dimensionName); - Files.write(dimensionRegistryFile, registeredDimensionsInFile); - } - } - - if (!isDimensionInRegistryFile && !isDimensionRegistered) { - Path structureMarkerPath = server.getWorldPath(LevelResource.ROOT) - .resolve("data") - .resolve("travelerssuitcase") - .resolve("pending_structures"); - Files.createDirectories(structureMarkerPath); - Files.writeString(structureMarkerPath.resolve(dimensionName + ".txt"), "pending"); - return true; - } - return false; - } catch (IOException e) { - TravelersSuitcase.LOGGER.error("Failed to create dimension: {}", dimensionName, e); - return false; } - } - private void createPackMcmeta(@NotNull Path datapackPath) throws IOException { - Path packMcmeta = datapackPath.resolve("pack.mcmeta"); - if (!Files.exists(packMcmeta)) { - String content = """ - { - "pack": { - "pack_format": 15, - "description": "travelerssuitcase Dimensions" - } - } - """; - Files.writeString(packMcmeta, content); + if (!world.isClientSide() && stack.hasTag() && stack.getTag().contains("Enchantments")) { + CompoundTag nbt = stack.getOrCreateTag(); + if (nbt.getInt("RepairCost") < 32767) { + nbt.putInt("RepairCost", 32767); + } } } } \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/mixin/LevelStemMixin.java b/src/main/java/io/lampnet/travelerssuitcase/mixin/LevelStemMixin.java new file mode 100644 index 0000000..eae5bf1 --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/mixin/LevelStemMixin.java @@ -0,0 +1,34 @@ +package io.lampnet.travelerssuitcase.mixin; + +import io.lampnet.travelerssuitcase.world.FantasyDimensionOptions; +import net.minecraft.world.level.dimension.LevelStem; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +@Mixin(LevelStem.class) +public class LevelStemMixin implements FantasyDimensionOptions { + @Unique + private boolean fantasy$save = true; + @Unique + private boolean fantasy$saveProperties = true; + + @Override + public void fantasy$setSave(boolean value) { + this.fantasy$save = value; + } + + @Override + public boolean fantasy$getSave() { + return this.fantasy$save; + } + + @Override + public void fantasy$setSaveProperties(boolean value) { + this.fantasy$saveProperties = value; + } + + @Override + public boolean fantasy$getSaveProperties() { + return this.fantasy$saveProperties; + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/mixin/MappedRegistryMixin.java b/src/main/java/io/lampnet/travelerssuitcase/mixin/MappedRegistryMixin.java new file mode 100644 index 0000000..963543c --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/mixin/MappedRegistryMixin.java @@ -0,0 +1,46 @@ +package io.lampnet.travelerssuitcase.mixin; + +import io.lampnet.travelerssuitcase.world.RemoveFromRegistry; +import net.minecraft.core.MappedRegistry; +import net.minecraft.resources.ResourceLocation; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; + +@Mixin(MappedRegistry.class) +public abstract class MappedRegistryMixin implements RemoveFromRegistry { + @Shadow + private boolean frozen; + + @Unique + private boolean fantasy$originalFrozenState = false; + + @Override + public boolean fantasy$remove(T value) { + // Implementation depends on access to private fields + // For now, return false as removal is complex + return false; + } + + @Override + public boolean fantasy$remove(ResourceLocation key) { + // Implementation depends on access to private fields + // For now, return false as removal is complex + return false; + } + + @Override + public void fantasy$setFrozen(boolean value) { + // Store the original frozen state so we can restore it later + if (!value && this.frozen) { + this.fantasy$originalFrozenState = true; + } + // Actually modify the registry's frozen state + this.frozen = value; + } + + @Override + public boolean fantasy$isFrozen() { + return this.frozen; + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/mixin/MinecraftServerAccess.java b/src/main/java/io/lampnet/travelerssuitcase/mixin/MinecraftServerAccess.java new file mode 100644 index 0000000..0368b6b --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/mixin/MinecraftServerAccess.java @@ -0,0 +1,20 @@ +package io.lampnet.travelerssuitcase.mixin; + +import net.minecraft.resources.ResourceKey; +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 org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.Map; + +@Mixin(MinecraftServer.class) +public interface MinecraftServerAccess { + @Accessor("levels") + Map, ServerLevel> getWorlds(); + + @Accessor("storageSource") + LevelStorageSource.LevelStorageAccess getSession(); +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/mixin/ServerChunkManagerMixin.java b/src/main/java/io/lampnet/travelerssuitcase/mixin/ServerChunkManagerMixin.java new file mode 100644 index 0000000..32c07dc --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/mixin/ServerChunkManagerMixin.java @@ -0,0 +1,30 @@ +package io.lampnet.travelerssuitcase.mixin; + +import io.lampnet.travelerssuitcase.world.FantasyWorldAccess; +import io.lampnet.travelerssuitcase.world.RuntimeWorld; +import net.minecraft.server.level.ServerChunkCache; +import net.minecraft.server.level.ServerLevel; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(ServerChunkCache.class) +public class ServerChunkManagerMixin { + @Shadow + @Final + private ServerLevel level; + + @Inject(method = "runDistanceManagerUpdates", at = @At("HEAD"), cancellable = true) + private void onRunDistanceManagerUpdates(CallbackInfoReturnable cir) { + // Only apply special chunk processing logic to RuntimeWorld instances (fantasy dimensions) + if (this.level instanceof RuntimeWorld) { + if (!((FantasyWorldAccess) this.level).fantasy$shouldTick()) { + cir.setReturnValue(false); + } + } + // Regular worlds (overworld, nether, end) process chunks normally without interference + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/mixin/ServerWorldMixin.java b/src/main/java/io/lampnet/travelerssuitcase/mixin/ServerWorldMixin.java new file mode 100644 index 0000000..008fa4f --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/mixin/ServerWorldMixin.java @@ -0,0 +1,58 @@ +package io.lampnet.travelerssuitcase.mixin; + +import io.lampnet.travelerssuitcase.world.FantasyWorldAccess; +import io.lampnet.travelerssuitcase.world.RuntimeWorld; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; +import java.util.function.BooleanSupplier; + +@Mixin(ServerLevel.class) +public abstract class ServerWorldMixin implements FantasyWorldAccess { + @Unique + private boolean fantasy$tickWhenEmpty = false; // Default to false, will be set to true for fantasy worlds + + @Inject(method = "tick", at = @At("HEAD"), cancellable = true) + private void onTick(BooleanSupplier shouldKeepTicking, CallbackInfo ci) { + // Only apply special tick logic to RuntimeWorld instances (fantasy dimensions) + if ((Object) this instanceof RuntimeWorld) { + if (!this.fantasy$shouldTick()) { + ci.cancel(); + } + } + // Regular worlds (overworld, nether, end) tick normally without interference + } + + @Shadow + public abstract List players(); + + @Shadow + public abstract net.minecraft.server.level.ServerChunkCache getChunkSource(); + + @Override + public void fantasy$setTickWhenEmpty(boolean tickWhenEmpty) { + this.fantasy$tickWhenEmpty = tickWhenEmpty; + } + + @Override + public boolean fantasy$shouldTick() { + // For RuntimeWorld instances, use the configured behavior + if ((Object) this instanceof RuntimeWorld) { + return this.fantasy$tickWhenEmpty || !this.isWorldEmpty(); + } + // For regular worlds, always tick (normal behavior) + return true; + } + + @Unique + private boolean isWorldEmpty() { + return this.players().isEmpty() && this.getChunkSource().getLoadedChunksCount() <= 0; + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/util/FilteredRegistry.java b/src/main/java/io/lampnet/travelerssuitcase/util/FilteredRegistry.java new file mode 100644 index 0000000..8ef5618 --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/util/FilteredRegistry.java @@ -0,0 +1,144 @@ +package io.lampnet.travelerssuitcase.util; + +import com.google.common.collect.Iterators; +import com.mojang.serialization.Lifecycle; +import net.minecraft.core.Holder; +import net.minecraft.core.MappedRegistry; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nullable; +import java.util.*; +import java.util.function.Predicate; +import java.util.stream.Stream; + +public class FilteredRegistry extends MappedRegistry { + private final Registry source; + private final Predicate check; + + public FilteredRegistry(Registry source, Predicate check) { + super(source.key(), source.registryLifecycle(), false); + this.source = source; + this.check = check; + } + + public Registry getSource() { + return this.source; + } + + @Nullable + @Override + public ResourceLocation getKey(T value) { + return check.test(value) ? this.source.getKey(value) : null; + } + + @Override + public Optional> getResourceKey(T entry) { + return check.test(entry) ? this.source.getResourceKey(entry) : Optional.empty(); + } + + @Override + public int getId(@Nullable T value) { + return check.test(value) ? this.source.getId(value) : -1; + } + + public T get(int index) { + return this.source.byId(index); + } + + @Override + public int size() { + return (int) this.source.stream().filter(check).count(); + } + + @Nullable + @Override + public T get(@Nullable ResourceKey key) { + T value = this.source.get(key); + return (value != null && check.test(value)) ? value : null; + } + + @Nullable + @Override + public T get(@Nullable ResourceLocation id) { + T value = this.source.get(id); + return (value != null && check.test(value)) ? value : null; + } + + @Override + public Lifecycle lifecycle(T entry) { + return this.source.lifecycle(entry); + } + + @Override + public @NotNull Set keySet() { + Set keys = new HashSet<>(); + this.source.keySet().forEach(key -> { + T value = this.source.get(key); + if(value != null && check.test(value)) { + keys.add(key); + } + }); + return keys; + } + + @Override + public @NotNull Set, T>> entrySet() { + Set, T>> set = new HashSet<>(); + for (Map.Entry, T> e : this.source.entrySet()) { + if (this.check.test(e.getValue())) { + set.add(e); + } + } + return set; + } + + @Override + public boolean containsKey(ResourceLocation id) { + T value = this.source.get(id); + return value != null && check.test(value); + } + + @Override + public boolean containsKey(ResourceKey key) { + T value = this.source.get(key); + return value != null && check.test(value); + } + + @Override + public @NotNull Iterator iterator() { + return Iterators.filter(this.source.iterator(), e -> this.check.test(e)); + } + + // Methods below are for WritableRegistry, we don't support writing to a filtered registry + @Override + public Holder.Reference register(ResourceKey resourceKey, T object, Lifecycle lifecycle) { + throw new UnsupportedOperationException("Cannot register to a filtered registry"); + } + + public Holder.Reference registerOrNah(ResourceKey resourceKey, T object, Lifecycle lifecycle) { + throw new UnsupportedOperationException("Cannot register to a filtered registry"); + } + + @Override + public Holder.Reference registerMapping(int i, ResourceKey resourceKey, T object, Lifecycle lifecycle) { + throw new UnsupportedOperationException("Cannot register to a filtered registry"); + } + + @Override + public Holder.Reference getHolderOrThrow(ResourceKey resourceKey) { + return this.source.getHolderOrThrow(resourceKey); + } + + @Override + public Optional> getHolder(ResourceKey resourceKey) { + return this.source.getHolder(resourceKey); + } + + @Override + public Stream> holders() { + return this.source.holders().filter(h -> check.test(h.value())); + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/util/GameRuleStore.java b/src/main/java/io/lampnet/travelerssuitcase/util/GameRuleStore.java new file mode 100644 index 0000000..cd76349 --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/util/GameRuleStore.java @@ -0,0 +1,37 @@ +package io.lampnet.travelerssuitcase.util; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.level.GameRules; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +public final class GameRuleStore { + private final Map, Boolean> booleanRules = new HashMap<>(); + private final Map, Integer> intRules = new HashMap<>(); + + public void set(GameRules.Key key, boolean value) { + this.booleanRules.put(key, value); + } + + public void set(GameRules.Key key, int value) { + this.intRules.put(key, value); + } + + public boolean contains(GameRules.Key key) { + return this.booleanRules.containsKey(key) || this.intRules.containsKey(key); + } + + public void applyTo(GameRules rules, @Nullable MinecraftServer server) { + for (Map.Entry, Boolean> entry : this.booleanRules.entrySet()) { + GameRules.BooleanValue rule = rules.getRule(entry.getKey()); + rule.set(entry.getValue(), server); + } + + for (Map.Entry, Integer> entry : this.intRules.entrySet()) { + GameRules.IntegerValue rule = rules.getRule(entry.getKey()); + rule.set(entry.getValue(), server); + } + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/util/SafeIterator.java b/src/main/java/io/lampnet/travelerssuitcase/util/SafeIterator.java new file mode 100644 index 0000000..4446537 --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/util/SafeIterator.java @@ -0,0 +1,23 @@ +package io.lampnet.travelerssuitcase.util; + +import java.util.Collection; +import java.util.Iterator; + +public final class SafeIterator implements Iterator { + private final Object[] values; + private int index = 0; + + public SafeIterator(Collection source) { + this.values = source.toArray(); + } + + @Override + public boolean hasNext() { + return this.values.length > this.index; + } + + @Override + public T next() { + return (T) this.values[this.index++]; + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/util/VoidChunkGenerator.java b/src/main/java/io/lampnet/travelerssuitcase/util/VoidChunkGenerator.java new file mode 100644 index 0000000..aa9c226 --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/util/VoidChunkGenerator.java @@ -0,0 +1,90 @@ +package io.lampnet.travelerssuitcase.util; + +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Registry; +import net.minecraft.server.level.WorldGenRegion; +import net.minecraft.world.level.LevelHeightAccessor; +import net.minecraft.world.level.NoiseColumn; +import net.minecraft.world.level.StructureManager; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeManager; +import net.minecraft.world.level.biome.Biomes; +import net.minecraft.world.level.biome.FixedBiomeSource; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.GenerationStep; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.RandomState; +import net.minecraft.world.level.levelgen.blending.Blender; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; + +public class VoidChunkGenerator extends ChunkGenerator { + public static final Codec CODEC = Codec.unit(VoidChunkGenerator::new); + + public VoidChunkGenerator(Registry biomeRegistry) { + super(new FixedBiomeSource(biomeRegistry.getHolderOrThrow(Biomes.THE_VOID))); + } + + public VoidChunkGenerator() { + super(new FixedBiomeSource(null)); + } + + @Override + protected @NotNull Codec codec() { + return CODEC; + } + + @Override + public void applyCarvers(WorldGenRegion worldGenRegion, long seed, RandomState randomState, BiomeManager biomeManager, StructureManager structureManager, ChunkAccess chunkAccess, GenerationStep.Carving carving) { + } + + @Override + public void spawnOriginalMobs(WorldGenRegion worldGenRegion) { + } + + @Override + public int getGenDepth() { + return 384; + } + + @Override + public @NotNull CompletableFuture fillFromNoise(Executor executor, Blender blender, RandomState randomState, StructureManager structureManager, ChunkAccess chunkAccess) { + return CompletableFuture.completedFuture(chunkAccess); + } + + @Override + public int getSeaLevel() { + return 0; + } + + @Override + public int getMinY() { + return 0; + } + + @Override + public int getBaseHeight(int i, int j, Heightmap.Types types, LevelHeightAccessor levelHeightAccessor, RandomState randomState) { + return 0; + } + + @Override + public @NotNull NoiseColumn getBaseColumn(int i, int j, LevelHeightAccessor levelHeightAccessor, RandomState randomState) { + return new NoiseColumn(0, new BlockState[0]); + } + + @Override + public void addDebugScreenInfo(List list, RandomState randomState, BlockPos blockPos) { + } + + @Override + public void buildSurface(WorldGenRegion worldGenRegion, StructureManager structureManager, RandomState randomState, + ChunkAccess chunkAccess) { + // No surface to build for void chunks + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/util/VoidWorldProgressListener.java b/src/main/java/io/lampnet/travelerssuitcase/util/VoidWorldProgressListener.java new file mode 100644 index 0000000..6469156 --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/util/VoidWorldProgressListener.java @@ -0,0 +1,33 @@ +package io.lampnet.travelerssuitcase.util; + +import net.minecraft.server.level.progress.ChunkProgressListener; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.chunk.ChunkStatus; +import org.jetbrains.annotations.Nullable; + +public class VoidWorldProgressListener implements ChunkProgressListener { + public static final VoidWorldProgressListener INSTANCE = new VoidWorldProgressListener(); + + private VoidWorldProgressListener() { + } + + @Override + public void updateSpawnPos(ChunkPos spawnPos) { + // Do nothing + } + + @Override + public void onStatusChange(ChunkPos pos, @Nullable ChunkStatus status) { + // Do nothing + } + + @Override + public void start() { + // Do nothing + } + + @Override + public void stop() { + // Do nothing + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/world/Fantasy.java b/src/main/java/io/lampnet/travelerssuitcase/world/Fantasy.java new file mode 100644 index 0000000..be30aa9 --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/world/Fantasy.java @@ -0,0 +1,198 @@ +package io.lampnet.travelerssuitcase.world; + +import com.google.common.base.Preconditions; +import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; +import io.lampnet.travelerssuitcase.mixin.MinecraftServerAccess; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.storage.LevelStorageSource; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.TickEvent; +import net.minecraftforge.event.server.ServerStoppingEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +public final class Fantasy { + public static final Logger LOGGER = LogManager.getLogger(Fantasy.class); + public static final String ID = "fantasy"; + public static final ResourceKey DEFAULT_DIM_TYPE = ResourceKey.create(Registries.LEVEL_STEM, ResourceLocation.fromNamespaceAndPath(Fantasy.ID, "default")); + + private static Fantasy instance; + + private final MinecraftServer server; + private final MinecraftServerAccess serverAccess; + + private final RuntimeWorldManager worldManager; + + private final Set deletionQueue = new ReferenceOpenHashSet<>(); + private final Set unloadingQueue = new ReferenceOpenHashSet<>(); + + static { + // We need to register the event listener on the bus. + MinecraftForge.EVENT_BUS.register(Fantasy.class); + } + + private Fantasy(MinecraftServer server) { + this.server = server; + this.serverAccess = (MinecraftServerAccess) server; + this.worldManager = new RuntimeWorldManager(server); + } + + public static Fantasy get(MinecraftServer server) { + Preconditions.checkState(server.isSameThread(), "cannot create worlds from off-thread!"); + + if (instance == null || instance.server != server) { + instance = new Fantasy(server); + } + + return instance; + } + + @SubscribeEvent + public static void onServerTick(TickEvent.ServerTickEvent event) { + if (event.phase == TickEvent.Phase.START && instance != null) { + instance.tick(); + } + } + + @SubscribeEvent + public static void onServerStopping(ServerStoppingEvent event) { + if(instance != null) { + instance.onServerStopping(); + } + } + + private void tick() { + Set deletionQueue = this.deletionQueue; + if (!deletionQueue.isEmpty()) { + deletionQueue.removeIf(this::tickDeleteWorld); + } + + Set unloadingQueue = this.unloadingQueue; + if (!unloadingQueue.isEmpty()) { + unloadingQueue.removeIf(this::tickUnloadWorld); + } + } + + public RuntimeWorldHandle openTemporaryWorld(RuntimeWorldConfig config) { + RuntimeWorld world = this.addTemporaryWorld(config); + return new RuntimeWorldHandle(this, world); + } + + public RuntimeWorldHandle getOrOpenPersistentWorld(ResourceLocation key, RuntimeWorldConfig config) { + ResourceKey worldKey = ResourceKey.create(Registries.DIMENSION, key); + + ServerLevel world = this.server.getLevel(worldKey); + if (world == null) { + world = this.addPersistentWorld(key, config); + } else { + this.deletionQueue.remove(world); + } + + return new RuntimeWorldHandle(this, world); + } + + private RuntimeWorld addPersistentWorld(ResourceLocation key, RuntimeWorldConfig config) { + ResourceKey worldKey = ResourceKey.create(Registries.DIMENSION, key); + return this.worldManager.add(worldKey, config, RuntimeWorld.Style.PERSISTENT); + } + + private RuntimeWorld addTemporaryWorld(RuntimeWorldConfig config) { + ResourceKey worldKey = ResourceKey.create(Registries.DIMENSION, generateTemporaryWorldKey()); + + try { + LevelStorageSource.LevelStorageAccess session = this.serverAccess.getSession(); + FileUtils.forceDeleteOnExit(session.getDimensionPath(worldKey).toFile()); + } catch (IOException ignored) { + } + + return this.worldManager.add(worldKey, config, RuntimeWorld.Style.TEMPORARY); + } + + void enqueueWorldDeletion(ServerLevel world) { + this.server.execute(() -> this.deletionQueue.add(world)); + } + + void enqueueWorldUnloading(ServerLevel world) { + this.server.execute(() -> this.unloadingQueue.add(world)); + } + + private boolean tickDeleteWorld(ServerLevel world) { + if (this.isWorldUnloaded(world)) { + this.worldManager.delete(world); + return true; + } else { + this.kickPlayers(world); + return false; + } + } + + private boolean tickUnloadWorld(ServerLevel world) { + if (this.isWorldUnloaded(world)) { + this.worldManager.unload(world); + return true; + } else { + this.kickPlayers(world); + return false; + } + } + + private void kickPlayers(ServerLevel world) { + if (world.players().isEmpty()) { + return; + } + + ServerLevel overworld = this.server.overworld(); + BlockPos spawnPos = overworld.getSharedSpawnPos(); + float spawnAngle = overworld.getSharedSpawnAngle(); + + List players = new ArrayList<>(world.players()); + for (ServerPlayer player : players) { + player.teleportTo(overworld, spawnPos.getX() + 0.5, spawnPos.getY(), spawnPos.getZ() + 0.5, spawnAngle, 0.0F); + } + } + + private boolean isWorldUnloaded(ServerLevel world) { + return world.players().isEmpty() && world.getChunkSource().getLoadedChunksCount() <= 0; + } + + private void onServerStopping() { + List temporaryWorlds = this.collectTemporaryWorlds(); + for (RuntimeWorld temporary : temporaryWorlds) { + this.kickPlayers(temporary); + this.worldManager.delete(temporary); + } + } + + private List collectTemporaryWorlds() { + List temporaryWorlds = new ArrayList<>(); + for (ServerLevel world : this.server.getAllLevels()) { + if (world instanceof RuntimeWorld runtimeWorld) { + if (runtimeWorld.style == RuntimeWorld.Style.TEMPORARY) { + temporaryWorlds.add(runtimeWorld); + } + } + } + return temporaryWorlds; + } + + private static ResourceLocation generateTemporaryWorldKey() { + String key = RandomStringUtils.random(16, "abcdefghijklmnopqrstuvwxyz0123456789"); + return ResourceLocation.fromNamespaceAndPath(Fantasy.ID, key); + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/world/FantasyDimensionOptions.java b/src/main/java/io/lampnet/travelerssuitcase/world/FantasyDimensionOptions.java new file mode 100644 index 0000000..372f888 --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/world/FantasyDimensionOptions.java @@ -0,0 +1,17 @@ +package io.lampnet.travelerssuitcase.world; + +import net.minecraft.world.level.dimension.LevelStem; +import org.jetbrains.annotations.ApiStatus; + +import java.util.function.Predicate; + +@ApiStatus.Internal +public interface FantasyDimensionOptions { + Predicate SAVE_PREDICATE = (e) -> ((FantasyDimensionOptions) (Object) e).fantasy$getSave(); + Predicate SAVE_PROPERTIES_PREDICATE = (e) -> ((FantasyDimensionOptions) (Object) e).fantasy$getSaveProperties(); + + void fantasy$setSave(boolean value); + boolean fantasy$getSave(); + void fantasy$setSaveProperties(boolean value); + boolean fantasy$getSaveProperties(); +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/world/FantasyInitializer.java b/src/main/java/io/lampnet/travelerssuitcase/world/FantasyInitializer.java new file mode 100644 index 0000000..5de6e8a --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/world/FantasyInitializer.java @@ -0,0 +1,15 @@ +package io.lampnet.travelerssuitcase.world; + +import io.lampnet.travelerssuitcase.util.VoidChunkGenerator; +import net.minecraft.core.Registry; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; + +import static io.lampnet.travelerssuitcase.TravelersSuitcase.MODID; + +public final class FantasyInitializer { + public void onInitialize() { + Registry.register(BuiltInRegistries.CHUNK_GENERATOR, ResourceLocation.fromNamespaceAndPath(MODID, "void"), VoidChunkGenerator.CODEC); + Registry.register(BuiltInRegistries.CHUNK_GENERATOR, ResourceLocation.fromNamespaceAndPath(MODID, "portal"), PortalChunkGenerator.CODEC); + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/world/FantasyWorldAccess.java b/src/main/java/io/lampnet/travelerssuitcase/world/FantasyWorldAccess.java new file mode 100644 index 0000000..9a51f2c --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/world/FantasyWorldAccess.java @@ -0,0 +1,10 @@ +package io.lampnet.travelerssuitcase.world; + +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +public interface FantasyWorldAccess { + void fantasy$setTickWhenEmpty(boolean tickWhenEmpty); + + boolean fantasy$shouldTick(); +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/world/PortalChunkGenerator.java b/src/main/java/io/lampnet/travelerssuitcase/world/PortalChunkGenerator.java new file mode 100644 index 0000000..347fb89 --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/world/PortalChunkGenerator.java @@ -0,0 +1,105 @@ +package io.lampnet.travelerssuitcase.world; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Registry; +import net.minecraft.server.level.WorldGenRegion; +import net.minecraft.world.level.LevelHeightAccessor; +import net.minecraft.world.level.NoiseColumn; +import net.minecraft.world.level.StructureManager; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeManager; +import net.minecraft.world.level.biome.BiomeSource; +import net.minecraft.world.level.biome.FixedBiomeSource; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.GenerationStep; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.RandomState; +import net.minecraft.world.level.levelgen.blending.Blender; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; + +public class PortalChunkGenerator extends ChunkGenerator { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> + instance.group( + BiomeSource.CODEC.fieldOf("biome_source").forGetter(ChunkGenerator::getBiomeSource) + ).apply(instance, PortalChunkGenerator::new) + ); + + public PortalChunkGenerator(BiomeSource biomeSource) { + super(biomeSource); + } + + public PortalChunkGenerator(Registry biomeRegistry) { + super(new FixedBiomeSource(biomeRegistry.getHolderOrThrow( + ResourceKey.create(Registries.BIOME, ResourceLocation.fromNamespaceAndPath("travelerssuitcase", "pocket_islands")) + ))); + } + + @Override + protected Codec codec() { + return CODEC; + } + + @Override + public void applyCarvers(WorldGenRegion level, long seed, RandomState randomState, BiomeManager biomeManager, StructureManager structureManager, ChunkAccess chunk, GenerationStep.Carving step) { + // Empty implementation - no carvers needed + } + + @Override + public void buildSurface(WorldGenRegion level, StructureManager structureManager, RandomState randomState, ChunkAccess chunk) { + // Empty implementation - no surface building needed + } + + @Override + public void spawnOriginalMobs(WorldGenRegion level) { + // Empty implementation - no mobs + } + + @Override + public int getGenDepth() { + return 384; + } + + @Override + public CompletableFuture fillFromNoise(Executor executor, Blender blender, RandomState randomState, StructureManager structureManager, ChunkAccess chunk) { + return CompletableFuture.completedFuture(chunk); + } + + @Override + public int getSeaLevel() { + return 63; + } + + @Override + public int getMinY() { + return -64; + } + + @Override + public int getBaseHeight(int x, int z, Heightmap.Types type, LevelHeightAccessor level, RandomState randomState) { + return 0; + } + + @Override + public NoiseColumn getBaseColumn(int x, int z, LevelHeightAccessor level, RandomState randomState) { + BlockState[] column = new BlockState[level.getHeight()]; + for (int i = 0; i < column.length; i++) { + column[i] = Blocks.AIR.defaultBlockState(); + } + return new NoiseColumn(level.getMinBuildHeight(), column); + } + + @Override + public void addDebugScreenInfo(java.util.List info, RandomState randomState, BlockPos pos) { + // Empty implementation + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/world/RemoveFromRegistry.java b/src/main/java/io/lampnet/travelerssuitcase/world/RemoveFromRegistry.java new file mode 100644 index 0000000..dba06b4 --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/world/RemoveFromRegistry.java @@ -0,0 +1,26 @@ +package io.lampnet.travelerssuitcase.world; + +import net.minecraft.core.MappedRegistry; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +public interface RemoveFromRegistry { + @SuppressWarnings("unchecked") + static boolean remove(MappedRegistry registry, ResourceLocation key) { + return ((RemoveFromRegistry) registry).fantasy$remove(key); + } + + @SuppressWarnings("unchecked") + static boolean remove(MappedRegistry registry, T value) { + return ((RemoveFromRegistry) registry).fantasy$remove(value); + } + + boolean fantasy$remove(T value); + + boolean fantasy$remove(ResourceLocation key); + + void fantasy$setFrozen(boolean value); + + boolean fantasy$isFrozen(); +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorld.java b/src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorld.java new file mode 100644 index 0000000..2023dcb --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorld.java @@ -0,0 +1,68 @@ +package io.lampnet.travelerssuitcase.world; + +import com.google.common.collect.ImmutableList; +import io.lampnet.travelerssuitcase.mixin.MinecraftServerAccess; +import io.lampnet.travelerssuitcase.util.VoidWorldProgressListener; +import net.minecraft.Util; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.ProgressListener; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.biome.BiomeManager; +import net.minecraft.world.level.dimension.LevelStem; +import org.jetbrains.annotations.Nullable; + +public class RuntimeWorld extends ServerLevel { + final Style style; + private boolean flat; + + protected RuntimeWorld(MinecraftServer server, ResourceKey registryKey, RuntimeWorldConfig config, Style style) { + super( + server, + Util.backgroundExecutor(), + ((MinecraftServerAccess) server).getSession(), + new RuntimeWorldProperties(server.getWorldData().overworldData(), config), + registryKey, + new LevelStem( + server.registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.DIMENSION_TYPE) + .getHolderOrThrow(net.minecraft.world.level.dimension.BuiltinDimensionTypes.OVERWORLD), + config.getGenerator() + ), + VoidWorldProgressListener.INSTANCE, + false, + BiomeManager.obfuscateSeed(config.getSeed()), + ImmutableList.of(), + config.shouldTickTime(), + null + ); + this.style = style; + this.flat = config.isFlat().equals(RuntimeWorldConfig.TriState.TRUE); + } + + @Override + public long getSeed() { + return super.getSeed(); + } + + @Override + public void save(@Nullable ProgressListener progressListener, boolean flush, boolean enabled) { + if (this.style == Style.PERSISTENT || !flush) { + super.save(progressListener, flush, enabled); + } + } + + @Override + public boolean isFlat() { + return this.flat; + } + + public enum Style { + PERSISTENT, + TEMPORARY + } + + public interface Constructor { + RuntimeWorld createWorld(MinecraftServer server, ResourceKey registryKey, RuntimeWorldConfig config, Style style); + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorldConfig.java b/src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorldConfig.java new file mode 100644 index 0000000..a8cbffe --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorldConfig.java @@ -0,0 +1,199 @@ +package io.lampnet.travelerssuitcase.world; + +import com.google.common.base.Preconditions; +import io.lampnet.travelerssuitcase.util.GameRuleStore; +import net.minecraft.core.Holder; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.Difficulty; +import net.minecraft.world.level.GameRules; +import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.chunk.ChunkGenerator; +import org.jetbrains.annotations.Nullable; + +public final class RuntimeWorldConfig { + private long seed = 0; + private ResourceKey dimensionTypeKey = Fantasy.DEFAULT_DIM_TYPE; + private Holder dimensionType; + private ChunkGenerator generator = null; + private boolean shouldTickTime = false; + private long timeOfDay = 6000; + private Difficulty difficulty = Difficulty.NORMAL; + private final GameRuleStore gameRules = new GameRuleStore(); + private RuntimeWorld.Constructor worldConstructor = RuntimeWorld::new; + + private int sunnyTime = Integer.MAX_VALUE; + private boolean raining; + private int rainTime; + private boolean thundering; + private int thunderTime; + private TriState flat = TriState.DEFAULT; + + // Simple TriState implementation + public enum TriState { + DEFAULT, + TRUE, + FALSE; + + public static TriState of(boolean value) { + return value ? TRUE : FALSE; + } + } + + public RuntimeWorldConfig setSeed(long seed) { + this.seed = seed; + return this; + } + + public RuntimeWorldConfig setWorldConstructor(RuntimeWorld.Constructor constructor) { + this.worldConstructor = constructor; + return this; + } + + public RuntimeWorldConfig setDimensionType(Holder dimensionType) { + this.dimensionType = dimensionType; + this.dimensionTypeKey = null; + return this; + } + + public RuntimeWorldConfig setDimensionType(ResourceKey dimensionTypeKey) { + this.dimensionTypeKey = dimensionTypeKey; + this.dimensionType = null; + return this; + } + + public RuntimeWorldConfig setGenerator(ChunkGenerator generator) { + this.generator = generator; + return this; + } + + public RuntimeWorldConfig setShouldTickTime(boolean shouldTickTime) { + this.shouldTickTime = shouldTickTime; + return this; + } + + public RuntimeWorldConfig setTimeOfDay(long timeOfDay) { + this.timeOfDay = timeOfDay; + return this; + } + + public RuntimeWorldConfig setDifficulty(Difficulty difficulty) { + this.difficulty = difficulty; + return this; + } + + public RuntimeWorldConfig setGameRule(GameRules.Key key, boolean value) { + this.gameRules.set(key, value); + return this; + } + + public RuntimeWorldConfig setGameRule(GameRules.Key key, int value) { + this.gameRules.set(key, value); + return this; + } + + public RuntimeWorldConfig setSunnyTime(int sunnyTime) { + this.sunnyTime = sunnyTime; + return this; + } + + public RuntimeWorldConfig setRaining(int rainTime) { + this.raining = rainTime > 0; + this.rainTime = rainTime; + return this; + } + + public RuntimeWorldConfig setRaining(boolean raining) { + this.raining = raining; + return this; + } + + public RuntimeWorldConfig setThundering(int thunderTime) { + this.thundering = thunderTime > 0; + this.thunderTime = thunderTime; + return this; + } + + public RuntimeWorldConfig setThundering(boolean thundering) { + this.thundering = thundering; + return this; + } + + public RuntimeWorldConfig setFlat(TriState state) { + this.flat = state; + return this; + } + + public RuntimeWorldConfig setFlat(boolean state) { + return this.setFlat(TriState.of(state)); + } + + public long getSeed() { + return this.seed; + } + + public LevelStem createDimensionOptions(MinecraftServer server) { + var dimensionTypeHolder = server.registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.DIMENSION_TYPE) + .getHolderOrThrow(net.minecraft.world.level.dimension.BuiltinDimensionTypes.OVERWORLD); + return new LevelStem(dimensionTypeHolder, this.generator); + } + + private Holder resolveDimensionType(MinecraftServer server) { + var dimensionType = this.dimensionType; + if (dimensionType == null) { + dimensionType = server.registryAccess().registryOrThrow(Registries.LEVEL_STEM).getHolder(this.dimensionTypeKey).orElse(null); + Preconditions.checkNotNull(dimensionType, "invalid dimension type " + this.dimensionTypeKey); + } + return dimensionType; + } + + @Nullable + public ChunkGenerator getGenerator() { + return this.generator; + } + + public RuntimeWorld.Constructor getWorldConstructor() { + return this.worldConstructor; + } + + public boolean shouldTickTime() { + return this.shouldTickTime; + } + + public long getTimeOfDay() { + return this.timeOfDay; + } + + public Difficulty getDifficulty() { + return this.difficulty; + } + + public GameRuleStore getGameRules() { + return this.gameRules; + } + + public int getSunnyTime() { + return this.sunnyTime; + } + + public int getRainTime() { + return this.rainTime; + } + + public int getThunderTime() { + return this.thunderTime; + } + + public boolean isRaining() { + return this.raining; + } + + public boolean isThundering() { + return this.thundering; + } + + public TriState isFlat() { + return this.flat; + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorldHandle.java b/src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorldHandle.java new file mode 100644 index 0000000..c2d0a05 --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorldHandle.java @@ -0,0 +1,37 @@ +package io.lampnet.travelerssuitcase.world; + +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.Level; + +public final class RuntimeWorldHandle { + private final Fantasy fantasy; + private final ServerLevel world; + + RuntimeWorldHandle(Fantasy fantasy, ServerLevel world) { + this.fantasy = fantasy; + this.world = world; + } + + public void setTickWhenEmpty(boolean tickWhenEmpty) { + ((FantasyWorldAccess) this.world).fantasy$setTickWhenEmpty(tickWhenEmpty); + } + + public void delete() { + if (this.world instanceof RuntimeWorld runtimeWorld) { + if (runtimeWorld.style == RuntimeWorld.Style.PERSISTENT) { + this.fantasy.enqueueWorldDeletion(this.world); + } else { + this.fantasy.enqueueWorldUnloading(this.world); + } + } + } + + public ServerLevel asWorld() { + return this.world; + } + + public ResourceKey getRegistryKey() { + return this.world.dimension(); + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorldManager.java b/src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorldManager.java new file mode 100644 index 0000000..93dab1e --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorldManager.java @@ -0,0 +1,115 @@ +package io.lampnet.travelerssuitcase.world; + +import com.mojang.serialization.Lifecycle; +import io.lampnet.travelerssuitcase.mixin.MinecraftServerAccess; +import net.minecraft.core.MappedRegistry; +import net.minecraft.core.Registry; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.ProgressListener; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.storage.LevelStorageSource; +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.IOException; + +final class RuntimeWorldManager { + private final MinecraftServer server; + private final MinecraftServerAccess serverAccess; + + RuntimeWorldManager(MinecraftServer server) { + this.server = server; + this.serverAccess = (MinecraftServerAccess) server; + } + + RuntimeWorld add(ResourceKey worldKey, RuntimeWorldConfig config, RuntimeWorld.Style style) { + LevelStem options = config.createDimensionOptions(this.server); + + if (style == RuntimeWorld.Style.TEMPORARY) { + ((FantasyDimensionOptions) (Object) options).fantasy$setSave(false); + } + ((FantasyDimensionOptions) (Object) options).fantasy$setSaveProperties(false); + + MappedRegistry dimensionsRegistry = getDimensionsRegistry(this.server); + boolean isFrozen = ((RemoveFromRegistry) dimensionsRegistry).fantasy$isFrozen(); + ((RemoveFromRegistry) dimensionsRegistry).fantasy$setFrozen(false); + + var key = ResourceKey.create(net.minecraft.core.registries.Registries.LEVEL_STEM, worldKey.location()); + if(!dimensionsRegistry.containsKey(key)) { + dimensionsRegistry.register(key, options, Lifecycle.stable()); + } + ((RemoveFromRegistry) dimensionsRegistry).fantasy$setFrozen(isFrozen); + + RuntimeWorld world = config.getWorldConstructor().createWorld(this.server, worldKey, config, style); + + this.serverAccess.getWorlds().put(world.dimension(), world); + + net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.level.LevelEvent.Load(world)); + world.tick(() -> true); + + return world; + } + + void delete(ServerLevel world) { + ResourceKey dimensionKey = world.dimension(); + + if (this.serverAccess.getWorlds().remove(dimensionKey, world)) { + net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.level.LevelEvent.Unload(world)); + + MappedRegistry dimensionsRegistry = getDimensionsRegistry(this.server); + RemoveFromRegistry.remove(dimensionsRegistry, dimensionKey.location()); + + LevelStorageSource.LevelStorageAccess session = this.serverAccess.getSession(); + File worldDirectory = session.getDimensionPath(dimensionKey).toFile(); + if (worldDirectory.exists()) { + try { + FileUtils.deleteDirectory(worldDirectory); + } catch (IOException e) { + Fantasy.LOGGER.warn("Failed to delete world directory", e); + try { + FileUtils.forceDeleteOnExit(worldDirectory); + } catch (IOException ignored) { + } + } + } + } + } + + void unload(ServerLevel world) { + ResourceKey dimensionKey = world.dimension(); + + if (this.serverAccess.getWorlds().remove(dimensionKey, world)) { + world.save(new ProgressListener() { + @Override + public void progressStartNoAbort(Component component) {} + + @Override + public void progressStart(Component component) {} + + @Override + public void progressStage(Component component) {} + + @Override + public void progressStagePercentage(int i) {} + + @Override + public void stop() { + net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.level.LevelEvent.Unload(world)); + + MappedRegistry dimensionsRegistry = getDimensionsRegistry(RuntimeWorldManager.this.server); + RemoveFromRegistry.remove(dimensionsRegistry, dimensionKey.location()); + } + }, true, false); + } + } + + private static MappedRegistry getDimensionsRegistry(MinecraftServer server) { + Registry registry = server.registryAccess().registryOrThrow(Registries.LEVEL_STEM); + return (MappedRegistry) registry; + } +} \ No newline at end of file diff --git a/src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorldProperties.java b/src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorldProperties.java new file mode 100644 index 0000000..59dd027 --- /dev/null +++ b/src/main/java/io/lampnet/travelerssuitcase/world/RuntimeWorldProperties.java @@ -0,0 +1,222 @@ +package io.lampnet.travelerssuitcase.world; + +import net.minecraft.CrashReportCategory; +import net.minecraft.core.BlockPos; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.Difficulty; +import net.minecraft.world.level.GameRules; +import net.minecraft.world.level.GameType; +import net.minecraft.world.level.border.WorldBorder; +import net.minecraft.world.level.storage.ServerLevelData; +import net.minecraft.world.level.timers.TimerQueue; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +public class RuntimeWorldProperties implements ServerLevelData { + private final ServerLevelData parent; + final RuntimeWorldConfig config; + + public RuntimeWorldProperties(ServerLevelData parent, RuntimeWorldConfig config) { + this.parent = parent; + this.config = config; + } + + @Override + public @NotNull String getLevelName() { + return "Runtime Pocket Dimension"; + } + + @Override + public void setThundering(boolean thundering) { + this.config.setThundering(thundering); + } + + @Override + public int getRainTime() { + return this.config.getRainTime(); + } + + @Override + public void setRainTime(int rainTime) { + this.config.setRaining(rainTime); + } + + @Override + public int getThunderTime() { + return this.config.getThunderTime(); + } + + @Override + public void setThunderTime(int thunderTime) { + this.config.setThundering(thunderTime); + } + + @Override + public boolean isThundering() { + return this.config.isThundering(); + } + + @Override + public boolean isRaining() { + return this.config.isRaining(); + } + + @Override + public void setRaining(boolean raining) { + this.config.setRaining(raining); + } + + @Override + public int getClearWeatherTime() { + return this.config.getSunnyTime(); + } + + @Override + public void setClearWeatherTime(int time) { + this.config.setSunnyTime(time); + } + + @Override + public int getWanderingTraderSpawnDelay() { + return parent.getWanderingTraderSpawnDelay(); + } + + @Override + public void setWanderingTraderSpawnDelay(int delay) { + parent.setWanderingTraderSpawnDelay(delay); + } + + @Override + public int getWanderingTraderSpawnChance() { + return parent.getWanderingTraderSpawnChance(); + } + + @Override + public void setWanderingTraderSpawnChance(int chance) { + parent.setWanderingTraderSpawnChance(chance); + } + + @Override + public UUID getWanderingTraderId() { + return parent.getWanderingTraderId(); + } + + @Override + public void setWanderingTraderId(UUID id) { + parent.setWanderingTraderId(id); + } + + @Override + public @NotNull GameType getGameType() { + return parent.getGameType(); + } + + @Override + public void setGameType(@NotNull GameType type) {} + + @Override + public boolean isHardcore() { + return parent.isHardcore(); + } + + @Override + public boolean getAllowCommands() { + return parent.getAllowCommands(); + } + + @Override + public boolean isInitialized() { + return true; + } + + @Override + public void setInitialized(boolean initialized) {} + + @Override + public @NotNull GameRules getGameRules() { + GameRules rules = new GameRules(); + this.config.getGameRules().applyTo(rules, null); + return rules; + } + + @Override + public @NotNull WorldBorder.Settings getWorldBorder() { + return parent.getWorldBorder(); + } + + @Override + public void setWorldBorder(@NotNull WorldBorder.Settings settings) {} + + @Override + public @NotNull Difficulty getDifficulty() { + return this.config.getDifficulty(); + } + + @Override + public boolean isDifficultyLocked() { + return parent.isDifficultyLocked(); + } + + @Override + public @NotNull TimerQueue getScheduledEvents() { + return new TimerQueue<>(null); + } + + @Override + public int getXSpawn() { + return 0; + } + + @Override + public int getYSpawn() { + return 64; + } + + @Override + public int getZSpawn() { + return 0; + } + + @Override + public float getSpawnAngle() { + return 0; + } + + @Override + public void setXSpawn(int x) {} + + @Override + public void setYSpawn(int y) {} + + @Override + public void setZSpawn(int z) {} + + @Override + public void setSpawnAngle(float angle) {} + + @Override + public long getGameTime() { + return parent.getGameTime(); + } + + @Override + public long getDayTime() { + return config.getTimeOfDay(); + } + + @Override + public void setGameTime(long time) {} + + @Override + public void setDayTime(long time) { + if (config.shouldTickTime()) { + config.setTimeOfDay(time); + } + } + + @Override + public void fillCrashReportCategory(@NotNull CrashReportCategory category, net.minecraft.world.level.LevelHeightAccessor context) { + parent.fillCrashReportCategory(category, context); + } +} \ No newline at end of file diff --git a/src/main/resources/data/travelerssuitcase/advancements/smaller_on_the_outside.json b/src/main/resources/data/travelerssuitcase/advancements/smaller_on_the_outside.json new file mode 100644 index 0000000..3aec126 --- /dev/null +++ b/src/main/resources/data/travelerssuitcase/advancements/smaller_on_the_outside.json @@ -0,0 +1,28 @@ +{ + "parent": "minecraft:adventure/root", + "display": { + "icon": { + "item": "travelerssuitcase:keystone" + }, + "title": { + "text": "Smaller on the Outside" + }, + "description": { + "text": "Enter a pocket dimension." + }, + "frame": "task", + "show_toast": true, + "announce_to_chat": true, + "hidden": false + }, + "criteria": { + "enter_pocket_dimension": { + "trigger": "travelerssuitcase:enter_pocket_dimension" + } + }, + "requirements": [ + [ + "enter_pocket_dimension" + ] + ] +} \ No newline at end of file diff --git a/src/main/resources/data/travelerssuitcase/dimension/pocket_dimension_.json b/src/main/resources/data/travelerssuitcase/dimension/pocket_dimension_.json deleted file mode 100644 index efdb077..0000000 --- a/src/main/resources/data/travelerssuitcase/dimension/pocket_dimension_.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "travelerssuitcase:pocket_dimension_type", - "generator": { - "type": "minecraft:flat", - "settings": { - "biome": "travelerssuitcase:pocket_islands", - "layers": [ - { - "block": "travelerssuitcase:portal", - "height": 1 - } - ], - "structure_overrides": [] - } - } -} \ No newline at end of file diff --git a/src/main/resources/data/travelerssuitcase/structures/pocket_island_01.nbt b/src/main/resources/data/travelerssuitcase/structures/pocket_island_01.nbt index bdbfe1ce053fcdbc137a5a916ae8e1f09df58794..6e4021b5999d6491c9ccbfc271ff415d42dfe48a 100644 GIT binary patch literal 317408 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�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�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