diff --git a/build.gradle b/build.gradle index 8e2f4028c..4305b4aa7 100644 --- a/build.gradle +++ b/build.gradle @@ -227,9 +227,6 @@ shadowJar { dependencies { implementation project(':core') - NMS_BINDINGS.each { - implementation project(":nms:${it.key}") - } } configurations.configureEach { diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index 7ae5816e2..2a710e83e 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -458,7 +458,6 @@ public class Iris extends VolmitPlugin implements Listener { instance = this; InitializeSafeguard(); ByteBuddyAgent.install(); - boolean configured; services = new KMap<>(); setupAudience(); initialize("com.volmit.iris.core.service").forEach((i) -> services.put((Class) i.getClass(), (IrisService) i)); @@ -474,7 +473,6 @@ public class Iris extends VolmitPlugin implements Listener { configWatcher = new FileWatcher(getDataFile("settings.json")); services.values().forEach(IrisService::onEnable); services.values().forEach(this::registerListener); - configured = ServerConfigurator.postConfigure(); installMainDimension(); if (!IrisSafeguard.instance.acceptUnstable && IrisSafeguard.instance.unstablemode) { Iris.info(C.RED + "World loading has been disabled until the incompatibility is resolved."); @@ -488,7 +486,7 @@ public class Iris extends VolmitPlugin implements Listener { J.ar(this::checkConfigHotload, 60); J.sr(this::tickQueue, 0); J.s(this::setupPapi); - if (!configured) J.a(ServerConfigurator::configure, 20); + J.a(ServerConfigurator::configure, 20); splash(); UtilsSFG.splash(); autoStartStudio(); diff --git a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java index 89261e309..dc75b46df 100644 --- a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java +++ b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java @@ -19,35 +19,15 @@ package com.volmit.iris.core; import com.volmit.iris.Iris; -import com.volmit.iris.core.loader.IrisData; -import com.volmit.iris.core.nms.INMS; -import com.volmit.iris.core.nms.datapack.DataVersion; -import com.volmit.iris.core.nms.datapack.IDataFixer; -import com.volmit.iris.engine.object.IrisBiome; -import com.volmit.iris.engine.object.IrisBiomeCustom; -import com.volmit.iris.engine.object.IrisDimension; -import com.volmit.iris.engine.object.IrisRange; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KSet; -import com.volmit.iris.util.format.C; -import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.scheduling.J; -import org.bukkit.Bukkit; -import org.bukkit.World; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Player; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; -import java.util.List; -import java.util.Properties; import java.util.concurrent.TimeUnit; -import static org.bukkit.Bukkit.getServer; - public class ServerConfigurator { public static void configure() { IrisSettings.IrisSettingsAutoconfiguration s = IrisSettings.get().getAutoConfiguration(); @@ -58,16 +38,6 @@ public class ServerConfigurator { if (s.isConfigurePaperWatchdogDelay()) { J.attempt(ServerConfigurator::increasePaperWatchdog); } - - installDataPacks(true); - } - - public static boolean postConfigure() { - if(postVerifyDataPacks(true)) { - configure(); - return true; - } - return false; } private static void increaseKeepAliveSpigot() throws IOException, InvalidConfigurationException { @@ -83,6 +53,7 @@ public class ServerConfigurator { f.save(spigotConfig); } } + private static void increasePaperWatchdog() throws IOException, InvalidConfigurationException { File spigotConfig = new File("config/paper-global.yml"); FileConfiguration f = new YamlConfiguration(); @@ -96,219 +67,4 @@ public class ServerConfigurator { f.save(spigotConfig); } } - - private static List getDatapacksFolder() { - if (!IrisSettings.get().getGeneral().forceMainWorld.isEmpty()) { - return new KList().qadd(new File(Bukkit.getWorldContainer(), IrisSettings.get().getGeneral().forceMainWorld + "/datapacks")); - } - KList worlds = new KList<>(); - Bukkit.getServer().getWorlds().forEach(w -> worlds.add(new File(w.getWorldFolder(), "datapacks"))); - if (worlds.isEmpty()) { - worlds.add(new File(getMainWorldFolder(), "datapacks")); - } - return worlds; - } - - private static File getMainWorldFolder() { - try { - Properties prop = new Properties(); - prop.load(new FileInputStream("server.properties")); - String world = prop.getProperty("level-name", "world"); - return new File(Bukkit.getWorldContainer(), world); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - private static boolean postVerifyDataPacks(boolean fast) { - try { - File datapacksFolder = new File(getMainWorldFolder(), "datapacks"); - File IrisDatapacks = new File(datapacksFolder, "iris"); - if (!datapacksFolder.exists() || !IrisDatapacks.exists()) { - return (true); - } - } catch (Exception e) { - e.printStackTrace(); - } - return false; - } - - public static void installDataPacks(boolean fullInstall) { - installDataPacks(DataVersion.getDefault(), fullInstall); - } - - public static void installDataPacks(IDataFixer fixer, boolean fullInstall) { - Iris.info("Checking Data Packs..."); - File packs = new File("plugins/Iris/packs"); - double ultimateMaxHeight = 0; - double ultimateMinHeight = 0; - if (packs.exists() && packs.isDirectory()) { - for (File pack : packs.listFiles()) { - IrisData data = IrisData.get(pack); - if (pack.isDirectory()) { - File dimensionsFolder = new File(pack, "dimensions"); - if (dimensionsFolder.exists() && dimensionsFolder.isDirectory()) { - for (File file : dimensionsFolder.listFiles()) { - if (file.isFile() && file.getName().endsWith(".json")) { - IrisDimension dim = data.getDimensionLoader().load(file.getName().split("\\Q.\\E")[0]); - if (ultimateMaxHeight < dim.getDimensionHeight().getMax()) { - ultimateMaxHeight = dim.getDimensionHeight().getMax(); - } - if (ultimateMinHeight > dim.getDimensionHeight().getMin()) { - ultimateMinHeight = dim.getDimensionHeight().getMin(); - } - } - } - } - } - } - } - - if (packs.exists()) { - for (File i : packs.listFiles()) { - if (i.isDirectory()) { - Iris.verbose("Checking Pack: " + i.getPath()); - IrisData data = IrisData.get(i); - File dims = new File(i, "dimensions"); - - if (dims.exists()) { - for (File j : dims.listFiles()) { - if (j.getName().endsWith(".json")) { - IrisDimension dim = data.getDimensionLoader().load(j.getName().split("\\Q.\\E")[0]); - - if (dim == null) { - continue; - } - - Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath()); - for (File dpack : getDatapacksFolder()) { - dim.installDataPack(fixer, () -> data, dpack); - } - } - } - } - } - } - } - - Iris.info("Data Packs Setup!"); - - if (fullInstall) - verifyDataPacksPost(IrisSettings.get().getAutoConfiguration().isAutoRestartOnCustomBiomeInstall()); - } - - private static void verifyDataPacksPost(boolean allowRestarting) { - File packs = new File("plugins/Iris/packs"); - - boolean bad = false; - if (packs.exists()) { - for (File i : packs.listFiles()) { - if (i.isDirectory()) { - Iris.verbose("Checking Pack: " + i.getPath()); - IrisData data = IrisData.get(i); - File dims = new File(i, "dimensions"); - - if (dims.exists()) { - for (File j : dims.listFiles()) { - if (j.getName().endsWith(".json")) { - IrisDimension dim = data.getDimensionLoader().load(j.getName().split("\\Q.\\E")[0]); - - if (dim == null) { - Iris.error("Failed to load " + j.getPath() + " "); - continue; - } - - if (!verifyDataPackInstalled(dim)) { - bad = true; - } - } - } - } - } - } - } - - if (bad) { - // Iris.info(""); - Iris.info( "Hotloading all Datapacks!"); - if (INMS.get().supportsDataPacks()) { - for (File folder : getDatapacksFolder()) { - INMS.get().loadDatapack(folder, false); - } - Iris.info("Datapacks Hotloaded!"); - Iris.info(C.YELLOW + "============================================================================"); - Iris.info(C.ITALIC + "" + C.YELLOW + "To ensure the stability of custom biome generation, a server restart is necessary."); - Iris.info(C.ITALIC + "" + C.YELLOW + "While datapacks have been hotloaded, a complete restart is advised."); - Iris.info(C.YELLOW + "----------------------------------------------------------------------------"); - Iris.info(C.UNDERLINE + "" + C.YELLOW + "IT IS HIGHLY RECOMMENDED YOU RESTART THE SERVER BEFORE GENERATING!"); - Iris.info(C.YELLOW + "============================================================================"); - - for (Player i : Bukkit.getOnlinePlayers()) { - if (i.isOp() || i.hasPermission("iris.all")) { - VolmitSender sender = new VolmitSender(i, Iris.instance.getTag("WARNING")); - sender.sendMessage("There are some Iris Packs that have custom biomes in them"); - sender.sendMessage("You need to restart your server to use these packs."); - } - } - - J.sleep(3000); - } - } - } - - public static void restart() { - J.s(() -> { - Iris.warn("New data pack entries have been installed in Iris! Restarting server!"); - Iris.warn("This will only happen when your pack changes (updates/first time setup)"); - Iris.warn("(You can disable this auto restart in iris settings)"); - J.s(() -> { - Iris.warn("Looks like the restart command didn't work. Stopping the server instead!"); - Bukkit.shutdown(); - }, 100); - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "restart"); - }); - } - - public static boolean verifyDataPackInstalled(IrisDimension dimension) { - IrisData idm = IrisData.get(Iris.instance.getDataFolder("packs", dimension.getLoadKey())); - KSet keys = new KSet<>(); - boolean warn = false; - - for (IrisBiome i : dimension.getAllBiomes(() -> idm)) { - if (i.isCustom()) { - for (IrisBiomeCustom j : i.getCustomDerivitives()) { - keys.add(dimension.getLoadKey() + ":" + j.getId()); - } - } - } - - if (!INMS.get().supportsDataPacks()) { - if (!keys.isEmpty()) { - Iris.warn("==================================================================================="); - Iris.warn("Pack " + dimension.getLoadKey() + " has " + keys.size() + " custom biome(s). "); - Iris.warn("Your server version does not yet support datapacks for iris."); - Iris.warn("The world will generate these biomes as backup biomes."); - Iris.warn("===================================================================================="); - } - - return true; - } - - for (String i : keys) { - Object o = INMS.get().getCustomBiomeBaseFor(i); - - if (o == null) { - Iris.warn("The Biome " + i + " is not registered on the server."); - warn = true; - } - } - - if (warn) { - Iris.error("The Pack " + dimension.getLoadKey() + " is INCAPABLE of generating custom biomes"); - Iris.error("Queued for Datapack Hotload."); - } - - return !warn; - } } diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java index 609278e99..6dac2f2fa 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java @@ -163,14 +163,6 @@ public class CommandDeveloper implements DecreeExecutor { } - @Decree(description = "Upgrade to another Minecraft version") - public void upgrade( - @Param(description = "The version to upgrade to", defaultValue = "latest") DataVersion version) { - sender().sendMessage(C.GREEN + "Upgrading to " + version.getVersion() + "..."); - ServerConfigurator.installDataPacks(version.get(), false); - sender().sendMessage(C.GREEN + "Done upgrading! You can now update your server version to " + version.getVersion()); - } - @Decree(description = "Test") public void updater( @Param(description = "Updater for chunks") diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java index 2188485c0..095e28406 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java @@ -20,21 +20,16 @@ package com.volmit.iris.core.commands; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.ServerConfigurator; import com.volmit.iris.core.gui.NoiseExplorerGUI; import com.volmit.iris.core.gui.VisionGUI; -import com.volmit.iris.core.loader.IrisData; -import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.project.IrisProject; import com.volmit.iris.core.service.ConversionSVC; import com.volmit.iris.core.service.StudioSVC; -import com.volmit.iris.core.tools.IrisConverter; import com.volmit.iris.core.tools.IrisNoiseBenchmark; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.*; import com.volmit.iris.engine.platform.PlatformChunkGenerator; -import com.volmit.iris.engine.platform.studio.StudioGenerator; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; @@ -43,30 +38,23 @@ import com.volmit.iris.util.decree.DecreeExecutor; import com.volmit.iris.util.decree.DecreeOrigin; import com.volmit.iris.util.decree.annotations.Decree; import com.volmit.iris.util.decree.annotations.Param; -import com.volmit.iris.util.decree.specialhandlers.NullablePlayerHandler; import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.function.Function2; -import com.volmit.iris.util.function.NoiseProvider; -import com.volmit.iris.util.interpolation.InterpolationMethod; -import com.volmit.iris.util.io.IO; import com.volmit.iris.util.json.JSONArray; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.Spiraler; -import com.volmit.iris.util.noise.CNG; import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.MultiBurst; import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.O; -import com.volmit.iris.util.scheduling.PrecisionStopwatch; import com.volmit.iris.util.scheduling.jobs.QueueJob; import io.papermc.lib.PaperLib; import org.bukkit.*; -import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.Inventory; import org.bukkit.util.BlockVector; @@ -85,7 +73,6 @@ import java.util.Date; import java.util.Objects; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; @Decree(name = "studio", aliases = {"std", "s"}, description = "Studio Commands", studio = true) @@ -286,7 +273,7 @@ public class CommandStudio implements DecreeExecutor { } @Decree(description = "Hotload a studio", aliases = {"reload", "h"}) - public void hotload(@Param(defaultValue = "false") boolean reloadDataPack) { + public void hotload() { if (!Iris.service(StudioSVC.class).isProjectOpen()) { sender().sendMessage(C.RED + "No studio world open!"); return; @@ -294,15 +281,6 @@ public class CommandStudio implements DecreeExecutor { var provider = Iris.service(StudioSVC.class).getActiveProject().getActiveProvider(); provider.getEngine().hotload(); sender().sendMessage(C.GREEN + "Hotloaded"); - if (reloadDataPack) { - var world = provider.getTarget().getWorld().realWorld(); - if (world == null) { - sender().sendMessage(C.RED + "Failed to reload datapacks."); - return; - } - boolean success = INMS.get().loadDatapack(new File(world.getWorldFolder(), "datapacks"), true); - sender().sendMessage(success ? C.GREEN + "Reloaded datapacks." : C.RED + "Failed to reload datapacks."); - } } @Decree(description = "Show loot if a chest were right here", origin = DecreeOrigin.PLAYER, sync = true) diff --git a/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java index d82d2cafc..7f72c84d7 100644 --- a/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java +++ b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java @@ -20,10 +20,10 @@ package com.volmit.iris.core.nms; import com.volmit.iris.core.nms.datapack.DataVersion; import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.object.IrisBiomeCustom; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.documentation.RegionCoordinates; import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.math.Vector3d; import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer; @@ -38,12 +38,9 @@ import org.bukkit.entity.Dolphin; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.event.entity.EntitySpawnEvent; import org.bukkit.generator.ChunkGenerator; import org.bukkit.inventory.ItemStack; -import java.io.File; - public interface INMSBinding { boolean hasTile(Location l); @@ -121,10 +118,10 @@ public interface INMSBinding { return DataVersion.V1192; } - boolean loadDatapack(File datapackFolder, boolean replace); - boolean registerDimension(String name, IrisDimension dimension); + boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace); + void injectBukkit(); default IHeadless createHeadless(Engine engine) { diff --git a/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java b/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java index 42a5e2507..d54ee7f6a 100644 --- a/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java +++ b/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java @@ -23,6 +23,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMSBinding; import com.volmit.iris.core.nms.container.BlockPos; import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.object.IrisBiomeCustom; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; @@ -108,12 +109,12 @@ public class NMSBinding1X implements INMSBinding { } @Override - public boolean loadDatapack(File datapackFolder, boolean replace) { + public boolean registerDimension(String name, IrisDimension dimension) { return false; } @Override - public boolean registerDimension(String name, IrisDimension dimension) { + public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) { return false; } diff --git a/core/src/main/java/com/volmit/iris/core/service/StudioSVC.java b/core/src/main/java/com/volmit/iris/core/service/StudioSVC.java index 720da652f..519a92b5f 100644 --- a/core/src/main/java/com/volmit/iris/core/service/StudioSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/StudioSVC.java @@ -22,7 +22,6 @@ import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.ServerConfigurator; import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.pack.IrisPack; import com.volmit.iris.core.project.IrisProject; @@ -296,7 +295,6 @@ public class StudioSVC implements IrisService { } sender.sendMessage("Successfully Aquired " + d.getName()); - ServerConfigurator.installDataPacks(true); } public KMap getListing(boolean cached) { diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java index 73ce06bb5..9f5b58e67 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java @@ -21,13 +21,10 @@ package com.volmit.iris.core.tools; import com.google.common.util.concurrent.AtomicDouble; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.ServerConfigurator; import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.core.service.StudioSVC; -import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.engine.platform.PlatformChunkGenerator; -import com.volmit.iris.core.safeguard.UtilsSFG; import com.volmit.iris.util.exceptions.IrisException; import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; @@ -144,7 +141,6 @@ public class IrisCreator { .studio(studio) .smartVanillaHeight(smartVanillaHeight) .create(); - ServerConfigurator.installDataPacks(false); access = (PlatformChunkGenerator) wc.generator(); PlatformChunkGenerator finalAccess1 = access; diff --git a/core/src/main/java/com/volmit/iris/engine/IrisEngine.java b/core/src/main/java/com/volmit/iris/engine/IrisEngine.java index 94b4294eb..18b67d056 100644 --- a/core/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/core/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -21,8 +21,6 @@ package com.volmit.iris.engine; import com.google.common.util.concurrent.AtomicDouble; import com.google.gson.Gson; import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.ServerConfigurator; import com.volmit.iris.core.events.IrisEngineHotloadEvent; import com.volmit.iris.core.gui.PregeneratorJob; import com.volmit.iris.core.nms.container.BlockPos; @@ -53,7 +51,6 @@ import com.volmit.iris.util.scheduling.PrecisionStopwatch; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -66,8 +63,6 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; -import java.util.regex.Matcher; -import java.util.regex.Pattern; @Data @EqualsAndHashCode(exclude = "context") @@ -242,11 +237,6 @@ public class IrisEngine implements Engine { getTarget().setDimension(getData().getDimensionLoader().load(getDimension().getLoadKey())); prehotload(); setupEngine(); - J.a(() -> { - synchronized (ServerConfigurator.class) { - ServerConfigurator.installDataPacks(false); - } - }); } @Override diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeCustom.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeCustom.java index dd3e16af6..f491dff68 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeCustom.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeCustom.java @@ -19,7 +19,7 @@ package com.volmit.iris.engine.object; import com.volmit.iris.Iris; -import com.volmit.iris.core.nms.datapack.IDataFixer; +import com.volmit.iris.core.nms.datapack.DataVersion; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; @@ -92,7 +92,7 @@ public class IrisBiomeCustom { @Desc("The color of foliage (hex format). Leave blank / don't define to not change") private String foliageColor = ""; - public String generateJson(IDataFixer fixer) { + public String generateJson() { JSONObject effects = new JSONObject(); effects.put("sky_color", parseColor(getSkyColor())); effects.put("fog_color", parseColor(getFogColor())); @@ -158,7 +158,7 @@ public class IrisBiomeCustom { j.put("spawners", spawners); } - return fixer.fixCustomBiome(this, j).toString(4); + return DataVersion.getDefault().fixCustomBiome(this, j).toString(4); } private int parseColor(String c) { diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index 1a364ec45..98049d32f 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -18,15 +18,12 @@ package com.volmit.iris.engine.object; -import com.volmit.iris.Iris; import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.loader.IrisRegistrant; -import com.volmit.iris.core.nms.datapack.IDataFixer; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.data.DataProvider; -import com.volmit.iris.util.io.IO; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.RNG; @@ -41,9 +38,6 @@ import org.bukkit.Material; import org.bukkit.World.Environment; import org.bukkit.block.data.BlockData; -import java.io.File; -import java.io.IOException; - @Accessors(chain = true) @AllArgsConstructor @NoArgsConstructor @@ -377,56 +371,6 @@ public class IrisDimension extends IrisRegistrant { return landBiomeStyle; } - public boolean installDataPack(IDataFixer fixer, DataProvider data, File datapacks) { - boolean write = false; - boolean changed = false; - - IO.delete(new File(datapacks, "iris/data/" + getLoadKey().toLowerCase())); - - for (IrisBiome i : getAllBiomes(data)) { - if (i.isCustom()) { - write = true; - - for (IrisBiomeCustom j : i.getCustomDerivitives()) { - File output = new File(datapacks, "iris/data/" + getLoadKey().toLowerCase() + "/worldgen/biome/" + j.getId() + ".json"); - - if (!output.exists()) { - changed = true; - } - - Iris.verbose(" Installing Data Pack Biome: " + output.getPath()); - output.getParentFile().mkdirs(); - try { - IO.writeAll(output, j.generateJson(fixer)); - } catch (IOException e) { - Iris.reportError(e); - e.printStackTrace(); - } - } - } - } - - if (write) { - File mcm = new File(datapacks, "iris/pack.mcmeta"); - try { - IO.writeAll(mcm, """ - { - "pack": { - "description": "Iris Data Pack. This pack contains all installed Iris Packs' resources.", - "pack_format": 10 - } - } - """); - } catch (IOException e) { - Iris.reportError(e); - e.printStackTrace(); - } - Iris.verbose(" Installing Data Pack MCMeta: " + mcm.getPath()); - } - - return changed; - } - @Override public String getFolderName() { return "dimensions"; diff --git a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/CustomBiomeSource.java b/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/CustomBiomeSource.java index a24e62d85..5a1f89970 100644 --- a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/CustomBiomeSource.java +++ b/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/CustomBiomeSource.java @@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_19_R1; import com.mojang.serialization.Codec; import com.volmit.iris.Iris; +import com.volmit.iris.core.nms.INMS; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.IrisBiome; @@ -11,6 +12,7 @@ import com.volmit.iris.util.math.RNG; import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.core.RegistryAccess; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeSource; @@ -25,6 +27,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import java.util.Optional; public class CustomBiomeSource extends BiomeSource { private final long seed; @@ -118,8 +121,28 @@ public class CustomBiomeSource extends BiomeSource { for (IrisBiome i : engine.getAllBiomes()) { if (i.isCustom()) { for (IrisBiomeCustom j : i.getCustomDerivitives()) { - m.put(j.getId(), customRegistry.getHolder(customRegistry.getResourceKey(customRegistry - .get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get()); + ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()); + Biome biome = customRegistry.get(location); + if (biome == null) { + INMS.get().registerBiome(location.getNamespace(), j, false); + biome = customRegistry.get(location); + if (biome == null) { + Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); + continue; + } + } + Optional> optionalBiomeKey = customRegistry.getResourceKey(biome); + if (optionalBiomeKey.isEmpty()) { + Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); + continue; + } + ResourceKey biomeKey = optionalBiomeKey.get(); + Optional> optionalReferenceHolder = customRegistry.getHolder(biomeKey); + if (optionalReferenceHolder.isEmpty()) { + Iris.error("Cannot find reference to biome " + biomeKey + " for engine " + engine.getName()); + continue; + } + m.put(j.getId(), optionalReferenceHolder.get()); } } } diff --git a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java b/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java index 8d01af591..2033666da 100644 --- a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java +++ b/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java @@ -5,12 +5,9 @@ import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.IdentityHashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -26,9 +23,9 @@ import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import com.mojang.serialization.JsonOps; import com.mojang.serialization.Lifecycle; +import com.volmit.iris.engine.object.IrisBiomeCustom; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.util.format.C; -import com.volmit.iris.util.io.IO; import it.unimi.dsi.fastutil.objects.Reference2IntMap; import net.bytebuddy.ByteBuddy; import net.bytebuddy.asm.Advice; @@ -587,51 +584,10 @@ public class NMSBinding implements INMSBinding { } @Override - public boolean loadDatapack(File folder, boolean replace) { - var data = new File(folder, "iris/data"); - if (!data.exists() || !data.isDirectory()) return false; - FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json"); - - var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory()); - if (files == null) return false; - for (File file : files) { - var biome = new File(file, "worldgen/biome"); - if (!biome.exists()) continue; - var biomeFiles = biome.listFiles(jsonFilter); - if (biomeFiles == null) continue; - for (File biomeFile : biomeFiles) { - String json = null; - int tries = 10; - while (json == null && tries-- > 0) { - try { - json = IO.readAll(biomeFile); - } catch (IOException e) { - Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries); - if (tries == 0) { - e.printStackTrace(); - } - try { - Thread.sleep(100); - } catch (InterruptedException ignored) {} - } - } - if (json == null) continue; - - try { - var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null); - register(Registry.BIOME_REGISTRY, from(file.getName(), biomeFile), value, replace); - } catch (Throwable e) { - Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName()); - e.printStackTrace(); - } - } - } - return true; - } - - private ResourceLocation from(String namespace, File file) { - var name = file.getName(); - return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.'))); + public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) { + var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null); + if (biomeBase == null) return false; + return register(Registry.BIOME_REGISTRY, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace); } private Optional decode(Codec codec, String json) { diff --git a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/CustomBiomeSource.java b/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/CustomBiomeSource.java index 7a82acf42..340c053cd 100644 --- a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/CustomBiomeSource.java +++ b/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/CustomBiomeSource.java @@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_19_R2; import com.mojang.serialization.Codec; import com.volmit.iris.Iris; +import com.volmit.iris.core.nms.INMS; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.IrisBiome; @@ -12,6 +13,7 @@ import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeSource; @@ -26,6 +28,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import java.util.Optional; public class CustomBiomeSource extends BiomeSource { @@ -120,8 +123,28 @@ public class CustomBiomeSource extends BiomeSource { for (IrisBiome i : engine.getAllBiomes()) { if (i.isCustom()) { for (IrisBiomeCustom j : i.getCustomDerivitives()) { - m.put(j.getId(), customRegistry.getHolder(customRegistry.getResourceKey(customRegistry - .get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get()); + ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()); + Biome biome = customRegistry.get(location); + if (biome == null) { + INMS.get().registerBiome(location.getNamespace(), j, false); + biome = customRegistry.get(location); + if (biome == null) { + Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); + continue; + } + } + Optional> optionalBiomeKey = customRegistry.getResourceKey(biome); + if (optionalBiomeKey.isEmpty()) { + Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); + continue; + } + ResourceKey biomeKey = optionalBiomeKey.get(); + Optional> optionalReferenceHolder = customRegistry.getHolder(biomeKey); + if (optionalReferenceHolder.isEmpty()) { + Iris.error("Cannot find reference to biome " + biomeKey + " for engine " + engine.getName()); + continue; + } + m.put(j.getId(), optionalReferenceHolder.get()); } } } diff --git a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java b/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java index 59c54c2ad..ed1a4a09e 100644 --- a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java +++ b/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java @@ -5,12 +5,9 @@ import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.IdentityHashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -26,9 +23,9 @@ import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import com.mojang.serialization.JsonOps; import com.mojang.serialization.Lifecycle; +import com.volmit.iris.engine.object.IrisBiomeCustom; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.util.format.C; -import com.volmit.iris.util.io.IO; import it.unimi.dsi.fastutil.objects.Reference2IntMap; import net.bytebuddy.ByteBuddy; import net.bytebuddy.asm.Advice; @@ -589,51 +586,10 @@ public class NMSBinding implements INMSBinding { } @Override - public boolean loadDatapack(File folder, boolean replace) { - var data = new File(folder, "iris/data"); - if (!data.exists() || !data.isDirectory()) return false; - FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json"); - - var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory()); - if (files == null) return false; - for (File file : files) { - var biome = new File(file, "worldgen/biome"); - if (!biome.exists()) continue; - var biomeFiles = biome.listFiles(jsonFilter); - if (biomeFiles == null) continue; - for (File biomeFile : biomeFiles) { - String json = null; - int tries = 10; - while (json == null && tries-- > 0) { - try { - json = IO.readAll(biomeFile); - } catch (IOException e) { - Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries); - if (tries == 0) { - e.printStackTrace(); - } - try { - Thread.sleep(100); - } catch (InterruptedException ignored) {} - } - } - if (json == null) continue; - - try { - var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null); - register(Registries.BIOME, from(file.getName(), biomeFile), value, replace); - } catch (Throwable e) { - Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName()); - e.printStackTrace(); - } - } - } - return true; - } - - private ResourceLocation from(String namespace, File file) { - var name = file.getName(); - return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.'))); + public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) { + var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null); + if (biomeBase == null) return false; + return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace); } private Optional decode(Codec codec, String json) { diff --git a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/CustomBiomeSource.java b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/CustomBiomeSource.java index f3debbaad..3e26f6f79 100644 --- a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/CustomBiomeSource.java +++ b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/CustomBiomeSource.java @@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_19_R3; import com.mojang.serialization.Codec; import com.volmit.iris.Iris; +import com.volmit.iris.core.nms.INMS; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.IrisBiome; @@ -125,8 +126,16 @@ public class CustomBiomeSource extends BiomeSource { for (IrisBiome i : engine.getAllBiomes()) { if (i.isCustom()) { for (IrisBiomeCustom j : i.getCustomDerivitives()) { - ResourceLocation resourceLocation = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()); - Biome biome = customRegistry.get(resourceLocation); + ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()); + Biome biome = customRegistry.get(location); + if (biome == null) { + INMS.get().registerBiome(location.getNamespace(), j, false); + biome = customRegistry.get(location); + if (biome == null) { + Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); + continue; + } + } Optional> optionalBiomeKey = customRegistry.getResourceKey(biome); if (optionalBiomeKey.isEmpty()) { Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); diff --git a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java index a1396ba1c..7499562de 100644 --- a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java +++ b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java @@ -5,12 +5,9 @@ import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.IdentityHashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -26,9 +23,9 @@ import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import com.mojang.serialization.JsonOps; import com.mojang.serialization.Lifecycle; +import com.volmit.iris.engine.object.IrisBiomeCustom; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.util.format.C; -import com.volmit.iris.util.io.IO; import it.unimi.dsi.fastutil.objects.Reference2IntMap; import net.bytebuddy.ByteBuddy; import net.bytebuddy.asm.Advice; @@ -593,51 +590,10 @@ public class NMSBinding implements INMSBinding { } @Override - public boolean loadDatapack(File folder, boolean replace) { - var data = new File(folder, "iris/data"); - if (!data.exists() || !data.isDirectory()) return false; - FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json"); - - var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory()); - if (files == null) return false; - for (File file : files) { - var biome = new File(file, "worldgen/biome"); - if (!biome.exists()) continue; - var biomeFiles = biome.listFiles(jsonFilter); - if (biomeFiles == null) continue; - for (File biomeFile : biomeFiles) { - String json = null; - int tries = 10; - while (json == null && tries-- > 0) { - try { - json = IO.readAll(biomeFile); - } catch (IOException e) { - Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries); - if (tries == 0) { - e.printStackTrace(); - } - try { - Thread.sleep(100); - } catch (InterruptedException ignored) {} - } - } - if (json == null) continue; - - try { - var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null); - register(Registries.BIOME, from(file.getName(), biomeFile), value, replace); - } catch (Throwable e) { - Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName()); - e.printStackTrace(); - } - } - } - return true; - } - - private ResourceLocation from(String namespace, File file) { - var name = file.getName(); - return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.'))); + public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) { + var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null); + if (biomeBase == null) return false; + return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace); } private Optional decode(Codec codec, String json) { diff --git a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/CustomBiomeSource.java b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/CustomBiomeSource.java index 41f4170c8..6ebea1093 100644 --- a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/CustomBiomeSource.java +++ b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/CustomBiomeSource.java @@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_20_R1; import com.mojang.serialization.Codec; import com.volmit.iris.Iris; +import com.volmit.iris.core.nms.INMS; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.IrisBiome; @@ -125,8 +126,16 @@ public class CustomBiomeSource extends BiomeSource { for (IrisBiome i : engine.getAllBiomes()) { if (i.isCustom()) { for (IrisBiomeCustom j : i.getCustomDerivitives()) { - ResourceLocation resourceLocation = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()); - Biome biome = customRegistry.get(resourceLocation); + ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()); + Biome biome = customRegistry.get(location); + if (biome == null) { + INMS.get().registerBiome(location.getNamespace(), j, false); + biome = customRegistry.get(location); + if (biome == null) { + Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); + continue; + } + } Optional> optionalBiomeKey = customRegistry.getResourceKey(biome); if (optionalBiomeKey.isEmpty()) { Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); diff --git a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java index ab01736a8..52102bc32 100644 --- a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java +++ b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java @@ -12,12 +12,12 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMSBinding; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.object.IrisBiomeCustom; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.format.C; import com.volmit.iris.util.hunk.Hunk; -import com.volmit.iris.util.io.IO; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.math.Vector3d; @@ -47,7 +47,6 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.progress.ChunkProgressListener; import net.minecraft.util.GsonHelper; import net.minecraft.world.RandomSequences; -import net.minecraft.world.entity.EntityDimensions; import net.minecraft.world.level.Level; import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.block.Block; @@ -73,9 +72,7 @@ import org.bukkit.craftbukkit.v1_20_R1.entity.CraftDolphin; import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; import org.bukkit.entity.Dolphin; import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.entity.EntityType; import org.bukkit.generator.BiomeProvider; import org.bukkit.generator.ChunkGenerator; import org.bukkit.inventory.ItemStack; @@ -87,12 +84,9 @@ import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.IdentityHashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -580,51 +574,10 @@ public class NMSBinding implements INMSBinding { } @Override - public boolean loadDatapack(File folder, boolean replace) { - var data = new File(folder, "iris/data"); - if (!data.exists() || !data.isDirectory()) return false; - FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json"); - - var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory()); - if (files == null) return false; - for (File file : files) { - var biome = new File(file, "worldgen/biome"); - if (!biome.exists()) continue; - var biomeFiles = biome.listFiles(jsonFilter); - if (biomeFiles == null) continue; - for (File biomeFile : biomeFiles) { - String json = null; - int tries = 10; - while (json == null && tries-- > 0) { - try { - json = IO.readAll(biomeFile); - } catch (IOException e) { - Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries); - if (tries == 0) { - e.printStackTrace(); - } - try { - Thread.sleep(100); - } catch (InterruptedException ignored) {} - } - } - if (json == null) continue; - - try { - var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null); - register(Registries.BIOME, from(file.getName(), biomeFile), value, replace); - } catch (Throwable e) { - Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName()); - e.printStackTrace(); - } - } - } - return true; - } - - private ResourceLocation from(String namespace, File file) { - var name = file.getName(); - return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.'))); + public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) { + var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null); + if (biomeBase == null) return false; + return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace); } private Optional decode(Codec codec, String json) { diff --git a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/CustomBiomeSource.java b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/CustomBiomeSource.java index fcf462f95..24ce23216 100644 --- a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/CustomBiomeSource.java +++ b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/CustomBiomeSource.java @@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_20_R2; import com.mojang.serialization.Codec; import com.volmit.iris.Iris; +import com.volmit.iris.core.nms.INMS; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.IrisBiome; @@ -124,8 +125,16 @@ public class CustomBiomeSource extends BiomeSource { for (IrisBiome i : engine.getAllBiomes()) { if (i.isCustom()) { for (IrisBiomeCustom j : i.getCustomDerivitives()) { - ResourceLocation resourceLocation = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()); - Biome biome = customRegistry.get(resourceLocation); + ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()); + Biome biome = customRegistry.get(location); + if (biome == null) { + INMS.get().registerBiome(location.getNamespace(), j, false); + biome = customRegistry.get(location); + if (biome == null) { + Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); + continue; + } + } Optional> optionalBiomeKey = customRegistry.getResourceKey(biome); if (optionalBiomeKey.isEmpty()) { Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); diff --git a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java index e4af087ec..63e36f06b 100644 --- a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java +++ b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java @@ -5,12 +5,9 @@ import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.IdentityHashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -26,9 +23,9 @@ import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import com.mojang.serialization.JsonOps; import com.mojang.serialization.Lifecycle; +import com.volmit.iris.engine.object.IrisBiomeCustom; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.util.format.C; -import com.volmit.iris.util.io.IO; import it.unimi.dsi.fastutil.objects.Reference2IntMap; import net.bytebuddy.ByteBuddy; import net.bytebuddy.asm.Advice; @@ -590,51 +587,10 @@ public class NMSBinding implements INMSBinding { } @Override - public boolean loadDatapack(File folder, boolean replace) { - var data = new File(folder, "iris/data"); - if (!data.exists() || !data.isDirectory()) return false; - FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json"); - - var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory()); - if (files == null) return false; - for (File file : files) { - var biome = new File(file, "worldgen/biome"); - if (!biome.exists()) continue; - var biomeFiles = biome.listFiles(jsonFilter); - if (biomeFiles == null) continue; - for (File biomeFile : biomeFiles) { - String json = null; - int tries = 10; - while (json == null && tries-- > 0) { - try { - json = IO.readAll(biomeFile); - } catch (IOException e) { - Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries); - if (tries == 0) { - e.printStackTrace(); - } - try { - Thread.sleep(100); - } catch (InterruptedException ignored) {} - } - } - if (json == null) continue; - - try { - var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null); - register(Registries.BIOME, from(file.getName(), biomeFile), value, replace); - } catch (Throwable e) { - Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName()); - e.printStackTrace(); - } - } - } - return true; - } - - private ResourceLocation from(String namespace, File file) { - var name = file.getName(); - return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.'))); + public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) { + var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null); + if (biomeBase == null) return false; + return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace); } private Optional decode(Codec codec, String json) { diff --git a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/CustomBiomeSource.java b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/CustomBiomeSource.java index 3d3582239..323fa255b 100644 --- a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/CustomBiomeSource.java +++ b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/CustomBiomeSource.java @@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_20_R3; import com.mojang.serialization.Codec; import com.volmit.iris.Iris; +import com.volmit.iris.core.nms.INMS; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.IrisBiome; @@ -124,8 +125,16 @@ public class CustomBiomeSource extends BiomeSource { for (IrisBiome i : engine.getAllBiomes()) { if (i.isCustom()) { for (IrisBiomeCustom j : i.getCustomDerivitives()) { - ResourceLocation resourceLocation = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()); - Biome biome = customRegistry.get(resourceLocation); + ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()); + Biome biome = customRegistry.get(location); + if (biome == null) { + INMS.get().registerBiome(location.getNamespace(), j, false); + biome = customRegistry.get(location); + if (biome == null) { + Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); + continue; + } + } Optional> optionalBiomeKey = customRegistry.getResourceKey(biome); if (optionalBiomeKey.isEmpty()) { Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); diff --git a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/Headless.java b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/Headless.java index 5284cbc83..36b552545 100644 --- a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/Headless.java +++ b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/Headless.java @@ -66,6 +66,14 @@ public class Headless implements IHeadless, LevelHeightAccessor { }; queueLooper.setName("Region Save Looper"); queueLooper.start(); + + var dimKey = engine.getDimension().getLoadKey(); + for (var biome : engine.getAllBiomes()) { + if (!biome.isCustom()) continue; + for (var custom : biome.getCustomDerivitives()) { + binding.registerBiome(dimKey, custom, false); + } + } } @Override diff --git a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java index 9743b4830..bb056b10e 100644 --- a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java +++ b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java @@ -5,8 +5,6 @@ import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -23,16 +21,9 @@ import com.mojang.serialization.JsonOps; import com.mojang.serialization.Lifecycle; import com.volmit.iris.core.nms.IHeadless; import com.volmit.iris.core.nms.v1_20_R3.mca.ChunkSerializer; -import com.volmit.iris.core.nms.v1_20_R3.mca.MCATerrainChunk; -import com.volmit.iris.core.nms.v1_20_R3.mca.RegionFileStorage; +import com.volmit.iris.engine.object.IrisBiomeCustom; import com.volmit.iris.engine.object.IrisDimension; -import com.volmit.iris.util.documentation.RegionCoordinates; import com.volmit.iris.util.format.C; -import com.volmit.iris.util.hunk.view.BiomeGridHunkHolder; -import com.volmit.iris.util.hunk.view.ChunkDataHunkHolder; -import com.volmit.iris.util.io.IO; -import com.volmit.iris.util.parallel.MultiBurst; -import com.volmit.iris.util.scheduling.PrecisionStopwatch; import it.unimi.dsi.fastutil.objects.Reference2IntMap; import net.bytebuddy.ByteBuddy; import net.bytebuddy.asm.Advice; @@ -601,51 +592,10 @@ public class NMSBinding implements INMSBinding { } @Override - public boolean loadDatapack(File folder, boolean replace) { - var data = new File(folder, "iris/data"); - if (!data.exists() || !data.isDirectory()) return false; - FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json"); - - var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory()); - if (files == null) return false; - for (File file : files) { - var biome = new File(file, "worldgen/biome"); - if (!biome.exists()) continue; - var biomeFiles = biome.listFiles(jsonFilter); - if (biomeFiles == null) continue; - for (File biomeFile : biomeFiles) { - String json = null; - int tries = 10; - while (json == null && tries-- > 0) { - try { - json = IO.readAll(biomeFile); - } catch (IOException e) { - Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries); - if (tries == 0) { - e.printStackTrace(); - } - try { - Thread.sleep(100); - } catch (InterruptedException ignored) {} - } - } - if (json == null) continue; - - try { - var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null); - register(Registries.BIOME, from(file.getName(), biomeFile), value, replace); - } catch (Throwable e) { - Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName()); - e.printStackTrace(); - } - } - } - return true; - } - - private ResourceLocation from(String namespace, File file) { - var name = file.getName(); - return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.'))); + public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) { + var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null); + if (biomeBase == null) return false; + return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace); } private Optional decode(Codec codec, String json) { diff --git a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/CustomBiomeSource.java b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/CustomBiomeSource.java index d37284c25..a27c9a306 100644 --- a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/CustomBiomeSource.java +++ b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/CustomBiomeSource.java @@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_20_R4; import com.mojang.serialization.MapCodec; import com.volmit.iris.Iris; +import com.volmit.iris.core.nms.INMS; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.IrisBiome; @@ -124,8 +125,16 @@ public class CustomBiomeSource extends BiomeSource { for (IrisBiome i : engine.getAllBiomes()) { if (i.isCustom()) { for (IrisBiomeCustom j : i.getCustomDerivitives()) { - ResourceLocation resourceLocation = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()); - Biome biome = customRegistry.get(resourceLocation); + ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()); + Biome biome = customRegistry.get(location); + if (biome == null) { + INMS.get().registerBiome(location.getNamespace(), j, false); + biome = customRegistry.get(location); + if (biome == null) { + Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); + continue; + } + } Optional> optionalBiomeKey = customRegistry.getResourceKey(biome); if (optionalBiomeKey.isEmpty()) { Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); diff --git a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java index 59f90620b..2c989e893 100644 --- a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java +++ b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java @@ -4,18 +4,47 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; +import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.Vector; +import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; +import com.google.common.base.Preconditions; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Codec; +import com.mojang.serialization.JsonOps; import com.volmit.iris.core.nms.datapack.DataVersion; +import com.volmit.iris.engine.object.IrisBiomeCustom; +import com.volmit.iris.engine.object.IrisDimension; +import com.volmit.iris.util.format.C; +import it.unimi.dsi.fastutil.objects.Reference2IntMap; +import net.bytebuddy.ByteBuddy; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.dynamic.loading.ClassReloadingStrategy; +import net.bytebuddy.matcher.ElementMatchers; +import net.minecraft.core.MappedRegistry; +import net.minecraft.core.RegistrationInfo; import net.minecraft.core.component.DataComponents; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.progress.ChunkProgressListener; +import net.minecraft.util.GsonHelper; +import net.minecraft.world.RandomSequences; import net.minecraft.world.item.component.CustomData; +import net.minecraft.world.level.Level; import net.minecraft.world.level.chunk.status.ChunkStatus; +import net.minecraft.world.level.dimension.DimensionType; +import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.storage.LevelStorageSource; +import net.minecraft.world.level.storage.PrimaryLevelData; import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -29,6 +58,7 @@ import org.bukkit.craftbukkit.v1_20_R4.util.CraftNamespacedKey; import org.bukkit.entity.Dolphin; import org.bukkit.entity.Entity; import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.generator.BiomeProvider; import org.bukkit.generator.ChunkGenerator; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; @@ -549,4 +579,189 @@ public class NMSBinding implements INMSBinding { public DataVersion getDataVersion() { return DataVersion.V1205; } + + @Override + public boolean registerDimension(String name, IrisDimension dimension) { + var registry = registry(Registries.DIMENSION_TYPE); + var baseLocation = switch (dimension.getEnvironment()) { + case NORMAL -> new ResourceLocation("minecraft", "overworld"); + case NETHER -> new ResourceLocation("minecraft", "the_nether"); + case THE_END -> new ResourceLocation("minecraft", "the_end"); + case CUSTOM -> throw new IllegalArgumentException("Cannot register custom dimension"); + }; + var base = registry.getHolder(ResourceKey.create(Registries.DIMENSION_TYPE, baseLocation)).orElse(null); + if (base == null) return false; + var json = encode(DimensionType.CODEC, base).orElse(null); + if (json == null) return false; + var object = json.getAsJsonObject(); + var height = dimension.getDimensionHeight(); + object.addProperty("min_y", height.getMin()); + object.addProperty("height", height.getMax() - height.getMin()); + object.addProperty("logical_height", dimension.getLogicalHeight()); + var value = decode(DimensionType.CODEC, object.toString()).map(Holder::value).orElse(null); + if (value == null) return false; + return register(Registries.DIMENSION_TYPE, new ResourceLocation("iris", name), value, true); + } + + @Override + public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) { + var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null); + if (biomeBase == null) return false; + return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace); + } + + private Optional decode(Codec codec, String json) { + return codec.decode(JsonOps.INSTANCE, GsonHelper.parse(json)).result().map(Pair::getFirst); + } + + private Optional encode(Codec codec, T value) { + return codec.encode(value, JsonOps.INSTANCE, new JsonObject()).result(); + } + + private boolean register(ResourceKey> registryKey, ResourceLocation location, T value, boolean replace) { + Preconditions.checkArgument(registryKey != null, "The registry cannot be null!"); + Preconditions.checkArgument(location != null, "The location cannot be null!"); + Preconditions.checkArgument(value != null, "The value cannot be null!"); + var registry = registry(registryKey); + var key = ResourceKey.create(registryKey, location); + try { + if (registry.containsKey(key)) { + if (!replace) return false; + return replace(registryKey, location, value); + } + Field field = getField(MappedRegistry.class, boolean.class); + field.setAccessible(true); + boolean frozen = field.getBoolean(registry); + field.setBoolean(registry, false); + Field valueField = getField(Holder.Reference.class, "T"); + valueField.setAccessible(true); + + try { + var holder = registry.register(key, value, RegistrationInfo.BUILT_IN); + if (frozen) valueField.set(holder, value); + return true; + } finally { + field.setBoolean(registry, frozen); + } + } catch (Throwable e) { + throw new IllegalStateException(e); + } + } + + @SuppressWarnings("unchecked") + private boolean replace(ResourceKey> registryKey, ResourceLocation location, T value) { + Preconditions.checkArgument(registryKey != null, "The registryKey cannot be null!"); + Preconditions.checkArgument(location != null, "The location cannot be null!"); + Preconditions.checkArgument(value != null, "The value cannot be null!"); + var registry = registry(registryKey); + var key = ResourceKey.create(registryKey, location); + try { + var holder = registry.getHolder(key).orElse(null); + if (holder == null) return false; + var oldValue = holder.value(); + Field valueField = getField(Holder.Reference.class, "T"); + valueField.setAccessible(true); + Field toIdField = getField(MappedRegistry.class, buildType(Reference2IntMap.class, "T")); + toIdField.setAccessible(true); + Field byValueField = getField(MappedRegistry.class, buildType(Map.class, "T", buildType(Holder.Reference.class, "T"))); + byValueField.setAccessible(true); + var toId = (Reference2IntMap) toIdField.get(registry); + var byValue = (Map>) byValueField.get(registry); + + valueField.set(holder, value); + toId.put(value, toId.removeInt(oldValue)); + byValue.put(value, byValue.remove(oldValue)); + return true; + } catch (Throwable e) { + throw new IllegalStateException(e); + } + } + + private MappedRegistry registry(ResourceKey> registryKey) { + var rawRegistry = registry().registry(registryKey).orElse(null); + if (!(rawRegistry instanceof MappedRegistry registry)) + throw new IllegalStateException("The Registry is not a mapped Registry!"); + return registry; + } + + private static String buildType(Class clazz, String... parameterTypes) { + if (parameterTypes.length == 0) return clazz.getName(); + var builder = new StringBuilder(clazz.getName()) + .append("<"); + for (int i = 0; i < parameterTypes.length; i++) { + builder.append(parameterTypes[i]).append(parameterTypes.length - 1 == i ? ">" : ", "); + } + return builder.toString(); + } + + private static Field getField(Class clazz, String type) throws NoSuchFieldException { + try { + for (Field f : clazz.getDeclaredFields()) { + if (f.getGenericType().getTypeName().equals(type)) + return f; + } + throw new NoSuchFieldException(type); + } catch (NoSuchFieldException e) { + Class superClass = clazz.getSuperclass(); + if (superClass == null) throw e; + return getField(superClass, type); + } + } + + public void injectBukkit() { + try { + Iris.info("Injecting Bukkit"); + new ByteBuddy() + .redefine(WorldCreator.class) + .visit(Advice.to(WorldCreatorAdvice.class).on(ElementMatchers.isConstructor().and(ElementMatchers.takesArguments(String.class)))) + .make() + .load(WorldCreator.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent()); + new ByteBuddy() + .redefine(ServerLevel.class) + .visit(Advice.to(ServerLevelAdvice.class).on(ElementMatchers.isConstructor().and(ElementMatchers.takesArguments(MinecraftServer.class, Executor.class, LevelStorageSource.LevelStorageAccess.class, + PrimaryLevelData.class, ResourceKey.class, LevelStem.class, ChunkProgressListener.class, boolean.class, long.class, + List.class, boolean.class, RandomSequences.class, World.Environment.class, ChunkGenerator.class, BiomeProvider.class)))) + .make() + .load(ServerLevel.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent()); + Iris.info("Injected Bukkit Successfully!"); + } catch (Exception e) { + Iris.info(C.RED + "Failed to Inject Bukkit!"); + e.printStackTrace(); + Iris.reportError(e); + } + + } + + private static class ServerLevelAdvice { + @Advice.OnMethodEnter + static void enter(@Advice.Argument(0) MinecraftServer server, @Advice.Argument(2) LevelStorageSource.LevelStorageAccess access, @Advice.Argument(4) ResourceKey key, @Advice.Argument(value = 5, readOnly = false) LevelStem levelStem) { + File iris = new File(access.levelDirectory.path().toFile(), "iris"); + if (!iris.exists() && !key.location().getPath().startsWith("iris/")) return; + ResourceKey typeKey = ResourceKey.create(Registries.DIMENSION_TYPE, new ResourceLocation("iris", key.location().getPath())); + RegistryAccess registryAccess = server.registryAccess(); + Registry registry = registryAccess.registry(Registries.DIMENSION_TYPE).orElse(null); + if (registry == null) throw new IllegalStateException("Unable to find registry for dimension type " + typeKey); + Holder holder = registry.getHolder(typeKey).orElse(null); + if (holder == null) throw new IllegalStateException("Unable to find dimension type " + typeKey); + levelStem = new LevelStem(holder, levelStem.generator()); + } + } + + private static class WorldCreatorAdvice { + @Advice.OnMethodEnter + static void enter(@Advice.Argument(0) String name) { + File isIrisWorld = new File(name, "iris"); + boolean isFromIris = false; + StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); + for (StackTraceElement stack : stackTrace) { + if (stack.getClassName().contains("Iris")) { + isFromIris = true; + break; + } + } + if (!isFromIris) { + Preconditions.checkArgument(!isIrisWorld.exists(), "Only Iris can load Iris Worlds!"); + } + } + } }