From c4f0722614b34d674d502edcf373c6496ea2298c Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Tue, 18 Mar 2025 11:15:57 +0100 Subject: [PATCH] improve datapack setup speed --- .../volmit/iris/core/ServerConfigurator.java | 40 ++++-- .../iris/engine/object/IrisDimension.java | 116 +++++++++--------- 2 files changed, 83 insertions(+), 73 deletions(-) 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 8d579d859..aace8e897 100644 --- a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java +++ b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java @@ -28,21 +28,23 @@ 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.KMap; 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 lombok.Data; +import lombok.NonNull; import org.bukkit.Bukkit; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; import java.util.Arrays; -import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Stream; @@ -89,7 +91,7 @@ public class ServerConfigurator { } } - private static List getDatapacksFolder() { + private static KList getDatapacksFolder() { if (!IrisSettings.get().getGeneral().forceMainWorld.isEmpty()) { return new KList().qadd(new File(Bukkit.getWorldContainer(), IrisSettings.get().getGeneral().forceMainWorld + "/datapacks")); } @@ -105,15 +107,16 @@ public class ServerConfigurator { public static void installDataPacks(IDataFixer fixer, boolean fullInstall) { Iris.info("Checking Data Packs..."); DimensionHeight height = new DimensionHeight(fixer); + KList folders = getDatapacksFolder(); + KMap> biomes = new KMap<>(); allPacks().flatMap(height::merge) - .toList() + .parallel() .forEach(dim -> { - for (File dpack : getDatapacksFolder()) { - Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath()); - dim.installDataPack(fixer, dim::getLoader, dpack, height); - } + Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath()); + dim.installBiomes(fixer, dim::getLoader, folders, biomes.computeIfAbsent(dim.getLoadKey(), k -> new KSet<>())); }); + IrisDimension.writeShared(folders, height); Iris.info("Data Packs Setup!"); @@ -165,7 +168,7 @@ public class ServerConfigurator { 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 diddn't work. Stopping the server instead!"); + Iris.warn("Looks like the restart command didn't work. Stopping the server instead!"); Bukkit.shutdown(); }, 100); Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "restart"); @@ -173,22 +176,24 @@ public class ServerConfigurator { } 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)) { + for (IrisBiome i : dimension.getAllBiomes(dimension::getLoader)) { if (i.isCustom()) { for (IrisBiomeCustom j : i.getCustomDerivitives()) { keys.add(dimension.getLoadKey() + ":" + j.getId()); } } } + String key = getWorld(dimension.getLoader()); + if (key == null) key = dimension.getLoadKey(); + else key += "/" + dimension.getLoadKey(); if (!INMS.get().supportsDataPacks()) { if (!keys.isEmpty()) { Iris.warn("==================================================================================="); - Iris.warn("Pack " + dimension.getLoadKey() + " has " + keys.size() + " custom biome(s). "); + Iris.warn("Pack " + key + " 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("===================================================================================="); @@ -207,7 +212,7 @@ public class ServerConfigurator { } if (warn) { - Iris.error("The Pack " + dimension.getLoadKey() + " is INCAPABLE of generating custom biomes"); + Iris.error("The Pack " + key + " is INCAPABLE of generating custom biomes"); Iris.error("If not done automatically, restart your server before generating with this pack!"); } @@ -221,6 +226,17 @@ public class ServerConfigurator { .map(IrisData::get); } + @Nullable + public static String getWorld(@NonNull IrisData data) { + String worldContainer = Bukkit.getWorldContainer().getAbsolutePath(); + if (!worldContainer.endsWith(File.separator)) worldContainer += File.separator; + + String path = data.getDataFolder().getAbsolutePath(); + if (!path.startsWith(worldContainer)) return null; + int l = path.endsWith(File.separator) ? 11 : 10; + return path.substring(worldContainer.length(), path.length() - l); + } + private static Stream listFiles(File parent) { var files = parent.listFiles(); return files == null ? Stream.empty() : Arrays.stream(files); 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 08dc3b77f..f2c5b724c 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 @@ -28,6 +28,7 @@ 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.collection.KSet; import com.volmit.iris.util.data.DataProvider; import com.volmit.iris.util.io.IO; import com.volmit.iris.util.json.JSONObject; @@ -378,57 +379,35 @@ public class IrisDimension extends IrisRegistrant { return landBiomeStyle; } - public boolean installDataPack(IDataFixer fixer, DataProvider data, File datapacks, DimensionHeight height) { - 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(); - } - } - } - } - - Iris.verbose(" Installing Data Pack Dimension Types: \"iris:overworld\", \"iris:the_nether\", \"iris:the_end\""); - changed = writeDimensionType(changed, datapacks, height); - - 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": {} - } + public void installBiomes(IDataFixer fixer, DataProvider data, KList folders, KSet biomes) { + getAllBiomes(data) + .stream() + .filter(IrisBiome::isCustom) + .map(IrisBiome::getCustomDerivitives) + .flatMap(KList::stream) + .parallel() + .forEach(j -> { + String json = j.generateJson(fixer); + synchronized (biomes) { + if (!biomes.add(j.getId())) { + Iris.verbose("Duplicate Data Pack Biome: " + getLoadKey() + "/" + j.getId()); + return; } - """.replace("{}", INMS.get().getDataVersion().getPackFormat() + "")); - } catch (IOException e) { - Iris.reportError(e); - e.printStackTrace(); - } - Iris.verbose(" Installing Data Pack MCMeta: " + mcm.getPath()); - } + } - return changed; + for (File datapacks : folders) { + File output = new File(datapacks, "iris/data/" + getLoadKey().toLowerCase() + "/worldgen/biome/" + j.getId() + ".json"); + + Iris.verbose(" Installing Data Pack Biome: " + output.getPath()); + output.getParentFile().mkdirs(); + try { + IO.writeAll(output, json); + } catch (IOException e) { + Iris.reportError(e); + e.printStackTrace(); + } + } + }); } @Override @@ -446,20 +425,39 @@ public class IrisDimension extends IrisRegistrant { } - public boolean writeDimensionType(boolean changed, File datapacks, DimensionHeight height) { - changed = write(changed, datapacks, "overworld", height.overworldType()); - changed = write(changed, datapacks, "the_nether", height.netherType()); - changed = write(changed, datapacks, "the_end", height.endType()); + public static void writeShared(KList folders, DimensionHeight height) { + Iris.verbose(" Installing Data Pack Dimension Types: \"iris:overworld\", \"iris:the_nether\", \"iris:the_end\""); + for (File datapacks : folders) { + write(datapacks, "overworld", height.overworldType()); + write(datapacks, "the_nether", height.netherType()); + write(datapacks, "the_end", height.endType()); + } - return changed; + String raw = """ + { + "pack": { + "description": "Iris Data Pack. This pack contains all installed Iris Packs' resources.", + "pack_format": {} + } + } + """.replace("{}", INMS.get().getDataVersion().getPackFormat() + ""); + + for (File datapacks : folders) { + File mcm = new File(datapacks, "iris/pack.mcmeta"); + try { + IO.writeAll(mcm, raw); + } catch (IOException e) { + Iris.reportError(e); + e.printStackTrace(); + } + Iris.verbose(" Installing Data Pack MCMeta: " + mcm.getPath()); + } } - private static boolean write(boolean changed, File datapacks, String type, String json) { + private static void write(File datapacks, String type, String json) { File dimType = new File(datapacks, "iris/data/iris/dimension_type/" + type + ".json"); File dimTypeVanilla = new File(datapacks, "iris/data/minecraft/dimension_type/" + type + ".json"); - if (!dimType.exists()) - changed = true; dimType.getParentFile().mkdirs(); try { IO.writeAll(dimType, json); @@ -469,8 +467,6 @@ public class IrisDimension extends IrisRegistrant { } if (IrisSettings.get().getGeneral().adjustVanillaHeight || dimTypeVanilla.exists()) { - if (!dimTypeVanilla.exists()) - changed = true; dimTypeVanilla.getParentFile().mkdirs(); try { IO.writeAll(dimTypeVanilla, json); @@ -479,7 +475,5 @@ public class IrisDimension extends IrisRegistrant { e.printStackTrace(); } } - - return changed; } }