From 6ff597591836f215dfb93671d592216be0b69f07 Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Sat, 11 Nov 2023 21:25:24 +0100 Subject: [PATCH] - HotDrop iris worlds lmao --- core/src/main/java/com/volmit/iris/Iris.java | 7 + .../com/volmit/iris/core/IrisSettings.java | 1 + .../core/commands/CommandWorldManager.java | 2 +- .../iris/core/safeguard/ServerBootSFG.java | 38 ++++ .../iris/core/service/HotDropWorldSVC.java | 142 ++++++++++++++ .../volmit/iris/util/SFG/WorldHandlerSFG.java | 179 ++++++++++++++++++ 6 files changed, 368 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/com/volmit/iris/core/service/HotDropWorldSVC.java create mode 100644 core/src/main/java/com/volmit/iris/util/SFG/WorldHandlerSFG.java diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index 849ac00e8..75af63cf8 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -30,7 +30,9 @@ import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.nms.v1X.NMSBinding1X; import com.volmit.iris.core.pregenerator.LazyPregenerator; +import com.volmit.iris.core.safeguard.ServerBootSFG; import com.volmit.iris.core.service.ChunkHandlerSVC; +import com.volmit.iris.core.service.HotDropWorldSVC; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.EnginePanic; @@ -478,7 +480,12 @@ public class Iris extends VolmitPlugin implements Listener { chunkHandlerSVC = new ChunkHandlerSVC(this); Iris.info(C.LIGHT_PURPLE + "Started Intergrated ChunkHandlerSVC"); } + + HotDropWorldSVC hotDropWorldSVC = new HotDropWorldSVC(this); + hotDropWorldSVC.start(); + autoStartStudio(); + ServerBootSFG.CheckIrisWorlds(); checkForBukkitWorlds(); IrisToolbelt.retainMantleDataForSlice(String.class.getCanonicalName()); IrisToolbelt.retainMantleDataForSlice(BlockData.class.getCanonicalName()); diff --git a/core/src/main/java/com/volmit/iris/core/IrisSettings.java b/core/src/main/java/com/volmit/iris/core/IrisSettings.java index 2c570a788..cefe5c9ec 100644 --- a/core/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/core/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -126,6 +126,7 @@ public class IrisSettings { public boolean markerEntitySpawningSystem = true; public boolean effectSystem = true; public boolean worldEditWandCUI = true; + public boolean AutoFindIrisWorlds = false; } @Data diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandWorldManager.java b/core/src/main/java/com/volmit/iris/core/commands/CommandWorldManager.java index 1f82ea3d9..4ea17348c 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandWorldManager.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandWorldManager.java @@ -85,7 +85,7 @@ public class CommandWorldManager implements DecreeExecutor { @Param(description = "The name of the world to load") String world ) { - World worldloaded = Bukkit.getWorld(world); + World worldloaded = Bukkit.getWorld(world); worldNameToCheck = world; boolean worldExists = doesWorldExist(worldNameToCheck); WorldEngine = world; diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java b/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java index 37b52939d..a677cf334 100644 --- a/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java +++ b/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java @@ -1,15 +1,20 @@ package com.volmit.iris.core.safeguard; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.nms.v1X.NMSBinding1X; +import com.volmit.iris.util.SFG.WorldHandlerSFG; import org.bukkit.Bukkit; +import org.bukkit.World; import org.bukkit.plugin.Plugin; +import java.io.File; import java.util.*; import static com.volmit.iris.Iris.instance; import static com.volmit.iris.core.safeguard.IrisSafeguard.unstablemode; +import static com.volmit.iris.core.tools.IrisToolbelt.access; public class ServerBootSFG { public static final Map incompatiblePlugins = new HashMap<>(); @@ -70,6 +75,39 @@ public class ServerBootSFG { unstablemode = true; Iris.safeguard("Unstable mode has been activated."); } + } + public static void CheckIrisWorlds() { + if (IrisSettings.get().getWorld().AutoFindIrisWorlds) { + StringJoiner joiner = new StringJoiner(", "); + // Get the main server folder + File serverFolder = Bukkit.getWorldContainer(); + + // List all files in the server folder + File[] listOfFiles = serverFolder.listFiles(); + + if (listOfFiles != null) { + for (File file : listOfFiles) { + // Check if it is a directory (world folders are directories) + if (file.isDirectory()) { + // Check for an "iris" folder inside the world directory + File irisFolder = new File(file, "iris"); + if (irisFolder.exists() && irisFolder.isDirectory()) { + String worldName = file.getName(); + joiner.add(worldName); + + // Check if the world is already loaded + if (Bukkit.getWorld(worldName) == null) { + WorldHandlerSFG.LoadWorld(worldName); + } + } + } + } + } else { + Bukkit.getLogger().warning("No files found in the server folder."); + } + // No Idea what I should do with this + String worldsList = joiner.toString(); + } } } diff --git a/core/src/main/java/com/volmit/iris/core/service/HotDropWorldSVC.java b/core/src/main/java/com/volmit/iris/core/service/HotDropWorldSVC.java new file mode 100644 index 000000000..20e9c8231 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/service/HotDropWorldSVC.java @@ -0,0 +1,142 @@ +package com.volmit.iris.core.service; + +import java.nio.file.*; +import static java.nio.file.StandardWatchEventKinds.*; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonParseException; +import com.volmit.iris.Iris; +import com.volmit.iris.util.SFG.WorldHandlerSFG; +import com.volmit.iris.util.format.C; +import com.volmit.iris.util.scheduling.Looper; +import org.bukkit.Bukkit; +import org.bukkit.plugin.java.JavaPlugin; + +public class HotDropWorldSVC extends Looper { + private WatchService watchService; + private JavaPlugin plugin; + + public HotDropWorldSVC(JavaPlugin plugin) { + this.plugin = plugin; + try { + this.watchService = FileSystems.getDefault().newWatchService(); + Path path = Paths.get(Bukkit.getWorldContainer().getAbsolutePath()); + path.register(watchService, ENTRY_CREATE); + } catch (Exception e) { + Iris.reportError(e); + e.printStackTrace(); + } + } + + @Override + protected long loop() { + WatchKey key; + try { + key = watchService.poll(); + if (key != null) { + for (WatchEvent event : key.pollEvents()) { + WatchEvent.Kind kind = event.kind(); + + if (kind == ENTRY_CREATE) { + WatchEvent ev = (WatchEvent) event; + Path filename = ev.context(); + + File newDir = new File(Bukkit.getWorldContainer(), filename.toString()); + File irisFolder = new File(newDir, "iris"); + if (irisFolder.exists() && irisFolder.isDirectory()) { + Iris.info("World HotDrop Detected!"); + String worldName = newDir.getName(); + String version = getVersionFromIrisFolder(irisFolder); + + if (Bukkit.getWorld(worldName) == null && isPackValid(worldName, version)) { + Bukkit.getScheduler().runTask(this.plugin, () -> WorldHandlerSFG.LoadWorld(worldName)); + } + } + } + } + key.reset(); + } + } catch (Throwable e) { + Iris.reportError(e); + e.printStackTrace(); + return -1; + } + + return 1000; // Loop every 1000 milliseconds (1 second) + } + + private String getVersionFromIrisFolder(File irisFolder) { + File versionFile = new File(irisFolder, "some_version_file.json"); // Replace with actual file name + + if (versionFile.exists() && versionFile.isFile()) { + try (FileReader reader = new FileReader(versionFile)) { + JsonObject jsonObject = JsonParser.parseReader(reader).getAsJsonObject(); + if (jsonObject.has("version")) { + return jsonObject.get("version").getAsString(); + } + } catch (IOException | JsonParseException e) { + Iris.reportError(e); + e.printStackTrace(); + // Optionally, log additional information or take alternative action + } + } + + return "???"; // Default or unknown version + } + + + private boolean isPackValid(String worldPackName, String version) { + try { + File packFolder = Iris.service(StudioSVC.class).getWorkspaceFolder(); + File[] serverPacks = packFolder.listFiles(File::isDirectory); + if (serverPacks != null) { + for (File serverPack : serverPacks) { + String serverPackName = serverPack.getName(); + String serverPackVersion = getPackVersion(serverPack); + + if (serverPackName.equals(worldPackName)) { + if (serverPackVersion.equals(version)) { + return true; + } else { + Iris.info("Version mismatch for pack '" + worldPackName + "'. Expected: " + serverPackVersion + ", Found: " + version); + Iris.info(C.GOLD + "Cant load the world!"); + return false; + } + } + } + Iris.info("Pack '" + worldPackName + "' not found on the server."); + Iris.info(C.GOLD + "Cant load the world!"); + } else { + Iris.info("No packs found in the server's workspace folder."); + } + } catch (Exception e) { + Iris.reportError(e); + e.printStackTrace(); + Iris.info("Error checking if pack is valid: " + e.getMessage()); + } + return false; + } + + + private String getPackVersion(File pack) { + String version = "???"; + File dimensionFile = new File(pack, "dimensions/" + pack.getName() + ".json"); + if (dimensionFile.isFile()) { + try (FileReader reader = new FileReader(dimensionFile)) { + JsonObject json = JsonParser.parseReader(reader).getAsJsonObject(); + if (json.has("version")) { + version = json.get("version").getAsString(); + } + } catch (IOException | JsonParseException e) { + Iris.reportError(e); + e.printStackTrace(); + // Handle error (e.g., logging, user notification) + } + } + return version; + } +} + diff --git a/core/src/main/java/com/volmit/iris/util/SFG/WorldHandlerSFG.java b/core/src/main/java/com/volmit/iris/util/SFG/WorldHandlerSFG.java new file mode 100644 index 000000000..8ff552d27 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/SFG/WorldHandlerSFG.java @@ -0,0 +1,179 @@ +package com.volmit.iris.util.SFG; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.core.service.StudioSVC; +import com.volmit.iris.engine.object.IrisDimension; +import com.volmit.iris.engine.object.IrisWorld; +import com.volmit.iris.engine.platform.BukkitChunkGenerator; +import com.volmit.iris.engine.platform.DummyChunkGenerator; +import com.volmit.iris.util.format.C; +import com.volmit.iris.util.plugin.VolmitSender; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.WorldCreator; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.generator.ChunkGenerator; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import static com.volmit.iris.Iris.service; + +public class WorldHandlerSFG { + static String WorldToLoad; + static String WorldEngine; + static String worldNameToCheck = "YourWorldName"; + private static VolmitSender sender; + public static void LoadWorld(String selectedWorld){ + if(Objects.equals(selectedWorld, "Benchmark")){ + return; + } + worldNameToCheck = selectedWorld; + boolean worldExists = doesWorldExist(worldNameToCheck); + WorldEngine = selectedWorld; + + if (!worldExists) { + return; + } + WorldToLoad = selectedWorld; + File BUKKIT_YML = new File("bukkit.yml"); + String pathtodim = selectedWorld + "\\iris\\pack\\dimensions\\"; + File directory = new File(Bukkit.getWorldContainer(), pathtodim); + + String dimension = null; + if (directory.exists() && directory.isDirectory()) { + File[] files = directory.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isFile()) { + String fileName = file.getName(); + if (fileName.endsWith(".json")) { + dimension = fileName.substring(0, fileName.length() - 5); + } + } + } + } + } else { + return; + } + + YamlConfiguration yml = YamlConfiguration.loadConfiguration(BUKKIT_YML); + String gen = "Iris:" + dimension; + ConfigurationSection section = yml.contains("worlds") ? yml.getConfigurationSection("worlds") : yml.createSection("worlds"); + if (!section.contains(selectedWorld)) { + section.createSection(selectedWorld).set("generator", gen); + try { + yml.save(BUKKIT_YML); + Iris.info("Registered \"" + selectedWorld + "\" in bukkit.yml"); + } catch (IOException e) { + Iris.error("Failed to update bukkit.yml!"); + e.printStackTrace(); + } + } + checkForBukkitWorlds(); + } + static boolean doesWorldExist(String worldName) { + File worldContainer = Bukkit.getWorldContainer(); + File worldDirectory = new File(worldContainer, worldName); + return worldDirectory.exists() && worldDirectory.isDirectory(); + } + private static void checkForBukkitWorlds() { + FileConfiguration fc = new YamlConfiguration(); + try { + fc.load(new File("bukkit.yml")); + ConfigurationSection section = fc.getConfigurationSection("worlds"); + if (section == null) { + return; + } + + List worldsToLoad = Collections.singletonList(WorldToLoad); + + for (String s : section.getKeys(false)) { + if (!worldsToLoad.contains(s)) { + continue; + } + ConfigurationSection entry = section.getConfigurationSection(s); + if (!entry.contains("generator", true)) { + continue; + } + String generator = entry.getString("generator"); + if (generator.startsWith("Iris:")) { + generator = generator.split("\\Q:\\E")[1]; + } else if (generator.equalsIgnoreCase("Iris")) { + generator = IrisSettings.get().getGenerator().getDefaultWorldType(); + } else { + continue; + } + Iris.info("2 World: %s | Generator: %s", s, generator); + if (Bukkit.getWorlds().stream().anyMatch(w -> w.getName().equals(s))) { + continue; + } + Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "..."); + new WorldCreator(s) + .generator(getDefaultWorldGenerator(s, generator)) + .environment(IrisData.loadAnyDimension(generator).getEnvironment()) + .createWorld(); + Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!"); + } + } catch (Throwable e) { + e.printStackTrace(); + } + } + public static ChunkGenerator getDefaultWorldGenerator(String worldName, String id) { + Iris.debug("Default World Generator Called for " + worldName + " using ID: " + id); + if (worldName.equals("test")) { + try { + throw new RuntimeException(); + } catch (Throwable e) { + Iris.info(e.getStackTrace()[1].getClassName()); + if (e.getStackTrace()[1].getClassName().contains("com.onarandombox.MultiverseCore")) { + Iris.debug("MVC Test detected, Quick! Send them the dummy!"); + return new DummyChunkGenerator(); + } + } + } + IrisDimension dim; + if (id == null || id.isEmpty()) { + dim = IrisData.loadAnyDimension(IrisSettings.get().getGenerator().getDefaultWorldType()); + } else { + dim = IrisData.loadAnyDimension(id); + } + Iris.debug("Generator ID: " + id + " requested by bukkit/plugin"); + + if (dim == null) { + Iris.warn("Unable to find dimension type " + id + " Looking for online packs..."); + + service(StudioSVC.class).downloadSearch(new VolmitSender(Bukkit.getConsoleSender()), id, true); + dim = IrisData.loadAnyDimension(id); + + if (dim == null) { + throw new RuntimeException("Can't find dimension " + id + "!"); + } else { + Iris.info("Resolved missing dimension, proceeding with generation."); + } + } + Iris.debug("Assuming IrisDimension: " + dim.getName()); + IrisWorld w = IrisWorld.builder() + .name(worldName) + .seed(1337) + .environment(dim.getEnvironment()) + .worldFolder(new File(Bukkit.getWorldContainer(), worldName)) + .minHeight(dim.getMinHeight()) + .maxHeight(dim.getMaxHeight()) + .build(); + Iris.debug("Generator Config: " + w.toString()); + File ff = new File(w.worldFolder(), "iris/pack"); + if (!ff.exists() || ff.listFiles().length == 0) { + ff.mkdirs(); + service(StudioSVC.class).installIntoWorld(sender, dim.getLoadKey(), ff.getParentFile()); + } + return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey()); + } +}