diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 000000000..b9104754f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,71 @@ +name: Iris Bug Report +description: File a bug report for Iris +labels: [bug] +body: + - type: markdown + attributes: + value: | + Thank you for taking the time to fill this out! + If this does not work for you, feel free to use the [blank](https://github.com/VolmitSoftware/Iris/issues/new) format. + - type: textarea + id: how + attributes: + label: Problem + description: Please give a text description of how you reached the problem + value: | + 1. Install Iris... + 2. Do this... + 3. Do that... + 4. Observe the error... + render: txt + validations: + required: true + - type: textarea + id: what + attributes: + label: Solution + description: Explain where you think the problem comes from (optional) + placeholder: The code to place a is missing b and c... + validations: + required: false + - type: dropdown + id: mcversion + attributes: + label: Minecraft Version + description: What version of Minecraft is the server on? + options: + - 1.14 to 1.16.5 + - 1.17.x + - 1.18.x + validations: + required: true + - type: input + id: irisversion + attributes: + label: Iris Version + description: What version of Iris are you running? (see console) + placeholder: DO NOT SAY "LATEST" + validations: + required: true + - type: input + id: logs + attributes: + label: Log + description: Paste a full log. Always use [mclogs](https://mclo.gs) Or [Pastebin](https://pastebin.com/). Must not be a crash report. Must be a full log. Must not be a screenshot of a log. + placeholder: https://mslog.gs/... + validations: + required: true + - type: checkboxes + id: checksum + attributes: + label: Checklist + description: Please ensure you meet each of the requirements below + options: + - label: I am using an unmodified version of Iris. (If you modified the plugin and see an issue, make sure it is reproducable on the latest spigot version or contact [support](discord.gg/volmit)) + required: true + - label: I am using Spigot, Paper, Tuinity, or Purpur. (If you are not, and still think it is a valid issue, contact [support](discord.gg/volmit)) + required: true + - type: markdown + id: thanks + attributes: + value: "Thank you for filling out the form! We will be with you soon. Please do not ask support to review your report." diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index c07dfb6be..000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -name: Bug report about: Create a report to help us improve title: '' -labels: Bug assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: - -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots or Video Recordings** -If applicable, add screenshots or video recordings to help explain your problem. - -**Server and Plugin Information** - -- Installed plugins: -- Iris Version: -- Server Platform and Version [eg: PaperSpigot 1.16.3 #240]: -- Operating System (if applicable): -- Server Logs: - -**Additional context** -Add any other context about the problem here, server timings reports, Iris dump information, complete console log etc. -Please do not make Pastebin dumps or screenshot expire. diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml new file mode 100644 index 000000000..afcfb2031 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -0,0 +1,46 @@ +name: Iris Feature Request +description: File a feature request for Iris. If you want to report a bug this is not the place. +labels: [feature] +body: + - type: markdown + attributes: + value: | + Thank you for taking the time to fill this out! + If this does not work for you, feel free to use the [blank](https://github.com/VolmitSoftware/Iris/issues/new) format. + - type: dropdown + id: arc + attributes: + label: Adding, Removing, or Changing + description: What are you doing + options: + - Adding + - Removing + - Changing + validations: + required: true + - type: input + id: atype + attributes: + label: Type of Modification + description: What is it for? + value: I want to ... + validations: + required: true + - type: textarea + id: desc + attributes: + label: What are you trying to modify + description: Give as detailed of a description as you can for the modification that you want done (include pictures if applicable) + value: The way I would implement this is ... + validations: + required: true + - type: textarea + id: alternative + attributes: + label: Alternatives + description: What alternatives have you considered? + value: If this could not be implemented I would ... + - type: markdown + id: thanks + attributes: + value: "Thank you for filling out the form! We will be with you soon. Please do not ask support to review your report." diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index aab81ed77..000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: Feature request about: Suggest an idea for this project title: '' -labels: Enhancement, Addition assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/README.md b/README.md index c437ec12e..b7e56f28c 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,39 @@ For 1.16 and below, see the 1.14-1.16 branch. The master branch is for the latest version of minecraft. # [Support](https://discord.gg/3xxPTpT) **|** [Documentation](https://docs.volmit.com/iris/) ** - |** [Git](https://github.com/IrisDimensions) -![Iris Image](https://raw.githubusercontent.com/VolmitSoftware/Iris/master/IRIS.png) +## Iris Toolbelt + +Everyone needs a toolbelt. + +```java +package com.volmit.iris.core.tools + +// Get IrisDataManager from a world +IrisToolbelt.access(anyWorld).getCompound().getData(); + +// Get Default Engine from world +IrisToolbelt.access(anyWorld).getCompound().getDefaultEngine(); + +// Get the engine at the given height +IrisToolbelt.access(anyWorld).getCompound().getEngineForHeight(68); + +// IS THIS THING ON? +boolean yes = IrisToolbelt.isIrisWorld(world); + +// GTFO for worlds (moves players to any other world, just not this one) +IrisToolbelt.evacuate(world); + +IrisAccess access = IrisToolbelt.createWorld() // If you like builders... + .name("myWorld") // The world name + .dimension("terrifyinghands") + .seed(69133742) // The world seed + .headless(true) // Headless make gen go fast + .pregen(PregenTask // Define a pregen job to run + .builder() + .center(new Position2(0,0)) // REGION coords (1 region = 32x32 chunks) + .radius(4) // Radius in REGIONS. Rad of 4 means a 9x9 Region map. + .build()) + .create(); +``` diff --git a/build.gradle b/build.gradle index f78189e2e..ab94995d0 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { } group 'com.volmit.iris' -version '1.5.2' +version '1.5.6' def apiVersion = '1.17' def name = 'Iris' def main = 'com.volmit.iris.Iris' @@ -81,6 +81,8 @@ shadowJar } } +manifest() + dependencies { compileOnly 'org.projectlombok:lombok:1.18.20' annotationProcessor 'org.projectlombok:lombok:1.18.20' diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index 47e906057..dd59cf35c 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -26,12 +26,13 @@ import com.volmit.iris.core.link.BKLink; import com.volmit.iris.core.link.MultiverseCoreLink; import com.volmit.iris.core.link.MythicMobsLink; import com.volmit.iris.core.nms.INMS; -import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.EngineCompositeGenerator; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisBiomeCustom; import com.volmit.iris.engine.object.IrisCompat; import com.volmit.iris.engine.object.IrisDimension; +import com.volmit.iris.engine.parallel.MultiBurst; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.format.C; @@ -79,9 +80,6 @@ public class Iris extends VolmitPlugin implements Listener { public static MythicMobsLink linkMythicMobs; public static TreeManager saplingManager; private static final Queue syncJobs = new ShurikenQueue<>(); - public static boolean customModels = doesSupportCustomModels(); - public static boolean awareEntities = doesSupportAwareness(); - public static boolean lowMemoryMode = false; public static IrisCompat compat; public static FileWatcher configWatcher; @@ -95,7 +93,6 @@ public class Iris extends VolmitPlugin implements Listener { instance = this; INMS.get(); IO.delete(new File("iris")); - lowMemoryMode = Runtime.getRuntime().maxMemory() < 4000000000L; // 4 * 1000 * 1000 * 1000 // 4; installDataPacks(); } @@ -156,54 +153,6 @@ public class Iris extends VolmitPlugin implements Listener { Iris.info("Data Packs Setup!"); } - public static int getThreadCount() { - int tc = IrisSettings.get().getConcurrency().getThreadCount(); - - if (tc <= 0) { - int p = Runtime.getRuntime().availableProcessors(); - - return p > 16 ? 16 : Math.max(p, 4); - } - - return tc; - } - - private static boolean doesSupport3DBiomes() { - try { - int v = Integer.parseInt(Bukkit.getBukkitVersion().split("\\Q-\\E")[0].split("\\Q.\\E")[1]); - - return v >= 15; - } catch (Throwable e) { - Iris.reportError(e); - } - - return false; - } - - private static boolean doesSupportCustomModels() { - try { - int v = Integer.parseInt(Bukkit.getBukkitVersion().split("\\Q-\\E")[0].split("\\Q.\\E")[1]); - - return v >= 14; - } catch (Throwable e) { - Iris.reportError(e); - } - - return false; - } - - private static boolean doesSupportAwareness() { - try { - int v = Integer.parseInt(Bukkit.getBukkitVersion().split("\\Q-\\E")[0].split("\\Q.\\E")[1]); - - return v >= 15; - } catch (Throwable e) { - Iris.reportError(e); - } - - return false; - } - @Override public void start() { @@ -276,6 +225,7 @@ public class Iris extends VolmitPlugin implements Listener { board.disable(); Bukkit.getScheduler().cancelTasks(this); HandlerList.unregisterAll((Plugin) this); + MultiBurst.burst.shutdown(); super.onDisable(); } @@ -571,18 +521,6 @@ public class Iris extends VolmitPlugin implements Listener { } Iris.info("\n\n " + new KList<>(splash).toString("\n") + "\n"); - - if (lowMemoryMode) { - Iris.verbose("* Low Memory mode Activated! For better performance, allocate 4gb or more to this server."); - } - - if (!customModels) { - Iris.verbose("* This version of minecraft does not support custom model data in loot items (1.14 and up). Iris will generate as normal, but loot will not have custom models."); - } - - if (!doesSupportAwareness()) { - Iris.verbose("* This version of minecraft does not support entity awareness."); - } } @SuppressWarnings("deprecation") diff --git a/src/main/java/com/volmit/iris/core/IrisBoardManager.java b/src/main/java/com/volmit/iris/core/IrisBoardManager.java index 84f70fec0..7d0bec2e5 100644 --- a/src/main/java/com/volmit/iris/core/IrisBoardManager.java +++ b/src/main/java/com/volmit/iris/core/IrisBoardManager.java @@ -19,7 +19,7 @@ package com.volmit.iris.core; import com.volmit.iris.Iris; -import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.util.board.BoardManager; diff --git a/src/main/java/com/volmit/iris/core/IrisProject.java b/src/main/java/com/volmit/iris/core/IrisProject.java index e300dd604..446bb3013 100644 --- a/src/main/java/com/volmit/iris/core/IrisProject.java +++ b/src/main/java/com/volmit/iris/core/IrisProject.java @@ -23,7 +23,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.report.Report; import com.volmit.iris.core.report.ReportType; -import com.volmit.iris.engine.IrisWorldCreator; +import com.volmit.iris.core.tools.IrisWorldCreator; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.object.*; @@ -273,8 +273,9 @@ public class IrisProject { break; } } - - sender.player().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(C.WHITE + "Generation Complete")); + if (sender.isPlayer()) { + sender.player().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(C.WHITE + "Generation Complete")); + } }); //@builder @@ -307,9 +308,9 @@ public class IrisProject { public void close() { activeProvider.close(); - File folder = activeProvider.getTarget().getWorld().getWorldFolder(); - Iris.linkMultiverseCore.removeFromConfig(activeProvider.getTarget().getWorld().getName()); - Bukkit.unloadWorld(activeProvider.getTarget().getWorld().getName(), false); + File folder = activeProvider.getTarget().getWorld().worldFolder(); + Iris.linkMultiverseCore.removeFromConfig(activeProvider.getTarget().getWorld().name()); + Bukkit.unloadWorld(activeProvider.getTarget().getWorld().name(), false); J.attemptAsync(() -> IO.delete(folder)); activeProvider = null; } diff --git a/src/main/java/com/volmit/iris/core/IrisSettings.java b/src/main/java/com/volmit/iris/core/IrisSettings.java index 40d625e93..84c583a9f 100644 --- a/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -56,14 +56,27 @@ public class IrisSettings { return getParallax().getParallaxRegionEvictionMS(); } + public static int getThreadCount(int c) { + if (c < 2 && c >= 0) { + return 2; + } + + return Math.max(2, c < 0 ? Runtime.getRuntime().availableProcessors() / -c : c); + } + @Data public static class IrisSettingsCache { - public int streamingCacheSize = 8192; + public int complexCacheSize = 131072; } @Data public static class IrisSettingsConcurrency { - public int threadCount = -1; + public int engineThreadCount = -1; + public int engineThreadPriority = 6; + public int pregenThreadCount = -1; + public int pregenThreadPriority = 8; + public int miscThreadCount = -4; + public int miscThreadPriority = 3; } @Data @@ -99,8 +112,7 @@ public class IrisSettings { public boolean systemEffects = true; public boolean systemEntitySpawnOverrides = true; public boolean systemEntityInitialSpawns = true; - public int maxBiomeChildDepth = 5; - + public int maxBiomeChildDepth = 4; } @Data diff --git a/src/main/java/com/volmit/iris/core/command/CommandIris.java b/src/main/java/com/volmit/iris/core/command/CommandIris.java index 16bde75eb..d69aa10e3 100644 --- a/src/main/java/com/volmit/iris/core/command/CommandIris.java +++ b/src/main/java/com/volmit/iris/core/command/CommandIris.java @@ -33,6 +33,9 @@ public class CommandIris extends MortarCommand { @Command private CommandIrisCreate create; + @Command + private CommandIrisVerify verify; + @Command private CommandIrisFix fix; diff --git a/src/main/java/com/volmit/iris/core/command/CommandIrisMetrics.java b/src/main/java/com/volmit/iris/core/command/CommandIrisMetrics.java index df8604d65..557039e41 100644 --- a/src/main/java/com/volmit/iris/core/command/CommandIrisMetrics.java +++ b/src/main/java/com/volmit/iris/core/command/CommandIrisMetrics.java @@ -19,7 +19,7 @@ package com.volmit.iris.core.command; import com.volmit.iris.Iris; -import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.plugin.MortarCommand; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioClose.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioClose.java index 6be720bbc..19080e304 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioClose.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioClose.java @@ -56,7 +56,7 @@ public class CommandIrisStudioClose extends MortarCommand { World f = null; for (World i : Bukkit.getWorlds()) { - if (i.getWorldFolder().getAbsolutePath().equals(Iris.proj.getActiveProject().getActiveProvider().getTarget().getWorld().getWorldFolder().getAbsolutePath())) { + if (i.getWorldFolder().getAbsolutePath().equals(Iris.proj.getActiveProject().getActiveProvider().getTarget().getWorld().worldFolder().getAbsolutePath())) { continue; } diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExplorer.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExplorer.java index f03483047..1967762af 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExplorer.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExplorer.java @@ -20,7 +20,7 @@ package com.volmit.iris.core.command.studio; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.gui.IrisExplorer; +import com.volmit.iris.core.gui.NoiseExplorerGUI; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.plugin.Command; import com.volmit.iris.util.plugin.MortarCommand; @@ -57,7 +57,7 @@ public class CommandIrisStudioExplorer extends MortarCommand { return true; } - IrisExplorer.launch(); + NoiseExplorerGUI.launch(); sender.sendMessage("Opening Noise Explorer!"); } return true; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExplorerGenerator.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExplorerGenerator.java index 7fe029d98..943b400cd 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExplorerGenerator.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExplorerGenerator.java @@ -21,7 +21,7 @@ package com.volmit.iris.core.command.studio; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisDataManager; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.gui.IrisExplorer; +import com.volmit.iris.core.gui.NoiseExplorerGUI; import com.volmit.iris.engine.object.IrisGenerator; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.math.RNG; @@ -63,14 +63,14 @@ public class CommandIrisStudioExplorerGenerator extends MortarCommand { if (Iris.proj.isProjectOpen()) { generator = Iris.proj.getActiveProject().getActiveProvider().getData().getGeneratorLoader().load(args[0]); - seed = Iris.proj.getActiveProject().getActiveProvider().getTarget().getWorld().getSeed(); + seed = Iris.proj.getActiveProject().getActiveProvider().getTarget().getWorld().seed(); } else { generator = IrisDataManager.loadAnyGenerator(args[0]); } if (generator != null) { long finalSeed = seed; - IrisExplorer.launch((x, z) -> + NoiseExplorerGUI.launch((x, z) -> generator.getHeight(x, z, new RNG(finalSeed).nextParallelRNG(3245).lmax()), "Gen: " + generator.getLoadKey()); sender.sendMessage("Opening Noise Explorer for gen " + generator.getLoadKey() + " (" + generator.getLoader().getDataFolder().getName() + ")"); diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioGoto.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioGoto.java index 15bb1b02a..1fc66fcd5 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioGoto.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioGoto.java @@ -20,7 +20,7 @@ package com.volmit.iris.core.command.studio; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisDataManager; -import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisRegion; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioHotload.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioHotload.java index cbac87405..9d1941634 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioHotload.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioHotload.java @@ -20,7 +20,7 @@ package com.volmit.iris.core.command.studio; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.VolmitSender; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioLoot.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioLoot.java index b66dd685d..f6d4c4bff 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioLoot.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioLoot.java @@ -20,7 +20,7 @@ package com.volmit.iris.core.command.studio; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.object.InventorySlotType; import com.volmit.iris.engine.object.IrisLootTable; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioMap.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioMap.java index 94b0b3036..90b4bde2f 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioMap.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioMap.java @@ -20,8 +20,8 @@ package com.volmit.iris.core.command.studio; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.gui.IrisVision; -import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.core.gui.VisionGUI; +import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.util.collection.KList; @@ -57,12 +57,12 @@ public class CommandIrisStudioMap extends MortarCommand { try { IrisAccess g = Iris.proj.getActiveProject().getActiveProvider(); - IrisVision.launch(g, 0); + VisionGUI.launch(g, 0); sender.sendMessage("Opening Map!"); } catch (Throwable e) { Iris.reportError(e); IrisAccess g = IrisWorlds.access(sender.player().getWorld()); - IrisVision.launch(g, 0); + VisionGUI.launch(g, 0); sender.sendMessage("Opening Map!"); } return true; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioSummon.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioSummon.java index 6239eecdc..b029392b0 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioSummon.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioSummon.java @@ -20,7 +20,7 @@ package com.volmit.iris.core.command.studio; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.object.IrisEntity; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioTPStudio.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioTPStudio.java index 63d0af4bd..f34d11cdc 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioTPStudio.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioTPStudio.java @@ -57,7 +57,7 @@ public class CommandIrisStudioTPStudio extends MortarCommand { try { sender.sendMessage("Teleporting you to the active studio world."); - sender.player().teleport(Iris.proj.getActiveProject().getActiveProvider().getTarget().getWorld().getSpawnLocation()); + sender.player().teleport(Iris.proj.getActiveProject().getActiveProvider().getTarget().getWorld().spawnLocation()); sender.player().setGameMode(GameMode.SPECTATOR); } catch (Throwable e) { Iris.reportError(e); diff --git a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBiome.java b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBiome.java index 39b6727ca..8af9e3b3c 100644 --- a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBiome.java +++ b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatBiome.java @@ -20,7 +20,7 @@ package com.volmit.iris.core.command.what; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMS; -import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.util.collection.KList; diff --git a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatObjects.java b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatObjects.java index b86d8939d..967db3b35 100644 --- a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatObjects.java +++ b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatObjects.java @@ -19,7 +19,7 @@ package com.volmit.iris.core.command.what; import com.volmit.iris.Iris; -import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisObject; diff --git a/src/main/java/com/volmit/iris/core/command/world/CommandIrisCreate.java b/src/main/java/com/volmit/iris/core/command/world/CommandIrisCreate.java index e63559b4b..a09d5abc4 100644 --- a/src/main/java/com/volmit/iris/core/command/world/CommandIrisCreate.java +++ b/src/main/java/com/volmit/iris/core/command/world/CommandIrisCreate.java @@ -21,10 +21,9 @@ package com.volmit.iris.core.command.world; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisDataManager; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.gui.Pregenerator; import com.volmit.iris.core.link.MultiverseCoreLink; import com.volmit.iris.core.nms.INMS; -import com.volmit.iris.engine.IrisWorldCreator; +import com.volmit.iris.core.tools.IrisWorldCreator; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.util.collection.KList; @@ -161,8 +160,7 @@ public class CommandIrisCreate extends MortarCommand { sender.sendMessage("Pregenerating " + worldName + " " + size + " x " + size); sender.sendMessage("Expect server lag during this time. Use '/iris pregen stop' to cancel"); - new Pregenerator(world.get(), size, () -> - b.set(true)); + } World ww = world.get(); @@ -223,7 +221,6 @@ public class CommandIrisCreate extends MortarCommand { .productionMode().seed(seed).create(); J.s(() -> { - sender.sendMessage("Generating with " + Iris.getThreadCount() + " threads per chunk"); O done = new O<>(); done.set(false); @@ -249,15 +246,6 @@ public class CommandIrisCreate extends MortarCommand { World w = INMS.get().createWorld(wc); world.set(w); - - try { - if (pregen.get() > 0) { - new Pregenerator(w, pregen.get()); - } - } catch (Throwable e) { - Iris.reportError(e); - } - done.set(true); }); } diff --git a/src/main/java/com/volmit/iris/core/command/world/CommandIrisFix.java b/src/main/java/com/volmit/iris/core/command/world/CommandIrisFix.java index 97d46bbac..8d91fa0a1 100644 --- a/src/main/java/com/volmit/iris/core/command/world/CommandIrisFix.java +++ b/src/main/java/com/volmit/iris/core/command/world/CommandIrisFix.java @@ -19,7 +19,7 @@ package com.volmit.iris.core.command.world; import com.volmit.iris.Iris; -import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.format.Form; diff --git a/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java b/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java index 66adeeca2..e01eabde8 100644 --- a/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java +++ b/src/main/java/com/volmit/iris/core/command/world/CommandIrisPregen.java @@ -19,8 +19,12 @@ package com.volmit.iris.core.command.world; import com.volmit.iris.Iris; -import com.volmit.iris.core.gui.Pregenerator; +import com.volmit.iris.core.gui.PregeneratorJob; +import com.volmit.iris.core.pregenerator.PregenTask; +import com.volmit.iris.core.pregenerator.methods.HybridPregenMethod; +import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.VolmitSender; import org.bukkit.Bukkit; @@ -69,17 +73,17 @@ public class CommandIrisPregen extends MortarCommand { } if (args[0].equalsIgnoreCase("stop") || args[0].equalsIgnoreCase("x")) { - if (Pregenerator.shutdownInstance()) { - sender.sendMessage("Stopped Pregen."); + if (PregeneratorJob.shutdownInstance()) { + sender.sendMessage("Stopped Pregen. Finishing last region file before shutting down..."); } else { sender.sendMessage("No Active Pregens."); } return true; } else if (args[0].equalsIgnoreCase("pause") || args[0].equalsIgnoreCase("resume")) { - if (Pregenerator.getInstance() != null) { - Pregenerator.pauseResume(); + if (PregeneratorJob.getInstance() != null) { + PregeneratorJob.pauseResume(); - if (Pregenerator.isPaused()) { + if (PregeneratorJob.isPaused()) { sender.sendMessage("Pregen Paused"); } else { sender.sendMessage("Pregen Resumed"); @@ -105,7 +109,11 @@ public class CommandIrisPregen extends MortarCommand { } } try { - new Pregenerator(world, getVal(args[0]) * 2); + IrisToolbelt.pregenerate(PregenTask + .builder() + .center(new Position2(0, 0)) + .radius(((getVal(args[0]) >> 4) >> 5) + 1) + .build(), world); } catch (NumberFormatException e) { Iris.reportError(e); sender.sendMessage("Invalid argument in command"); @@ -131,7 +139,12 @@ public class CommandIrisPregen extends MortarCommand { } World world = Bukkit.getWorld(args[1]); try { - new Pregenerator(world, getVal(args[0]) * 2); + new PregeneratorJob(PregenTask + .builder() + .center(new Position2(0, 0)) + .radius(((getVal(args[0]) >> 4) >> 5) + 1) + .build(), + new HybridPregenMethod(world, Runtime.getRuntime().availableProcessors())); } catch (NumberFormatException e) { Iris.reportError(e); sender.sendMessage("Invalid argument in command"); diff --git a/src/main/java/com/volmit/iris/core/command/world/CommandIrisVerify.java b/src/main/java/com/volmit/iris/core/command/world/CommandIrisVerify.java new file mode 100644 index 000000000..ab0f56e02 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/world/CommandIrisVerify.java @@ -0,0 +1,104 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.command.world; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.tools.IrisWorlds; +import com.volmit.iris.engine.data.mca.Chunk; +import com.volmit.iris.engine.data.mca.MCAFile; +import com.volmit.iris.engine.data.mca.MCAUtil; +import com.volmit.iris.engine.framework.IrisAccess; +import com.volmit.iris.engine.parallel.BurstExecutor; +import com.volmit.iris.engine.parallel.MultiBurst; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KSet; +import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.math.Position2; +import com.volmit.iris.util.math.Spiraler; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; +import com.volmit.iris.util.scheduling.J; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.atomic.AtomicInteger; + +public class CommandIrisVerify extends MortarCommand { + public CommandIrisVerify() { + super("verifymca"); + requiresPermission(Iris.perm.studio); + setDescription("Fix nearby chunks"); + setCategory("Studio"); + } + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + try { + IrisAccess a = IrisWorlds.access(sender.player().getWorld()); + File folder = a.getTarget().getWorld().worldFolder(); + File r = new File(folder, "region"); + BurstExecutor e = MultiBurst.burst.burst(r.listFiles().length); + AtomicInteger f = new AtomicInteger(0); + for(File i : r.listFiles()) + { + e.queue(() -> { + MCAFile file = null; + try { + file = MCAUtil.read(i); + int rx = Integer.valueOf(i.getName().split("\\Q.\\E")[1]); + int rz = Integer.valueOf(i.getName().split("\\Q.\\E")[2]); + for(int j = 0; j < 32; j++) + { + for(int k = 0; k < 32; k++) + { + f.incrementAndGet(); + Chunk c = file.getChunk(j, k); + if(c == null) + { + sender.sendMessage("Found Missing Chunk " + i.getName() + ", chunk #" + j + "," + k + " (see " + (((rx << 5)<<4)+(j<<4)) + "," + (((rz << 5)<<4)+(k<<4))); + } + } + } + } catch (IOException ioException) { + ioException.printStackTrace(); + sender.sendMessage("Error loading region " + i.getName()); + } + }); + } + + e.complete(); + sender.sendMessage("Done! Checked " + f.get() + " chunks"); + } catch (Throwable e) { + Iris.reportError(e); + sender.sendMessage("Not a valid Iris World (or bad argument)"); + } + + return true; + } + + @Override + protected String getArgsUsage() { + return "[view-distance]"; + } +} diff --git a/src/main/java/com/volmit/iris/core/command/world/CommandLocate.java b/src/main/java/com/volmit/iris/core/command/world/CommandLocate.java index 7f6b02a0b..1fd701543 100644 --- a/src/main/java/com/volmit/iris/core/command/world/CommandLocate.java +++ b/src/main/java/com/volmit/iris/core/command/world/CommandLocate.java @@ -19,7 +19,7 @@ package com.volmit.iris.core.command.world; import com.volmit.iris.Iris; -import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.VolmitSender; diff --git a/src/main/java/com/volmit/iris/core/edit/DustRevealer.java b/src/main/java/com/volmit/iris/core/edit/DustRevealer.java index 0fa4344c2..654ac9d72 100644 --- a/src/main/java/com/volmit/iris/core/edit/DustRevealer.java +++ b/src/main/java/com/volmit/iris/core/edit/DustRevealer.java @@ -19,7 +19,7 @@ package com.volmit.iris.core.edit; import com.volmit.iris.Iris; -import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.parallax.ParallaxAccess; import com.volmit.iris.util.collection.KList; diff --git a/src/main/java/com/volmit/iris/core/gui/IrisExplorer.java b/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java similarity index 97% rename from src/main/java/com/volmit/iris/core/gui/IrisExplorer.java rename to src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java index c45dc8742..ddc23e332 100644 --- a/src/main/java/com/volmit/iris/core/gui/IrisExplorer.java +++ b/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java @@ -38,7 +38,7 @@ import java.io.File; import java.io.IOException; import java.util.concurrent.locks.ReentrantLock; -public class IrisExplorer extends JPanel implements MouseWheelListener { +public class NoiseExplorerGUI extends JPanel implements MouseWheelListener { private static final long serialVersionUID = 2094606939770332040L; @@ -74,7 +74,7 @@ public class IrisExplorer extends JPanel implements MouseWheelListener { double t; double tz; - public IrisExplorer() { + public NoiseExplorerGUI() { addMouseWheelListener(this); addMouseMotionListener(new MouseMotionListener() { @Override @@ -237,7 +237,7 @@ public class IrisExplorer extends JPanel implements MouseWheelListener { private static void createAndShowGUI(Function2 gen, String genName) { JFrame frame = new JFrame("Noise Explorer: " + genName); - IrisExplorer nv = new IrisExplorer(); + NoiseExplorerGUI nv = new NoiseExplorerGUI(); frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); JLayeredPane pane = new JLayeredPane(); nv.setSize(new Dimension(1440, 820)); @@ -259,7 +259,7 @@ public class IrisExplorer extends JPanel implements MouseWheelListener { private static void createAndShowGUI() { JFrame frame = new JFrame("Noise Explorer"); - IrisExplorer nv = new IrisExplorer(); + NoiseExplorerGUI nv = new NoiseExplorerGUI(); frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); KList li = new KList<>(NoiseStyle.values()).toStringList(); combo = new JComboBox<>(li.toArray(new String[0])); @@ -296,7 +296,7 @@ public class IrisExplorer extends JPanel implements MouseWheelListener { } public static void launch() { - EventQueue.invokeLater(IrisExplorer::createAndShowGUI); + EventQueue.invokeLater(NoiseExplorerGUI::createAndShowGUI); } static class HandScrollListener extends MouseAdapter { diff --git a/src/main/java/com/volmit/iris/core/gui/Pregenerator.java b/src/main/java/com/volmit/iris/core/gui/Pregenerator.java deleted file mode 100644 index 4aa0b77d8..000000000 --- a/src/main/java/com/volmit/iris/core/gui/Pregenerator.java +++ /dev/null @@ -1,639 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.core.gui; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.engine.IrisWorlds; -import com.volmit.iris.engine.data.mca.MCAFile; -import com.volmit.iris.engine.data.mca.NBTWorld; -import com.volmit.iris.engine.framework.IrisAccess; -import com.volmit.iris.engine.parallel.BurstExecutor; -import com.volmit.iris.engine.parallel.MultiBurst; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.format.Form; -import com.volmit.iris.util.function.Consumer2; -import com.volmit.iris.util.function.Consumer3; -import com.volmit.iris.util.io.IO; -import com.volmit.iris.util.math.ChunkPosition; -import com.volmit.iris.util.math.M; -import com.volmit.iris.util.math.RollingSequence; -import com.volmit.iris.util.math.Spiraler; -import com.volmit.iris.util.scheduling.ChronoLatch; -import com.volmit.iris.util.scheduling.J; -import com.volmit.iris.util.scheduling.PrecisionStopwatch; -import com.volmit.iris.util.scheduling.SR; -import io.papermc.lib.PaperLib; -import lombok.Data; -import org.bukkit.Bukkit; -import org.bukkit.Chunk; -import org.bukkit.World; -import org.bukkit.event.Listener; - -import javax.imageio.ImageIO; -import javax.swing.*; -import java.awt.*; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.util.Comparator; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.ReentrantLock; - -@Data -public class Pregenerator implements Listener { - private static Pregenerator instance; - private static final Color COLOR_ERROR = Color.decode("#E34113"); - private static final Color COLOR_MCA_PREPARE = Color.decode("#3CAAB5"); - private static final Color COLOR_MCA_RELOAD = Color.decode("#41FF61"); - private static final Color COLOR_MCA_GENERATE = Color.decode("#33FF8F"); - private static final Color COLOR_MCA_GENERATE_SLOW = Color.decode("#13BAE3"); - private static final Color COLOR_MCA_GENERATE_SLOW_ASYNC = Color.decode("#13BAE3"); - private static final Color COLOR_MCA_GENERATED = Color.decode("#33FF8F"); - private static final Color COLOR_MCA_GENERATED_MCA = Color.decode("#13E3C9"); - private static final Color COLOR_MCA_SEALED = Color.decode("#33FF8F"); - private static final Color COLOR_MCA_DEFERRED = Color.decode("#3CB57A"); - private final World world; - private int lowestBedrock; - private final NBTWorld directWriter; - private final AtomicBoolean active; - private final AtomicBoolean running; - private final KList errors; - private final KList onComplete; - private final ChunkPosition max; - private final ChunkPosition min; - private final MCAPregenGui gui; - private final KList mcaDefer; - private final AtomicInteger generated; - private final AtomicInteger generatedLast; - private final RollingSequence perSecond; - private final RollingSequence perMinute; - private final AtomicInteger totalChunks; - private final AtomicLong memory; - private final AtomicReference memoryMetric; - private final AtomicReference method; - private final AtomicInteger vmcax; - private final AtomicInteger vmcaz; - private final AtomicInteger vcax; - private final AtomicInteger vcaz; - private final long elapsed; - private final ChronoLatch latch; - private IrisAccess access; - private final KList regionReload; - private KList wait = new KList<>(); - - public Pregenerator(World world, int blockSize, Runnable onComplete) { - this(world, blockSize); - this.onComplete.add(onComplete); - } - - public Pregenerator(World world, int blockSize) throws HeadlessException { - this(world, blockSize, true); - } - - public Pregenerator(World world, int blockSize, boolean dogui) throws HeadlessException { - instance(); - regionReload = new KList<>(); - latch = new ChronoLatch(5000); - memoryMetric = new AtomicReference<>("..."); - method = new AtomicReference<>("STARTUP"); - memory = new AtomicLong(0); - this.world = world; - errors = new KList<>(); - vmcax = new AtomicInteger(); - vmcaz = new AtomicInteger(); - vcax = new AtomicInteger(); - vcaz = new AtomicInteger(); - perMinute = new RollingSequence(200); - perSecond = new RollingSequence(20); - generatedLast = new AtomicInteger(0); - totalChunks = new AtomicInteger(0); - generated = new AtomicInteger(0); - mcaDefer = new KList<>(); - access = IrisWorlds.access(world); - this.directWriter = new NBTWorld(world.getWorldFolder()); - this.running = new AtomicBoolean(true); - this.active = new AtomicBoolean(true); - MultiBurst burst = new MultiBurst("Iris Pregenerator", 9, Runtime.getRuntime().availableProcessors()); - int mcaSize = (((blockSize >> 4) + 2) >> 5) + 1; - onComplete = new KList<>(); - max = new ChunkPosition(0, 0); - min = new ChunkPosition(0, 0); - KList draw = new KList<>(); - new Spiraler(mcaSize, mcaSize, (xx, zz) -> { - min.setX(Math.min(xx << 5, min.getX())); - min.setZ(Math.min(zz << 5, min.getZ())); - max.setX(Math.max((xx << 5) + 31, max.getX())); - max.setZ(Math.max((zz << 5) + 31, max.getZ())); - totalChunks.getAndAdd(1024); - draw.add(() -> drawMCA(xx, zz, COLOR_MCA_PREPARE)); - }).drain(); - if (access != null) { - lowestBedrock = access.getCompound().getLowestBedrock(); - } - gui = dogui ? (IrisSettings.get().getGui().isLocalPregenGui() && IrisSettings.get().getGui().isUseServerLaunchedGuis() ? MCAPregenGui.createAndShowGUI(this) : null) : null; - flushWorld(); - KList order = computeChunkOrder(); - Consumer3> mcaIteration = - (ox, oz, r) -> order.forEach((i) - -> r.accept(i.getX() + ox, i.getZ() + oz)); - draw.forEach(Runnable::run); - Spiraler spiraler = new Spiraler(mcaSize, mcaSize, (xx, zz) -> { - vmcax.set(xx); - vmcaz.set(zz); - flushWorld(); - drawMCA(xx, zz, COLOR_MCA_PREPARE); - if (access != null && generateMCARegion(xx, zz, burst, access, mcaIteration)) { - flushWorld(); - } - }); - - elapsed = M.ms(); - - new Thread(() -> { - flushWorld(); - J.sleep(2000); - flushWorld(); - - while (running.get() && spiraler.hasNext()) { - if (active.get()) { - spiraler.next(); - } - } - - mcaDefer.removeDuplicates(); - - while (running.get() && mcaDefer.isNotEmpty()) { - ChunkPosition p = mcaDefer.popLast(); - vmcax.set(p.getX()); - vmcaz.set(p.getZ()); - generateDeferedMCARegion(p.getX(), p.getZ(), burst, mcaIteration); - flushWorld(); - } - - while (wait.isNotEmpty()) { - J.sleep(50); - } - - burst.shutdownNow(); - directWriter.close(); - flushWorld(); - onComplete.forEach(Runnable::run); - running.set(false); - active.set(false); - if (gui != null) { - gui.close(); - } - }).start(); - new Thread(() -> { - PrecisionStopwatch p = PrecisionStopwatch.start(); - - while (running.get() && active.get()) { - int m = generated.get(); - int w = generatedLast.get(); - int up = m - w; - double dur = p.getMilliseconds(); - perSecond.put((int) (up / (dur / 1000D))); - perSecond.put((int) (up / (dur / 60000D))); - p.reset(); - p.begin(); - updateProgress(); - generatedLast.set(m); - J.sleep(100); - long lmem = memory.get(); - memory.set(Runtime.getRuntime().freeMemory()); - - if (memory.get() > lmem) { - long free = memory.get(); - long max = Runtime.getRuntime().maxMemory(); - long total = Runtime.getRuntime().totalMemory(); - long use = total - free; - memoryMetric.set(Form.memSize(use, 2) + " (" + Form.pc((double) use / (double) max, 0) + ")"); - } - } - }).start(); - } - - private boolean generateMCARegion(int x, int z, MultiBurst burst, IrisAccess access, Consumer3> mcaIteration) { - if (!Iris.instance.isMCA()) { - generateDeferedMCARegion(x, z, burst, mcaIteration); - return false; - } - - File mca = directWriter.getRegionFile(x, z); - BurstExecutor e = burst.burst(1024); - int mcaox = x << 5; - int mcaoz = z << 5; - if (isMCAWritable(x, z) && !mca.exists()) { - method.set("Direct (Fast)"); - mcaIteration.accept(mcaox, mcaoz, (ii, jj) -> e.queue(() -> { - draw(ii, jj, COLOR_MCA_GENERATE); - access.directWriteChunk(world, ii, jj, directWriter); - draw(ii, jj, COLOR_MCA_GENERATED_MCA); - generated.getAndIncrement(); - vcax.set(ii); - vcaz.set(jj); - })); - e.complete(); - //verifyMCA(x, z, burst); - directWriter.save(); - } else { - totalChunks.getAndAdd(1024); - mcaDefer.add(new ChunkPosition(x, z)); - e.complete(); - return false; - } - - return true; - } - - private void verifyMCA(int x, int z, MultiBurst burst) { - MCAFile rg = directWriter.getMCA(x, z); - KList requeue = new KList<>(); - - for (int i = 0; i < 32; i++) - { - for(int j = 0; j < 32; j++) - { - com.volmit.iris.engine.data.mca.Chunk c = rg.getChunk(i, j); - - if(c == null) - { - draw(((x << 5) + i), ((z << 5) + j), COLOR_ERROR); - int finalI = i; - int finalJ = j; - requeue.add(() -> { - draw(((x << 5) + finalI), ((z << 5) + finalJ), COLOR_MCA_GENERATE); - access.directWriteChunk(world, ((x << 5) + finalI), ((z << 5) + finalJ), directWriter); - draw(((x << 5) + finalI), ((z << 5) + finalJ), COLOR_MCA_GENERATED_MCA); - }); - } - } - } - - if(requeue.isNotEmpty()) - { - burst.burst(requeue); - verifyMCA(x, z, burst); - } - } - - public void updateProgress() { - if (!latch.flip()) { - return; - } - - String[] v = getProgress(); - Iris.info("Pregeneration " + v[0] + " | " + v[1] + " | " + v[2] + " | " + v[3]); - } - - private void generateDeferedMCARegion(int x, int z, MultiBurst burst, Consumer3> mcaIteration) { - int mcaox = x << 5; - int mcaoz = z << 5; - if (PaperLib.isPaper()) { - method.set("PaperAsync (Slow)"); - - while (wait.size() > 16) { - J.sleep(5); - } - - mcaIteration.accept(mcaox, mcaoz, (ii, jj) -> { - ChunkPosition cx = new ChunkPosition(ii, jj); - PaperLib.getChunkAtAsync(world, ii, jj).thenAccept((c) -> { - draw(ii, jj, COLOR_MCA_GENERATE_SLOW_ASYNC); - draw(ii, jj, COLOR_MCA_GENERATED); - generated.getAndIncrement(); - vcax.set(ii); - vcaz.set(jj); - - synchronized (wait) { - wait.remove(cx); - } - }); - - wait.add(cx); - }); - } else { - AtomicInteger m = new AtomicInteger(); - method.set("Spigot (Very Slow)"); - KList q = new KList<>(); - mcaIteration.accept(mcaox, mcaoz, (ii, jj) -> q.add(() -> { - draw(ii, jj, COLOR_MCA_GENERATE_SLOW); - world.getChunkAt(ii, jj).load(true); - Chunk c = world.getChunkAt(ii, jj); - draw(ii, jj, COLOR_MCA_GENERATED); - m.getAndIncrement(); - generated.getAndIncrement(); - vcax.set(ii); - vcaz.set(jj); - })); - ChronoLatch tick = new ChronoLatch(1000); - new SR(0) { - @Override - public void run() { - if (tick.flip()) { - return; - } - - if (q.isEmpty()) { - cancel(); - return; - } - - try { - q.pop().run(); - } catch (Throwable e) { - Iris.reportError(e); - - } - } - }; - - while (m.get() < 1024) { - J.sleep(25); - } - } - } - - private KList computeChunkOrder() { - ChunkPosition center = new ChunkPosition(15, 15); - KList p = new KList<>(); - new Spiraler(33, 33, (x, z) -> { - int xx = x + 15; - int zz = z + 15; - if (xx < 0 || xx > 31 || zz < 0 || zz > 31) { - return; - } - - p.add(new ChunkPosition(xx, zz)); - }).drain(); - p.sort(Comparator.comparing((i) -> i.distance(center))); - return p; - } - - public static Pregenerator getInstance() { - return instance; - } - - public static boolean shutdownInstance() { - if (instance != null) { - instance.shutdown(); - instance = null; - return true; - } - - return false; - } - - public static void pauseResume() { - instance.active.set(!instance.active.get()); - } - - public static boolean isPaused() { - return instance.paused(); - } - - private void instance() { - if (instance != null) { - instance.shutdown(); - } - - instance = this; - } - - public void shutdown() { - running.set(false); - active.set(false); - } - - private void draw(int cx, int cz, Color color) { - if (gui != null) { - gui.func.accept(new ChunkPosition(cx, cz), color); - } - } - - private void drawMCA(int cx, int cz, Color color) { - for (int i = 0; i < 32; i++) { - for (int j = 0; j < 32; j++) { - draw((cx << 5) + i, (cz << 5) + j, color); - } - } - } - - private void flushWorld() { - if (Bukkit.isPrimaryThread()) { - flushWorldSync(); - return; - } - - AtomicBoolean b = new AtomicBoolean(false); - J.s(() -> { - flushWorldSync(); - b.set(true); - }); - - while (!b.get()) { - J.sleep(1); - } - } - - private void flushWorldSync() { - for (Chunk i : world.getLoadedChunks()) { - i.unload(true); - } - - world.save(); - } - - private boolean isMCAWritable(int x, int z) { - File mca = new File(world.getWorldFolder(), "region/r." + x + "." + z + ".mca"); - - if (mca.exists()) { - return false; - } - - for (Chunk i : world.getLoadedChunks()) { - if (i.getX() >> 5 == x && i.getZ() >> 5 == z) { - return false; - } - } - - return true; - } - - public String[] getProgress() { - long eta = (long) ((totalChunks.get() - generated.get()) * ((double) (M.ms() - elapsed) / (double) generated.get())); - - return new String[]{ - "Progress: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (" + Form.pc((double) generated.get() / (double) totalChunks.get(), 0) + ")", - "ETA: " + Form.duration(eta, 0), - "Chunks/s: " + Form.f((int) perSecond.getAverage()) + " (" + Form.f((int)perSecond.getMax()) + " Peak)", - "Chunks/min: " + Form.f((int) perMinute.getAverage())+ " (" + Form.f((int)perMinute.getMax()) + " Peak)", - "Memory: " + memoryMetric.get(), - "Cursor: " + "MCA(" + vmcax.get() + ", " + vmcaz.get() + ") @ (" + vcax.get() + ", " + vcaz.get() + ")", - "Gen Mode: " + method.get(), - }; - } - - public boolean paused() { - return !active.get(); - } - - public static class MCAPregenGui extends JPanel implements KeyListener { - private Pregenerator job; - private static final long serialVersionUID = 2094606939770332040L; - private final KList order = new KList<>(); - private final int res = 512; - Graphics2D bg; - private ReentrantLock l; - private final BufferedImage image = new BufferedImage(res, res, BufferedImage.TYPE_INT_RGB); - private Consumer2 func; - private JFrame frame; - - public MCAPregenGui() { - - } - - public void paint(int x, int z, Color c) { - func.accept(new ChunkPosition(x, z), c); - } - - @Override - public void paint(Graphics gx) { - Graphics2D g = (Graphics2D) gx; - bg = (Graphics2D) image.getGraphics(); - - l.lock(); - while (order.isNotEmpty()) { - try { - order.pop().run(); - } catch (Throwable e) { - Iris.reportError(e); - - } - } - l.unlock(); - - g.drawImage(image, 0, 0, getParent().getWidth(), getParent().getHeight(), (img, infoflags, x, y, width, height) -> true); - - g.setColor(Color.WHITE); - g.setFont(new Font("Hevetica", Font.BOLD, 28)); - String[] prog = job.getProgress(); - int h = g.getFontMetrics().getHeight() + 5; - int hh = 20; - - if (job.paused()) { - g.drawString("PAUSED", 20, hh += h); - - g.drawString("Press P to Resume", 20, hh += h); - } else { - for (String i : prog) { - g.drawString(i, 20, hh += h); - } - - g.drawString("Press P to Pause", 20, hh += h); - } - - J.sleep(IrisSettings.get().getGui().isMaximumPregenGuiFPS() ? 4 : 250); - repaint(); - } - - private void draw(ChunkPosition p, Color c, Graphics2D bg) { - double pw = M.lerpInverse(job.getMin().getX(), job.getMax().getX(), p.getX()); - double ph = M.lerpInverse(job.getMin().getZ(), job.getMax().getZ(), p.getZ()); - double pwa = M.lerpInverse(job.getMin().getX(), job.getMax().getX(), p.getX() + 1); - double pha = M.lerpInverse(job.getMin().getZ(), job.getMax().getZ(), p.getZ() + 1); - int x = (int) M.lerp(0, res, pw); - int z = (int) M.lerp(0, res, ph); - int xa = (int) M.lerp(0, res, pwa); - int za = (int) M.lerp(0, res, pha); - bg.setColor(c); - bg.fillRect(x, z, xa - x, za - z); - } - - @SuppressWarnings("deprecation") - private static MCAPregenGui createAndShowGUI(Pregenerator j) throws HeadlessException { - JFrame frame; - frame = new JFrame("Pregen View"); - MCAPregenGui nv = new MCAPregenGui(); - frame.addKeyListener(nv); - nv.l = new ReentrantLock(); - nv.frame = frame; - nv.job = j; - nv.func = (c, b) -> - { - if (b.equals(Color.pink) && c.equals(new ChunkPosition(Integer.MAX_VALUE, Integer.MAX_VALUE))) { - frame.hide(); - } - nv.l.lock(); - nv.order.add(() -> nv.draw(c, b, nv.bg)); - nv.l.unlock(); - }; - frame.add(nv); - frame.setSize(1000, 1000); - frame.setVisible(true); - File file = Iris.getCached("Iris Icon", "https://raw.githubusercontent.com/VolmitSoftware/Iris/master/icon.png"); - - if (file != null) { - try { - frame.setIconImage(ImageIO.read(file)); - } catch (IOException ignored) { - Iris.reportError(ignored); - - } - } - - return nv; - } - - public static void launch(Pregenerator g) { - J.a(() -> - { - createAndShowGUI(g); - }); - } - - @Override - public void keyTyped(KeyEvent e) { - - } - - @Override - public void keyPressed(KeyEvent e) { - - } - - @Override - public void keyReleased(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_P) { - Pregenerator.pauseResume(); - } - } - - public void close() { - frame.setVisible(false); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java new file mode 100644 index 000000000..c43255ca0 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java @@ -0,0 +1,389 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.gui; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.pregenerator.IrisPregenerator; +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregenTask; +import com.volmit.iris.core.pregenerator.PregeneratorMethod; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.function.Consumer2; +import com.volmit.iris.util.math.M; +import com.volmit.iris.util.math.Position2; +import com.volmit.iris.util.scheduling.J; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.image.BufferedImage; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Consumer; + +public class PregeneratorJob implements PregenListener { + public static PregeneratorJob instance; + private static final Color COLOR_EXISTS = parseColor("#4d7d5b"); + private static final Color COLOR_GENERATING = parseColor("#0062ff"); + private static final Color COLOR_NETWORK = parseColor("#a863c2"); + private static final Color COLOR_NETWORK_GENERATING = parseColor("#836b8c"); + private static final Color COLOR_GENERATED = parseColor("#34eb93"); + private JFrame frame; + private final PregenTask task; + private boolean saving; + private KList> onProgress = new KList<>(); + private KList whenDone = new KList<>(); + private final IrisPregenerator pregenerator; + private PregenRenderer renderer; + private String[] info; + private Position2 min; + private Position2 max; + + public PregeneratorJob(PregenTask task, PregeneratorMethod method) { + instance = this; + saving = false; + info = new String[]{"Initializing..."}; + this.task = task; + this.pregenerator = new IrisPregenerator(task, method, this); + max = new Position2(0, 0); + min = new Position2(0, 0); + KList draw = new KList<>(); + task.iterateRegions((xx, zz) -> { + min.setX(Math.min(xx << 5, min.getX())); + min.setZ(Math.min(zz << 5, min.getZ())); + max.setX(Math.max((xx << 5) + 31, max.getX())); + max.setZ(Math.max((zz << 5) + 31, max.getZ())); + }); + + if (IrisSettings.get().getGui().isUseServerLaunchedGuis()) { + open(); + } + + J.a(this.pregenerator::start, 20); + } + + public PregeneratorJob onProgress(Consumer c) { + onProgress.add(c); + return this; + } + + public PregeneratorJob whenDone(Runnable r) { + whenDone.add(r); + return this; + } + + public static boolean shutdownInstance() { + if (instance == null) { + return false; + } + + J.a(() -> instance.pregenerator.close()); + return true; + } + + public static PregeneratorJob getInstance() { + return instance; + } + + public static void pauseResume() { + if (instance == null) { + return; + } + + if (isPaused()) { + instance.pregenerator.resume(); + } else { + instance.pregenerator.pause(); + } + } + + public static boolean isPaused() { + if (instance == null) { + return true; + } + + return instance.paused(); + } + + public void drawRegion(int x, int z, Color color) { + J.a(() -> { + PregenTask.iterateRegion(x, z, (xx, zz) -> { + draw(xx, zz, color); + J.sleep(3); + }); + }); + } + + public void draw(int x, int z, Color color) { + try { + if (renderer != null && frame != null && frame.isVisible()) { + renderer.func.accept(new Position2(x, z), color); + } + } catch (Throwable ignored) { + + } + } + + public void stop() { + J.a(() -> { + pregenerator.close(); + close(); + instance = null; + }); + } + + public void close() { + J.a(() -> { + try { + J.sleep(3000); + frame.setVisible(false); + } catch (Throwable e) { + + } + }); + } + + public void open() { + J.a(() -> { + try { + frame = new JFrame("Pregen View"); + renderer = new PregenRenderer(); + frame.addKeyListener(renderer); + renderer.l = new ReentrantLock(); + renderer.frame = frame; + renderer.job = this; + renderer.func = (c, b) -> + { + renderer.l.lock(); + renderer.order.add(() -> renderer.draw(c, b, renderer.bg)); + renderer.l.unlock(); + }; + frame.add(renderer); + frame.setSize(1000, 1000); + frame.setVisible(true); + } catch (Throwable e) { + + } + }); + } + + @Override + public void onTick(double chunksPerSecond, double chunksPerMinute, double regionsPerMinute, double percent, int generated, int totalChunks, int chunksRemaining, long eta, long elapsed, String method) { + info = new String[]{ + (paused() ? "PAUSED" : (saving ? "Saving... " : "Generating")) + " " + Form.f(generated) + " of " + Form.f(totalChunks) + " (" + Form.pc(percent, 0) + " Complete)", + "Speed: " + Form.f(chunksPerSecond, 0) + " Chunks/s, " + Form.f(regionsPerMinute, 1) + " Regions/m, " + Form.f(chunksPerMinute, 0) + " Chunks/m", + Form.duration(eta, 2) + " Remaining " + " (" + Form.duration(elapsed, 2) + " Elapsed)", + "Generation Method: " + method, + }; + + for (Consumer i : onProgress) { + i.accept(percent); + } + } + + @Override + public void onChunkGenerating(int x, int z) { + draw(x, z, COLOR_GENERATING); + } + + @Override + public void onChunkGenerated(int x, int z) { + draw(x, z, COLOR_GENERATED); + } + + @Override + public void onRegionGenerated(int x, int z) { + + } + + @Override + public void onRegionGenerating(int x, int z) { + + } + + @Override + public void onRegionSkipped(int x, int z) { + + } + + @Override + public void onNetworkStarted(int x, int z) { + drawRegion(x, z, COLOR_NETWORK); + } + + @Override + public void onNetworkFailed(int x, int z) { + + } + + @Override + public void onNetworkReclaim(int revert) { + + } + + @Override + public void onNetworkGeneratedChunk(int x, int z) { + draw(x, z, COLOR_NETWORK_GENERATING); + } + + @Override + public void onNetworkDownloaded(int x, int z) { + drawRegion(x, z, COLOR_NETWORK); + } + + @Override + public void onClose() { + close(); + instance = null; + whenDone.forEach(Runnable::run); + } + + @Override + public void onSaving() { + + } + + @Override + public void onChunkExistsInRegionGen(int x, int z) { + draw(x, z, COLOR_EXISTS); + } + + private Position2 getMax() { + return max; + } + + private Position2 getMin() { + return min; + } + + private boolean paused() { + return pregenerator.paused(); + } + + private String[] getProgress() { + return info; + } + + public static class PregenRenderer extends JPanel implements KeyListener { + private PregeneratorJob job; + private static final long serialVersionUID = 2094606939770332040L; + private final KList order = new KList<>(); + private final int res = 512; + Graphics2D bg; + private ReentrantLock l; + private final BufferedImage image = new BufferedImage(res, res, BufferedImage.TYPE_INT_RGB); + private Consumer2 func; + private JFrame frame; + + public PregenRenderer() { + + } + + public void paint(int x, int z, Color c) { + func.accept(new Position2(x, z), c); + } + + @Override + public void paint(Graphics gx) { + Graphics2D g = (Graphics2D) gx; + bg = (Graphics2D) image.getGraphics(); + l.lock(); + + while (order.isNotEmpty()) { + try { + order.pop().run(); + } catch (Throwable e) { + Iris.reportError(e); + + } + } + + l.unlock(); + g.drawImage(image, 0, 0, getParent().getWidth(), getParent().getHeight(), (img, infoflags, x, y, width, height) -> true); + g.setColor(Color.WHITE); + g.setFont(new Font("Hevetica", Font.BOLD, 28)); + String[] prog = job.getProgress(); + int h = g.getFontMetrics().getHeight() + 5; + int hh = 20; + + if (job.paused()) { + g.drawString("PAUSED", 20, hh += h); + + g.drawString("Press P to Resume", 20, hh += h); + } else { + for (String i : prog) { + g.drawString(i, 20, hh += h); + } + + g.drawString("Press P to Pause", 20, hh += h); + } + + J.sleep(IrisSettings.get().getGui().isMaximumPregenGuiFPS() ? 4 : 250); + repaint(); + } + + private void draw(Position2 p, Color c, Graphics2D bg) { + double pw = M.lerpInverse(job.getMin().getX(), job.getMax().getX(), p.getX()); + double ph = M.lerpInverse(job.getMin().getZ(), job.getMax().getZ(), p.getZ()); + double pwa = M.lerpInverse(job.getMin().getX(), job.getMax().getX(), p.getX() + 1); + double pha = M.lerpInverse(job.getMin().getZ(), job.getMax().getZ(), p.getZ() + 1); + int x = (int) M.lerp(0, res, pw); + int z = (int) M.lerp(0, res, ph); + int xa = (int) M.lerp(0, res, pwa); + int za = (int) M.lerp(0, res, pha); + bg.setColor(c); + bg.fillRect(x, z, xa - x, za - z); + } + + @Override + public void keyTyped(KeyEvent e) { + + } + + @Override + public void keyPressed(KeyEvent e) { + + } + + @Override + public void keyReleased(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_P) { + PregeneratorJob.pauseResume(); + } + } + + public void close() { + frame.setVisible(false); + } + } + + private static Color parseColor(String c) { + String v = (c.startsWith("#") ? c : "#" + c).trim(); + try { + return Color.decode(v); + } catch (Throwable e) { + Iris.reportError(e); + Iris.error("Error Parsing 'color', (" + c + ")"); + } + + return Color.RED; + } +} diff --git a/src/main/java/com/volmit/iris/core/gui/IrisVision.java b/src/main/java/com/volmit/iris/core/gui/VisionGUI.java similarity index 97% rename from src/main/java/com/volmit/iris/core/gui/IrisVision.java rename to src/main/java/com/volmit/iris/core/gui/VisionGUI.java index d8dacadc7..5b538a040 100644 --- a/src/main/java/com/volmit/iris/core/gui/IrisVision.java +++ b/src/main/java/com/volmit/iris/core/gui/VisionGUI.java @@ -19,11 +19,14 @@ package com.volmit.iris.core.gui; import com.volmit.iris.Iris; +import com.volmit.iris.core.gui.components.IrisRenderer; +import com.volmit.iris.core.gui.components.RenderType; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisRegion; +import com.volmit.iris.engine.object.common.IrisWorld; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; @@ -36,7 +39,6 @@ import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.O; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import org.bukkit.Location; -import org.bukkit.World; import org.bukkit.attribute.Attribute; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; @@ -54,7 +56,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.BiFunction; -public class IrisVision extends JPanel implements MouseWheelListener, KeyListener, MouseMotionListener, MouseInputListener { +public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener, MouseMotionListener, MouseInputListener { private static final long serialVersionUID = 2094606939770332040L; private RenderType currentType = RenderType.BIOME; @@ -70,7 +72,7 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene private boolean alt = false; private int posX = 0; private IrisRenderer renderer; - private World world; + private IrisWorld world; private double velocity = 0; private int lowq = 12; private int posZ = 0; @@ -128,7 +130,7 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene }); private BufferedImage texture; - public IrisVision(JFrame frame) { + public VisionGUI(JFrame frame) { m.set(8); rs.put(1); addMouseWheelListener(this); @@ -142,6 +144,13 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene help = false; } }); + frame.addWindowListener(new java.awt.event.WindowAdapter() { + @Override + public void windowClosing(java.awt.event.WindowEvent windowEvent) { + e.shutdown(); + eh.shutdown(); + } + }); } @Override @@ -726,9 +735,9 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene } } - private static void createAndShowGUI(Engine r, int s, World world) { + private static void createAndShowGUI(Engine r, int s, IrisWorld world) { JFrame frame = new JFrame("Vision"); - IrisVision nv = new IrisVision(frame); + VisionGUI nv = new VisionGUI(frame); nv.world = world; nv.engine = r; nv.renderer = new IrisRenderer(r); diff --git a/src/main/java/com/volmit/iris/core/gui/IrisRenderer.java b/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java similarity index 93% rename from src/main/java/com/volmit/iris/core/gui/IrisRenderer.java rename to src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java index 436d57951..00a31d77c 100644 --- a/src/main/java/com/volmit/iris/core/gui/IrisRenderer.java +++ b/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java @@ -16,11 +16,10 @@ * along with this program. If not, see . */ -package com.volmit.iris.core.gui; +package com.volmit.iris.core.gui.components; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.interpolation.IrisInterpolation; -import org.bukkit.Material; import java.awt.*; import java.awt.image.BufferedImage; @@ -60,8 +59,4 @@ public class IrisRenderer { return image; } - - public void set(double worldX, double worldZ) { - renderer.getWorld().getBlockAt((int) worldX, 20, (int) worldZ).setType(Material.DIAMOND_BLOCK); - } } diff --git a/src/main/java/com/volmit/iris/core/gui/RenderType.java b/src/main/java/com/volmit/iris/core/gui/components/RenderType.java similarity index 95% rename from src/main/java/com/volmit/iris/core/gui/RenderType.java rename to src/main/java/com/volmit/iris/core/gui/components/RenderType.java index 99c5098fb..002601621 100644 --- a/src/main/java/com/volmit/iris/core/gui/RenderType.java +++ b/src/main/java/com/volmit/iris/core/gui/components/RenderType.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package com.volmit.iris.core.gui; +package com.volmit.iris.core.gui.components; public enum RenderType { BIOME, BIOME_LAND, BIOME_SEA, REGION, CAVE_LAND, HEIGHT, OBJECT_LOAD, DECORATOR_LOAD, LAYER_LOAD diff --git a/src/main/java/com/volmit/iris/core/gui/Renderer.java b/src/main/java/com/volmit/iris/core/gui/components/Renderer.java similarity index 95% rename from src/main/java/com/volmit/iris/core/gui/Renderer.java rename to src/main/java/com/volmit/iris/core/gui/components/Renderer.java index 956b68e31..ca33e0ec5 100644 --- a/src/main/java/com/volmit/iris/core/gui/Renderer.java +++ b/src/main/java/com/volmit/iris/core/gui/components/Renderer.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package com.volmit.iris.core.gui; +package com.volmit.iris.core.gui.components; import java.awt.*; diff --git a/src/main/java/com/volmit/iris/core/gui/TileRender.java b/src/main/java/com/volmit/iris/core/gui/components/TileRender.java similarity index 95% rename from src/main/java/com/volmit/iris/core/gui/TileRender.java rename to src/main/java/com/volmit/iris/core/gui/components/TileRender.java index caca47173..ec7eddd65 100644 --- a/src/main/java/com/volmit/iris/core/gui/TileRender.java +++ b/src/main/java/com/volmit/iris/core/gui/components/TileRender.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package com.volmit.iris.core.gui; +package com.volmit.iris.core.gui.components; import lombok.Builder; import lombok.Data; diff --git a/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java b/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java new file mode 100644 index 000000000..a0bbf3fb4 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java @@ -0,0 +1,267 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator; + +import com.volmit.iris.util.collection.KSet; +import com.volmit.iris.util.math.M; +import com.volmit.iris.util.math.Position2; +import com.volmit.iris.util.math.RollingSequence; +import com.volmit.iris.util.scheduling.ChronoLatch; +import com.volmit.iris.util.scheduling.J; +import com.volmit.iris.util.scheduling.Looper; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; + +public class IrisPregenerator { + private final PregenTask task; + private final PregeneratorMethod generator; + private final PregenListener listener; + private final Looper ticker; + private final AtomicBoolean paused; + private final AtomicBoolean shutdown; + private final RollingSequence chunksPerSecond; + private final RollingSequence chunksPerMinute; + private final RollingSequence regionsPerMinute; + private final AtomicInteger generated; + private final AtomicInteger generatedLast; + private final AtomicInteger generatedLastMinute; + private final AtomicInteger totalChunks; + private final AtomicLong startTime; + private final ChronoLatch minuteLatch; + private final AtomicReference currentGeneratorMethod; + private final KSet generatedRegions; + private final KSet retry; + private final KSet net; + + public IrisPregenerator(PregenTask task, PregeneratorMethod generator, PregenListener listener) { + this.listener = listenify(listener); + generatedRegions = new KSet<>(); + this.shutdown = new AtomicBoolean(false); + this.paused = new AtomicBoolean(false); + this.task = task; + this.generator = generator; + retry = new KSet<>(); + net = new KSet<>(); + currentGeneratorMethod = new AtomicReference<>("Void"); + minuteLatch = new ChronoLatch(60000, false); + chunksPerSecond = new RollingSequence(10); + chunksPerMinute = new RollingSequence(10); + regionsPerMinute = new RollingSequence(10); + generated = new AtomicInteger(0); + generatedLast = new AtomicInteger(0); + generatedLastMinute = new AtomicInteger(0); + totalChunks = new AtomicInteger(0); + task.iterateRegions((_a, _b) -> totalChunks.addAndGet(1024)); + startTime = new AtomicLong(M.ms()); + ticker = new Looper() { + @Override + protected long loop() { + long eta = computeETA(); + int secondGenerated = generated.get() - generatedLast.get(); + generatedLast.set(generated.get()); + chunksPerSecond.put(secondGenerated); + + if (minuteLatch.flip()) { + int minuteGenerated = generated.get() - generatedLastMinute.get(); + generatedLastMinute.set(generated.get()); + chunksPerMinute.put(minuteGenerated); + regionsPerMinute.put((double) minuteGenerated / 1024D); + } + + listener.onTick(chunksPerSecond.getAverage(), chunksPerMinute.getAverage(), + regionsPerMinute.getAverage(), + (double) generated.get() / (double) totalChunks.get(), + generated.get(), totalChunks.get(), + totalChunks.get() - generated.get(), + eta, M.ms() - startTime.get(), currentGeneratorMethod.get()); + + return 1000; + } + }; + } + + private long computeETA() { + return (long) ((totalChunks.get() - generated.get()) * + ((double) (M.ms() - startTime.get()) / (double) generated.get())); + } + + public void close() { + shutdown.set(true); + } + + public void start() { + init(); + ticker.start(); + checkRegions(); + task.iterateRegions((x, z) -> visitRegion(x, z, true)); + task.iterateRegions((x, z) -> visitRegion(x, z, false)); + shutdown(); + } + + private void checkRegions() { + task.iterateRegions(this::checkRegion); + } + + private void init() { + generator.init(); + generator.save(); + } + + private void shutdown() { + listener.onSaving(); + generator.close(); + ticker.interrupt(); + listener.onClose(); + } + + private void visitRegion(int x, int z, boolean regions) { + while (paused.get() && !shutdown.get()) { + J.sleep(50); + } + + if (shutdown.get()) { + listener.onRegionSkipped(x, z); + return; + } + + Position2 pos = new Position2(x, z); + + if (generatedRegions.contains(pos)) { + return; + } + + currentGeneratorMethod.set(generator.getMethod(x, z)); + boolean hit = false; + if (generator.supportsRegions(x, z, listener) && regions) { + hit = true; + listener.onRegionGenerating(x, z); + generator.generateRegion(x, z, listener); + } else if (!regions) { + hit = true; + listener.onRegionGenerating(x, z); + PregenTask.iterateRegion(x, z, (xx, zz) -> generator.generateChunk(xx, zz, listener)); + } + + if (hit) { + listener.onRegionGenerated(x, z); + listener.onSaving(); + generator.save(); + generatedRegions.add(pos); + checkRegions(); + } + } + + private void checkRegion(int x, int z) { + if (generatedRegions.contains(new Position2(x, z))) { + return; + } + + generator.supportsRegions(x, z, listener); + } + + public void pause() { + paused.set(true); + } + + public void resume() { + paused.set(false); + } + + private PregenListener listenify(PregenListener listener) { + return new PregenListener() { + @Override + public void onTick(double chunksPerSecond, double chunksPerMinute, double regionsPerMinute, double percent, int generated, int totalChunks, int chunksRemaining, long eta, long elapsed, String method) { + listener.onTick(chunksPerSecond, chunksPerMinute, regionsPerMinute, percent, generated, totalChunks, chunksRemaining, eta, elapsed, method); + } + + @Override + public void onChunkGenerating(int x, int z) { + listener.onChunkGenerating(x, z); + } + + @Override + public void onChunkGenerated(int x, int z) { + listener.onChunkGenerated(x, z); + generated.addAndGet(1); + } + + @Override + public void onRegionGenerated(int x, int z) { + listener.onRegionGenerated(x, z); + } + + @Override + public void onRegionGenerating(int x, int z) { + listener.onRegionGenerating(x, z); + } + + @Override + public void onRegionSkipped(int x, int z) { + listener.onRegionSkipped(x, z); + } + + @Override + public void onNetworkStarted(int x, int z) { + net.add(new Position2(x, z)); + } + + @Override + public void onNetworkFailed(int x, int z) { + retry.add(new Position2(x, z)); + } + + @Override + public void onNetworkReclaim(int revert) { + generated.addAndGet(-revert); + } + + @Override + public void onNetworkGeneratedChunk(int x, int z) { + generated.addAndGet(1); + } + + @Override + public void onNetworkDownloaded(int x, int z) { + net.remove(new Position2(x, z)); + } + + @Override + public void onClose() { + listener.onClose(); + } + + @Override + public void onSaving() { + listener.onSaving(); + } + + @Override + public void onChunkExistsInRegionGen(int x, int z) { + listener.onChunkExistsInRegionGen(x, z); + } + }; + } + + public boolean paused() { + return paused.get(); + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/PregenListener.java b/src/main/java/com/volmit/iris/core/pregenerator/PregenListener.java new file mode 100644 index 000000000..16b8d0b2c --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/PregenListener.java @@ -0,0 +1,49 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator; + +public interface PregenListener { + void onTick(double chunksPerSecond, double chunksPerMinute, double regionsPerMinute, double percent, int generated, int totalChunks, int chunksRemaining, long eta, long elapsed, String method); + + void onChunkGenerating(int x, int z); + + void onChunkGenerated(int x, int z); + + void onRegionGenerated(int x, int z); + + void onRegionGenerating(int x, int z); + + void onRegionSkipped(int x, int z); + + void onNetworkStarted(int x, int z); + + void onNetworkFailed(int x, int z); + + void onNetworkReclaim(int revert); + + void onNetworkGeneratedChunk(int x, int z); + + void onNetworkDownloaded(int x, int z); + + void onClose(); + + void onSaving(); + + void onChunkExistsInRegionGen(int x, int z); +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java b/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java new file mode 100644 index 000000000..cc87b439d --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java @@ -0,0 +1,72 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator; + +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.math.Position2; +import com.volmit.iris.util.math.Spiraled; +import com.volmit.iris.util.math.Spiraler; +import lombok.Builder; +import lombok.Data; + +import java.util.Comparator; + +@Builder +@Data +public class PregenTask { + @Builder.Default + private Position2 center = new Position2(0, 0); + + @Builder.Default + private int radius = 1; + + private static final KList order = computeChunkOrder(); + + public void iterateRegions(Spiraled s) { + new Spiraler(radius * 2, radius * 2, s) + .setOffset(center.getX(), center.getZ()).drain(); + } + + public static void iterateRegion(int xr, int zr, Spiraled s) { + for (Position2 i : order) { + s.on(i.getX() + (xr << 5), i.getZ() + (zr << 5)); + } + } + + public void iterateAllChunks(Spiraled s) { + new Spiraler(radius * 2, radius * 2, (x, z) -> iterateRegion(x, z, s)) + .setOffset(center.getX(), center.getZ()).drain(); + } + + private static KList computeChunkOrder() { + Position2 center = new Position2(15, 15); + KList p = new KList<>(); + new Spiraler(33, 33, (x, z) -> { + int xx = x + 15; + int zz = z + 15; + if (xx < 0 || xx > 31 || zz < 0 || zz > 31) { + return; + } + + p.add(new Position2(xx, zz)); + }).drain(); + p.sort(Comparator.comparing((i) -> i.distance(center))); + return p; + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/PregeneratorMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/PregeneratorMethod.java new file mode 100644 index 000000000..ceed620cf --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/PregeneratorMethod.java @@ -0,0 +1,77 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator; + +/** + * Represents something that is capable of generating in chunks or regions, or both + */ +public interface PregeneratorMethod { + /** + * This is called before any generate methods are called. Setup your generator here + */ + void init(); + + /** + * This is called after the pregenerator is done. Save your work and stop threads + */ + void close(); + + /** + * This is called every X amount of chunks or regions. Save work, + * but no need to save all of it. At the end, close() will still be called. + */ + void save(); + + /** + * Return true if regions can be generated + * + * @param x the x region + * @param z the z region + * @return true if they can be + */ + boolean supportsRegions(int x, int z, PregenListener listener); + + /** + * Return the name of the method being used + * + * @param x the x region + * @param z the z region + * @return the name + */ + String getMethod(int x, int z); + + /** + * Called to generate a region. Execute sync, if multicore internally, wait + * for the task to complete + * + * @param x the x + * @param z the z + * @param listener signal chunks generating & generated. Parallel capable. + */ + void generateRegion(int x, int z, PregenListener listener); + + /** + * Called to generate a chunk. You can go async so long as save will wait on the threads to finish + * + * @param x the x + * @param z the z + * @param listener + */ + void generateChunk(int x, int z, PregenListener listener); +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncOrMedievalPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncOrMedievalPregenMethod.java new file mode 100644 index 000000000..bd65bf4c0 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncOrMedievalPregenMethod.java @@ -0,0 +1,67 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.methods; + +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregeneratorMethod; +import io.papermc.lib.PaperLib; +import org.bukkit.World; + +public class AsyncOrMedievalPregenMethod implements PregeneratorMethod { + private final PregeneratorMethod method; + + public AsyncOrMedievalPregenMethod(World world, int threads) { + method = PaperLib.isPaper() ? new AsyncPregenMethod(world, threads) : new MedievalPregenMethod(world); + } + + @Override + public void init() { + method.init(); + } + + @Override + public void close() { + method.close(); + } + + @Override + public void save() { + method.save(); + } + + @Override + public String getMethod(int x, int z) { + return method.getMethod(x, z); + } + + @Override + public boolean supportsRegions(int x, int z, PregenListener listener) { + return false; + } + + @Override + public void generateRegion(int x, int z, PregenListener listener) { + throw new UnsupportedOperationException(); + } + + @Override + public void generateChunk(int x, int z, PregenListener listener) { + method.generateChunk(x, z, listener); + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java new file mode 100644 index 000000000..ffedcaa5b --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java @@ -0,0 +1,124 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.methods; + +import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregeneratorMethod; +import com.volmit.iris.engine.parallel.MultiBurst; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.scheduling.J; +import io.papermc.lib.PaperLib; +import org.bukkit.Chunk; +import org.bukkit.World; + +import java.util.concurrent.CompletableFuture; + +public class AsyncPregenMethod implements PregeneratorMethod { + private final World world; + private final MultiBurst burst; + private final KList> future; + + public AsyncPregenMethod(World world, int threads) { + if (!PaperLib.isPaper()) { + throw new UnsupportedOperationException("Cannot use PaperAsync on non paper!"); + } + + this.world = world; + burst = new MultiBurst("Iris Async Pregenerator", IrisSettings.get().getConcurrency().getPregenThreadPriority(), threads); + future = new KList<>(1024); + } + + private void unloadAndSaveAllChunks() { + try { + J.sfut(() -> { + for (Chunk i : world.getLoadedChunks()) { + i.unload(true); + } + world.save(); + }).get(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + private void completeChunk(int x, int z, PregenListener listener) { + try { + PaperLib.getChunkAtAsync(world, x, z, true).get(); + listener.onChunkGenerated(x, z); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + private void waitForChunks() { + for (CompletableFuture i : future) { + try { + i.get(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + future.clear(); + } + + @Override + public void init() { + unloadAndSaveAllChunks(); + } + + @Override + public String getMethod(int x, int z) { + return "Async"; + } + + @Override + public void close() { + waitForChunks(); + burst.shutdownAndAwait(); + unloadAndSaveAllChunks(); + } + + @Override + public void save() { + waitForChunks(); + unloadAndSaveAllChunks(); + } + + @Override + public boolean supportsRegions(int x, int z, PregenListener listener) { + return false; + } + + @Override + public void generateRegion(int x, int z, PregenListener listener) { + throw new UnsupportedOperationException(); + } + + @Override + public void generateChunk(int x, int z, PregenListener listener) { + if (future.size() > IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount())) { + waitForChunks(); + } + + listener.onChunkGenerating(x, z); + future.add(burst.complete(() -> completeChunk(x, z, listener))); + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/DummyPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/DummyPregenMethod.java new file mode 100644 index 000000000..1842054fa --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/DummyPregenMethod.java @@ -0,0 +1,59 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.methods; + +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregeneratorMethod; + +public class DummyPregenMethod implements PregeneratorMethod { + @Override + public void init() { + + } + + @Override + public void close() { + + } + + @Override + public String getMethod(int x, int z) { + return "Dummy"; + } + + @Override + public void save() { + + } + + @Override + public boolean supportsRegions(int x, int z, PregenListener listener) { + return false; + } + + @Override + public void generateRegion(int x, int z, PregenListener listener) { + + } + + @Override + public void generateChunk(int x, int z, PregenListener listener) { + + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/HeadlessPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/HeadlessPregenMethod.java new file mode 100644 index 000000000..c91071478 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/HeadlessPregenMethod.java @@ -0,0 +1,76 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.methods; + +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregeneratorMethod; +import com.volmit.iris.engine.headless.HeadlessGenerator; +import com.volmit.iris.engine.headless.HeadlessWorld; +import lombok.Getter; + +public class HeadlessPregenMethod implements PregeneratorMethod { + private final HeadlessWorld world; + + @Getter + private final HeadlessGenerator generator; + + public HeadlessPregenMethod(HeadlessWorld world) { + this(world, world.generate()); + } + + public HeadlessPregenMethod(HeadlessWorld world, HeadlessGenerator generator) { + this.world = world; + this.generator = generator; + } + + @Override + public void init() { + + } + + @Override + public void close() { + generator.close(); + } + + @Override + public void save() { + generator.save(); + } + + @Override + public boolean supportsRegions(int x, int z, PregenListener listener) { + return true; + } + + @Override + public String getMethod(int x, int z) { + return "Headless"; + } + + @Override + public void generateRegion(int x, int z, PregenListener listener) { + generator.generateRegion(x, z, listener); + } + + @Override + public void generateChunk(int x, int z, PregenListener listener) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java new file mode 100644 index 000000000..bd843feb5 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java @@ -0,0 +1,101 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.methods; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregeneratorMethod; +import com.volmit.iris.core.tools.IrisWorlds; +import com.volmit.iris.engine.headless.HeadlessWorld; +import com.volmit.iris.util.math.Position2; +import org.bukkit.World; + +import java.io.File; + +public class HybridPregenMethod implements PregeneratorMethod { + private final PregeneratorMethod headless; + private final PregeneratorMethod inWorld; + private final World world; + + public HybridPregenMethod(World world, int threads) { + this.world = world; + headless = supportsHeadless(world) + ? new HeadlessPregenMethod(HeadlessWorld.from(world)) : new DummyPregenMethod(); + inWorld = new AsyncOrMedievalPregenMethod(world, threads); + } + + private boolean supportsHeadless(World world) { + return IrisWorlds.access(world) != null && IrisSettings.get().getGenerator().isMcaPregenerator(); + } + + @Override + public String getMethod(int x, int z) { + return "Hybrid<" + ((supportsRegions(x, z, null) ? headless.getMethod(x, z) : inWorld.getMethod(x, z)) + ">"); + } + + @Override + public void init() { + headless.init(); + inWorld.init(); + } + + @Override + public void close() { + headless.close(); + inWorld.close(); + } + + @Override + public void save() { + headless.save(); + inWorld.save(); + } + + @Override + public boolean supportsRegions(int x, int z, PregenListener listener) { + if (headless instanceof DummyPregenMethod) { + return false; + } + + boolean r = !new File(world.getWorldFolder(), "region/r." + x + "." + z + ".mca").exists(); + + if (!r && listener != null) { + try { + for (Position2 i : ((HeadlessPregenMethod) headless).getGenerator().getChunksInRegion(x, z)) { + listener.onChunkExistsInRegionGen((x << 5) + i.getX(), (z << 5) + i.getZ()); + } + } catch (Throwable e) { + Iris.reportError(e); + } + } + + return r; + } + + @Override + public void generateRegion(int x, int z, PregenListener listener) { + headless.generateRegion(x, z, listener); + } + + @Override + public void generateChunk(int x, int z, PregenListener listener) { + inWorld.generateChunk(x, z, listener); + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java new file mode 100644 index 000000000..6a378f786 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java @@ -0,0 +1,108 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.methods; + +import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregeneratorMethod; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.scheduling.J; +import org.bukkit.Chunk; +import org.bukkit.World; + +import java.util.concurrent.CompletableFuture; + +public class MedievalPregenMethod implements PregeneratorMethod { + private final World world; + private final KList> futures; + + public MedievalPregenMethod(World world) { + this.world = world; + futures = new KList<>(); + } + + private void waitForChunks() { + for (CompletableFuture i : futures) { + try { + i.get(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + futures.clear(); + } + + private void unloadAndSaveAllChunks() { + waitForChunks(); + try { + J.sfut(() -> { + for (Chunk i : world.getLoadedChunks()) { + i.unload(true); + } + world.save(); + }).get(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + @Override + public void init() { + unloadAndSaveAllChunks(); + } + + @Override + public void close() { + unloadAndSaveAllChunks(); + } + + @Override + public void save() { + unloadAndSaveAllChunks(); + } + + @Override + public boolean supportsRegions(int x, int z, PregenListener listener) { + return false; + } + + @Override + public void generateRegion(int x, int z, PregenListener listener) { + throw new UnsupportedOperationException(); + } + + @Override + public String getMethod(int x, int z) { + return "Medieval"; + } + + @Override + public void generateChunk(int x, int z, PregenListener listener) { + if (futures.size() > IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount())) { + waitForChunks(); + } + + listener.onChunkGenerating(x, z); + futures.add(J.sfut(() -> { + world.getChunkAt(x, z); + listener.onChunkGenerated(x, z); + })); + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/SyndicatePregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/SyndicatePregenMethod.java new file mode 100644 index 000000000..9f1519e08 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/SyndicatePregenMethod.java @@ -0,0 +1,261 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.methods; + +import com.google.common.util.concurrent.AtomicDouble; +import com.volmit.iris.Iris; +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregenTask; +import com.volmit.iris.core.pregenerator.PregeneratorMethod; +import com.volmit.iris.core.pregenerator.syndicate.SyndicateClient; +import com.volmit.iris.core.pregenerator.syndicate.command.*; +import com.volmit.iris.engine.object.IrisDimension; +import com.volmit.iris.util.io.IO; +import com.volmit.iris.util.scheduling.J; +import lombok.Getter; +import org.zeroturnaround.zip.ZipUtil; + +import java.io.File; +import java.io.IOException; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; + +public class SyndicatePregenMethod implements PregeneratorMethod { + @Getter + private String address; + private String nickname; + private int port; + private String password; + private IrisDimension dimension; + private boolean ready = false; + private File worldFolder; + private UUID pack = UUID.randomUUID(); + private long seed; + + public SyndicatePregenMethod(String nickname, File worldFolder, String address, int port, String password, IrisDimension dimension, long seed) { + this.seed = seed; + this.worldFolder = worldFolder; + this.address = address; + this.port = port; + this.password = password; + this.dimension = dimension; + } + + private SyndicateClient.SyndicateClientBuilder connect() { + return SyndicateClient.builder().address(address).port(port); + } + + public synchronized void setup() { + if (ready) { + return; + } + + ready = false; + try { + connect().command(SyndicateInstallPack + .builder() + .dimension(dimension) + .pack(pack) + .seed(seed) + .build()) + .output((o) -> { + File to = new File(Iris.getTemp(), "send-" + pack.toString() + ".zip"); + ZipUtil.pack(dimension.getLoader().getDataFolder(), to); + + try { + IO.writeAll(to, o); + } catch (IOException e) { + e.printStackTrace(); + } + + to.deleteOnExit(); + }) + .build().go((response, data) -> { + if (response instanceof SyndicateBusy) { + throw new RuntimeException("Service is busy, will try later"); + } + + ready = true; + }); + ready = true; + } catch (Throwable throwable) { + if (throwable instanceof RuntimeException) { + ready = false; + return; + } + + throwable.printStackTrace(); + } + } + + public boolean canGenerate() { + if (!ready) { + J.a(this::setup); + } + + return ready; + } + + @Override + public void init() { + J.a(this::setup); + } + + @Override + public void close() { + if (ready) { + try { + connect() + .command(SyndicateClose + .builder() + .pack(pack) + .build()) + .build() + .go((__, __b) -> { + }); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + } + } + + @Override + public void save() { + + } + + @Override + public boolean supportsRegions(int x, int z, PregenListener listener) { + return true; + } + + @Override + public String getMethod(int x, int z) { + return "Syndicate<" + nickname + ">"; + } + + private double checkProgress(int x, int z) { + AtomicDouble progress = new AtomicDouble(-1); + try { + connect() + .command(SyndicateGetProgress.builder() + .pack(pack).build()).output((i) -> { + }).build().go((response, o) -> { + if (response instanceof SyndicateSendProgress) { + if (((SyndicateSendProgress) response).isAvailable()) { + progress.set(((SyndicateSendProgress) response).getProgress()); + File f = new File(worldFolder, "region/r." + x + "." + z + ".mca"); + try { + f.getParentFile().mkdirs(); + IO.writeAll(f, o); + progress.set(1000); + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + }); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + + return progress.get(); + } + + @Override + public void generateRegion(int x, int z, PregenListener listener) { + if (!ready) { + throw new RuntimeException(); + } + + try { + connect().command(SyndicateGenerate + .builder() + .x(x).z(z).pack(pack) + .build()) + .build().go((response, data) -> { + if (response instanceof SyndicateOK) { + listener.onNetworkStarted(x, z); + J.a(() -> { + double lastp = 0; + int calls = 0; + boolean installed = false; + while (true) { + J.sleep(100); + double progress = checkProgress(x, z); + + if (progress == 1000) { + installed = true; + AtomicInteger a = new AtomicInteger(calls); + PregenTask.iterateRegion(x, z, (xx, zz) -> { + if (a.decrementAndGet() < 0) { + listener.onNetworkGeneratedChunk(xx, zz); + } + }); + calls = 1024; + } else if (progress < 0) { + break; + } + + int change = (int) Math.floor((progress - lastp) * 1024D); + change = change == 0 ? 1 : change; + + AtomicInteger a = new AtomicInteger(calls); + AtomicInteger b = new AtomicInteger(change); + PregenTask.iterateRegion(x, z, (xx, zz) -> { + if (a.decrementAndGet() < 0) { + if (b.decrementAndGet() >= 0) { + listener.onNetworkGeneratedChunk(xx, zz); + } + } + }); + calls += change; + } + + if (!installed) { + // TODO RETRY REGION + return; + } + + listener.onNetworkDownloaded(x, z); + }); + } else if (response instanceof SyndicateInstallFirst) { + ready = false; + throw new RuntimeException(); + } else if (response instanceof SyndicateBusy) { + throw new RuntimeException(); + } else { + throw new RuntimeException(); + } + }); + } catch (Throwable throwable) { + + if (throwable instanceof RuntimeException) { + throw (RuntimeException) throwable; + } + + throwable.printStackTrace(); + } + } + + @Override + public void generateChunk(int x, int z, PregenListener listener) { + + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/syndicate/SyndicateClient.java b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/SyndicateClient.java new file mode 100644 index 000000000..2f7c9e848 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/SyndicateClient.java @@ -0,0 +1,51 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.syndicate; + +import com.volmit.iris.core.pregenerator.syndicate.command.SyndicateCommand; +import com.volmit.iris.util.function.Consumer2; +import lombok.Builder; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.net.Socket; +import java.util.function.Consumer; + +@Builder +public class SyndicateClient { + private String address; + private int port; + private SyndicateCommand command; + private Consumer output; + + public void go(Consumer2 handler) throws Throwable { + Socket socket = new Socket(address, port); + DataInputStream i = new DataInputStream(socket.getInputStream()); + DataOutputStream o = new DataOutputStream(socket.getOutputStream()); + SyndicateCommandIO.write(command, o); + + if (output != null) { + output.accept(o); + } + + o.flush(); + handler.accept(SyndicateCommandIO.read(i), i); + socket.close(); + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/syndicate/SyndicateCommandIO.java b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/SyndicateCommandIO.java new file mode 100644 index 000000000..a3cc8c97f --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/SyndicateCommandIO.java @@ -0,0 +1,40 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.syndicate; + +import com.google.gson.Gson; +import com.volmit.iris.core.pregenerator.syndicate.command.SyndicateCommand; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class SyndicateCommandIO { + private static final Gson gson = new Gson(); + + public static SyndicateCommand read(DataInputStream in) throws IOException, ClassNotFoundException { + String clazz = in.readUTF(); + return (SyndicateCommand) gson.fromJson(in.readUTF(), Class.forName(clazz)); + } + + public static void write(SyndicateCommand c, DataOutputStream out) throws IOException { + out.writeUTF(c.getClass().getCanonicalName()); + out.writeUTF(gson.toJson(c)); + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/syndicate/SyndicateServer.java b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/SyndicateServer.java new file mode 100644 index 000000000..11ae61fbd --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/SyndicateServer.java @@ -0,0 +1,247 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.syndicate; + +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.syndicate.command.*; +import com.volmit.iris.engine.headless.HeadlessGenerator; +import com.volmit.iris.engine.headless.HeadlessWorld; +import com.volmit.iris.util.io.IO; +import com.volmit.iris.util.scheduling.J; +import org.zeroturnaround.zip.ZipUtil; + +import java.io.*; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.util.Objects; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; + +public class SyndicateServer extends Thread implements PregenListener { + private int port; + private String password; + private boolean busy; + private int tc; + private HeadlessGenerator generator; + private ServerSocket server; + private File cache; + private UUID currentId = null; + private AtomicInteger g = new AtomicInteger(0); + private File lastGeneratedRegion = null; + + public SyndicateServer(File cache, int port, String password, int tc) throws IOException { + this.port = port; + this.cache = cache; + this.password = password; + this.tc = tc; + start(); + server = new ServerSocket(port); + server.setSoTimeout(1000); + } + + public void run() { + while (!interrupted()) { + try { + Socket client = server.accept(); + DataInputStream i = new DataInputStream(client.getInputStream()); + DataOutputStream o = new DataOutputStream(client.getOutputStream()); + try { + handle(client, i, o); + o.flush(); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + client.close(); + } catch (SocketTimeoutException ignored) { + + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + private void handle(Socket client, DataInputStream i, DataOutputStream o) throws Throwable { + SyndicateCommand cmd = handle(SyndicateCommandIO.read(i), i, o); + + if (cmd != null) { + SyndicateCommandIO.write(cmd, o); + } + + o.flush(); + } + + private File getCachedDim(UUID id) { + return new File(cache, id.toString().charAt(2) + "/" + id.toString().substring(0, 4) + "/" + id); + } + + private SyndicateCommand handle(SyndicateCommand command, DataInputStream i, DataOutputStream o) throws Throwable { + if (command instanceof SyndicateInstallPack) { + if (busy) { + return new SyndicateBusy(); + } + + if (generator != null) { + generator.close(); + IO.delete(generator.getWorld().getWorld().worldFolder()); + generator = null; + } + + UUID id = ((SyndicateInstallPack) command).getPack(); + File cacheload = new File(cache, id.toString().charAt(2) + "/" + id.toString().substring(0, 4) + "/" + id + ".zip"); + File cachestore = getCachedDim(id); + IO.delete(cachestore); + int len = i.readInt(); + cacheload.getParentFile().mkdirs(); + byte[] buf = new byte[8192]; + FileOutputStream fos = new FileOutputStream(cacheload); + IO.transfer(i, fos, buf, len); + fos.close(); + ZipUtil.unpack(cacheload, cachestore); + cacheload.deleteOnExit(); + HeadlessWorld w = new HeadlessWorld("turbo/" + id.toString(), ((SyndicateInstallPack) command).getDimension(), ((SyndicateInstallPack) command).getSeed()); + w.setStudio(true); + generator = w.generate(); + return new SyndicateOK(); + } + + if (command instanceof SyndicateGenerate) { + if (busy) { + return new SyndicateBusy(); + } + + if (generator == null || !Objects.equals(currentId, ((SyndicateGenerate) command).getPack())) { + return new SyndicateInstallFirst(); + } + + g.set(0); + busy = true; + J.a(() -> { + busy = false; + lastGeneratedRegion = generator.generateRegionToFile(((SyndicateGenerate) command).getX(), ((SyndicateGenerate) command).getZ(), this); + }); + return new SyndicateOK(); + } + + if (command instanceof SyndicateClose) { + if (generator != null && Objects.equals(currentId, ((SyndicateClose) command).getPack()) && !busy) { + generator.close(); + IO.delete(generator.getWorld().getWorld().worldFolder()); + generator = null; + currentId = null; + } + } + + if (command instanceof SyndicateGetProgress) { + if (generator != null && busy && Objects.equals(currentId, ((SyndicateGetProgress) command).getPack())) { + return SyndicateSendProgress.builder().progress((double) g.get() / 1024D).build(); + } else if (generator != null && !busy && Objects.equals(currentId, ((SyndicateGetProgress) command).getPack()) && lastGeneratedRegion != null && lastGeneratedRegion.exists()) { + SyndicateCommandIO.write(SyndicateSendProgress + .builder() + .progress(1).available(true) + .build(), o); + o.writeLong(lastGeneratedRegion.length()); + IO.writeAll(lastGeneratedRegion, o); + return null; + } else if (generator == null) { + return new SyndicateInstallFirst(); + } else { + return new SyndicateBusy(); + } + } + + throw new IllegalStateException("Unexpected value: " + command.getClass()); + } + + public void close() throws IOException { + interrupt(); + generator.close(); + server.close(); + } + + @Override + public void onTick(double chunksPerSecond, double chunksPerMinute, double regionsPerMinute, double percent, int generated, int totalChunks, int chunksRemaining, long eta, long elapsed, String method) { + + } + + @Override + public void onChunkGenerating(int x, int z) { + + } + + @Override + public void onChunkGenerated(int x, int z) { + g.incrementAndGet(); + } + + @Override + public void onRegionGenerated(int x, int z) { + + } + + @Override + public void onRegionGenerating(int x, int z) { + + } + + @Override + public void onRegionSkipped(int x, int z) { + + } + + @Override + public void onNetworkStarted(int x, int z) { + + } + + @Override + public void onNetworkFailed(int x, int z) { + + } + + @Override + public void onNetworkReclaim(int revert) { + + } + + @Override + public void onNetworkGeneratedChunk(int x, int z) { + + } + + @Override + public void onNetworkDownloaded(int x, int z) { + + } + + @Override + public void onClose() { + + } + + @Override + public void onSaving() { + + } + + @Override + public void onChunkExistsInRegionGen(int x, int z) { + + } +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateBusy.java b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateBusy.java new file mode 100644 index 000000000..3b0766dee --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateBusy.java @@ -0,0 +1,22 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.syndicate.command; + +public class SyndicateBusy implements SyndicateCommand { +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateClose.java b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateClose.java new file mode 100644 index 000000000..782c356c7 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateClose.java @@ -0,0 +1,35 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.syndicate.command; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.UUID; + +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Data +public class SyndicateClose implements SyndicateCommand { + @Builder.Default + private UUID pack = UUID.randomUUID(); +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateCommand.java b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateCommand.java new file mode 100644 index 000000000..28fa034b9 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateCommand.java @@ -0,0 +1,23 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.syndicate.command; + +public interface SyndicateCommand { + +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateError.java b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateError.java new file mode 100644 index 000000000..581e229e8 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateError.java @@ -0,0 +1,22 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.syndicate.command; + +public class SyndicateError implements SyndicateCommand { +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateGenerate.java b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateGenerate.java new file mode 100644 index 000000000..df73ab983 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateGenerate.java @@ -0,0 +1,39 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.syndicate.command; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.UUID; + +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Data +public class SyndicateGenerate implements SyndicateCommand { + @Builder.Default + private int x = 0; + @Builder.Default + private int z = 0; + @Builder.Default + private UUID pack = UUID.randomUUID(); +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateGetProgress.java b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateGetProgress.java new file mode 100644 index 000000000..838b14eff --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateGetProgress.java @@ -0,0 +1,35 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.syndicate.command; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.UUID; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class SyndicateGetProgress implements SyndicateCommand { + @Builder.Default + private UUID pack = UUID.randomUUID(); +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateInstallFirst.java b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateInstallFirst.java new file mode 100644 index 000000000..c948cfb57 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateInstallFirst.java @@ -0,0 +1,22 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.syndicate.command; + +public class SyndicateInstallFirst implements SyndicateCommand { +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateInstallPack.java b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateInstallPack.java new file mode 100644 index 000000000..d399ee546 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateInstallPack.java @@ -0,0 +1,42 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.syndicate.command; + +import com.volmit.iris.engine.object.IrisDimension; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.UUID; + +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Data +public class SyndicateInstallPack implements SyndicateCommand { + @Builder.Default + private UUID pack = UUID.randomUUID(); + + @Builder.Default + private long seed = 1337; + + @Builder.Default + private IrisDimension dimension = null; +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateOK.java b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateOK.java new file mode 100644 index 000000000..ad78888a8 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateOK.java @@ -0,0 +1,22 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.syndicate.command; + +public class SyndicateOK implements SyndicateCommand { +} diff --git a/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateSendProgress.java b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateSendProgress.java new file mode 100644 index 000000000..9014f4c37 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pregenerator/syndicate/command/SyndicateSendProgress.java @@ -0,0 +1,35 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pregenerator.syndicate.command; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SyndicateSendProgress implements SyndicateCommand { + @Builder.Default + private double progress = 0; + @Builder.Default + private boolean available = false; +} diff --git a/src/main/java/com/volmit/iris/core/tools/IrisCreator.java b/src/main/java/com/volmit/iris/core/tools/IrisCreator.java new file mode 100644 index 000000000..8f4cb4622 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/tools/IrisCreator.java @@ -0,0 +1,220 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.tools; + +import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.pregenerator.PregenTask; +import com.volmit.iris.engine.framework.IrisAccess; +import com.volmit.iris.engine.headless.HeadlessWorld; +import com.volmit.iris.engine.object.IrisDimension; +import com.volmit.iris.util.exceptions.IrisException; +import com.volmit.iris.util.exceptions.MissingDimensionException; +import com.volmit.iris.util.format.C; +import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.plugin.VolmitSender; +import com.volmit.iris.util.scheduling.J; +import com.volmit.iris.util.scheduling.O; +import lombok.Data; +import lombok.experimental.Accessors; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.WorldCreator; + +import java.util.function.Consumer; + +/** + * Makes it a lot easier to setup an engine, world, studio or whatever + */ +@Data +@Accessors(fluent = true, chain = true) +public class IrisCreator { + /** + * Specify an area to pregenerate during creation + */ + private PregenTask pregen; + + /** + * Specify a sender to get updates & progress info + tp when world is created. + */ + private VolmitSender sender; + + /** + * The seed to use for this generator + */ + private long seed = RNG.r.nextLong(); + + /** + * The dimension to use. This can be any online dimension, or a dimension in the + * packs folder + */ + private String dimension = IrisSettings.get().getGenerator().getDefaultWorldType(); + + /** + * The name of this world. + */ + private String name = "irisworld"; + + /** + * Headless mode allows Iris to generate / query engine information + * without needing an actual world loaded. This is normally only used + * for pregeneration purposes but it could be used for mapping. + */ + private boolean headless = false; + + /** + * Studio mode makes the engine hotloadable and uses the dimension in + * your Iris/packs folder instead of copying the dimension files into + * the world itself. Studio worlds are deleted when they are unloaded. + */ + private boolean studio = false; + + /** + * Create the IrisAccess (contains the world) + * + * @return the IrisAccess + * @throws IrisException shit happens + */ + public IrisAccess create() throws IrisException { + IrisDimension d = IrisToolbelt.getDimension(dimension()); + IrisAccess access = null; + Consumer prog = (pxx) -> { + double px = (headless && pregen != null) ? pxx / 2 : pxx; + + if (pregen != null && !headless) { + px = (px / 2) + 0.5; + } + + if (sender != null) { + if (sender.isPlayer()) { + sender.player().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(C.WHITE + "Generating " + Form.pc(px))); + } else { + sender.sendMessage("Generating " + Form.f(px, 0)); + } + } + }; + + if (d == null) { + throw new MissingDimensionException("Cannot find dimension '" + dimension() + "'"); + } + + if (headless) { + HeadlessWorld w = new HeadlessWorld(name, d, seed, studio); + access = w.generate().getGenerator(); + } else { + O done = new O<>(); + done.set(false); + WorldCreator wc = new IrisWorldCreator() + .dimension(dimension) + .name(name) + .seed(seed) + .studio(studio) + .create(); + access = (IrisAccess) wc.generator(); + IrisAccess finalAccess1 = access; + + J.a(() -> + { + int req = 400; + + while (finalAccess1.getGenerated() < req && !done.get()) { + double v = (double) finalAccess1.getGenerated() / (double) req; + + if (pregen != null) { + v /= 2; + } + + if (sender.isPlayer()) { + sender.player().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(C.WHITE + "Generating " + Form.pc(v) + ((C.GRAY + " (" + (req - finalAccess1.getGenerated()) + " Left)")))); + J.sleep(50); + } else { + sender.sendMessage(C.WHITE + "Generating " + Form.pc(v) + ((C.GRAY + " (" + (req - finalAccess1.getGenerated()) + " Left)"))); + J.sleep(1000); + } + + if (finalAccess1.isFailing()) { + + sender.sendMessage("Generation Failed!"); + break; + } + } + + sender.player().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(C.WHITE + "Generation Complete")); + }); + + wc.createWorld(); + done.set(true); + } + + if (access == null) { + throw new IrisException("Access is null. Something bad happened."); + } + + IrisAccess finalAccess = access; + Runnable loadup = () -> { + try { + J.sfut(() -> { + if (headless) { + O done = new O<>(); + done.set(false); + + J.a(() -> + { + int req = 400; + + while (finalAccess.getGenerated() < req && !done.get()) { + double v = (double) finalAccess.getGenerated() / (double) req; + v = (v / 2) + 0.5; + + if (sender.isPlayer()) { + sender.player().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(C.WHITE + "Generating " + Form.pc(v) + ((C.GRAY + " (" + (req - finalAccess.getGenerated()) + " Left)")))); + J.sleep(50); + } else { + sender.sendMessage(C.WHITE + "Generating " + Form.pc(v) + ((C.GRAY + " (" + (req - finalAccess.getGenerated()) + " Left)"))); + J.sleep(1000); + } + + if (finalAccess.isFailing()) { + + sender.sendMessage("Generation Failed!"); + break; + } + } + + sender.player().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(C.WHITE + "Generation Complete")); + }); + + finalAccess.getHeadlessGenerator().getWorld().load(); + done.set(true); + } + }).get(); + } catch (Throwable e) { + e.printStackTrace(); + } + }; + + if (pregen != null) { + IrisToolbelt.pregenerate(pregen, access).onProgress(prog).whenDone(loadup); + } else { + loadup.run(); + } + + return access; + } +} diff --git a/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java b/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java new file mode 100644 index 000000000..25d6f5c4f --- /dev/null +++ b/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java @@ -0,0 +1,148 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.tools; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisDataManager; +import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.gui.PregeneratorJob; +import com.volmit.iris.core.pregenerator.PregenTask; +import com.volmit.iris.core.pregenerator.PregeneratorMethod; +import com.volmit.iris.core.pregenerator.methods.HeadlessPregenMethod; +import com.volmit.iris.core.pregenerator.methods.HybridPregenMethod; +import com.volmit.iris.engine.framework.IrisAccess; +import com.volmit.iris.engine.object.IrisDimension; +import com.volmit.iris.util.plugin.VolmitSender; +import org.bukkit.Bukkit; +import org.bukkit.World; + +import java.io.File; + +/** + * Something you really want to wear if working on Iris. Shit gets pretty hectic down there. + * Hope you packed snacks & road sodas. + */ +public class IrisToolbelt { + /** + * Will find / download / search for the dimension or return null + *

+ * - You can provide a dimenson in the packs folder by the folder name + * - You can provide a github repo by using (assumes branch is master unless specified) + * - GithubUsername/repository + * - GithubUsername/repository/branch + * + * @param dimension the dimension id such as overworld or flat + * @return the IrisDimension or null + */ + public static IrisDimension getDimension(String dimension) { + File pack = Iris.instance.getDataFolder("packs", dimension); + + if (!pack.exists()) { + Iris.proj.downloadSearch(new VolmitSender(Bukkit.getConsoleSender(), Iris.instance.getTag()), dimension, false, false); + } + + if (!pack.exists()) { + return null; + } + + return new IrisDataManager(pack).getDimensionLoader().load(dimension); + } + + /** + * Create a world with plenty of options + * + * @return the creator builder + */ + public static IrisCreator createWorld() { + return new IrisCreator(); + } + + /** + * Checks if the given world is an Iris World (same as access(world) != null) + * + * @param world the world + * @return true if it is an Iris Access world + */ + public static boolean isIrisWorld(World world) { + return access(world) != null; + } + + /** + * Get the Iris generator for the given world + * + * @param world the given world + * @return the IrisAccess or null if it's not an Iris World + */ + public static IrisAccess access(World world) { + return IrisWorlds.access(world); + } + + /** + * Start a pregenerator task + * + * @param task the scheduled task + * @param method the method to execute the task + * @return the pregenerator job (already started) + */ + public static PregeneratorJob pregenerate(PregenTask task, PregeneratorMethod method) { + return new PregeneratorJob(task, method); + } + + /** + * Start a pregenerator task. If the supplied generator is headless, headless mode is used, + * otherwise Hybrid mode is used. + * + * @param task the scheduled task + * @param access the Iris Generator + * @return the pregenerator job (already started) + */ + public static PregeneratorJob pregenerate(PregenTask task, IrisAccess access) { + if (access.isHeadless()) { + return pregenerate(task, new HeadlessPregenMethod(access.getHeadlessGenerator().getWorld(), access.getHeadlessGenerator())); + } + + return pregenerate(task, new HybridPregenMethod(access.getCompound().getWorld().realWorld(), IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount()))); + } + + /** + * Start a pregenerator task. If the supplied generator is headless, headless mode is used, + * otherwise Hybrid mode is used. + * + * @param task the scheduled task + * @param world the World + * @return the pregenerator job (already started) + */ + public static PregeneratorJob pregenerate(PregenTask task, World world) { + if (isIrisWorld(world)) { + return pregenerate(task, access(world)); + } + + return pregenerate(task, new HybridPregenMethod(world, IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount()))); + } + + /** + * Evacuate all players from the world into literally any other world. + * If there are no other worlds, kick them! Not the best but what's mine is mine sometimes... + * + * @param world the world to evac + */ + public static void evacuate(World world) { + IrisWorlds.evacuate(world); + } +} diff --git a/src/main/java/com/volmit/iris/engine/IrisWorldCreator.java b/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java similarity index 84% rename from src/main/java/com/volmit/iris/engine/IrisWorldCreator.java rename to src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java index ce830b071..07d6aa7d7 100644 --- a/src/main/java/com/volmit/iris/engine/IrisWorldCreator.java +++ b/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java @@ -16,12 +16,12 @@ * along with this program. If not, see . */ -package com.volmit.iris.engine; +package com.volmit.iris.core.tools; import com.volmit.iris.core.IrisDataManager; import com.volmit.iris.engine.framework.EngineCompositeGenerator; import com.volmit.iris.engine.object.IrisDimension; -import com.volmit.iris.util.fakenews.FakeWorld; +import com.volmit.iris.engine.object.common.IrisWorld; import org.bukkit.World; import org.bukkit.WorldCreator; @@ -78,8 +78,14 @@ public class IrisWorldCreator { public WorldCreator create() { EngineCompositeGenerator g = new EngineCompositeGenerator(dimensionName, !studio); - g.initialize(new FakeWorld(name, minHeight, maxHeight, seed, new File(name), findEnvironment())); - + g.initialize(IrisWorld.builder() + .name(name) + .minHeight(minHeight) + .maxHeight(maxHeight) + .seed(seed) + .worldFolder(new File(name)) + .environment(findEnvironment()) + .build()); return new WorldCreator(name) .environment(findEnvironment()) .generateStructures(true) @@ -94,4 +100,9 @@ public class IrisWorldCreator { return dim.getEnvironment(); } } + + public IrisWorldCreator studio(boolean studio) { + this.studio = studio; + return this; + } } diff --git a/src/main/java/com/volmit/iris/engine/IrisWorlds.java b/src/main/java/com/volmit/iris/core/tools/IrisWorlds.java similarity index 98% rename from src/main/java/com/volmit/iris/engine/IrisWorlds.java rename to src/main/java/com/volmit/iris/core/tools/IrisWorlds.java index 5d3b85328..505ae581a 100644 --- a/src/main/java/com/volmit/iris/engine/IrisWorlds.java +++ b/src/main/java/com/volmit/iris/core/tools/IrisWorlds.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package com.volmit.iris.engine; +package com.volmit.iris.core.tools; import com.volmit.iris.Iris; import com.volmit.iris.engine.framework.IrisAccess; diff --git a/src/main/java/com/volmit/iris/engine/IrisComplex.java b/src/main/java/com/volmit/iris/engine/IrisComplex.java index 1d2878269..d5b838920 100644 --- a/src/main/java/com/volmit/iris/engine/IrisComplex.java +++ b/src/main/java/com/volmit/iris/engine/IrisComplex.java @@ -107,15 +107,16 @@ public class IrisComplex implements DataProvider { } public IrisComplex(Engine engine, boolean simple) { - int cacheSize = 1024 * 128; - this.rng = new RNG(engine.getWorld().getSeed()); + int cacheSize = 131072; + IrisBiome emptyBiome = new IrisBiome(); + this.rng = new RNG(engine.getWorld().seed()); this.data = engine.getData(); double height = engine.getHeight(); fluidHeight = engine.getDimension().getFluidHeight(); generators = new KList<>(); focus = engine.getFocus(); IrisRegion focusRegion = focus != null ? findRegion(focus, engine) : null; - RNG rng = new RNG(engine.getWorld().getSeed()); + RNG rng = new RNG(engine.getWorld().seed()); //@builder engine.getDimension().getRegions().forEach((i) -> data.getRegionLoader().load(i) .getAllBiomes(this).forEach((b) -> b @@ -124,7 +125,7 @@ public class IrisComplex implements DataProvider { overlayStream = ProceduralStream.ofDouble((x, z) -> 0D); engine.getDimension().getOverlayNoise().forEach((i) -> overlayStream.add((x, z) -> i.get(rng, x, z))); rngStream = ProceduralStream.of((x, z) -> new RNG(((x.longValue()) << 32) | (z.longValue() & 0xffffffffL)) - .nextParallelRNG(engine.getWorld().getSeed()), Interpolated.RNG); + .nextParallelRNG(engine.getWorld().seed()), Interpolated.RNG); chunkRngStream = rngStream.blockToChunkCoords(); rockStream = engine.getDimension().getRockPalette().getLayerGenerator(rng.nextParallelRNG(45), data).stream() .select(engine.getDimension().getRockPalette().getBlockData(data)); @@ -151,7 +152,7 @@ public class IrisComplex implements DataProvider { .onNull("") .convertCached((s) -> { if (s.isEmpty()) { - return new IrisBiome(); + return emptyBiome; } return data.getBiomeLoader().load(s) @@ -193,12 +194,11 @@ public class IrisComplex implements DataProvider { .convertAware2D(this::implode).cache2D(cacheSize); heightStream = ProceduralStream.of((x, z) -> { IrisBiome b = focus != null ? focus : baseBiomeStream.get(x, z); - return getHeight(engine, b, x, z, engine.getWorld().getSeed()); + return getHeight(engine, b, x, z, engine.getWorld().seed()); }, Interpolated.DOUBLE).cache2D(cacheSize); - slopeStream = heightStream.slope(3).interpolate().bilinear(3, 3).cache2D(cacheSize); + slopeStream = heightStream.slope(3).cache2D(cacheSize); objectChanceStream = ProceduralStream.ofDouble((x, z) -> { - if(engine.getDimension().hasFeatures(engine)) - { + if (engine.getDimension().hasFeatures(engine)) { AtomicDouble str = new AtomicDouble(1D); engine.getFramework().getEngineParallax().forEachFeature(x, z, (i) -> str.set(Math.min(str.get(), i.getObjectChanceModifier(x, z)))); diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index cb66c1d98..f495cf5e7 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -25,9 +25,9 @@ import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisBiomePaletteLayer; import com.volmit.iris.engine.object.IrisDecorator; import com.volmit.iris.engine.object.IrisObjectPlacement; +import com.volmit.iris.engine.parallel.BurstExecutor; import com.volmit.iris.engine.parallel.MultiBurst; -import com.volmit.iris.util.format.C; -import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.PrecisionStopwatch; @@ -41,8 +41,6 @@ import org.bukkit.generator.BlockPopulator; import org.jetbrains.annotations.NotNull; import java.util.Random; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Future; public class IrisEngine extends BlockPopulator implements Engine { @Getter @@ -88,7 +86,7 @@ public class IrisEngine extends BlockPopulator implements Engine { private double maxBiomeDecoratorDensity; public IrisEngine(EngineTarget target, EngineCompound compound, int index) { - Iris.info("Initializing Engine: " + target.getWorld().getName() + "/" + target.getDimension().getLoadKey() + " (" + target.getHeight() + " height)"); + Iris.info("Initializing Engine: " + target.getWorld().name() + "/" + target.getDimension().getLoadKey() + " (" + target.getHeight() + " height)"); metrics = new EngineMetrics(32); this.target = target; this.framework = new IrisEngineFramework(this); @@ -136,6 +134,7 @@ public class IrisEngine extends BlockPopulator implements Engine { closed = true; getWorldManager().close(); getFramework().close(); + getTarget().close(); } @Override @@ -158,21 +157,39 @@ public class IrisEngine extends BlockPopulator implements Engine { return z / getDimension().getTerrainZoom(); } + @ChunkCoordinates @Override public void generate(int x, int z, Hunk vblocks, Hunk vbiomes) { try { PrecisionStopwatch p = PrecisionStopwatch.start(); + BurstExecutor b = burst().burst(16); + + // This is a very weird optimization, but it works + // Basically we precache multicore the biome stream which effectivley + // makes the biome stream, interpolation & noise engine run in parallel without mca + for(int i = 0; i < vblocks.getWidth(); i++) + { + int finalI = i; + b.queue(() -> { + for(int j = 0; j < vblocks.getDepth(); j++) + { + getFramework().getComplex().getTrueBiomeStream().get(x+ finalI,z+j); + } + }); + } + + b.complete(); switch (getDimension().getTerrainMode()) { case NORMAL -> { getFramework().getEngineParallax().generateParallaxArea(x >> 4, z >> 4); - getFramework().getBiomeActuator().actuate(x, z, vbiomes); getFramework().getTerrainActuator().actuate(x, z, vblocks); + getFramework().getBiomeActuator().actuate(x, z, vbiomes); getFramework().getCaveModifier().modify(x, z, vblocks); getFramework().getRavineModifier().modify(x, z, vblocks); getFramework().getPostModifier().modify(x, z, vblocks); getFramework().getDecorantActuator().actuate(x, z, vblocks); - getFramework().getEngineParallax().insertParallax(x, z, vblocks); + getFramework().getEngineParallax().insertParallax(x >> 4, z >> 4, vblocks); getFramework().getDepositModifier().modify(x, z, vblocks); } case ISLANDS -> { @@ -195,6 +212,11 @@ public class IrisEngine extends BlockPopulator implements Engine { return getData().getBiomeLoader().load(getDimension().getFocus()); } + @Override + public void hotloading() { + close(); + } + @Override public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk c) { getWorldManager().spawnInitialEntities(c); diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineCompound.java b/src/main/java/com/volmit/iris/engine/IrisEngineCompound.java index 2ba9b78ca..4d562646a 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngineCompound.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngineCompound.java @@ -20,6 +20,7 @@ package com.volmit.iris.engine; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisDataManager; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.EngineCompound; import com.volmit.iris.engine.framework.EngineData; @@ -28,6 +29,7 @@ import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.engine.object.IrisDimensionIndex; import com.volmit.iris.engine.object.IrisPosition; +import com.volmit.iris.engine.object.common.IrisWorld; import com.volmit.iris.engine.parallel.MultiBurst; import com.volmit.iris.util.atomics.AtomicRollingSequence; import com.volmit.iris.util.collection.KList; @@ -37,7 +39,6 @@ import com.volmit.iris.util.format.Form; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import lombok.Getter; import lombok.Setter; -import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; import org.bukkit.command.CommandSender; @@ -50,7 +51,7 @@ import java.util.List; public class IrisEngineCompound implements EngineCompound { @Getter - private World world; + private IrisWorld world; private final AtomicRollingSequence wallClock; @@ -77,10 +78,10 @@ public class IrisEngineCompound implements EngineCompound { @Setter private boolean studio; - public IrisEngineCompound(World world, IrisDimension rootDimension, IrisDataManager data, int maximumThreads) { + public IrisEngineCompound(IrisWorld world, IrisDimension rootDimension, IrisDataManager data, int maximumThreads) { wallClock = new AtomicRollingSequence(32); this.rootDimension = rootDimension; - Iris.info("Initializing Engine Composite for " + world.getName()); + Iris.info("Initializing Engine Composite for " + world.name()); this.world = world; engineMetadata = EngineData.load(getEngineMetadataFile()); engineMetadata.setDimension(rootDimension.getLoadKey()); @@ -97,7 +98,7 @@ public class IrisEngineCompound implements EngineCompound { } else { double totalWeight = 0D; engines = new Engine[rootDimension.getDimensionalComposite().size()]; - burster = engines.length > 1 ? new MultiBurst(engines.length) : null; + burster = engines.length > 1 ? new MultiBurst("Iris Compound " + rootDimension.getName(), IrisSettings.get().getConcurrency().getEngineThreadPriority(), engines.length) : null; int threadDist = (Math.max(2, maximumThreads - engines.length)) / engines.length; if ((threadDist * engines.length) + engines.length > maximumThreads) { @@ -208,7 +209,7 @@ public class IrisEngineCompound implements EngineCompound { } private File getEngineMetadataFile() { - return new File(world.getWorldFolder(), "iris/engine-metadata.json"); + return new File(world.worldFolder(), "iris/engine-metadata.json"); } @Override @@ -274,11 +275,6 @@ public class IrisEngineCompound implements EngineCompound { return defaultEngine; } - @Override - public void updateWorld(World world) { - this.world = world; - } - @Override public void hotload() { for (int i = 0; i < getSize(); i++) { diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java index 5e9a9dd89..4d93858ed 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java @@ -27,6 +27,7 @@ import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.hunk.view.BiomeGridHunkView; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisBiomeCustom; +import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import org.bukkit.block.Biome; @@ -37,9 +38,10 @@ public class IrisBiomeActuator extends EngineAssignedActuator { public IrisBiomeActuator(Engine engine) { super(engine, "Biome"); - rng = new RNG(engine.getWorld().getSeed() + 243995); + rng = new RNG(engine.getWorld().seed() + 243995); } + @BlockCoordinates private boolean injectBiome(Hunk h, int x, int y, int z, Object bb) { try { if (h instanceof BiomeGridHunkView hh) { @@ -59,6 +61,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator { return false; } + @BlockCoordinates @Override public void onActuate(int x, int z, Hunk h) { PrecisionStopwatch p = PrecisionStopwatch.start(); diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java index 7ddde6c93..51aaefb61 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java @@ -24,6 +24,7 @@ import com.volmit.iris.engine.framework.EngineAssignedActuator; import com.volmit.iris.engine.framework.EngineDecorator; import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.IrisBiome; +import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import lombok.Getter; @@ -50,7 +51,7 @@ public class IrisDecorantActuator extends EngineAssignedActuator { public IrisDecorantActuator(Engine engine) { super(engine, "Decorant"); shouldRay = shouldRayDecorate(); - this.rng = new RNG(engine.getTarget().getWorld().getSeed()); + this.rng = new RNG(engine.getTarget().getWorld().seed()); surfaceDecorator = new IrisSurfaceDecorator(getEngine()); ceilingDecorator = new IrisCeilingDecorator(getEngine()); seaSurfaceDecorator = new IrisSeaSurfaceDecorator(getEngine()); @@ -58,6 +59,7 @@ public class IrisDecorantActuator extends EngineAssignedActuator { seaFloorDecorator = new IrisSeaFloorDecorator(getEngine()); } + @BlockCoordinates @Override public void onActuate(int x, int z, Hunk output) { if (!getEngine().getDimension().isDecorate()) { diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java index ee92ad37c..434a49dee 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java @@ -23,6 +23,7 @@ import com.volmit.iris.engine.framework.EngineAssignedActuator; import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import lombok.Getter; @@ -45,11 +46,12 @@ public class IrisTerrainIslandActuator extends EngineAssignedActuator public IrisTerrainIslandActuator(Engine engine) { super(engine, "TerrainIsland"); - rng = new RNG(engine.getWorld().getSeed()); + rng = new RNG(engine.getWorld().seed()); carving = getDimension().isCarving() && getDimension().getCarveLayers().isNotEmpty(); hasUnder = getDimension().getUndercarriage() != null && !getDimension().getUndercarriage().getGenerator().isFlat(); } + @BlockCoordinates @Override public void onActuate(int x, int z, Hunk h) { PrecisionStopwatch p = PrecisionStopwatch.start(); diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java index b06397c27..8530b4402 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java @@ -23,6 +23,7 @@ import com.volmit.iris.engine.framework.EngineAssignedActuator; import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import lombok.Getter; @@ -42,11 +43,12 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator public IrisTerrainNormalActuator(Engine engine) { super(engine, "Terrain"); - rng = new RNG(engine.getWorld().getSeed()); + rng = new RNG(engine.getWorld().seed()); carving = getDimension().isCarving() && getDimension().getCarveLayers().isNotEmpty(); hasUnder = getDimension().getUndercarriage() != null && !getDimension().getUndercarriage().getGenerator().isFlat(); } + @BlockCoordinates @Override public void onActuate(int x, int z, Hunk h) { PrecisionStopwatch p = PrecisionStopwatch.start(); diff --git a/src/main/java/com/volmit/iris/engine/data/B.java b/src/main/java/com/volmit/iris/engine/data/B.java index 14bddd451..b6d64d1a2 100644 --- a/src/main/java/com/volmit/iris/engine/data/B.java +++ b/src/main/java/com/volmit/iris/engine/data/B.java @@ -25,6 +25,7 @@ import com.volmit.iris.util.collection.KSet; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.type.Leaves; public class B { private static final Material AIR_MATERIAL = Material.AIR; @@ -103,7 +104,6 @@ public class B { public static BlockData getOrNull(String bdxf) { try { String bd = bdxf.trim(); - BlockData bdx = parseBlockData(bd); if (bdx == null) { @@ -143,6 +143,12 @@ public class B { } BlockData bx = Bukkit.createBlockData(ix); + + if(bx instanceof Leaves) + { + ((Leaves) bx).setPersistent(true); + } + blockDataCache.put(ix, bx); return bx; } catch (Throwable e) { @@ -151,6 +157,7 @@ public class B { } String i = ix.toUpperCase().trim(); + i = i.equals("GRASS_PATH") ? "DIRT_PATH" : i; i = i.equals("WOOL") ? "WHITE_WOOL" : i; i = i.equals("CONCRETE") ? "WHITE_CONCRETE" : i; diff --git a/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java b/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java index 92ca2792e..b1e0af0e0 100644 --- a/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java +++ b/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java @@ -18,13 +18,12 @@ package com.volmit.iris.engine.data.chunk; -import com.volmit.iris.Iris; import com.volmit.iris.core.nms.BiomeBaseInjector; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.util.data.IrisBiomeStorage; -import com.volmit.iris.util.fakenews.HeightedFakeWorld; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; import org.bukkit.generator.ChunkGenerator.BiomeGrid; @@ -38,8 +37,12 @@ public class LinkedTerrainChunk implements TerrainChunk { private ChunkData rawChunkData; private final BiomeGrid storage; - public LinkedTerrainChunk(int maxHeight) { - this(null, maxHeight); + public LinkedTerrainChunk(World world) { + this(null, Bukkit.createChunkData(world)); + } + + public LinkedTerrainChunk(World world, BiomeGrid storage) { + this(storage, Bukkit.createChunkData(world)); } public LinkedTerrainChunk(BiomeGrid storage, ChunkData data) { @@ -48,23 +51,6 @@ public class LinkedTerrainChunk implements TerrainChunk { biome3D = storage != null ? null : new IrisBiomeStorage(); } - public LinkedTerrainChunk(BiomeGrid storage, int maxHeight) { - this.storage = storage; - rawChunkData = createChunkData(maxHeight); - biome3D = storage != null ? null : new IrisBiomeStorage(); - } - - private ChunkData createChunkData(int maxHeight) { - try { - return Bukkit.createChunkData(new HeightedFakeWorld(maxHeight)); - } catch (Throwable e) { - Iris.reportError(e); - e.printStackTrace(); - } - - return null; - } - @Override public BiomeBaseInjector getBiomeBaseInjector() { return (x, y, z, bb) -> INMS.get().forceBiomeInto(x, y, z, bb, storage); diff --git a/src/main/java/com/volmit/iris/engine/data/chunk/TerrainChunk.java b/src/main/java/com/volmit/iris/engine/data/chunk/TerrainChunk.java index 785962413..078a39bef 100644 --- a/src/main/java/com/volmit/iris/engine/data/chunk/TerrainChunk.java +++ b/src/main/java/com/volmit/iris/engine/data/chunk/TerrainChunk.java @@ -28,25 +28,17 @@ import org.jetbrains.annotations.NotNull; public interface TerrainChunk extends BiomeGrid, ChunkData { static TerrainChunk create(World world) { - return create(world.getMaxHeight()); - } - - static TerrainChunk create(int maxHeight) { - return new LinkedTerrainChunk(maxHeight); + return new LinkedTerrainChunk(world); } static TerrainChunk create(World world, BiomeGrid grid) { - return create(world.getMaxHeight(), grid); + return new LinkedTerrainChunk(world, grid); } static TerrainChunk create(ChunkData raw, BiomeGrid grid) { return new LinkedTerrainChunk(grid, raw); } - static TerrainChunk create(int maxHeight, BiomeGrid grid) { - return new LinkedTerrainChunk(grid, maxHeight); - } - BiomeBaseInjector getBiomeBaseInjector(); void setRaw(ChunkData data); diff --git a/src/main/java/com/volmit/iris/engine/data/mca/MCAFile.java b/src/main/java/com/volmit/iris/engine/data/mca/MCAFile.java index 86b04fe1b..7e9f4df13 100644 --- a/src/main/java/com/volmit/iris/engine/data/mca/MCAFile.java +++ b/src/main/java/com/volmit/iris/engine/data/mca/MCAFile.java @@ -19,6 +19,8 @@ package com.volmit.iris.engine.data.mca; import com.volmit.iris.engine.data.nbt.tag.CompoundTag; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.math.Position2; import java.io.IOException; import java.io.RandomAccessFile; @@ -88,6 +90,27 @@ public class MCAFile { } } + public KList samplePositions(RandomAccessFile raf) throws IOException { + KList p2 = new KList<>(); + chunks = new AtomicReferenceArray<>(1024); + int x = 0; + int z = 0; + for (int i = 0; i < 1024; i++) { + x++; + z++; + + raf.seek(i * 4); + int offset = raf.read() << 16; + offset |= (raf.read() & 0xFF) << 8; + offset |= raf.read() & 0xFF; + if (raf.readByte() == 0) { + continue; + } + p2.add(new Position2(x & 31, (z / 32) & 31)); + } + return p2; + } + public AtomicReferenceArray getChunks() { return chunks; } @@ -218,8 +241,7 @@ public class MCAFile { return getChunk(getChunkIndex(chunkX, chunkZ)); } - public boolean hasChunk(int chunkX, int chunkZ) - { + public boolean hasChunk(int chunkX, int chunkZ) { return getChunk(chunkX, chunkZ) != null; } diff --git a/src/main/java/com/volmit/iris/engine/data/mca/MCAUtil.java b/src/main/java/com/volmit/iris/engine/data/mca/MCAUtil.java index e438cae10..68a23e4b8 100644 --- a/src/main/java/com/volmit/iris/engine/data/mca/MCAUtil.java +++ b/src/main/java/com/volmit/iris/engine/data/mca/MCAUtil.java @@ -18,6 +18,9 @@ package com.volmit.iris.engine.data.mca; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.math.Position2; + import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; @@ -83,6 +86,13 @@ public final class MCAUtil { } } + public static KList sampleChunkPositions(File file) throws IOException { + MCAFile mcaFile = newMCAFile(file); + try (RandomAccessFile raf = new RandomAccessFile(file, "r")) { + return mcaFile.samplePositions(raf); + } + } + /** * Calls {@link MCAUtil#write(MCAFile, File, boolean)} without changing the timestamps. * diff --git a/src/main/java/com/volmit/iris/engine/data/mca/NBTWorld.java b/src/main/java/com/volmit/iris/engine/data/mca/NBTWorld.java index 2f910e469..7b1206844 100644 --- a/src/main/java/com/volmit/iris/engine/data/mca/NBTWorld.java +++ b/src/main/java/com/volmit/iris/engine/data/mca/NBTWorld.java @@ -24,21 +24,20 @@ import com.volmit.iris.engine.cache.Cache; import com.volmit.iris.engine.data.B; import com.volmit.iris.engine.data.nbt.tag.CompoundTag; import com.volmit.iris.engine.data.nbt.tag.StringTag; -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.math.M; import com.volmit.iris.util.scheduling.IrisLock; import org.bukkit.NamespacedKey; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; -import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; import java.util.Map; -import java.util.concurrent.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; public class NBTWorld { private static final BlockData AIR = B.get("AIR"); @@ -50,8 +49,7 @@ public class NBTWorld { private final File worldFolder; private final ExecutorService saveQueue; - public NBTWorld(File worldFolder) - { + public NBTWorld(File worldFolder) { this.worldFolder = worldFolder; this.loadedRegions = new KMap<>(); this.lastUse = new KMap<>(); @@ -63,20 +61,17 @@ public class NBTWorld { }); } - public void close() - { + public void close() { regionLock.lock(); - for(Long i : loadedRegions.k()) - { + for (Long i : loadedRegions.k()) { queueSaveUnload(Cache.keyX(i), Cache.keyZ(i)); } regionLock.unlock(); saveQueue.shutdown(); try { - while(!saveQueue.awaitTermination(3, TimeUnit.SECONDS)) - { + while (!saveQueue.awaitTermination(3, TimeUnit.SECONDS)) { Iris.info("Still Waiting to save MCA Files..."); } } catch (InterruptedException e) { @@ -84,37 +79,43 @@ public class NBTWorld { } } - public void queueSaveUnload(int x, int z) - { - saveQueue.submit(() -> { - MCAFile f = getMCAOrNull(x, z); - if(f != null) - { - unloadRegion(x, z); - } + public void flushNow() { + regionLock.lock(); - saveRegion(x, z, f); - }); + for (Long i : loadedRegions.k()) { + doSaveUnload(Cache.keyX(i), Cache.keyZ(i)); + } + + regionLock.unlock(); } - public void save() - { + public void queueSaveUnload(int x, int z) { + saveQueue.submit(() -> doSaveUnload(x, z)); + } + + public void doSaveUnload(int x, int z) { + MCAFile f = getMCAOrNull(x, z); + if (f != null) { + unloadRegion(x, z); + } + + saveRegion(x, z, f); + } + + public void save() { regionLock.lock(); boolean saving = true; - for(Long i : loadedRegions.k()) - { + for (Long i : loadedRegions.k()) { int x = Cache.keyX(i); int z = Cache.keyZ(i); - if(!lastUse.containsKey(i)) - { + if (!lastUse.containsKey(i)) { lastUse.put(i, M.ms()); } - if(shouldUnload(x, z)) - { + if (shouldUnload(x, z)) { queueSaveUnload(x, z); } } @@ -124,13 +125,11 @@ public class NBTWorld { regionLock.unlock(); } - public void queueSave() - { + public void queueSave() { } - public synchronized void unloadRegion(int x, int z) - { + public synchronized void unloadRegion(int x, int z) { long key = Cache.key(x, z); regionLock.lock(); loadedRegions.remove(key); @@ -139,8 +138,7 @@ public class NBTWorld { Iris.debug("Unloaded Region " + C.GOLD + x + " " + z); } - public void saveRegion(int x, int z) - { + public void saveRegion(int x, int z) { long k = Cache.key(x, z); MCAFile mca = getMCAOrNull(x, z); try { @@ -152,8 +150,7 @@ public class NBTWorld { } } - public void saveRegion(int x, int z, MCAFile mca) - { + public void saveRegion(int x, int z, MCAFile mca) { try { MCAUtil.write(mca, getRegionFile(x, z), true); Iris.debug("Saved Region " + C.GOLD + x + " " + z); @@ -163,8 +160,7 @@ public class NBTWorld { } } - public boolean shouldUnload(int x, int z) - { + public boolean shouldUnload(int x, int z) { return getIdleDuration(x, z) > 60000; } @@ -281,8 +277,7 @@ public class NBTWorld { return c; } - public long getIdleDuration(int x, int z) - { + public long getIdleDuration(int x, int z) { Long l = lastUse.get(Cache.key(x, z)); return l == null ? 0 : (M.ms() - l); @@ -296,17 +291,8 @@ public class NBTWorld { MCAFile mcaf = loadedRegions.get(key); regionLock.unlock(); - if(mcaf == null) - { - File f = getRegionFile(x, z); - try { - mcaf = f.exists() ? MCAUtil.read(f) : new MCAFile(x, z); - } catch (IOException e) { - Iris.error("Failed to properly read MCA File " + f.getPath() + " Using a blank one."); - e.printStackTrace(); - mcaf = new MCAFile(x, z); - } - + if (mcaf == null) { + mcaf = new MCAFile(x, z); regionLock.lock(); loadedRegions.put(key, mcaf); regionLock.unlock(); @@ -320,8 +306,7 @@ public class NBTWorld { MCAFile ff = null; regionLock.lock(); - if(loadedRegions.containsKey(key)) - { + if (loadedRegions.containsKey(key)) { lastUse.put(key, M.ms()); ff = loadedRegions.get(key); } diff --git a/src/main/java/com/volmit/iris/engine/decorator/IrisCeilingDecorator.java b/src/main/java/com/volmit/iris/engine/decorator/IrisCeilingDecorator.java index 1d7b762a9..0c6703d8b 100644 --- a/src/main/java/com/volmit/iris/engine/decorator/IrisCeilingDecorator.java +++ b/src/main/java/com/volmit/iris/engine/decorator/IrisCeilingDecorator.java @@ -24,6 +24,7 @@ import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.DecorationPart; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisDecorator; +import com.volmit.iris.util.documentation.BlockCoordinates; import org.bukkit.block.data.BlockData; public class IrisCeilingDecorator extends IrisEngineDecorator { @@ -31,6 +32,7 @@ public class IrisCeilingDecorator extends IrisEngineDecorator { super(engine, "Ceiling", DecorationPart.CEILING); } + @BlockCoordinates @Override public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk data, IrisBiome biome, int height, int max) { IrisDecorator decorator = getDecorator(biome, realX, realZ); diff --git a/src/main/java/com/volmit/iris/engine/decorator/IrisSeaFloorDecorator.java b/src/main/java/com/volmit/iris/engine/decorator/IrisSeaFloorDecorator.java index cd0d09c24..5caa572d0 100644 --- a/src/main/java/com/volmit/iris/engine/decorator/IrisSeaFloorDecorator.java +++ b/src/main/java/com/volmit/iris/engine/decorator/IrisSeaFloorDecorator.java @@ -24,6 +24,7 @@ import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.DecorationPart; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisDecorator; +import com.volmit.iris.util.documentation.BlockCoordinates; import org.bukkit.block.data.BlockData; public class IrisSeaFloorDecorator extends IrisEngineDecorator { @@ -31,6 +32,7 @@ public class IrisSeaFloorDecorator extends IrisEngineDecorator { super(engine, "Sea Floor", DecorationPart.SEA_FLOOR); } + @BlockCoordinates @Override public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk data, IrisBiome biome, int height, int max) { if (height <= getDimension().getFluidHeight()) { diff --git a/src/main/java/com/volmit/iris/engine/decorator/IrisSeaSurfaceDecorator.java b/src/main/java/com/volmit/iris/engine/decorator/IrisSeaSurfaceDecorator.java index 950f69d66..6c19c5825 100644 --- a/src/main/java/com/volmit/iris/engine/decorator/IrisSeaSurfaceDecorator.java +++ b/src/main/java/com/volmit/iris/engine/decorator/IrisSeaSurfaceDecorator.java @@ -24,6 +24,7 @@ import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.DecorationPart; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisDecorator; +import com.volmit.iris.util.documentation.BlockCoordinates; import org.bukkit.block.data.BlockData; public class IrisSeaSurfaceDecorator extends IrisEngineDecorator { @@ -31,6 +32,7 @@ public class IrisSeaSurfaceDecorator extends IrisEngineDecorator { super(engine, "Sea Surface", DecorationPart.SEA_SURFACE); } + @BlockCoordinates @Override public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk data, IrisBiome biome, int height, int max) { IrisDecorator decorator = getDecorator(biome, realX, realZ); diff --git a/src/main/java/com/volmit/iris/engine/decorator/IrisShoreLineDecorator.java b/src/main/java/com/volmit/iris/engine/decorator/IrisShoreLineDecorator.java index 0b7f4cccf..7cd34c40a 100644 --- a/src/main/java/com/volmit/iris/engine/decorator/IrisShoreLineDecorator.java +++ b/src/main/java/com/volmit/iris/engine/decorator/IrisShoreLineDecorator.java @@ -24,6 +24,7 @@ import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.DecorationPart; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisDecorator; +import com.volmit.iris.util.documentation.BlockCoordinates; import org.bukkit.block.data.BlockData; public class IrisShoreLineDecorator extends IrisEngineDecorator { @@ -31,6 +32,7 @@ public class IrisShoreLineDecorator extends IrisEngineDecorator { super(engine, "Shore Line", DecorationPart.SHORE_LINE); } + @BlockCoordinates @Override public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk data, IrisBiome biome, int height, int max) { diff --git a/src/main/java/com/volmit/iris/engine/decorator/IrisSurfaceDecorator.java b/src/main/java/com/volmit/iris/engine/decorator/IrisSurfaceDecorator.java index 84675c40a..caff5114e 100644 --- a/src/main/java/com/volmit/iris/engine/decorator/IrisSurfaceDecorator.java +++ b/src/main/java/com/volmit/iris/engine/decorator/IrisSurfaceDecorator.java @@ -26,6 +26,7 @@ import com.volmit.iris.engine.object.DecorationPart; import com.volmit.iris.engine.object.InferredType; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisDecorator; +import com.volmit.iris.util.documentation.BlockCoordinates; import org.bukkit.block.data.Bisected; import org.bukkit.block.data.BlockData; @@ -34,6 +35,7 @@ public class IrisSurfaceDecorator extends IrisEngineDecorator { super(engine, "Surface", DecorationPart.NONE); } + @BlockCoordinates @Override public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk data, IrisBiome biome, int height, int max) { if (biome.getInferredType().equals(InferredType.SHORE) && height < getDimension().getFluidHeight()) { diff --git a/src/main/java/com/volmit/iris/engine/framework/Engine.java b/src/main/java/com/volmit/iris/engine/framework/Engine.java index d2ad0638a..6f3a00435 100644 --- a/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -20,13 +20,14 @@ package com.volmit.iris.engine.framework; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisDataManager; -import com.volmit.iris.core.gui.RenderType; -import com.volmit.iris.core.gui.Renderer; +import com.volmit.iris.core.gui.components.RenderType; +import com.volmit.iris.core.gui.components.Renderer; import com.volmit.iris.engine.cache.Cache; import com.volmit.iris.engine.data.B; import com.volmit.iris.engine.data.DataProvider; import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.*; +import com.volmit.iris.engine.object.common.IrisWorld; import com.volmit.iris.engine.parallax.ParallaxAccess; import com.volmit.iris.engine.parallel.MultiBurst; import com.volmit.iris.util.collection.KList; @@ -37,7 +38,6 @@ import com.volmit.iris.util.scheduling.PrecisionStopwatch; import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; @@ -105,7 +105,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro return getTarget().getData(); } - default World getWorld() { + default IrisWorld getWorld() { return getTarget().getWorld(); } @@ -357,8 +357,12 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro return getCompound().isStudio(); } + default MultiBurst burst() { + return getTarget().getBurster(); + } + default void clean() { - MultiBurst.burst.lazy(() -> getParallax().cleanup()); + burst().lazy(() -> getParallax().cleanup()); } default IrisBiome getBiome(Location l) { @@ -374,4 +378,6 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro } IrisBiome getFocus(); + + void hotloading(); } diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineActuator.java b/src/main/java/com/volmit/iris/engine/framework/EngineActuator.java index 242f151b9..c249e4548 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineActuator.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineActuator.java @@ -19,7 +19,9 @@ package com.volmit.iris.engine.framework; import com.volmit.iris.engine.hunk.Hunk; +import com.volmit.iris.util.documentation.BlockCoordinates; public interface EngineActuator extends EngineComponent { + @BlockCoordinates void actuate(int x, int z, Hunk output); } diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java index 9496ea1c6..118e98eec 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java @@ -19,6 +19,7 @@ package com.volmit.iris.engine.framework; import com.volmit.iris.engine.hunk.Hunk; +import com.volmit.iris.util.documentation.BlockCoordinates; public abstract class EngineAssignedActuator extends EngineAssignedComponent implements EngineActuator { public EngineAssignedActuator(Engine engine, String name) { @@ -27,6 +28,7 @@ public abstract class EngineAssignedActuator extends EngineAssignedComponent public abstract void onActuate(int x, int z, Hunk output); + @BlockCoordinates @Override public void actuate(int x, int z, Hunk output) { onActuate(x, z, output); diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java b/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java index f62641efc..440525632 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java @@ -69,7 +69,7 @@ public interface EngineComponent { } default long getSeed() { - return getTarget().getWorld().getSeed(); + return getTarget().getWorld().seed(); } default EngineFramework getFramework() { diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java b/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java index 0039e714a..677000a5b 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java @@ -23,21 +23,22 @@ import com.volmit.iris.core.IrisDataManager; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.nms.BiomeBaseInjector; import com.volmit.iris.core.nms.INMS; +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.engine.IrisEngineCompound; -import com.volmit.iris.engine.IrisWorlds; -import com.volmit.iris.engine.cache.Cache; import com.volmit.iris.engine.data.B; import com.volmit.iris.engine.data.chunk.TerrainChunk; import com.volmit.iris.engine.data.mca.NBTWorld; +import com.volmit.iris.engine.headless.HeadlessGenerator; import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.engine.object.IrisPosition; +import com.volmit.iris.engine.object.common.IrisWorld; import com.volmit.iris.engine.parallel.BurstExecutor; import com.volmit.iris.engine.parallel.MultiBurst; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.fakenews.FakeWorld; import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.io.ReactiveFolder; @@ -48,7 +49,6 @@ import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import io.netty.util.internal.ConcurrentSet; -import io.papermc.lib.PaperLib; import lombok.Getter; import org.bukkit.*; import org.bukkit.block.Biome; @@ -77,11 +77,11 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce private final boolean production; private final KList populators; private long mst = 0; + private HeadlessGenerator headlessGenerator; + private NBTWorld nbtWorld; private int generated = 0; private int lgenerated = 0; - private final KMap chunkCache; private final ChronoLatch hotloadcd; - private final AtomicBoolean fake; @Getter private double generatedPerSecond = 0; private final int art; @@ -93,8 +93,6 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce public EngineCompositeGenerator(String query, boolean production) { super(); - chunkCache = new KMap<>(); - fake = new AtomicBoolean(true); hotloadcd = new ChronoLatch(3500); mst = M.ms(); this.production = production; @@ -113,6 +111,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce }); } + @Override public void hotload() { if (isStudio()) { Iris.proj.updateWorkspace(); @@ -128,12 +127,14 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce } }); + + getComposite().close(); initialized.lazySet(false); } } public void tick() { - if (isClosed()) { + if (getComposite() == null || isClosed()) { return; } @@ -158,14 +159,14 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce } } - private synchronized IrisDimension getDimension(World world) { + private synchronized IrisDimension getDimension(IrisWorld world) { String query = dimensionQuery; - query = Iris.linkMultiverseCore.getWorldNameType(world.getName(), query); + query = Iris.linkMultiverseCore.getWorldNameType(world.name(), query); IrisDimension dim = null; if (query == null) { - File iris = new File(world.getWorldFolder(), "iris"); + File iris = new File(world.worldFolder(), "iris"); if (iris.exists() && iris.isDirectory()) { for (File i : iris.listFiles()) { @@ -191,7 +192,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce } if (query == null) { - Iris.error("Cannot find iris dimension data for world: " + world.getName() + "! Assuming " + IrisSettings.get().getGenerator().getDefaultWorldType() + "!"); + Iris.error("Cannot find iris dimension data for world: " + world.name() + "! Assuming " + IrisSettings.get().getGenerator().getDefaultWorldType() + "!"); query = IrisSettings.get().getGenerator().getDefaultWorldType(); } @@ -213,8 +214,8 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce dim = new IrisDataManager(getDataFolder(world)).getDimensionLoader().load(od.getLoadKey()); if (dim == null) { - Iris.info("Installing Iris pack " + od.getName() + " into world " + world.getName() + "..."); - Iris.proj.installIntoWorld(new VolmitSender(Bukkit.getConsoleSender(), Iris.instance.getTag()), od.getLoadKey(), world.getWorldFolder()); + Iris.info("Installing Iris pack " + od.getName() + " into world " + world.name() + "..."); + Iris.proj.installIntoWorld(new VolmitSender(Bukkit.getConsoleSender(), Iris.instance.getTag()), od.getLoadKey(), world.worldFolder()); dim = new IrisDataManager(getDataFolder(world)).getDimensionLoader().load(od.getLoadKey()); if (dim == null) { @@ -294,20 +295,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce return dim; } - public synchronized void initialize(World world) { - if (!(world instanceof FakeWorld) && fake.get() && this.compound.get() != null) { - fake.set(false); - this.compound.get().updateWorld(world); - getTarget().updateWorld(world); - placeStrongholds(world); - - for (int i = 0; i < getComposite().getSize(); i++) { - getComposite().getEngine(i).getTarget().updateWorld(world); - } - - Iris.info("Attached Real World to Engine Target"); - } - + public synchronized void initialize(IrisWorld world) { if (initialized.get()) { return; } @@ -316,12 +304,16 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce initialized.set(true); IrisDimension dim = getDimension(world); IrisDataManager data = production ? new IrisDataManager(getDataFolder(world)) : dim.getLoader().copy(); - compound.set(new IrisEngineCompound(world, dim, data, Iris.getThreadCount())); + compound.set(new IrisEngineCompound(world, dim, data, IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getEngineThreadCount()))); compound.get().setStudio(!production); populators.clear(); populators.addAll(compound.get().getPopulators()); hotloader = new ReactiveFolder(data.getDataFolder(), (a, c, d) -> hotload()); - dim.installDataPack(() -> data, Iris.instance.getDatapacksFolder()); + + if(isStudio()) + { + dim.installDataPack(() -> data, Iris.instance.getDatapacksFolder()); + } } catch (Throwable e) { Iris.reportError(e); e.printStackTrace(); @@ -445,8 +437,8 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce ); } - private File getDataFolder(World world) { - return new File(world.getWorldFolder(), "iris/pack"); + private File getDataFolder(IrisWorld world) { + return new File(world.worldFolder(), "iris/pack"); } private File getDataFolder(String world) { @@ -458,7 +450,13 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce public ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) { PrecisionStopwatch ps = PrecisionStopwatch.start(); TerrainChunk tc = TerrainChunk.create(world, biome); - generateChunkRawData(world, x, z, tc).run(); + IrisWorld ww = (getComposite() == null || getComposite().getWorld() == null) ? IrisWorld.fromWorld(world) : getComposite().getWorld(); + generateChunkRawData(ww, x, z, tc).run(); + + if (!getComposite().getWorld().hasRealWorld()) { + getComposite().getWorld().bind(world); + } + generated++; ps.end(); @@ -469,23 +467,48 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce return tc.getRaw(); } - public void directWriteMCA(World w, int x, int z, NBTWorld writer, MultiBurst burst) { - BurstExecutor e = burst.burst(1024); - int mcaox = x << 5; - int mcaoz = z << 5; + public void assignHeadlessGenerator(HeadlessGenerator headlessGenerator) { + this.headlessGenerator = headlessGenerator; + } - for (int i = 0; i < 32; i++) { - int ii = i; - for (int j = 0; j < 32; j++) { - int jj = j; - e.queue(() -> directWriteChunk(w, ii + mcaox, jj + mcaoz, writer)); + @Override + public HeadlessGenerator getHeadlessGenerator() { + return headlessGenerator; + } + + public void assignHeadlessNBTWriter(NBTWorld writer) { + this.nbtWorld = writer; + } + + @Override + public NBTWorld getHeadlessNBTWriter() { + return nbtWorld; + } + + @Override + public void directWriteMCA(IrisWorld w, int x, int z, NBTWorld writer, MultiBurst burst) { + directWriteMCA(w, x, z, writer, burst, null); + } + + @Override + public void directWriteMCA(IrisWorld w, int x, int z, NBTWorld writer, MultiBurst burst, PregenListener l) { + BurstExecutor e = burst.burst(1024); + + PregenTask.iterateRegion(x, z, (ii, jj) -> e.queue(() -> { + if (l != null) { + l.onChunkGenerating(ii, jj); } - } + directWriteChunk(w, ii, jj, writer); + if (l != null) { + l.onChunkGenerated(ii, jj); + } + })); e.complete(); } - public void directWriteChunk(World w, int x, int z, NBTWorld writer) { + @Override + public void directWriteChunk(IrisWorld w, int x, int z, NBTWorld writer) { int ox = x << 4; int oz = z << 4; com.volmit.iris.engine.data.mca.Chunk cc = writer.getChunk(x, z); @@ -526,12 +549,12 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce @Override public int getMinHeight() { - return w.getMinHeight(); + return w.minHeight(); } @Override public int getMaxHeight() { - return w.getMaxHeight(); + return w.maxHeight(); } @Override @@ -614,50 +637,8 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce }).run(); } - public Chunk generatePaper(World world, int x, int z) { - precache(world, x, z); - Chunk c = PaperLib.getChunkAtAsync(world, x, z, true).join(); - chunkCache.remove(Cache.key(x, z)); - return c; - } - - public void precache(World world, int x, int z) { - synchronized (this) { - initialize(world); - } - - synchronized (chunkCache) { - if (chunkCache.containsKey(Cache.key(x, z))) { - return; - } - } - - PregeneratedData data = new PregeneratedData(getComposite().getHeight() - 1); - compound.get().generate(x * 16, z * 16, data.getBlocks(), data.getPost(), data.getBiomes()); - synchronized (chunkCache) { - chunkCache.put(Cache.key(x, z), data); - } - } - - @Override - public int getPrecacheSize() { - return chunkCache.size(); - } - - public int getCachedChunks() { - return chunkCache.size(); - } - - public Runnable generateChunkRawData(World world, int x, int z, TerrainChunk tc) { + public Runnable generateChunkRawData(IrisWorld world, int x, int z, TerrainChunk tc) { initialize(world); - - synchronized (chunkCache) { - long g = Cache.key(x, z); - if (chunkCache.containsKey(g)) { - return chunkCache.remove(g).inject(tc); - } - } - Hunk blocks = Hunk.view((ChunkData) tc); Hunk biomes = Hunk.view((BiomeGrid) tc); Hunk post = Hunk.newAtomicHunk(biomes.getWidth(), biomes.getHeight(), biomes.getDepth()); @@ -783,146 +764,15 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce // TODO: DO IT } - @Override - public void clearRegeneratedLists(int x, int z) { - for (int i = 0; i < getComposite().getSize(); i++) { - getComposite().getEngine(i).getParallax().delete(x, z); - } - } - - @Override - public void regenerate(int x, int z) { - - clearRegeneratedLists(x, z); - int xx = x * 16; - int zz = z * 16; - BiomeBaseInjector inj = (a, b, c, d) -> { - }; - //noinspection deprecation - generateChunkRawData(getComposite().getWorld(), x, z, new TerrainChunk() { - @Override - public BiomeBaseInjector getBiomeBaseInjector() { - return inj; - } - - @Override - public void setRaw(ChunkData data) { - - } - - @NotNull - @Override - public Biome getBiome(int x, int z) { - return Biome.THE_VOID; - } - - @NotNull - @Override - public Biome getBiome(int x, int y, int z) { - return Biome.THE_VOID; - } - - @Override - public void setBiome(int x, int z, Biome bio) { - - } - - @Override - public void setBiome(int x, int y, int z, Biome bio) { - - } - - @Override - public int getMinHeight() { - return getComposite().getWorld().getMinHeight(); - } - - @Override - public int getMaxHeight() { - return getComposite().getWorld().getMaxHeight(); - } - - @Override - public void setBlock(int x, int y, int z, BlockData blockData) { - if (!getBlockData(x, y, z).matches(blockData)) { - Iris.edit.set(compound.get().getWorld(), x + xx, y, z + zz, blockData); - } - } - - @NotNull - @Override - public BlockData getBlockData(int x, int y, int z) { - return Iris.edit.get(compound.get().getWorld(), x + xx, y, z + zz); - } - - @Override - public ChunkData getRaw() { - return null; - } - - @Override - public void inject(BiomeGrid biome) { - - } - - @Override - public void setBlock(int i, int i1, int i2, @NotNull Material material) { - setBlock(i, i1, i2, material.createBlockData()); - } - - @Override - public void setBlock(int i, int i1, int i2, @NotNull MaterialData materialData) { - setBlock(i, i1, i2, materialData.getItemType()); - } - - @Override - public void setRegion(int i, int i1, int i2, int i3, int i4, int i5, @NotNull Material material) { - - } - - @Override - public void setRegion(int i, int i1, int i2, int i3, int i4, int i5, @NotNull MaterialData materialData) { - - } - - @Override - public void setRegion(int i, int i1, int i2, int i3, int i4, int i5, @NotNull BlockData blockData) { - - } - - @NotNull - @Override - public Material getType(int i, int i1, int i2) { - return getBlockData(i, i1, i2).getMaterial(); - } - - @NotNull - @Override - public MaterialData getTypeAndData(int i, int i1, int i2) { - return null; - } - - @Override - public byte getData(int i, int i1, int i2) { - return 0; - } - }); - - Iris.edit.flushNow(); - - } - - @Override public void close() { J.car(art); if (getComposite() != null) { getComposite().close(); - - if (isStudio()) { - IrisWorlds.evacuate(getComposite().getWorld()); - Bukkit.unloadWorld(getComposite().getWorld(), !isStudio()); + if (isStudio() && getComposite().getWorld().hasRealWorld()) { + getComposite().getWorld().evacuate(); + Bukkit.unloadWorld(getComposite().getWorld().realWorld(), !isStudio()); } } } diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java b/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java index cff9a2dd9..257e192ff 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java @@ -26,10 +26,10 @@ import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.engine.object.IrisPosition; +import com.volmit.iris.engine.object.common.IrisWorld; import com.volmit.iris.engine.parallel.MultiBurst; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; -import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; import org.bukkit.command.CommandSender; @@ -43,7 +43,7 @@ public interface EngineCompound extends Listener, Hotloadable, DataProvider { void generate(int x, int z, Hunk blocks, Hunk postblocks, Hunk biomes); - World getWorld(); + IrisWorld getWorld(); List getStrongholdPositions(); @@ -149,8 +149,6 @@ public interface EngineCompound extends Listener, Hotloadable, DataProvider { return v.v(); } - void updateWorld(World world); - default int getLowestBedrock() { int f = Integer.MAX_VALUE; diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineDecorator.java b/src/main/java/com/volmit/iris/engine/framework/EngineDecorator.java index 3affbaea5..feb489a1c 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineDecorator.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineDecorator.java @@ -21,11 +21,15 @@ package com.volmit.iris.engine.framework; import com.volmit.iris.engine.data.B; import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.IrisBiome; +import com.volmit.iris.util.documentation.BlockCoordinates; import org.bukkit.block.data.BlockData; public interface EngineDecorator extends EngineComponent { + + @BlockCoordinates void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk data, IrisBiome biome, int height, int max); + @BlockCoordinates default void decorate(int x, int z, int realX, int realZ, Hunk data, IrisBiome biome, int height, int max) { decorate(x, z, realX, realX, realX, realZ, realZ, realZ, data, biome, height, max); } diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineModifier.java b/src/main/java/com/volmit/iris/engine/framework/EngineModifier.java index 257f3f2ae..21642ae35 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineModifier.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineModifier.java @@ -19,7 +19,9 @@ package com.volmit.iris.engine.framework; import com.volmit.iris.engine.hunk.Hunk; +import com.volmit.iris.util.documentation.BlockCoordinates; public interface EngineModifier extends EngineComponent { + @BlockCoordinates void modify(int x, int z, Hunk t); } diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java b/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java index cea30dd0f..f9f8ef5f5 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineParallaxManager.java @@ -34,10 +34,10 @@ import com.volmit.iris.engine.object.tile.TileData; import com.volmit.iris.engine.parallax.ParallaxAccess; import com.volmit.iris.engine.parallax.ParallaxChunkMeta; import com.volmit.iris.engine.parallel.BurstExecutor; -import com.volmit.iris.engine.parallel.MultiBurst; 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.documentation.ChunkCoordinates; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.function.Consumer4; import com.volmit.iris.util.math.RNG; @@ -165,14 +165,19 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { }); } + @ChunkCoordinates default void insertParallax(int x, int z, Hunk data) { + if (!getEngine().getDimension().isPlaceObjects()) { + return; + } + try { PrecisionStopwatch p = PrecisionStopwatch.start(); - ParallaxChunkMeta meta = getParallaxAccess().getMetaR(x >> 4, z >> 4); + ParallaxChunkMeta meta = getParallaxAccess().getMetaR(x, z); if (!meta.isParallaxGenerated()) { generateParallaxLayer(x, z, true); - meta = getParallaxAccess().getMetaR(x >> 4, z >> 4); + meta = getParallaxAccess().getMetaR(x, z); } if (!meta.isObjects()) { @@ -180,7 +185,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { return; } - getParallaxAccess().getBlocksR(x >> 4, z >> 4).iterateSync((a, b, c, d) -> { + getParallaxAccess().getBlocksR(x, z).iterateSync((a, b, c, d) -> { if (d != null) { data.set(a, b, c, d); } @@ -199,8 +204,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { IrisLock getFeatureLock(); default void forEachFeature(double x, double z, Consumer f) { - if(!getEngine().getDimension().hasFeatures(getEngine())) - { + if (!getEngine().getDimension().hasFeatures(getEngine())) { return; } @@ -229,14 +233,18 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { for (j = -s; j <= s; j++) { ParallaxChunkMeta m = getParallaxAccess().getMetaR(i + cx, j + cz); - try { - for (IrisFeaturePositional k : m.getFeatures()) { - if (k.shouldFilter(x, z)) { - pos.add(k); + synchronized (m) { + try { + for (IrisFeaturePositional k : m.getFeatures()) { + if (k.shouldFilter(x, z)) { + pos.add(k); + } } + } catch (Throwable e) { + Iris.error("FILTER ERROR" + " AT " + (cx + i) + " " + (j + cz)); + e.printStackTrace(); + Iris.reportError(e); } - } catch (Throwable e) { - Iris.reportError(e); } } } @@ -261,7 +269,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { int i, j; KList after = new KList<>(); int bs = (int) Math.pow((s * 2) + 1, 2); - BurstExecutor burst = MultiBurst.burst.burst(bs); + BurstExecutor burst = getEngine().getTarget().getBurster().burst(bs); for (i = -s; i <= s; i++) { for (j = -s; j <= s; j++) { int xx = i + x; @@ -271,7 +279,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { if (!getParallaxAccess().isFeatureGenerated(xx, zz)) { burst.queue(() -> { getParallaxAccess().setFeatureGenerated(xx, zz); - RNG rng = new RNG(Cache.key(xx, zz)).nextParallelRNG(getEngine().getTarget().getWorld().getSeed()); + RNG rng = new RNG(Cache.key(xx, zz)).nextParallelRNG(getEngine().getTarget().getWorld().seed()); IrisRegion region = getComplex().getRegionStream().get(xxx, zzz); IrisBiome biome = getComplex().getTrueBiomeStream().get(xxx, zzz); generateParallaxFeatures(rng, xx, zz, region, biome); @@ -283,7 +291,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { burst.complete(); if (getEngine().getDimension().isPlaceObjects()) { - burst = MultiBurst.burst.burst(bs); + burst = getEngine().getTarget().getBurster().burst(bs); for (i = -s; i <= s; i++) { int ii = i; @@ -299,7 +307,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { } burst.complete(); - burst = MultiBurst.burst.burst(bs); + burst = getEngine().getTarget().getBurster().burst(bs); for (i = -s; i <= s; i++) { int ii = i; @@ -312,7 +320,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { burst.complete(); } - MultiBurst.burst.burst(after); + getEngine().getTarget().getBurster().burst(after); getParallaxAccess().setChunkGenerated(x, z); p.end(); getEngine().getMetrics().getParallax().put(p.getMilliseconds()); @@ -325,14 +333,14 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { default KList generateParallaxVacuumLayer(int x, int z) { KList after = new KList<>(); - if (getParallaxAccess().isParallaxGenerated(x, z)) { + if (getParallaxAccess().isParallaxGenerated(x >> 4, z >> 4)) { return after; } if (getEngine().getDimension().isPlaceObjects()) { int xx = x << 4; int zz = z << 4; - RNG rng = new RNG(Cache.key(x, z)).nextParallelRNG(getEngine().getTarget().getWorld().getSeed()); + RNG rng = new RNG(Cache.key(x, z)).nextParallelRNG(getEngine().getTarget().getWorld().seed()); IrisRegion region = getComplex().getRegionStream().get(xx + 8, zz + 8); IrisBiome biome = getComplex().getTrueBiomeStream().get(xx + 8, zz + 8); after.addAll(generateParallaxJigsaw(rng, x, z, biome, region)); @@ -351,7 +359,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { int xx = x << 4; int zz = z << 4; getParallaxAccess().setParallaxGenerated(x, z); - RNG rng = new RNG(Cache.key(x, z)).nextParallelRNG(getEngine().getTarget().getWorld().getSeed()); + RNG rng = new RNG(Cache.key(x, z)).nextParallelRNG(getEngine().getTarget().getWorld().seed()); IrisBiome biome = getComplex().getTrueBiomeStream().get(xx + 8, zz + 8); IrisRegion region = getComplex().getRegionStream().get(xx + 8, zz + 8); generateParallaxSurface(rng, x, z, biome, region, false); @@ -666,7 +674,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer { } Iris.verbose("Checking sizes for " + Form.f(objects.size()) + " referenced objects."); - BurstExecutor e = MultiBurst.burst.burst(objects.size()); + BurstExecutor e = getEngine().getTarget().getBurster().burst(objects.size()); KMap sizeCache = new KMap<>(); for (String i : objects) { e.queue(() -> { diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java b/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java index bdd833b0b..50c565c93 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java @@ -19,11 +19,12 @@ package com.volmit.iris.engine.framework; import com.volmit.iris.core.IrisDataManager; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.engine.object.IrisDimension; +import com.volmit.iris.engine.object.common.IrisWorld; import com.volmit.iris.engine.parallax.ParallaxWorld; import com.volmit.iris.engine.parallel.MultiBurst; import lombok.Data; -import org.bukkit.World; import java.io.File; @@ -31,27 +32,27 @@ import java.io.File; public class EngineTarget { private final MultiBurst burster; private final IrisDimension dimension; - private World world; + private IrisWorld world; private final int height; private final IrisDataManager data; private final ParallaxWorld parallaxWorld; private final boolean inverted; - public EngineTarget(World world, IrisDimension dimension, IrisDataManager data, int height, boolean inverted, int threads) { + public EngineTarget(IrisWorld world, IrisDimension dimension, IrisDataManager data, int height, boolean inverted, int threads) { this.world = world; this.height = height; this.dimension = dimension; this.data = data; - this.parallaxWorld = new ParallaxWorld(256, new File(world.getWorldFolder(), "iris/" + dimension.getLoadKey() + "/parallax")); this.inverted = inverted; - this.burster = new MultiBurst(threads); + this.burster = new MultiBurst("Iris Engine " + dimension.getName(), IrisSettings.get().getConcurrency().getEngineThreadPriority(), threads); + this.parallaxWorld = new ParallaxWorld(burster, 256, new File(world.worldFolder(), "iris/" + dimension.getLoadKey() + "/parallax")); } - public void updateWorld(World world) { - this.world = world; - } - - public EngineTarget(World world, IrisDimension dimension, IrisDataManager data, int height, int threads) { + public EngineTarget(IrisWorld world, IrisDimension dimension, IrisDataManager data, int height, int threads) { this(world, dimension, data, height, false, threads); } + + public void close() { + burster.shutdownAndAwait(); + } } diff --git a/src/main/java/com/volmit/iris/engine/framework/GeneratorAccess.java b/src/main/java/com/volmit/iris/engine/framework/GeneratorAccess.java index 2b455093d..a824fe71e 100644 --- a/src/main/java/com/volmit/iris/engine/framework/GeneratorAccess.java +++ b/src/main/java/com/volmit/iris/engine/framework/GeneratorAccess.java @@ -19,7 +19,7 @@ package com.volmit.iris.engine.framework; import com.volmit.iris.core.IrisDataManager; -import com.volmit.iris.core.gui.Renderer; +import com.volmit.iris.core.gui.components.Renderer; import com.volmit.iris.engine.data.DataProvider; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisObjectPlacement; diff --git a/src/main/java/com/volmit/iris/engine/framework/IrisAccess.java b/src/main/java/com/volmit/iris/engine/framework/IrisAccess.java index ebc927194..e064ddc78 100644 --- a/src/main/java/com/volmit/iris/engine/framework/IrisAccess.java +++ b/src/main/java/com/volmit/iris/engine/framework/IrisAccess.java @@ -20,20 +20,21 @@ package com.volmit.iris.engine.framework; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisDataManager; +import com.volmit.iris.core.pregenerator.PregenListener; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.data.DataProvider; import com.volmit.iris.engine.data.mca.NBTWorld; +import com.volmit.iris.engine.headless.HeadlessGenerator; import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisRegion; +import com.volmit.iris.engine.object.common.IrisWorld; import com.volmit.iris.engine.parallel.MultiBurst; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.J; -import org.bukkit.Chunk; import org.bukkit.Location; -import org.bukkit.World; import org.bukkit.command.CommandSender; import java.util.concurrent.atomic.AtomicBoolean; @@ -44,9 +45,19 @@ import java.util.function.Consumer; @SuppressWarnings("EmptyMethod") public interface IrisAccess extends Hotloadable, DataProvider { - void directWriteMCA(World w, int x, int z, NBTWorld writer, MultiBurst burst); + HeadlessGenerator getHeadlessGenerator(); - void directWriteChunk(World w, int x, int z, NBTWorld writer); + default boolean isHeadless() { + return getHeadlessGenerator() != null; + } + + NBTWorld getHeadlessNBTWriter(); + + void directWriteMCA(IrisWorld w, int x, int z, NBTWorld writer, MultiBurst burst); + + void directWriteMCA(IrisWorld w, int x, int z, NBTWorld writer, MultiBurst burst, PregenListener listener); + + void directWriteChunk(IrisWorld w, int x, int z, NBTWorld writer); int getGenerated(); @@ -72,8 +83,6 @@ public interface IrisAccess extends Hotloadable, DataProvider { void changeThreadCount(int m); - void regenerate(int x, int z); - void close(); boolean isClosed(); @@ -87,6 +96,11 @@ public interface IrisAccess extends Hotloadable, DataProvider { boolean isStudio(); default Location lookForBiome(IrisBiome biome, long timeout, Consumer triesc) { + if (!getCompound().getWorld().hasRealWorld()) { + Iris.error("Cannot GOTO without a bound world (headless mode)"); + return null; + } + IrisComplex.cacheLock.set(true); ChronoLatch cl = new ChronoLatch(250, false); long s = M.ms(); @@ -130,7 +144,7 @@ public interface IrisAccess extends Hotloadable, DataProvider { if (b != null && b.getLoadKey().equals(biome.getLoadKey())) { found.lazySet(true); - location.lazySet(new Location(e.getWorld(), x, e.getHeight(x, z), z)); + location.lazySet(new Location(e.getWorld().realWorld(), x, e.getHeight(x, z), z)); } tries.getAndIncrement(); @@ -167,6 +181,11 @@ public interface IrisAccess extends Hotloadable, DataProvider { } default Location lookForRegion(IrisRegion reg, long timeout, Consumer triesc) { + if (!getCompound().getWorld().hasRealWorld()) { + Iris.error("Cannot GOTO without a bound world (headless mode)"); + return null; + } + IrisComplex.cacheLock.set(true); ChronoLatch cl = new ChronoLatch(3000, false); long s = M.ms(); @@ -204,7 +223,7 @@ public interface IrisAccess extends Hotloadable, DataProvider { if (b != null && b.getLoadKey() != null && b.getLoadKey().equals(reg.getLoadKey())) { found.lazySet(true); - location.lazySet(new Location(e.getWorld(), x, e.getHeight(x, z) + e.getMinHeight(), z)); + location.lazySet(new Location(e.getWorld().realWorld(), x, e.getHeight(x, z) + e.getMinHeight(), z)); } tries.getAndIncrement(); @@ -238,14 +257,6 @@ public interface IrisAccess extends Hotloadable, DataProvider { return location.get(); } - void clearRegeneratedLists(int x, int z); - - void precache(World world, int x, int z); - - int getPrecacheSize(); - - Chunk generatePaper(World world, int cx, int cz); - default int getParallaxChunkCount() { int v = 0; diff --git a/src/main/java/com/volmit/iris/engine/headless/HeadlessGenerator.java b/src/main/java/com/volmit/iris/engine/headless/HeadlessGenerator.java new file mode 100644 index 000000000..9191fdaa4 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/headless/HeadlessGenerator.java @@ -0,0 +1,93 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.headless; + +import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.pregenerator.PregenListener; +import com.volmit.iris.engine.data.mca.MCAUtil; +import com.volmit.iris.engine.data.mca.NBTWorld; +import com.volmit.iris.engine.framework.EngineCompositeGenerator; +import com.volmit.iris.engine.parallel.MultiBurst; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.math.Position2; +import lombok.Data; + +import java.io.File; +import java.io.IOException; + +@Data +public class HeadlessGenerator { + private static KList EMPTYPOINTS = new KList<>(); + private final HeadlessWorld world; + private final EngineCompositeGenerator generator; + private final NBTWorld writer; + private final MultiBurst burst; + + public HeadlessGenerator(HeadlessWorld world) { + this.world = world; + burst = new MultiBurst("Iris Headless Generator", 9, IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount())); + writer = new NBTWorld(world.getWorld().worldFolder()); + generator = new EngineCompositeGenerator(world.getDimension().getLoadKey(), !world.isStudio()); + generator.assignHeadlessGenerator(this); + generator.assignHeadlessNBTWriter(writer); + generator.initialize(world.getWorld()); + } + + public void generateChunk(int x, int z) { + generator.directWriteChunk(world.getWorld(), x, z, writer); + } + + public void generateRegion(int x, int z) { + generator.directWriteMCA(world.getWorld(), x, z, writer, burst); + } + + public void generateRegion(int x, int z, PregenListener listener) { + generator.directWriteMCA(world.getWorld(), x, z, writer, burst, listener); + } + + public File generateRegionToFile(int x, int z, PregenListener listener) { + generateRegionToFile(x, z, listener); + flush(); + return writer.getRegionFile(x, z); + } + + public void flush() { + writer.flushNow(); + } + + public void save() { + writer.save(); + } + + public void close() { + burst.shutdownAndAwait(); + generator.close(); + writer.close(); + } + + public KList getChunksInRegion(int x, int z) { + try { + return MCAUtil.sampleChunkPositions(writer.getRegionFile(x, z)); + } catch (IOException e) { + e.printStackTrace(); + } + + return EMPTYPOINTS; + } +} diff --git a/src/main/java/com/volmit/iris/engine/headless/HeadlessWorld.java b/src/main/java/com/volmit/iris/engine/headless/HeadlessWorld.java new file mode 100644 index 000000000..90e7cb2a4 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/headless/HeadlessWorld.java @@ -0,0 +1,86 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.headless; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisDataManager; +import com.volmit.iris.core.tools.IrisWorlds; +import com.volmit.iris.engine.framework.EngineCompositeGenerator; +import com.volmit.iris.engine.object.IrisDimension; +import com.volmit.iris.engine.object.common.IrisWorld; +import com.volmit.iris.util.plugin.VolmitSender; +import lombok.Data; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.WorldCreator; + +import java.io.File; + +@Data +@SuppressWarnings("ResultOfMethodCallIgnored") +public class HeadlessWorld { + private final IrisDimension dimension; + private final String worldName; + private final IrisWorld world; + private boolean studio = false; + + public HeadlessWorld(String worldName, IrisDimension dimension, long seed) { + this(worldName, dimension, seed, false); + } + + public HeadlessWorld(String worldName, IrisDimension dimension, long seed, boolean studio) { + this.worldName = worldName; + this.dimension = dimension; + this.studio = studio; + world = IrisWorld.builder() + .environment(dimension.getEnvironment()) + .worldFolder(new File(worldName)) + .seed(seed) + .maxHeight(256) + .minHeight(0) + .name(worldName) + .build(); + world.worldFolder().mkdirs(); + new File(world.worldFolder(), "region").mkdirs(); + + if (!studio && !new File(world.worldFolder(), "iris").exists()) { + Iris.proj.installIntoWorld(new VolmitSender(Bukkit.getConsoleSender(), Iris.instance.getTag("Headless")), dimension.getLoadKey(), world.worldFolder()); + } + } + + public HeadlessGenerator generate() { + return new HeadlessGenerator(this); + } + + public World load() { + return new WorldCreator(worldName) + .environment(dimension.getEnvironment()) + .seed(world.seed()) + .generator(new EngineCompositeGenerator(dimension.getLoadKey(), !studio)) + .createWorld(); + } + + public static HeadlessWorld from(World world) { + return new HeadlessWorld(world.getName(), IrisWorlds.access(world).getTarget().getDimension(), world.getSeed()); + } + + public static HeadlessWorld from(String name, String dimension, long seed) { + return new HeadlessWorld(name, IrisDataManager.loadAnyDimension(dimension), seed); + } +} diff --git a/src/main/java/com/volmit/iris/engine/hunk/Hunk.java b/src/main/java/com/volmit/iris/engine/hunk/Hunk.java index 75798328e..695d37ae7 100644 --- a/src/main/java/com/volmit/iris/engine/hunk/Hunk.java +++ b/src/main/java/com/volmit/iris/engine/hunk/Hunk.java @@ -865,18 +865,6 @@ public interface Hunk { return this; } - default void enforceBounds(int x, int y, int z) { - if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight() || z < 0 || z >= getDepth()) { - //Iris.warn(x + "," + y + "," + z + " does not fit within size " + getWidth() + "," + getHeight() + "," + getDepth() + " (0,0,0 to " + (getWidth() - 1) + "," + (getHeight() - 1) + "," + (getDepth() - 1) + ")"); - } - } - - default void enforceBounds(int x, int y, int z, int w, int h, int d) { - if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight() || z < 0 || z >= getDepth() || x + w < 0 || x + w > getWidth() || y + h < 0 || y + h > getHeight() || z + d < 0 || z + d > getDepth()) { - //Iris.warn("The hunk " + w + "," + h + "," + d + " with an offset of " + x + "," + y + "," + z + " does not fit within the parent hunk " + getWidth() + "," + getHeight() + "," + getDepth() + " (0,0,0 to " + (getWidth() - 1) + "," + (getHeight() - 1) + "," + (getDepth() - 1) + ")"); - } - } - /** * Create a new hunk from a section of this hunk. * @@ -890,7 +878,6 @@ public interface Hunk { */ default ArrayHunk crop(int x1, int y1, int z1, int x2, int y2, int z2) { ArrayHunk h = new ArrayHunk(x2 - x1, y2 - y1, z2 - z1); - enforceBounds(x1, y1, z1, x2 - x1, y2 - y1, z2 - z1); for (int i = x1; i < x2; i++) { for (int j = y1; j < y2; j++) { @@ -916,7 +903,6 @@ public interface Hunk { * @return the cropped view of this hunk (x2-x1, y2-y1, z2-z1) */ default Hunk croppedView(int x1, int y1, int z1, int x2, int y2, int z2) { - enforceBounds(x1, y1, z1, x2 - x1, y2 - y1, z2 - z1); return new HunkView(this, x2 - x1, y2 - y1, z2 - z1, x1, y1, z1); } @@ -947,7 +933,6 @@ public interface Hunk { * @param t the value to set */ default void set(int x1, int y1, int z1, int x2, int y2, int z2, T t) { - enforceBounds(x1, y1, z1, x2 - x1, y2 - y1, z2 - z1); for (int i = x1; i <= x2; i++) { for (int j = y1; j <= y2; j++) { for (int k = z1; k <= z2; k++) { @@ -1036,7 +1021,6 @@ public interface Hunk { * @param t the value */ default void set(int x, int y, int z, T t) { - enforceBounds(x, y, z); setRaw(x, y, z, t); } @@ -1089,12 +1073,10 @@ public interface Hunk { * @return the value or null */ default T get(int x, int y, int z) { - enforceBounds(x, y, z); return getRaw(x, y, z); } default T getOr(int x, int y, int z, T t) { - enforceBounds(x, y, z); T v = getRaw(x, y, z); if (v == null) { @@ -1161,8 +1143,6 @@ public interface Hunk { * @param invertY should the inserted hunk be inverted */ default void insert(int offX, int offY, int offZ, Hunk hunk, boolean invertY) { - enforceBounds(offX, offY, offZ, hunk.getWidth(), hunk.getHeight(), hunk.getDepth()); - for (int i = offX; i < offX + hunk.getWidth(); i++) { for (int j = offY; j < offY + hunk.getHeight(); j++) { for (int k = offZ; k < offZ + hunk.getDepth(); k++) { @@ -1183,8 +1163,6 @@ public interface Hunk { * @param invertY should the inserted hunk be inverted */ default void insertSoftly(int offX, int offY, int offZ, Hunk hunk, boolean invertY, Predicate shouldOverwrite) { - enforceBounds(offX, offY, offZ, hunk.getWidth(), hunk.getHeight(), hunk.getDepth()); - for (int i = offX; i < offX + hunk.getWidth(); i++) { for (int j = offY; j < offY + hunk.getHeight(); j++) { for (int k = offZ; k < offZ + hunk.getDepth(); k++) { diff --git a/src/main/java/com/volmit/iris/engine/hunk/io/HunkRegionSlice.java b/src/main/java/com/volmit/iris/engine/hunk/io/HunkRegionSlice.java index 9e1dd3706..7d1632d5f 100644 --- a/src/main/java/com/volmit/iris/engine/hunk/io/HunkRegionSlice.java +++ b/src/main/java/com/volmit/iris/engine/hunk/io/HunkRegionSlice.java @@ -22,19 +22,17 @@ import com.volmit.iris.Iris; import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.object.tile.TileData; import com.volmit.iris.engine.parallel.BurstExecutor; -import com.volmit.iris.engine.parallel.GridLock; import com.volmit.iris.engine.parallel.MultiBurst; 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.function.Function2; import com.volmit.iris.util.function.Function3; -import com.volmit.iris.util.math.ChunkPosition; import com.volmit.iris.util.math.M; +import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.oldnbt.ByteArrayTag; import com.volmit.iris.util.oldnbt.CompoundTag; import com.volmit.iris.util.oldnbt.Tag; -import io.papermc.lib.PaperLib; import org.bukkit.block.TileState; import org.bukkit.block.data.BlockData; @@ -42,22 +40,20 @@ import java.io.IOException; import java.util.concurrent.atomic.AtomicReference; public class HunkRegionSlice { - public static final Function2> BLOCKDATA = (h, c) -> new HunkRegionSlice<>(h, Hunk::newMappedHunkSynced, new BlockDataHunkIOAdapter(), c, "blockdata"); - public static final Function2>> TILE = (h, c) -> new HunkRegionSlice<>(h, Hunk::newMappedHunkSynced, new TileDataHunkIOAdapter(), c, "tile"); - public static final Function3> STRING = (h, c, t) -> new HunkRegionSlice<>(h, Hunk::newMappedHunkSynced, new StringHunkIOAdapter(), c, t); - public static final Function3> BOOLEAN = (h, c, t) -> new HunkRegionSlice<>(h, Hunk::newMappedHunkSynced, new BooleanHunkIOAdapter(), c, t); + public static final Function2> BLOCKDATA = (h, c) -> new HunkRegionSlice<>(h, Hunk::newMappedHunk, new BlockDataHunkIOAdapter(), c, "blockdata"); + public static final Function2>> TILE = (h, c) -> new HunkRegionSlice<>(h, Hunk::newMappedHunk, new TileDataHunkIOAdapter(), c, "tile"); + public static final Function3> STRING = (h, c, t) -> new HunkRegionSlice<>(h, Hunk::newMappedHunk, new StringHunkIOAdapter(), c, t); + public static final Function3> BOOLEAN = (h, c, t) -> new HunkRegionSlice<>(h, Hunk::newMappedHunk, new BooleanHunkIOAdapter(), c, t); private final Function3> factory; - private final GridLock lock; private final HunkIOAdapter adapter; private final CompoundTag compound; private final String key; - private final KMap> loadedChunks; - private final KMap lastUse; - private final KSet save; + private final KMap> loadedChunks; + private final KMap lastUse; + private final KSet save; private final int height; public HunkRegionSlice(int height, Function3> factory, HunkIOAdapter adapter, CompoundTag compound, String key) { - this.lock = new GridLock(32, 32); this.height = height; this.loadedChunks = new KMap<>(); this.factory = factory; @@ -73,18 +69,20 @@ public class HunkRegionSlice { if (loadedChunks.size() != lastUse.size()) { Iris.warn("Incorrect chunk use counts in " + key); - for (ChunkPosition i : lastUse.k()) { + for (Position2 i : lastUse.k()) { if (!loadedChunks.containsKey(i)) { Iris.warn(" Missing LoadChunkKey " + i); } } } - for (ChunkPosition i : lastUse.k()) { + for (Position2 i : lastUse.k()) { Long l = lastUse.get(i); if (l == null || M.ms() - l > t) { v++; - unload(i.getX(), i.getZ()); + MultiBurst.burst.lazy(() -> { + unload(i.getX(), i.getZ()); + }); } } @@ -99,30 +97,23 @@ public class HunkRegionSlice { } } - public synchronized void save() { - BurstExecutor e = MultiBurst.burst.burst(); + public synchronized void save(MultiBurst burst) { - try - { - for (ChunkPosition i : save.copy()) { + try { + for (Position2 i : save.copy()) { if (i == null) { continue; } - e.queue(() -> save(i.getX(), i.getZ())); + save(i.getX(), i.getZ()); try { - lock.withNasty(i.getX(), i.getZ(), () -> save.remove(i)); + save.remove(i); } catch (Throwable eer) { Iris.reportError(eer); } } - - e.complete(); - } - - catch(Throwable ee) - { + } catch (Throwable ee) { Iris.reportError(ee); } } @@ -132,28 +123,23 @@ public class HunkRegionSlice { } public void delete(int x, int z) { - lock.with(x, z, () -> compound.getValue().remove(key(x, z))); + compound.getValue().remove(key(x, z)); } public Hunk read(int x, int z) throws IOException { AtomicReference e = new AtomicReference<>(); - Hunk xt = lock.withResult(x, z, () -> { - Tag t = compound.getValue().get(key(x, z)); + Hunk xt = null; - if (!(t instanceof ByteArrayTag)) { - Iris.verbose("NOT BYTE ARRAY!"); - return null; - } + Tag t = compound.getValue().get(key(x, z)); + if ((t instanceof ByteArrayTag)) { try { - return adapter.read(factory, (ByteArrayTag) t); + xt = adapter.read(factory, (ByteArrayTag) t); } catch (IOException xe) { Iris.reportError(xe); e.set(xe); } - - return null; - }); + } if (xt != null) { return xt; @@ -167,12 +153,12 @@ public class HunkRegionSlice { } public void write(Hunk hunk, int x, int z) throws IOException { - lock.withIO(x, z, () -> compound.getValue().put(key(x, z), hunk.writeByteArrayTag(adapter, key(x, z)))); + compound.getValue().put(key(x, z), hunk.writeByteArrayTag(adapter, key(x, z))); } public synchronized int unloadAll() { int v = 0; - for (ChunkPosition i : loadedChunks.k()) { + for (Position2 i : loadedChunks.k()) { unload(i.getX(), i.getZ()); v++; } @@ -185,7 +171,7 @@ public class HunkRegionSlice { public void save(Hunk region, int x, int z) { try { - lock.withIO(x, z, () -> write(region, x, z)); + write(region, x, z); } catch (IOException e) { Iris.reportError(e); e.printStackTrace(); @@ -193,84 +179,74 @@ public class HunkRegionSlice { } public boolean isLoaded(int x, int z) { - return lock.withResult(x, z, () -> loadedChunks.containsKey(new ChunkPosition(x, z))); + return loadedChunks.containsKey(new Position2(x, z)); } public void save(int x, int z) { - lock.with(x, z, () -> { - if (isLoaded(x, z)) { - save(get(x, z), x, z); - } - }); + if (isLoaded(x, z)) { + save(get(x, z), x, z); + } } public void unload(int x, int z) { - lock.with(x, z, () -> { - ChunkPosition key = new ChunkPosition(x, z); - if (isLoaded(x, z)) { - if (save.contains(key)) { - save(x, z); - save.remove(key); - } - - lastUse.remove(key); - loadedChunks.remove(key); + Position2 key = new Position2(x, z); + if (isLoaded(x, z)) { + if (save.contains(key)) { + save(x, z); + save.remove(key); } - }); + + lastUse.remove(key); + loadedChunks.remove(key); + } } public Hunk load(int x, int z) { - return lock.withResult(x, z, () -> { - if (isLoaded(x, z)) { - return loadedChunks.get(new ChunkPosition(x, z)); + if (isLoaded(x, z)) { + return loadedChunks.get(new Position2(x, z)); + } + + Hunk v = null; + + if (contains(x, z)) { + try { + v = read(x, z); + } catch (IOException e) { + Iris.reportError(e); + e.printStackTrace(); } + } - Hunk v = null; + if (v == null) { + v = factory.apply(16, height, 16); + } - if (contains(x, z)) { - try { - v = read(x, z); - } catch (IOException e) { - Iris.reportError(e); - e.printStackTrace(); - } - } + loadedChunks.put(new Position2(x, z), v); - if (v == null) { - v = factory.apply(16, height, 16); - } - - loadedChunks.put(new ChunkPosition(x, z), v); - - return v; - }); + return v; } public Hunk get(int x, int z) { - return lock.withResult(x, z, () -> { - ChunkPosition key = new ChunkPosition(x, z); + Position2 key = new Position2(x, z); - Hunk c = loadedChunks.get(key); + Hunk c = loadedChunks.get(key); - if (c == null) { - c = load(x, z); - } + if (c == null) { + c = load(x, z); + } - lastUse.put(new ChunkPosition(x, z), M.ms()); + lastUse.put(new Position2(x, z), M.ms()); - return c; - }); + return c; } public Hunk getR(int x, int z) { - return lock.withResult(x, z, () -> get(x, z).readOnly()); + return get(x, z).readOnly(); } public Hunk getRW(int x, int z) { - return lock.withResult(x, z, () -> { - save.add(new ChunkPosition(x, z)); - return get(x, z); - }); + save.add(new Position2(x, z)); + return get(x, z); } private String key(int x, int z) { diff --git a/src/main/java/com/volmit/iris/engine/hunk/view/ChunkDataHunkView.java b/src/main/java/com/volmit/iris/engine/hunk/view/ChunkDataHunkView.java index 6911a956d..c236fa422 100644 --- a/src/main/java/com/volmit/iris/engine/hunk/view/ChunkDataHunkView.java +++ b/src/main/java/com/volmit/iris/engine/hunk/view/ChunkDataHunkView.java @@ -51,7 +51,6 @@ public class ChunkDataHunkView implements Hunk { return; } - enforceBounds(x1, y1, z1, x2 - x1, y2 - y1, z2 - z1); chunk.setRegion(x1, y1, z1, x2, y2, z2, t); } diff --git a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java index 266829c7b..d323ab8c3 100644 --- a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java +++ b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java @@ -19,7 +19,7 @@ package com.volmit.iris.engine.jigsaw; import com.volmit.iris.core.IrisDataManager; -import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.object.*; diff --git a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index d2b82a939..55c6af355 100644 --- a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -20,7 +20,7 @@ package com.volmit.iris.engine.jigsaw; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisDataManager; -import com.volmit.iris.engine.IrisWorlds; +import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.EngineParallaxManager; import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.interpolation.InterpolationMethod; diff --git a/src/main/java/com/volmit/iris/engine/lighting/LightingTaskBatch.java b/src/main/java/com/volmit/iris/engine/lighting/LightingTaskBatch.java index c95450ad9..0d4e171d9 100644 --- a/src/main/java/com/volmit/iris/engine/lighting/LightingTaskBatch.java +++ b/src/main/java/com/volmit/iris/engine/lighting/LightingTaskBatch.java @@ -25,6 +25,7 @@ import com.bergerkiller.bukkit.common.utils.MathUtil; import com.bergerkiller.bukkit.common.utils.WorldUtil; import com.bergerkiller.bukkit.common.wrappers.LongHashSet; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import org.bukkit.Chunk; import org.bukkit.World; @@ -261,7 +262,7 @@ public class LightingTaskBatch implements LightingTask { LightingChunk nextChunk = null; CompletableFuture nextChunkFuture = null; synchronized (chunks_lock) { - for (; i < chunks.length && numBeingLoaded < Iris.getThreadCount(); i++) { + for (; i < chunks.length && numBeingLoaded < IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getEngineThreadCount()); i++) { LightingChunk lc = chunks[i]; if (lc.loadingStarted) { continue; // Already (being) loaded diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java index 8e2cd9644..1596152f1 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java @@ -43,7 +43,7 @@ public class IrisCaveModifier extends EngineAssignedModifier { public IrisCaveModifier(Engine engine) { super(engine, "Cave"); - rng = new RNG(engine.getWorld().getSeed() + 28934555); + rng = new RNG(engine.getWorld().seed() + 28934555); gg = new FastNoiseDouble(324895L * rng.nextParallelRNG(49678).imax()); } diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java index 623678fee..035e95383 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java @@ -36,7 +36,7 @@ public class IrisDepositModifier extends EngineAssignedModifier { public IrisDepositModifier(Engine engine) { super(engine, "Deposit"); - rng = new RNG(getEngine().getWorld().getSeed() + 12938).nextParallelRNG(28348777); + rng = new RNG(getEngine().getWorld().seed() + 12938).nextParallelRNG(28348777); } @Override diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java index 89aeaf6e7..67309d589 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java @@ -40,7 +40,7 @@ public class IrisPostModifier extends EngineAssignedModifier { public IrisPostModifier(Engine engine) { super(engine, "Post"); - rng = new RNG(getEngine().getWorld().getSeed() + 12938).nextParallelRNG(28348777); + rng = new RNG(getEngine().getWorld().seed() + 12938).nextParallelRNG(28348777); } @Override diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisRavineModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisRavineModifier.java index 25fcaa5ac..70f64ae8e 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisRavineModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisRavineModifier.java @@ -25,8 +25,8 @@ import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.noise.CNG; import com.volmit.iris.engine.object.NoiseStyle; import com.volmit.iris.util.math.BlockPosition; -import com.volmit.iris.util.math.ChunkPosition; import com.volmit.iris.util.math.MathHelper; +import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import org.bukkit.Material; @@ -41,7 +41,7 @@ public class IrisRavineModifier extends EngineAssignedModifier { public IrisRavineModifier(Engine engine) { super(engine, "Ravine"); - rng = new RNG(getEngine().getWorld().getSeed()).nextParallelRNG(29596878); + rng = new RNG(getEngine().getWorld().seed()).nextParallelRNG(29596878); cng = NoiseStyle.IRIS_THICK.create(rng); } @@ -76,7 +76,7 @@ public class IrisRavineModifier extends EngineAssignedModifier { private final float[] ravineCache = new float[1024]; - private void doRavine(long seed, int tx, int tz, ChunkPosition pos, double sx, double sy, double sz, float f, float f2, float f3, @SuppressWarnings("SameParameterValue") int n3, @SuppressWarnings("SameParameterValue") int n4, @SuppressWarnings("SameParameterValue") double d4, RNG bbx, Hunk terrain) { + private void doRavine(long seed, int tx, int tz, Position2 pos, double sx, double sy, double sz, float f, float f2, float f3, @SuppressWarnings("SameParameterValue") int n3, @SuppressWarnings("SameParameterValue") int n4, @SuppressWarnings("SameParameterValue") double d4, RNG bbx, Hunk terrain) { int n5; RNG random = new RNG(seed); double x = tx * 16 + 8; @@ -248,7 +248,7 @@ public class IrisRavineModifier extends EngineAssignedModifier { //@done } - public void genRavines(int n, int n2, ChunkPosition chunkSnapshot, RNG bbb, Hunk terrain) { + public void genRavines(int n, int n2, Position2 chunkSnapshot, RNG bbb, Hunk terrain) { RNG b = this.rng.nextParallelRNG(21949666); RNG bx = this.rng.nextParallelRNG(6676121); long l = b.nextLong(); @@ -263,7 +263,7 @@ public class IrisRavineModifier extends EngineAssignedModifier { } } - private void doRavines(int tx, int tz, int sx, int sz, ChunkPosition chunkSnapshot, RNG b, Hunk terrain) { + private void doRavines(int tx, int tz, int sx, int sz, Position2 chunkSnapshot, RNG b, Hunk terrain) { if (b.nextInt(getDimension().getRavineRarity()) != 0) { return; } @@ -281,6 +281,6 @@ public class IrisRavineModifier extends EngineAssignedModifier { } public void generateRavines(RNG nextParallelRNG, int x, int z, Hunk terrain) { - genRavines(x, z, new ChunkPosition(x, z), nextParallelRNG.nextParallelRNG(x).nextParallelRNG(z), terrain); + genRavines(x, z, new Position2(x, z), nextParallelRNG.nextParallelRNG(x).nextParallelRNG(z), terrain); } } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisBiome.java b/src/main/java/com/volmit/iris/engine/object/IrisBiome.java index cb268b35e..31b597924 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisBiome.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisBiome.java @@ -20,7 +20,7 @@ package com.volmit.iris.engine.object; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisDataManager; -import com.volmit.iris.core.gui.RenderType; +import com.volmit.iris.core.gui.components.RenderType; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.cache.AtomicCache; import com.volmit.iris.engine.data.B; diff --git a/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index 189360432..a356b9bb9 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -26,7 +26,7 @@ import com.volmit.iris.engine.noise.CNG; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.io.IO; -import com.volmit.iris.util.math.ChunkPosition; +import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.RNG; import lombok.AllArgsConstructor; import lombok.Data; @@ -341,7 +341,7 @@ public class IrisDimension extends IrisRegistrant { @Desc("Define biome mutations for this dimension") private KList mutations = new KList<>(); - private final transient AtomicCache parallaxSize = new AtomicCache<>(); + private final transient AtomicCache parallaxSize = new AtomicCache<>(); private final transient AtomicCache rockLayerGenerator = new AtomicCache<>(); private final transient AtomicCache fluidLayerGenerator = new AtomicCache<>(); private final transient AtomicCache coordFracture = new AtomicCache<>(); @@ -520,37 +520,28 @@ public class IrisDimension extends IrisRegistrant { public boolean hasFeatures(DataProvider data) { return featuresUsed.aquire(() -> { - if(getFeatures().isNotEmpty() || getSpecificFeatures().isNotEmpty()) - { + if (getFeatures().isNotEmpty() || getSpecificFeatures().isNotEmpty()) { return true; } - for(IrisRegion i : getAllRegions(data)) - { - if(i.getFeatures().isNotEmpty()) - { + for (IrisRegion i : getAllRegions(data)) { + if (i.getFeatures().isNotEmpty()) { return true; } - for(IrisObjectPlacement j : i.getObjects()) - { - if(j.isVacuum()) - { + for (IrisObjectPlacement j : i.getObjects()) { + if (j.isVacuum()) { return true; } } - for(IrisBiome j : i.getAllBiomes(data)) - { - if(j.getFeatures().isNotEmpty()) - { + for (IrisBiome j : i.getAllBiomes(data)) { + if (j.getFeatures().isNotEmpty()) { return true; } - for(IrisObjectPlacement k : i.getObjects()) - { - if(k.isVacuum()) - { + for (IrisObjectPlacement k : i.getObjects()) { + if (k.isVacuum()) { return true; } } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisEntity.java b/src/main/java/com/volmit/iris/engine/object/IrisEntity.java index f2256a2a6..b12bddea6 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisEntity.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisEntity.java @@ -279,7 +279,7 @@ public class IrisEntity extends IrisRegistrant { }, 1); } - if (Iris.awareEntities && e instanceof Mob) { + if (e instanceof Mob) { Mob m = (Mob) e; m.setAware(isAware()); } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisEntityInitialSpawn.java b/src/main/java/com/volmit/iris/engine/object/IrisEntityInitialSpawn.java index 8feff8a42..1e72382a3 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisEntityInitialSpawn.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisEntityInitialSpawn.java @@ -82,7 +82,7 @@ public class IrisEntityInitialSpawn { return null; } - if (rng.aquire(() -> new RNG(g.getTarget().getWorld().getSeed() + 4)).i(1, getRarity()) == 1) { + if (rng.aquire(() -> new RNG(g.getTarget().getWorld().seed() + 4)).i(1, getRarity()) == 1) { return spawn100(g, at); } @@ -90,6 +90,6 @@ public class IrisEntityInitialSpawn { } private Entity spawn100(Engine g, Location at) { - return getRealEntity(g).spawn(g, at.clone().add(0.5, 1, 0.5), rng.aquire(() -> new RNG(g.getTarget().getWorld().getSeed() + 4))); + return getRealEntity(g).spawn(g, at.clone().add(0.5, 1, 0.5), rng.aquire(() -> new RNG(g.getTarget().getWorld().seed() + 4))); } } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawnOverride.java b/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawnOverride.java index 488cb519a..1cc0150f9 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawnOverride.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawnOverride.java @@ -88,8 +88,8 @@ public class IrisEntitySpawnOverride { return null; } - if (rng.aquire(() -> new RNG(g.getTarget().getWorld().getSeed() + 4)).i(1, getRarity()) == 1) { - return getRealEntity(g).spawn(g, at, rng.aquire(() -> new RNG(g.getTarget().getWorld().getSeed() + 4))); + if (rng.aquire(() -> new RNG(g.getTarget().getWorld().seed() + 4)).i(1, getRarity()) == 1) { + return getRealEntity(g).spawn(g, at, rng.aquire(() -> new RNG(g.getTarget().getWorld().seed() + 4))); } return null; diff --git a/src/main/java/com/volmit/iris/engine/object/IrisLoot.java b/src/main/java/com/volmit/iris/engine/object/IrisLoot.java index e4d69c109..ea5dd7a1a 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisLoot.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisLoot.java @@ -142,10 +142,11 @@ public class IrisLoot { i.apply(rng, m); } - if (Iris.customModels) { + try { m.setCustomModelData(getCustomModel()); + } catch (Throwable e) { + Iris.reportError(e); } - m.setLocalizedName(C.translateAlternateColorCodes('&', displayName)); m.setDisplayName(C.translateAlternateColorCodes('&', displayName)); m.setUnbreakable(isUnbreakable()); @@ -226,8 +227,10 @@ public class IrisLoot { i.apply(rng, m); } - if (Iris.customModels) { + try { m.setCustomModelData(getCustomModel()); + } catch (Throwable e) { + Iris.reportError(e); } m.setLocalizedName(C.translateAlternateColorCodes('&', displayName)); diff --git a/src/main/java/com/volmit/iris/engine/object/IrisObject.java b/src/main/java/com/volmit/iris/engine/object/IrisObject.java index 846546e58..99f5a4cae 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisObject.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisObject.java @@ -30,7 +30,7 @@ import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.math.AxisAlignedBB; import com.volmit.iris.util.math.BlockPosition; -import com.volmit.iris.util.math.ChunkPosition; +import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.scheduling.IrisLock; import lombok.Data; @@ -44,6 +44,7 @@ import org.bukkit.block.TileState; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Waterlogged; import org.bukkit.block.data.type.Leaves; +import org.bukkit.entity.ThrownExpBottle; import org.bukkit.util.BlockVector; import org.bukkit.util.Vector; @@ -470,7 +471,7 @@ public class IrisObject extends IrisRegistrant { boolean warped = !config.getWarp().isFlat(); boolean stilting = (config.getMode().equals(ObjectPlaceMode.STILT) || config.getMode().equals(ObjectPlaceMode.FAST_STILT)); - KMap heightmap = config.getSnow() > 0 ? new KMap<>() : null; + KMap heightmap = config.getSnow() > 0 ? new KMap<>() : null; int spinx = rng.imax() / 1000; int spiny = rng.imax() / 1000; int spinz = rng.imax() / 1000; @@ -581,97 +582,109 @@ public class IrisObject extends IrisRegistrant { int lowest = Integer.MAX_VALUE; y += yrand; readLock.lock(); - for (BlockVector g : getBlocks().keySet()) { - BlockData d; - TileData tile = null; + try + { + for (BlockVector g : getBlocks().keySet()) { + BlockData d; + TileData tile = null; - try { - d = getBlocks().get(g); - tile = getStates().get(g); - } catch (Throwable e) { - Iris.reportError(e); - Iris.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (cme)"); - d = AIR; - } + try { + d = getBlocks().get(g); + tile = getStates().get(g); + } catch (Throwable e) { + Iris.reportError(e); + Iris.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (cme)"); + d = AIR; + } - if (d == null) { - Iris.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (null)"); - d = AIR; - } + if (d == null) { + Iris.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (null)"); + d = AIR; + } - BlockVector i = g.clone(); - BlockData data = d.clone(); - i = config.getRotation().rotate(i.clone(), spinx, spiny, spinz).clone(); - i = config.getTranslate().translate(i.clone(), config.getRotation(), spinx, spiny, spinz).clone(); + BlockVector i = g.clone(); + BlockData data = d.clone(); + i = config.getRotation().rotate(i.clone(), spinx, spiny, spinz).clone(); + i = config.getTranslate().translate(i.clone(), config.getRotation(), spinx, spiny, spinz).clone(); - if (stilting && i.getBlockY() < lowest && !B.isAir(data)) { - lowest = i.getBlockY(); - } + if (stilting && i.getBlockY() < lowest && !B.isAir(data)) { + lowest = i.getBlockY(); + } - if (placer.isPreventingDecay() && (data) instanceof Leaves && !((Leaves) (data)).isPersistent()) { - ((Leaves) data).setPersistent(true); - } + if (placer.isPreventingDecay() && (data) instanceof Leaves && !((Leaves) (data)).isPersistent()) { + ((Leaves) data).setPersistent(true); + } - for (IrisObjectReplace j : config.getEdit()) { - if (rng.chance(j.getChance())) { - for (BlockData k : j.getFind(rdata)) { - if (j.isExact() ? k.matches(data) : k.getMaterial().equals(data.getMaterial())) { - BlockData newData = j.getReplace(rng, i.getX() + x, i.getY() + y, i.getZ() + z, rdata).clone(); + for (IrisObjectReplace j : config.getEdit()) { + if (rng.chance(j.getChance())) { + for (BlockData k : j.getFind(rdata)) { + if (j.isExact() ? k.matches(data) : k.getMaterial().equals(data.getMaterial())) { + BlockData newData = j.getReplace(rng, i.getX() + x, i.getY() + y, i.getZ() + z, rdata).clone(); - if (newData.getMaterial() == data.getMaterial()) - data = data.merge(newData); - else - data = newData; + if (newData.getMaterial() == data.getMaterial()) + { + data = data.merge(newData); + } + else + { + data = newData; + } + } } } } - } - data = config.getRotation().rotate(data, spinx, spiny, spinz); - xx = x + (int) Math.round(i.getX()); - int yy = y + (int) Math.round(i.getY()); - zz = z + (int) Math.round(i.getZ()); + data = config.getRotation().rotate(data, spinx, spiny, spinz); + xx = x + (int) Math.round(i.getX()); + int yy = y + (int) Math.round(i.getY()); + zz = z + (int) Math.round(i.getZ()); - if (warped) { - xx += config.warp(rng, i.getX() + x, i.getY() + y, i.getZ() + z); - zz += config.warp(rng, i.getZ() + z, i.getY() + y, i.getX() + x); - } - - if (yv < 0 && (config.getMode().equals(ObjectPlaceMode.PAINT))) { - yy = (int) Math.round(i.getY()) + Math.floorDiv(h, 2) + placer.getHighest(xx, zz, config.isUnderwater()); - } - - if (heightmap != null) { - ChunkPosition pos = new ChunkPosition(xx, zz); - - if (!heightmap.containsKey(pos)) { - heightmap.put(pos, yy); + if (warped) { + xx += config.warp(rng, i.getX() + x, i.getY() + y, i.getZ() + z); + zz += config.warp(rng, i.getZ() + z, i.getY() + y, i.getX() + x); } - if (heightmap.get(pos) < yy) { - heightmap.put(pos, yy); + if (yv < 0 && (config.getMode().equals(ObjectPlaceMode.PAINT))) { + yy = (int) Math.round(i.getY()) + Math.floorDiv(h, 2) + placer.getHighest(xx, zz, config.isUnderwater()); + } + + if (heightmap != null) { + Position2 pos = new Position2(xx, zz); + + if (!heightmap.containsKey(pos)) { + heightmap.put(pos, yy); + } + + if (heightmap.get(pos) < yy) { + heightmap.put(pos, yy); + } + } + + if (config.isMeld() && !placer.isSolid(xx, yy, zz)) { + continue; + } + + if (config.isWaterloggable() && yy <= placer.getFluidHeight() && data instanceof Waterlogged) { + ((Waterlogged) data).setWaterlogged(true); + } + + if (listener != null) { + listener.accept(new BlockPosition(xx, yy, zz)); + } + + if (!data.getMaterial().equals(Material.AIR) && !data.getMaterial().equals(Material.CAVE_AIR)) { + placer.set(xx, yy, zz, data); + + if (tile != null) { + placer.setTile(xx, yy, zz, tile); + } } } + } - if (config.isMeld() && !placer.isSolid(xx, yy, zz)) { - continue; - } - - if (config.isWaterloggable() && yy <= placer.getFluidHeight() && data instanceof Waterlogged) { - ((Waterlogged) data).setWaterlogged(true); - } - - if (listener != null) { - listener.accept(new BlockPosition(xx, yy, zz)); - } - - if (!data.getMaterial().equals(Material.AIR) && !data.getMaterial().equals(Material.CAVE_AIR)) { - placer.set(xx, yy, zz, data); - - if (tile != null) { - placer.setTile(xx, yy, zz, tile); - } - } + catch(Throwable e) + { + Iris.reportError(e); } readLock.unlock(); @@ -731,7 +744,7 @@ public class IrisObject extends IrisRegistrant { if (heightmap != null) { RNG rngx = rng.nextParallelRNG(3468854); - for (ChunkPosition i : heightmap.k()) { + for (Position2 i : heightmap.k()) { int vx = i.getX(); int vy = heightmap.get(i); int vz = i.getZ(); @@ -996,4 +1009,8 @@ public class IrisObject extends IrisRegistrant { } return locations; } + + public int volume() { + return blocks.size(); + } } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisRegion.java b/src/main/java/com/volmit/iris/engine/object/IrisRegion.java index 47a587219..4c391eb14 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisRegion.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisRegion.java @@ -20,7 +20,7 @@ package com.volmit.iris.engine.object; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisDataManager; -import com.volmit.iris.core.gui.RenderType; +import com.volmit.iris.core.gui.components.RenderType; import com.volmit.iris.engine.cache.AtomicCache; import com.volmit.iris.engine.data.DataProvider; import com.volmit.iris.engine.noise.CNG; diff --git a/src/main/java/com/volmit/iris/engine/object/common/IrisWorld.java b/src/main/java/com/volmit/iris/engine/object/common/IrisWorld.java new file mode 100644 index 000000000..182db04fd --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/common/IrisWorld.java @@ -0,0 +1,103 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.object.common; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.tools.IrisWorlds; +import com.volmit.iris.util.collection.KList; +import lombok.Builder; +import lombok.Data; +import lombok.experimental.Accessors; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import java.io.File; +import java.util.Collection; +import java.util.List; + +@Builder +@Data +@Accessors(chain = true, fluent = true) +public class IrisWorld { + private static final KList NO_PLAYERS = new KList<>(); + private static final KList NO_ENTITIES = new KList<>(); + private String name; + private File worldFolder; + private long seed; + private World.Environment environment; + private World realWorld; + private int minHeight; + private int maxHeight; + + public static IrisWorld fromWorld(World world) { + return bindWorld(IrisWorld.builder().build(), world); + } + + private static IrisWorld bindWorld(IrisWorld iw, World world) { + return iw.name(world.getName()) + .worldFolder(world.getWorldFolder()) + .seed(world.getSeed()) + .minHeight(world.getMinHeight()) + .maxHeight(world.getMaxHeight()) + .realWorld(world) + .environment(world.getEnvironment()); + } + + public boolean hasRealWorld() { + return realWorld != null; + } + + public List getPlayers() { + + if (hasRealWorld()) { + return realWorld().getPlayers(); + } + + return NO_PLAYERS; + } + + public void evacuate() { + if (hasRealWorld()) { + IrisWorlds.evacuate(realWorld()); + } + } + + public void bind(World world) { + bindWorld(this, world); + } + + public Location spawnLocation() { + if (hasRealWorld()) { + return realWorld().getSpawnLocation(); + } + + Iris.error("This world is not real yet, cannot get spawn location! HEADLESS!"); + return null; + } + + public Collection getEntitiesByClass(Class t) { + if (hasRealWorld()) { + return realWorld().getEntitiesByClass(t); + } + + return (KList) NO_ENTITIES; + } +} diff --git a/src/main/java/com/volmit/iris/engine/parallax/ParallaxChunkMeta.java b/src/main/java/com/volmit/iris/engine/parallax/ParallaxChunkMeta.java index f9f169d8b..60c42750f 100644 --- a/src/main/java/com/volmit/iris/engine/parallax/ParallaxChunkMeta.java +++ b/src/main/java/com/volmit/iris/engine/parallax/ParallaxChunkMeta.java @@ -22,14 +22,15 @@ import com.google.gson.Gson; import com.volmit.iris.engine.hunk.io.HunkIOAdapter; import com.volmit.iris.engine.hunk.io.PaletteHunkIOAdapter; import com.volmit.iris.engine.object.IrisFeaturePositional; -import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.io.IO; import com.volmit.iris.util.oldnbt.CompoundTag; import lombok.AllArgsConstructor; import lombok.Data; - import java.io.DataInputStream; import java.io.DataOutputStream; +import java.io.File; import java.io.IOException; +import java.util.UUID; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Function; @@ -39,7 +40,15 @@ public class ParallaxChunkMeta { public static final Function> adapter = (c) -> new PaletteHunkIOAdapter<>() { @Override public void write(ParallaxChunkMeta parallaxChunkMeta, DataOutputStream dos) throws IOException { - dos.writeUTF(new Gson().toJson(parallaxChunkMeta)); + try + { + dos.writeUTF(new Gson().toJson(parallaxChunkMeta)); + } + + catch(Throwable e) + { + IO.writeAll(new File("WTF", UUID.randomUUID().toString()), new Gson().toJson(parallaxChunkMeta)); + } } @Override diff --git a/src/main/java/com/volmit/iris/engine/parallax/ParallaxRegion.java b/src/main/java/com/volmit/iris/engine/parallax/ParallaxRegion.java index 9b169d18f..d131a508b 100644 --- a/src/main/java/com/volmit/iris/engine/parallax/ParallaxRegion.java +++ b/src/main/java/com/volmit/iris/engine/parallax/ParallaxRegion.java @@ -25,13 +25,12 @@ import com.volmit.iris.engine.hunk.io.HunkRegion; import com.volmit.iris.engine.hunk.io.HunkRegionSlice; import com.volmit.iris.engine.object.tile.TileData; import com.volmit.iris.engine.parallel.GridLock; +import com.volmit.iris.engine.parallel.MultiBurst; import com.volmit.iris.util.format.C; -import com.volmit.iris.util.format.Form; import com.volmit.iris.util.math.M; import com.volmit.iris.util.oldnbt.ByteArrayTag; import com.volmit.iris.util.oldnbt.CompoundTag; import com.volmit.iris.util.oldnbt.Tag; -import com.volmit.iris.util.scheduling.PrecisionStopwatch; import org.bukkit.block.TileState; import org.bukkit.block.data.BlockData; @@ -50,16 +49,19 @@ public class ParallaxRegion extends HunkRegion { private final GridLock lock; private long lastUse; private final int height; + private final MultiBurst burst; - public ParallaxRegion(int height, File folder, int x, int z, CompoundTag compound) { + public ParallaxRegion(MultiBurst burst, int height, File folder, int x, int z, CompoundTag compound) { super(folder, x, z, compound); + this.burst = burst; this.height = height; setupSlices(); lock = new GridLock(32, 32); } - public ParallaxRegion(int height, File folder, int x, int z) { + public ParallaxRegion(MultiBurst burst, int height, File folder, int x, int z) { super(folder, x, z); + this.burst = burst; this.height = height; setupSlices(); lock = new GridLock(32, 32); @@ -155,13 +157,15 @@ public class ParallaxRegion extends HunkRegion { } } + @Override public synchronized void save() throws IOException { - blockSlice.save(); - objectSlice.save(); - entitySlice.save(); - tileSlice.save(); - updateSlice.save(); + blockSlice.save(burst); + objectSlice.save(burst); + entitySlice.save(burst); + tileSlice.save(burst); + updateSlice.save(burst); saveMetaHunk(); + Iris.debug("Saved Parallax Region " + C.GOLD + getX() + " " + getZ()); super.save(); } diff --git a/src/main/java/com/volmit/iris/engine/parallax/ParallaxWorld.java b/src/main/java/com/volmit/iris/engine/parallax/ParallaxWorld.java index c05f91da7..c0e6065c2 100644 --- a/src/main/java/com/volmit/iris/engine/parallax/ParallaxWorld.java +++ b/src/main/java/com/volmit/iris/engine/parallax/ParallaxWorld.java @@ -25,23 +25,29 @@ import com.volmit.iris.engine.object.tile.TileData; import com.volmit.iris.engine.parallel.MultiBurst; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.documentation.ChunkCoordinates; +import com.volmit.iris.util.documentation.RegionCoordinates; import com.volmit.iris.util.format.C; +import com.volmit.iris.util.plugin.Command; import com.volmit.iris.util.scheduling.J; import org.bukkit.block.TileState; import org.bukkit.block.data.BlockData; import java.io.File; import java.io.IOException; +import java.util.concurrent.CompletableFuture; @SuppressWarnings("ALL") public class ParallaxWorld implements ParallaxAccess { private final KMap loadedRegions; private final KList save; private final File folder; + private final MultiBurst burst; private final int height; - public ParallaxWorld(int height, File folder) { + public ParallaxWorld(MultiBurst burst, int height, File folder) { this.height = height; + this.burst = burst; this.folder = folder; save = new KList<>(); loadedRegions = new KMap<>(); @@ -85,16 +91,19 @@ public class ParallaxWorld implements ParallaxAccess { } } + @RegionCoordinates public boolean isLoaded(int x, int z) { return loadedRegions.containsKey(key(x, z)); } + @RegionCoordinates public void save(int x, int z) { if (isLoaded(x, z)) { save(getR(x, z)); } } + @RegionCoordinates public int unload(int x, int z) { long key = key(x, z); int v = 0; @@ -114,17 +123,19 @@ public class ParallaxWorld implements ParallaxAccess { return v; } + @RegionCoordinates public ParallaxRegion load(int x, int z) { if (isLoaded(x, z)) { return loadedRegions.get(key(x, z)); } - ParallaxRegion v = new ParallaxRegion(height, folder, x, z); + ParallaxRegion v = new ParallaxRegion(burst, height, folder, x, z); loadedRegions.put(key(x, z), v); return v; } + @RegionCoordinates public ParallaxRegion getR(int x, int z) { long key = key(x, z); @@ -137,70 +148,84 @@ public class ParallaxWorld implements ParallaxAccess { return region; } + @RegionCoordinates public ParallaxRegion getRW(int x, int z) { save.addIfMissing(key(x, z)); return getR(x, z); } + @RegionCoordinates private long key(int x, int z) { return (((long) x) << 32) | (((long) z) & 0xffffffffL); } + @ChunkCoordinates @Override public Hunk getBlocksR(int x, int z) { return getR(x >> 5, z >> 5).getBlockSlice().getR(x & 31, z & 31); } + @ChunkCoordinates @Override public Hunk getBlocksRW(int x, int z) { return getRW(x >> 5, z >> 5).getBlockSlice().getRW(x & 31, z & 31); } + @ChunkCoordinates @Override public Hunk> getTilesR(int x, int z) { return getR(x >> 5, z >> 5).getTileSlice().getR(x & 31, z & 31); } + @ChunkCoordinates @Override public Hunk> getTilesRW(int x, int z) { return getRW(x >> 5, z >> 5).getTileSlice().getRW(x & 31, z & 31); } + @ChunkCoordinates @Override public Hunk getObjectsR(int x, int z) { return getR(x >> 5, z >> 5).getObjectSlice().getR(x & 31, z & 31); } + @ChunkCoordinates @Override public Hunk getObjectsRW(int x, int z) { return getRW(x >> 5, z >> 5).getObjectSlice().getRW(x & 31, z & 31); } + @ChunkCoordinates @Override public Hunk getEntitiesRW(int x, int z) { return getRW(x >> 5, z >> 5).getEntitySlice().getRW(x & 31, z & 31); } + @ChunkCoordinates @Override public Hunk getEntitiesR(int x, int z) { return getRW(x >> 5, z >> 5).getEntitySlice().getR(x & 31, z & 31); } + @ChunkCoordinates @Override public Hunk getUpdatesR(int x, int z) { return getR(x >> 5, z >> 5).getUpdateSlice().getR(x & 31, z & 31); } + @ChunkCoordinates @Override public Hunk getUpdatesRW(int x, int z) { return getRW(x >> 5, z >> 5).getUpdateSlice().getRW(x & 31, z & 31); } + @ChunkCoordinates @Override public ParallaxChunkMeta getMetaR(int x, int z) { return getR(x >> 5, z >> 5).getMetaR(x & 31, z & 31); } + @ChunkCoordinates @Override public ParallaxChunkMeta getMetaRW(int x, int z) { return getRW(x >> 5, z >> 5).getMetaRW(x & 31, z & 31); @@ -211,30 +236,27 @@ public class ParallaxWorld implements ParallaxAccess { } @Override - public void cleanup(long r, long c) { - J.a(() -> { - try { - int rr = 0; - int cc = 0; - - for (ParallaxRegion i : loadedRegions.v()) { + public synchronized void cleanup(long r, long c) { + try { + int rr = 0; + for (ParallaxRegion i : loadedRegions.v()) { + burst.lazy(() -> { if (i.hasBeenIdleLongerThan(r)) { - rr++; unload(i.getX(), i.getZ()); } else { - cc += i.cleanup(c); + i.cleanup(c); } - } - } catch (Throwable e) { - Iris.reportError(e); - e.printStackTrace(); + }); } - }); + } catch (Throwable e) { + Iris.reportError(e); + e.printStackTrace(); + } } @Override public void saveAll() { - MultiBurst.burst.lazy(this::saveAllNOW); + burst.lazy(this::saveAllNOW); } @Override diff --git a/src/main/java/com/volmit/iris/engine/parallel/MultiBurst.java b/src/main/java/com/volmit/iris/engine/parallel/MultiBurst.java index da965047b..180372615 100644 --- a/src/main/java/com/volmit/iris/engine/parallel/MultiBurst.java +++ b/src/main/java/com/volmit/iris/engine/parallel/MultiBurst.java @@ -19,17 +19,17 @@ package com.volmit.iris.engine.parallel; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.util.collection.KList; import java.util.concurrent.*; public class MultiBurst { - public static final MultiBurst burst = new MultiBurst("Iris", 6, Runtime.getRuntime().availableProcessors()); + public static final MultiBurst burst = new MultiBurst("Iris", IrisSettings.get().getConcurrency().getMiscThreadPriority(), IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getMiscThreadCount())); private final ExecutorService service; private ExecutorService syncService; private int tid; - public MultiBurst(int tc) { this("Iris", 6, tc); } @@ -95,4 +95,17 @@ public class MultiBurst { public void shutdown() { service.shutdown(); } + + public void shutdownAndAwait() { + service.shutdown(); + + try { + while (!service.awaitTermination(10, TimeUnit.SECONDS)) { + Iris.info("Still waiting to shutdown burster..."); + } + } catch (Throwable e) { + e.printStackTrace(); + Iris.reportError(e); + } + } } diff --git a/src/main/java/com/volmit/iris/engine/stream/utility/CachedStream2D.java b/src/main/java/com/volmit/iris/engine/stream/utility/CachedStream2D.java index 8d1632ec9..216580a08 100644 --- a/src/main/java/com/volmit/iris/engine/stream/utility/CachedStream2D.java +++ b/src/main/java/com/volmit/iris/engine/stream/utility/CachedStream2D.java @@ -50,10 +50,6 @@ public class CachedStream2D extends BasicStream implements ProceduralStrea @Override public T get(double x, double z) { - if (IrisComplex.cacheLock.get()) { - return stream.get((int) x, (int) z); - } - return cache.compute(Cache.key((int) x, (int) z), (k, v) -> v != null ? v : stream.get((int) x, (int) z)); } diff --git a/src/main/java/com/volmit/iris/util/documentation/BlockCoordinates.java b/src/main/java/com/volmit/iris/util/documentation/BlockCoordinates.java new file mode 100644 index 000000000..8b59590b4 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/documentation/BlockCoordinates.java @@ -0,0 +1,26 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.documentation; + +/** + * This method expects coords in block + */ +public @interface BlockCoordinates { + +} diff --git a/src/main/java/com/volmit/iris/util/documentation/ChunkCoordinates.java b/src/main/java/com/volmit/iris/util/documentation/ChunkCoordinates.java new file mode 100644 index 000000000..59d30ea7c --- /dev/null +++ b/src/main/java/com/volmit/iris/util/documentation/ChunkCoordinates.java @@ -0,0 +1,26 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.documentation; + +/** + * This method expects blocks in chunk coordinates + */ +public @interface ChunkCoordinates { + +} diff --git a/src/main/java/com/volmit/iris/util/documentation/RegionCoordinates.java b/src/main/java/com/volmit/iris/util/documentation/RegionCoordinates.java new file mode 100644 index 000000000..6c04a08b1 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/documentation/RegionCoordinates.java @@ -0,0 +1,26 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.documentation; + +/** + * This method expects coordinates in region coords + */ +public @interface RegionCoordinates { + +} diff --git a/src/main/java/com/volmit/iris/util/exceptions/IrisException.java b/src/main/java/com/volmit/iris/util/exceptions/IrisException.java new file mode 100644 index 000000000..b6a70e696 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/exceptions/IrisException.java @@ -0,0 +1,29 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.exceptions; + +public class IrisException extends Exception { + public IrisException() { + super(); + } + + public IrisException(String message) { + super(message); + } +} diff --git a/src/main/java/com/volmit/iris/util/exceptions/MissingDimensionException.java b/src/main/java/com/volmit/iris/util/exceptions/MissingDimensionException.java new file mode 100644 index 000000000..28954faf5 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/exceptions/MissingDimensionException.java @@ -0,0 +1,29 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.exceptions; + +public class MissingDimensionException extends IrisException { + public MissingDimensionException() { + super(); + } + + public MissingDimensionException(String message) { + super(message); + } +} diff --git a/src/main/java/com/volmit/iris/util/fakenews/FakeEngine.java b/src/main/java/com/volmit/iris/util/fakenews/FakeEngine.java deleted file mode 100644 index b6fb97c02..000000000 --- a/src/main/java/com/volmit/iris/util/fakenews/FakeEngine.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.util.fakenews; - -import com.volmit.iris.core.IrisDataManager; -import com.volmit.iris.engine.IrisEngineFramework; -import com.volmit.iris.engine.framework.*; -import com.volmit.iris.engine.hunk.Hunk; -import com.volmit.iris.engine.object.*; -import lombok.Getter; -import org.bukkit.World; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; - - -public class FakeEngine implements Engine { - - - @Getter - private double maxBiomeObjectDensity; - - @Getter - private double maxBiomeLayerDensity; - - @Getter - private double maxBiomeDecoratorDensity; - - @Getter - private final IrisDimension dimension; - - private final EngineFramework framework; - - @Getter - private final World world; - - public FakeEngine(IrisDimension dimension, FakeWorld world) { - this.dimension = dimension; - this.world = world; - computeBiomeMaxes(); - this.framework = new IrisEngineFramework(this); - } - - private void computeBiomeMaxes() { - for (IrisBiome i : getDimension().getAllBiomes(this)) { - double density = 0; - - for (IrisObjectPlacement j : i.getObjects()) { - density += j.getDensity() * j.getChance(); - } - - maxBiomeObjectDensity = Math.max(maxBiomeObjectDensity, density); - density = 0; - - for (IrisDecorator j : i.getDecorators()) { - density += Math.max(j.getStackMax(), 1) * j.getChance(); - } - - maxBiomeDecoratorDensity = Math.max(maxBiomeDecoratorDensity, density); - density = 0; - - for (IrisBiomePaletteLayer j : i.getLayers()) { - density++; - } - - maxBiomeLayerDensity = Math.max(maxBiomeLayerDensity, density); - } - } - - @Override - public void close() { - } - - @Override - public boolean isClosed() { - return false; - } - - @Override - public IrisDataManager getData() { - return dimension.getLoader().copy(); - } - - @Override - public EngineWorldManager getWorldManager() { - return null; - } - - @Override - public void setParallelism(int parallelism) { - } - - @Override - public int getParallelism() { - return 0; - } - - @Override - public EngineTarget getTarget() { - return null; - } - - @Override - public EngineFramework getFramework() { - return null; - } - - @Override - public void setMinHeight(int min) { - } - - @Override - public void recycle() { - } - - @Override - public int getIndex() { - return 0; - } - - @Override - public int getMinHeight() { - return 0; - } - - @Override - public int getHeight() { - return 64; - } - - @Override - public double modifyX(double x) { - return 0; - } - - @Override - public double modifyZ(double z) { - return 0; - } - - @Override - public void generate(int x, int z, Hunk blocks, Hunk biomes) { - } - - @Override - public EngineMetrics getMetrics() { - return null; - } - - @Override - public EngineEffects getEffects() { - return null; - } - - @Override - public EngineCompound getCompound() { - return null; - } - - @Override - public IrisBiome getFocus() { - return null; - } - - @Override - public void fail(String error, Throwable e) { - } - - @Override - public boolean hasFailed() { - return false; - } - - @Override - public int getCacheID() { - return 0; - } - - @Override - public void hotload() { - } -} diff --git a/src/main/java/com/volmit/iris/util/fakenews/FakeWorld.java b/src/main/java/com/volmit/iris/util/fakenews/FakeWorld.java deleted file mode 100644 index a86b67185..000000000 --- a/src/main/java/com/volmit/iris/util/fakenews/FakeWorld.java +++ /dev/null @@ -1,1214 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.util.fakenews; - -import lombok.Setter; -import org.bukkit.*; -import org.bukkit.block.Biome; -import org.bukkit.block.Block; -import org.bukkit.block.data.BlockData; -import org.bukkit.boss.DragonBattle; -import org.bukkit.entity.*; -import org.bukkit.generator.BlockPopulator; -import org.bukkit.generator.ChunkGenerator; -import org.bukkit.inventory.ItemStack; -import org.bukkit.material.MaterialData; -import org.bukkit.metadata.MetadataValue; -import org.bukkit.plugin.Plugin; -import org.bukkit.util.BoundingBox; -import org.bukkit.util.Consumer; -import org.bukkit.util.RayTraceResult; -import org.bukkit.util.Vector; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.File; -import java.util.*; -import java.util.function.Predicate; - -@SuppressWarnings("deprecation") -public class FakeWorld implements World { - private final int height; - private final int minHeight; - private final long seed; - private final File worldFolder; - private final Environment environment; - @Setter - private String worldName; - - public FakeWorld(String name, int minHeight, int height, long seed, File worldFolder, Environment environment) { - this.worldName = name; - this.height = height; - this.seed = seed; - this.worldFolder = worldFolder; - this.minHeight = minHeight; - this.environment = environment; - worldFolder.mkdirs(); - } - - @Override - public void sendPluginMessage(@NotNull Plugin source, @NotNull String channel, @NotNull byte[] message) { - - } - - @NotNull - @Override - public Set getListeningPluginChannels() { - - return null; - } - - @Override - public void setMetadata(@NotNull String metadataKey, @NotNull MetadataValue newMetadataValue) { - - } - - @NotNull - @Override - public List getMetadata(@NotNull String metadataKey) { - - return null; - } - - @Override - public boolean hasMetadata(@NotNull String metadataKey) { - - return false; - } - - @Override - public void removeMetadata(@NotNull String metadataKey, @NotNull Plugin owningPlugin) { - - } - - @NotNull - @Override - public Block getBlockAt(int x, int y, int z) { - - return null; - } - - @NotNull - @Override - public Block getBlockAt(@NotNull Location location) { - - return null; - } - - @Override - public int getHighestBlockYAt(int x, int z) { - - return 0; - } - - @Override - public int getHighestBlockYAt(@NotNull Location location) { - - return 0; - } - - @NotNull - @Override - public Block getHighestBlockAt(int x, int z) { - - return null; - } - - @NotNull - @Override - public Block getHighestBlockAt(@NotNull Location location) { - - return null; - } - - @Override - public int getHighestBlockYAt(int x, int z, @NotNull HeightMap heightMap) { - - return 0; - } - - @Override - public int getHighestBlockYAt(@NotNull Location location, @NotNull HeightMap heightMap) { - - return 0; - } - - @NotNull - @Override - public Block getHighestBlockAt(int x, int z, @NotNull HeightMap heightMap) { - - return null; - } - - @NotNull - @Override - public Block getHighestBlockAt(@NotNull Location location, @NotNull HeightMap heightMap) { - - return null; - } - - @NotNull - @Override - public Chunk getChunkAt(int x, int z) { - - return null; - } - - @NotNull - @Override - public Chunk getChunkAt(@NotNull Location location) { - - return null; - } - - @NotNull - @Override - public Chunk getChunkAt(@NotNull Block block) { - - return null; - } - - @Override - public boolean isChunkLoaded(@NotNull Chunk chunk) { - - return false; - } - - @NotNull - @Override - public Chunk[] getLoadedChunks() { - - return null; - } - - @Override - public void loadChunk(@NotNull Chunk chunk) { - - } - - @Override - public boolean isChunkLoaded(int x, int z) { - - return false; - } - - @Override - public boolean isChunkGenerated(int x, int z) { - - return false; - } - - @Override - public boolean isChunkInUse(int x, int z) { - - return false; - } - - @Override - public void loadChunk(int x, int z) { - - } - - @Override - public boolean loadChunk(int x, int z, boolean generate) { - - return false; - } - - @Override - public boolean unloadChunk(@NotNull Chunk chunk) { - - return false; - } - - @Override - public boolean unloadChunk(int x, int z) { - - return false; - } - - @Override - public boolean unloadChunk(int x, int z, boolean save) { - - return false; - } - - @Override - public boolean unloadChunkRequest(int x, int z) { - - return false; - } - - @Override - public boolean regenerateChunk(int x, int z) { - - return false; - } - - @Override - public boolean refreshChunk(int x, int z) { - - return false; - } - - @Override - public boolean isChunkForceLoaded(int x, int z) { - - return false; - } - - @Override - public void setChunkForceLoaded(int x, int z, boolean forced) { - - } - - @NotNull - @Override - public Collection getForceLoadedChunks() { - - return null; - } - - @Override - public boolean addPluginChunkTicket(int x, int z, @NotNull Plugin plugin) { - - return false; - } - - @Override - public boolean removePluginChunkTicket(int x, int z, @NotNull Plugin plugin) { - - return false; - } - - @Override - public void removePluginChunkTickets(@NotNull Plugin plugin) { - - } - - @NotNull - @Override - public Collection getPluginChunkTickets(int x, int z) { - - return null; - } - - @NotNull - @Override - public Map> getPluginChunkTickets() { - - return null; - } - - @NotNull - @Override - public Item dropItem(@NotNull Location location, @NotNull ItemStack item) { - - return null; - } - - @NotNull - @Override - public Item dropItem(@NotNull Location location, @NotNull ItemStack itemStack, @Nullable Consumer consumer) { - return null; - } - - @NotNull - @Override - public Item dropItemNaturally(@NotNull Location location, @NotNull ItemStack item) { - - return null; - } - - @NotNull - @Override - public Item dropItemNaturally(@NotNull Location location, @NotNull ItemStack itemStack, @Nullable Consumer consumer) { - return null; - } - - @NotNull - @Override - public Arrow spawnArrow(@NotNull Location location, @NotNull Vector direction, float speed, float spread) { - - return null; - } - - @NotNull - @Override - public T spawnArrow(@NotNull Location location, @NotNull Vector direction, float speed, float spread, @NotNull Class clazz) { - - return null; - } - - @Override - public boolean generateTree(@NotNull Location location, @NotNull TreeType type) { - - return false; - } - - @Override - public boolean generateTree(@NotNull Location loc, @NotNull TreeType type, @NotNull BlockChangeDelegate delegate) { - - return false; - } - - @NotNull - @Override - public Entity spawnEntity(@NotNull Location loc, @NotNull EntityType type) { - - return null; - } - - @NotNull - @Override - public LightningStrike strikeLightning(@NotNull Location loc) { - - return null; - } - - @NotNull - @Override - public LightningStrike strikeLightningEffect(@NotNull Location loc) { - - return null; - } - - @NotNull - @Override - public List getEntities() { - - return null; - } - - @NotNull - @Override - public List getLivingEntities() { - - return null; - } - - @NotNull - @SuppressWarnings({"RedundantSuppression", "unchecked"}) - @Override - public Collection getEntitiesByClass(@NotNull @SuppressWarnings("unchecked") Class... classes) { - - return null; - } - - @NotNull - @Override - public Collection getEntitiesByClass(@NotNull Class cls) { - - return null; - } - - @NotNull - @Override - public Collection getEntitiesByClasses(@NotNull Class... classes) { - - return null; - } - - @NotNull - @Override - public List getPlayers() { - - return null; - } - - @NotNull - @Override - public Collection getNearbyEntities(@NotNull Location location, double x, double y, double z) { - - return null; - } - - @NotNull - @Override - public Collection getNearbyEntities(@NotNull Location location, double x, double y, double z, Predicate filter) { - - return null; - } - - @NotNull - @Override - public Collection getNearbyEntities(@NotNull BoundingBox boundingBox) { - - return null; - } - - @NotNull - @Override - public Collection getNearbyEntities(@NotNull BoundingBox boundingBox, Predicate filter) { - - return null; - } - - @Override - public RayTraceResult rayTraceEntities(@NotNull Location start, @NotNull Vector direction, double maxDistance) { - - return null; - } - - @Override - public RayTraceResult rayTraceEntities(@NotNull Location start, @NotNull Vector direction, double maxDistance, double raySize) { - - return null; - } - - @Override - public RayTraceResult rayTraceEntities(@NotNull Location start, @NotNull Vector direction, double maxDistance, Predicate filter) { - - return null; - } - - @Override - public RayTraceResult rayTraceEntities(@NotNull Location start, @NotNull Vector direction, double maxDistance, double raySize, Predicate filter) { - - return null; - } - - @Override - public RayTraceResult rayTraceBlocks(@NotNull Location start, @NotNull Vector direction, double maxDistance) { - - return null; - } - - @Override - public RayTraceResult rayTraceBlocks(@NotNull Location start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode) { - - return null; - } - - @Override - public RayTraceResult rayTraceBlocks(@NotNull Location start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks) { - - return null; - } - - @Override - public RayTraceResult rayTrace(@NotNull Location start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, Predicate filter) { - - return null; - } - - @NotNull - @Override - public String getName() { - - return worldName; - } - - @NotNull - @Override - public UUID getUID() { - - return null; - } - - @NotNull - @Override - public Location getSpawnLocation() { - - return null; - } - - @Override - public boolean setSpawnLocation(@NotNull Location location) { - - return false; - } - - @Override - public boolean setSpawnLocation(int i, int i1, int i2, float v) { - return false; - } - - @Override - public boolean setSpawnLocation(int x, int y, int z) { - - return false; - } - - @Override - public long getTime() { - - return 0; - } - - @Override - public void setTime(long time) { - - } - - @Override - public long getFullTime() { - - return 0; - } - - @Override - public void setFullTime(long time) { - - } - - @Override - public long getGameTime() { - return 0; - } - - @Override - public boolean hasStorm() { - - return false; - } - - @Override - public void setStorm(boolean hasStorm) { - - } - - @Override - public int getWeatherDuration() { - - return 0; - } - - @Override - public void setWeatherDuration(int duration) { - - } - - @Override - public boolean isThundering() { - - return false; - } - - @Override - public void setThundering(boolean thundering) { - - } - - @Override - public int getThunderDuration() { - - return 0; - } - - @Override - public void setThunderDuration(int duration) { - - } - - @Override - public boolean isClearWeather() { - return false; - } - - @Override - public void setClearWeatherDuration(int i) { - - } - - @Override - public int getClearWeatherDuration() { - return 0; - } - - @Override - public boolean createExplosion(double x, double y, double z, float power) { - - return false; - } - - @Override - public boolean createExplosion(double x, double y, double z, float power, boolean setFire) { - - return false; - } - - @Override - public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks) { - - return false; - } - - @Override - public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks, Entity source) { - - return false; - } - - @Override - public boolean createExplosion(@NotNull Location loc, float power) { - - return false; - } - - @Override - public boolean createExplosion(@NotNull Location loc, float power, boolean setFire) { - - return false; - } - - @Override - public boolean createExplosion(@NotNull Location loc, float power, boolean setFire, boolean breakBlocks) { - - return false; - } - - @Override - public boolean createExplosion(@NotNull Location loc, float power, boolean setFire, boolean breakBlocks, Entity source) { - - return false; - } - - @NotNull - @Override - public Environment getEnvironment() { - - return environment; - } - - @Override - public long getSeed() { - - return seed; - } - - @Override - public boolean getPVP() { - - return false; - } - - @Override - public void setPVP(boolean pvp) { - - } - - @Override - public ChunkGenerator getGenerator() { - - return null; - } - - @Override - public void save() { - - } - - @NotNull - @Override - public List getPopulators() { - - return null; - } - - @NotNull - @Override - public T spawn(@NotNull Location location, @NotNull Class clazz) throws IllegalArgumentException { - - return null; - } - - @NotNull - @Override - public T spawn(@NotNull Location location, @NotNull Class clazz, Consumer function) throws IllegalArgumentException { - - return null; - } - - @NotNull - @Override - public FallingBlock spawnFallingBlock(@NotNull Location location, @NotNull MaterialData data) throws IllegalArgumentException { - - return null; - } - - @NotNull - @Override - public FallingBlock spawnFallingBlock(@NotNull Location location, @NotNull BlockData data) throws IllegalArgumentException { - - return null; - } - - @NotNull - @Override - public FallingBlock spawnFallingBlock(@NotNull Location location, @NotNull Material material, byte data) throws IllegalArgumentException { - - return null; - } - - @Override - public void playEffect(@NotNull Location location, @NotNull Effect effect, int data) { - - } - - @Override - public void playEffect(@NotNull Location location, @NotNull Effect effect, int data, int radius) { - - } - - @Override - public void playEffect(@NotNull Location location, @NotNull Effect effect, T data) { - - } - - @Override - public void playEffect(@NotNull Location location, @NotNull Effect effect, T data, int radius) { - - } - - @NotNull - @Override - public ChunkSnapshot getEmptyChunkSnapshot(int x, int z, boolean includeBiome, boolean includeBiomeTemp) { - - return null; - } - - @Override - public void setSpawnFlags(boolean allowMonsters, boolean allowAnimals) { - - } - - @Override - public boolean getAllowAnimals() { - - return false; - } - - @Override - public boolean getAllowMonsters() { - - return false; - } - - @NotNull - @Override - public Biome getBiome(int x, int z) { - - return null; - } - - @NotNull - @Override - public Biome getBiome(int x, int y, int z) { - - return null; - } - - @Override - public void setBiome(int x, int z, @NotNull Biome bio) { - - } - - @Override - public void setBiome(int x, int y, int z, @NotNull Biome bio) { - - } - - @Override - public double getTemperature(int x, int z) { - - return 0; - } - - @Override - public double getTemperature(int x, int y, int z) { - - return 0; - } - - @Override - public double getHumidity(int x, int z) { - - return 0; - } - - @Override - public double getHumidity(int x, int y, int z) { - - return 0; - } - - @Override - public int getMinHeight() { - return minHeight; - } - - @Override - public int getMaxHeight() { - - return height; - } - - @Override - public int getSeaLevel() { - - return 0; - } - - @Override - public boolean getKeepSpawnInMemory() { - - return false; - } - - @Override - public void setKeepSpawnInMemory(boolean keepLoaded) { - - } - - @Override - public boolean isAutoSave() { - - return false; - } - - @Override - public void setAutoSave(boolean value) { - - } - - @Override - public void setDifficulty(@NotNull Difficulty difficulty) { - - } - - @NotNull - @Override - public Difficulty getDifficulty() { - - return null; - } - - @NotNull - @Override - public File getWorldFolder() { - - return worldFolder; - } - - @Override - public WorldType getWorldType() { - - return null; - } - - @Override - public boolean canGenerateStructures() { - - return false; - } - - @Override - public boolean isHardcore() { - - return false; - } - - @Override - public void setHardcore(boolean hardcore) { - - } - - @Override - public long getTicksPerAnimalSpawns() { - - return 0; - } - - @Override - public void setTicksPerAnimalSpawns(int ticksPerAnimalSpawns) { - - } - - @Override - public long getTicksPerMonsterSpawns() { - - return 0; - } - - @Override - public void setTicksPerMonsterSpawns(int ticksPerMonsterSpawns) { - - } - - @Override - public long getTicksPerWaterSpawns() { - - return 0; - } - - @Override - public void setTicksPerWaterSpawns(int ticksPerWaterSpawns) { - - } - - @Override - public long getTicksPerWaterAmbientSpawns() { - - return 0; - } - - @Override - public void setTicksPerWaterAmbientSpawns(int ticksPerAmbientSpawns) { - - } - - @Override - public long getTicksPerAmbientSpawns() { - - return 0; - } - - @Override - public void setTicksPerAmbientSpawns(int ticksPerAmbientSpawns) { - - } - - @Override - public int getMonsterSpawnLimit() { - - return 0; - } - - @Override - public void setMonsterSpawnLimit(int limit) { - - } - - @Override - public int getAnimalSpawnLimit() { - - return 0; - } - - @Override - public void setAnimalSpawnLimit(int limit) { - - } - - @Override - public int getWaterAnimalSpawnLimit() { - - return 0; - } - - @Override - public void setWaterAnimalSpawnLimit(int limit) { - - } - - @Override - public int getWaterAmbientSpawnLimit() { - - return 0; - } - - @Override - public void setWaterAmbientSpawnLimit(int limit) { - - } - - @Override - public int getAmbientSpawnLimit() { - - return 0; - } - - @Override - public void setAmbientSpawnLimit(int limit) { - - } - - @Override - public void playSound(@NotNull Location location, @NotNull Sound sound, float volume, float pitch) { - - } - - @Override - public void playSound(@NotNull Location location, @NotNull String sound, float volume, float pitch) { - - } - - @Override - public void playSound(@NotNull Location location, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) { - - } - - @Override - public void playSound(@NotNull Location location, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch) { - - } - - @NotNull - @Override - public String[] getGameRules() { - - return null; - } - - @Override - public String getGameRuleValue(String rule) { - - return null; - } - - @Override - public boolean setGameRuleValue(@NotNull String rule, @NotNull String value) { - - return false; - } - - @Override - public boolean isGameRule(@NotNull String rule) { - - return false; - } - - @Override - public T getGameRuleValue(@NotNull GameRule rule) { - - return null; - } - - @Override - public T getGameRuleDefault(@NotNull GameRule rule) { - - return null; - } - - @Override - public boolean setGameRule(@NotNull GameRule rule, @NotNull T newValue) { - - return false; - } - - @NotNull - @Override - public WorldBorder getWorldBorder() { - - return null; - } - - @Override - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, T data) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, T data) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, double offsetX, double offsetY, double offsetZ) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, double offsetX, double offsetY, double offsetZ, T data) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, T data) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, double offsetX, double offsetY, double offsetZ, double extra) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, double offsetX, double offsetY, double offsetZ, double extra, T data) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) { - - } - - @Override - public Location locateNearestStructure(@NotNull Location origin, @NotNull StructureType structureType, int radius, boolean findUnexplored) { - return null; - } - - @Override - public int getViewDistance() { - return 0; - } - - @NotNull - @Override - public Spigot spigot() { - return null; - } - - @Override - public Raid locateNearestRaid(@NotNull Location location, int radius) { - return null; - } - - @NotNull - @Override - public List getRaids() { - return null; - } - - @Override - public DragonBattle getEnderDragonBattle() { - return null; - } -} diff --git a/src/main/java/com/volmit/iris/util/fakenews/HeightedFakeWorld.java b/src/main/java/com/volmit/iris/util/fakenews/HeightedFakeWorld.java deleted file mode 100644 index 8176f0cb9..000000000 --- a/src/main/java/com/volmit/iris/util/fakenews/HeightedFakeWorld.java +++ /dev/null @@ -1,1200 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.util.fakenews; - -import org.bukkit.*; -import org.bukkit.block.Biome; -import org.bukkit.block.Block; -import org.bukkit.block.data.BlockData; -import org.bukkit.boss.DragonBattle; -import org.bukkit.entity.*; -import org.bukkit.generator.BlockPopulator; -import org.bukkit.generator.ChunkGenerator; -import org.bukkit.inventory.ItemStack; -import org.bukkit.material.MaterialData; -import org.bukkit.metadata.MetadataValue; -import org.bukkit.plugin.Plugin; -import org.bukkit.util.BoundingBox; -import org.bukkit.util.Consumer; -import org.bukkit.util.RayTraceResult; -import org.bukkit.util.Vector; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.File; -import java.util.*; -import java.util.function.Predicate; - -@SuppressWarnings({"deprecation", "ClassCanBeRecord", "unchecked"}) -public class HeightedFakeWorld implements World { - private final int height; - - public HeightedFakeWorld(int height) { - this.height = height; - } - - @Override - public void sendPluginMessage(@NotNull Plugin source, @NotNull String channel, @NotNull byte[] message) { - - } - - @NotNull - @Override - public Set getListeningPluginChannels() { - - return null; - } - - @Override - public void setMetadata(@NotNull String metadataKey, @NotNull MetadataValue newMetadataValue) { - - } - - @NotNull - @Override - public List getMetadata(@NotNull String metadataKey) { - - return null; - } - - @Override - public boolean hasMetadata(@NotNull String metadataKey) { - - return false; - } - - @Override - public void removeMetadata(@NotNull String metadataKey, @NotNull Plugin owningPlugin) { - - } - - @NotNull - @Override - public Block getBlockAt(int x, int y, int z) { - - return null; - } - - @NotNull - @Override - public Block getBlockAt(@NotNull Location location) { - - return null; - } - - @Override - public int getHighestBlockYAt(int x, int z) { - - return 0; - } - - @Override - public int getHighestBlockYAt(@NotNull Location location) { - - return 0; - } - - @NotNull - @Override - public Block getHighestBlockAt(int x, int z) { - - return null; - } - - @NotNull - @Override - public Block getHighestBlockAt(@NotNull Location location) { - - return null; - } - - @Override - public int getHighestBlockYAt(int x, int z, @NotNull HeightMap heightMap) { - - return 0; - } - - @Override - public int getHighestBlockYAt(@NotNull Location location, @NotNull HeightMap heightMap) { - - return 0; - } - - @NotNull - @Override - public Block getHighestBlockAt(int x, int z, @NotNull HeightMap heightMap) { - - return null; - } - - @NotNull - @Override - public Block getHighestBlockAt(@NotNull Location location, @NotNull HeightMap heightMap) { - - return null; - } - - @NotNull - @Override - public Chunk getChunkAt(int x, int z) { - - return null; - } - - @NotNull - @Override - public Chunk getChunkAt(@NotNull Location location) { - - return null; - } - - @NotNull - @Override - public Chunk getChunkAt(@NotNull Block block) { - - return null; - } - - @Override - public boolean isChunkLoaded(@NotNull Chunk chunk) { - - return false; - } - - @NotNull - @Override - public Chunk[] getLoadedChunks() { - - return null; - } - - @Override - public void loadChunk(@NotNull Chunk chunk) { - - } - - @Override - public boolean isChunkLoaded(int x, int z) { - - return false; - } - - @Override - public boolean isChunkGenerated(int x, int z) { - - return false; - } - - @Override - public boolean isChunkInUse(int x, int z) { - - return false; - } - - @Override - public void loadChunk(int x, int z) { - - } - - @Override - public boolean loadChunk(int x, int z, boolean generate) { - - return false; - } - - @Override - public boolean unloadChunk(@NotNull Chunk chunk) { - - return false; - } - - @Override - public boolean unloadChunk(int x, int z) { - - return false; - } - - @Override - public boolean unloadChunk(int x, int z, boolean save) { - - return false; - } - - @Override - public boolean unloadChunkRequest(int x, int z) { - - return false; - } - - @Override - public boolean regenerateChunk(int x, int z) { - - return false; - } - - @Override - public boolean refreshChunk(int x, int z) { - - return false; - } - - @Override - public boolean isChunkForceLoaded(int x, int z) { - - return false; - } - - @Override - public void setChunkForceLoaded(int x, int z, boolean forced) { - - } - - @NotNull - @Override - public Collection getForceLoadedChunks() { - - return null; - } - - @Override - public boolean addPluginChunkTicket(int x, int z, @NotNull Plugin plugin) { - - return false; - } - - @Override - public boolean removePluginChunkTicket(int x, int z, @NotNull Plugin plugin) { - - return false; - } - - @Override - public void removePluginChunkTickets(@NotNull Plugin plugin) { - - } - - @NotNull - @Override - public Collection getPluginChunkTickets(int x, int z) { - - return null; - } - - @NotNull - @Override - public Map> getPluginChunkTickets() { - - return null; - } - - @NotNull - @Override - public Item dropItem(@NotNull Location location, @NotNull ItemStack item) { - - return null; - } - - @NotNull - @Override - public Item dropItem(@NotNull Location location, @NotNull ItemStack itemStack, @Nullable Consumer consumer) { - return null; - } - - @NotNull - @Override - public Item dropItemNaturally(@NotNull Location location, @NotNull ItemStack item) { - - return null; - } - - @NotNull - @Override - public Item dropItemNaturally(@NotNull Location location, @NotNull ItemStack itemStack, @Nullable Consumer consumer) { - return null; - } - - @NotNull - @Override - public Arrow spawnArrow(@NotNull Location location, @NotNull Vector direction, float speed, float spread) { - - return null; - } - - @NotNull - @Override - public T spawnArrow(@NotNull Location location, @NotNull Vector direction, float speed, float spread, @NotNull Class clazz) { - - return null; - } - - @Override - public boolean generateTree(@NotNull Location location, @NotNull TreeType type) { - - return false; - } - - @Override - public boolean generateTree(@NotNull Location loc, @NotNull TreeType type, @NotNull BlockChangeDelegate delegate) { - - return false; - } - - @NotNull - @Override - public Entity spawnEntity(@NotNull Location loc, @NotNull EntityType type) { - - return null; - } - - @NotNull - @Override - public LightningStrike strikeLightning(@NotNull Location loc) { - - return null; - } - - @NotNull - @Override - public LightningStrike strikeLightningEffect(@NotNull Location loc) { - - return null; - } - - @NotNull - @Override - public List getEntities() { - - return null; - } - - @NotNull - @Override - public List getLivingEntities() { - - return null; - } - - @NotNull - @Override - public Collection getEntitiesByClass(@NotNull Class... classes) { - - return null; - } - - @NotNull - @Override - public Collection getEntitiesByClass(@NotNull Class cls) { - - return null; - } - - @NotNull - @Override - public Collection getEntitiesByClasses(@NotNull Class... classes) { - - return null; - } - - @NotNull - @Override - public List getPlayers() { - - return null; - } - - @NotNull - @Override - public Collection getNearbyEntities(@NotNull Location location, double x, double y, double z) { - - return null; - } - - @NotNull - @Override - public Collection getNearbyEntities(@NotNull Location location, double x, double y, double z, Predicate filter) { - - return null; - } - - @NotNull - @Override - public Collection getNearbyEntities(@NotNull BoundingBox boundingBox) { - - return null; - } - - @NotNull - @Override - public Collection getNearbyEntities(@NotNull BoundingBox boundingBox, Predicate filter) { - - return null; - } - - @Override - public RayTraceResult rayTraceEntities(@NotNull Location start, @NotNull Vector direction, double maxDistance) { - - return null; - } - - @Override - public RayTraceResult rayTraceEntities(@NotNull Location start, @NotNull Vector direction, double maxDistance, double raySize) { - - return null; - } - - @Override - public RayTraceResult rayTraceEntities(@NotNull Location start, @NotNull Vector direction, double maxDistance, Predicate filter) { - - return null; - } - - @Override - public RayTraceResult rayTraceEntities(@NotNull Location start, @NotNull Vector direction, double maxDistance, double raySize, Predicate filter) { - - return null; - } - - @Override - public RayTraceResult rayTraceBlocks(@NotNull Location start, @NotNull Vector direction, double maxDistance) { - - return null; - } - - @Override - public RayTraceResult rayTraceBlocks(@NotNull Location start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode) { - - return null; - } - - @Override - public RayTraceResult rayTraceBlocks(@NotNull Location start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks) { - - return null; - } - - @Override - public RayTraceResult rayTrace(@NotNull Location start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, Predicate filter) { - - return null; - } - - @NotNull - @Override - public String getName() { - - return null; - } - - @NotNull - @Override - public UUID getUID() { - - return null; - } - - @NotNull - @Override - public Location getSpawnLocation() { - - return null; - } - - @Override - public boolean setSpawnLocation(@NotNull Location location) { - - return false; - } - - @Override - public boolean setSpawnLocation(int i, int i1, int i2, float v) { - return false; - } - - @Override - public boolean setSpawnLocation(int x, int y, int z) { - - return false; - } - - @Override - public long getTime() { - - return 0; - } - - @Override - public void setTime(long time) { - - } - - @Override - public long getFullTime() { - - return 0; - } - - @Override - public void setFullTime(long time) { - - } - - @Override - public long getGameTime() { - return 0; - } - - @Override - public boolean hasStorm() { - - return false; - } - - @Override - public void setStorm(boolean hasStorm) { - - } - - @Override - public int getWeatherDuration() { - - return 0; - } - - @Override - public void setWeatherDuration(int duration) { - - } - - @Override - public boolean isThundering() { - - return false; - } - - @Override - public void setThundering(boolean thundering) { - - } - - @Override - public int getThunderDuration() { - - return 0; - } - - @Override - public void setThunderDuration(int duration) { - - } - - @Override - public boolean isClearWeather() { - return false; - } - - @Override - public void setClearWeatherDuration(int i) { - - } - - @Override - public int getClearWeatherDuration() { - return 0; - } - - @Override - public boolean createExplosion(double x, double y, double z, float power) { - - return false; - } - - @Override - public boolean createExplosion(double x, double y, double z, float power, boolean setFire) { - - return false; - } - - @Override - public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks) { - - return false; - } - - @Override - public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks, Entity source) { - - return false; - } - - @Override - public boolean createExplosion(@NotNull Location loc, float power) { - - return false; - } - - @Override - public boolean createExplosion(@NotNull Location loc, float power, boolean setFire) { - - return false; - } - - @Override - public boolean createExplosion(@NotNull Location loc, float power, boolean setFire, boolean breakBlocks) { - - return false; - } - - @Override - public boolean createExplosion(@NotNull Location loc, float power, boolean setFire, boolean breakBlocks, Entity source) { - - return false; - } - - @NotNull - @Override - public Environment getEnvironment() { - - return null; - } - - @Override - public long getSeed() { - - return 0; - } - - @Override - public boolean getPVP() { - - return false; - } - - @Override - public void setPVP(boolean pvp) { - - } - - @Override - public ChunkGenerator getGenerator() { - - return null; - } - - @Override - public void save() { - - } - - @NotNull - @Override - public List getPopulators() { - - return null; - } - - @NotNull - @Override - public T spawn(@NotNull Location location, @NotNull Class clazz) throws IllegalArgumentException { - - return null; - } - - @NotNull - @Override - public T spawn(@NotNull Location location, @NotNull Class clazz, Consumer function) throws IllegalArgumentException { - - return null; - } - - @NotNull - @Override - public FallingBlock spawnFallingBlock(@NotNull Location location, @NotNull MaterialData data) throws IllegalArgumentException { - - return null; - } - - @NotNull - @Override - public FallingBlock spawnFallingBlock(@NotNull Location location, @NotNull BlockData data) throws IllegalArgumentException { - - return null; - } - - @NotNull - @Override - public FallingBlock spawnFallingBlock(@NotNull Location location, @NotNull Material material, byte data) throws IllegalArgumentException { - - return null; - } - - @Override - public void playEffect(@NotNull Location location, @NotNull Effect effect, int data) { - - } - - @Override - public void playEffect(@NotNull Location location, @NotNull Effect effect, int data, int radius) { - - } - - @Override - public void playEffect(@NotNull Location location, @NotNull Effect effect, T data) { - - } - - @Override - public void playEffect(@NotNull Location location, @NotNull Effect effect, T data, int radius) { - - } - - @NotNull - @Override - public ChunkSnapshot getEmptyChunkSnapshot(int x, int z, boolean includeBiome, boolean includeBiomeTemp) { - - return null; - } - - @Override - public void setSpawnFlags(boolean allowMonsters, boolean allowAnimals) { - - } - - @Override - public boolean getAllowAnimals() { - - return false; - } - - @Override - public boolean getAllowMonsters() { - - return false; - } - - @NotNull - @Override - public Biome getBiome(int x, int z) { - - return null; - } - - @NotNull - @Override - public Biome getBiome(int x, int y, int z) { - - return null; - } - - @Override - public void setBiome(int x, int z, @NotNull Biome bio) { - - } - - @Override - public void setBiome(int x, int y, int z, @NotNull Biome bio) { - - } - - @Override - public double getTemperature(int x, int z) { - - return 0; - } - - @Override - public double getTemperature(int x, int y, int z) { - - return 0; - } - - @Override - public double getHumidity(int x, int z) { - - return 0; - } - - @Override - public double getHumidity(int x, int y, int z) { - - return 0; - } - - @Override - public int getMinHeight() { - return 0; - } - - @Override - public int getMaxHeight() { - - return height; - } - - @Override - public int getSeaLevel() { - - return 0; - } - - @Override - public boolean getKeepSpawnInMemory() { - - return false; - } - - @Override - public void setKeepSpawnInMemory(boolean keepLoaded) { - - } - - @Override - public boolean isAutoSave() { - - return false; - } - - @Override - public void setAutoSave(boolean value) { - - } - - @Override - public void setDifficulty(@NotNull Difficulty difficulty) { - - } - - @NotNull - @Override - public Difficulty getDifficulty() { - - return null; - } - - @NotNull - @Override - public File getWorldFolder() { - - return null; - } - - @Override - public WorldType getWorldType() { - - return null; - } - - @Override - public boolean canGenerateStructures() { - - return false; - } - - @Override - public boolean isHardcore() { - - return false; - } - - @Override - public void setHardcore(boolean hardcore) { - - } - - @Override - public long getTicksPerAnimalSpawns() { - - return 0; - } - - @Override - public void setTicksPerAnimalSpawns(int ticksPerAnimalSpawns) { - - } - - @Override - public long getTicksPerMonsterSpawns() { - - return 0; - } - - @Override - public void setTicksPerMonsterSpawns(int ticksPerMonsterSpawns) { - - } - - @Override - public long getTicksPerWaterSpawns() { - - return 0; - } - - @Override - public void setTicksPerWaterSpawns(int ticksPerWaterSpawns) { - - } - - @Override - public long getTicksPerWaterAmbientSpawns() { - - return 0; - } - - @Override - public void setTicksPerWaterAmbientSpawns(int ticksPerAmbientSpawns) { - - } - - @Override - public long getTicksPerAmbientSpawns() { - - return 0; - } - - @Override - public void setTicksPerAmbientSpawns(int ticksPerAmbientSpawns) { - - } - - @Override - public int getMonsterSpawnLimit() { - - return 0; - } - - @Override - public void setMonsterSpawnLimit(int limit) { - - } - - @Override - public int getAnimalSpawnLimit() { - - return 0; - } - - @Override - public void setAnimalSpawnLimit(int limit) { - - } - - @Override - public int getWaterAnimalSpawnLimit() { - - return 0; - } - - @Override - public void setWaterAnimalSpawnLimit(int limit) { - - } - - @Override - public int getWaterAmbientSpawnLimit() { - - return 0; - } - - @Override - public void setWaterAmbientSpawnLimit(int limit) { - - } - - @Override - public int getAmbientSpawnLimit() { - - return 0; - } - - @Override - public void setAmbientSpawnLimit(int limit) { - - } - - @Override - public void playSound(@NotNull Location location, @NotNull Sound sound, float volume, float pitch) { - - } - - @Override - public void playSound(@NotNull Location location, @NotNull String sound, float volume, float pitch) { - - } - - @Override - public void playSound(@NotNull Location location, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch) { - - } - - @Override - public void playSound(@NotNull Location location, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch) { - - } - - @NotNull - @Override - public String[] getGameRules() { - - return null; - } - - @Override - public String getGameRuleValue(String rule) { - - return null; - } - - @Override - public boolean setGameRuleValue(@NotNull String rule, @NotNull String value) { - - return false; - } - - @Override - public boolean isGameRule(@NotNull String rule) { - - return false; - } - - @Override - public T getGameRuleValue(@NotNull GameRule rule) { - - return null; - } - - @Override - public T getGameRuleDefault(@NotNull GameRule rule) { - - return null; - } - - @Override - public boolean setGameRule(@NotNull GameRule rule, @NotNull T newValue) { - - return false; - } - - @NotNull - @Override - public WorldBorder getWorldBorder() { - - return null; - } - - @Override - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, T data) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, T data) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, double offsetX, double offsetY, double offsetZ) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, double offsetX, double offsetY, double offsetZ, T data) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, T data) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, double offsetX, double offsetY, double offsetZ, double extra) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, double offsetX, double offsetY, double offsetZ, double extra, T data) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) { - - } - - @Override - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) { - - } - - @Override - public Location locateNearestStructure(@NotNull Location origin, @NotNull StructureType structureType, int radius, boolean findUnexplored) { - return null; - } - - @Override - public int getViewDistance() { - return 0; - } - - @NotNull - @Override - public Spigot spigot() { - return null; - } - - @Override - public Raid locateNearestRaid(@NotNull Location location, int radius) { - return null; - } - - @NotNull - @Override - public List getRaids() { - return null; - } - - @Override - public DragonBattle getEnderDragonBattle() { - return null; - } -} diff --git a/src/main/java/com/volmit/iris/util/io/IO.java b/src/main/java/com/volmit/iris/util/io/IO.java index 2f43b3660..46f626eb9 100644 --- a/src/main/java/com/volmit/iris/util/io/IO.java +++ b/src/main/java/com/volmit/iris/util/io/IO.java @@ -321,12 +321,26 @@ public class IO { } public static void writeAll(File f, Object c) throws IOException { - f.getParentFile().mkdirs(); + try { + f.getParentFile().mkdirs(); + } + catch(Throwable ignored) + { + + } + PrintWriter pw = new PrintWriter(new FileWriter(f)); pw.println(c.toString()); pw.close(); } + public static void writeAll(File f, OutputStream c) throws IOException { + f.getParentFile().mkdirs(); + FileInputStream in = new FileInputStream(f); + IO.fullTransfer(in, c, 8192); + in.close(); + } + public static String readAll(File f) throws IOException { FileReader fr; try { @@ -621,6 +635,7 @@ public class IO { * @return the requested byte array * @deprecated Use {@link String#getBytes()} */ + @Deprecated public static byte[] toByteArray(String input) { return input.getBytes(); } @@ -756,6 +771,7 @@ public class IO { * @return the requested String * @deprecated Use {@link String#String(byte[])} */ + @Deprecated public static String toString(byte[] input) { return new String(input); } @@ -774,6 +790,7 @@ public class IO { * @throws IOException if an I/O error occurs (never occurs) * @deprecated Use {@link String#String(byte[], String)} */ + @Deprecated public static String toString(byte[] input, String encoding) throws IOException { if (encoding == null) { return new String(input); diff --git a/src/main/java/com/volmit/iris/util/json/JSONArray.java b/src/main/java/com/volmit/iris/util/json/JSONArray.java index 9fff59f9f..170f9c547 100644 --- a/src/main/java/com/volmit/iris/util/json/JSONArray.java +++ b/src/main/java/com/volmit/iris/util/json/JSONArray.java @@ -697,7 +697,7 @@ public class JSONArray implements Iterable { * @throws JSONException if the value is not finite. */ public JSONArray put(double value) throws JSONException { - Double d = new Double(value); + Double d = Double.valueOf(value); JSONObject.testValidity(d); this.put(d); return this; @@ -710,7 +710,7 @@ public class JSONArray implements Iterable { * @return this. */ public JSONArray put(int value) { - this.put(new Integer(value)); + this.put(Integer.valueOf(value)); return this; } @@ -721,7 +721,7 @@ public class JSONArray implements Iterable { * @return this. */ public JSONArray put(long value) { - this.put(new Long(value)); + this.put(Long.valueOf(value)); return this; } @@ -790,7 +790,7 @@ public class JSONArray implements Iterable { * @throws JSONException If the index is negative or if the value is not finite. */ public JSONArray put(int index, double value) throws JSONException { - this.put(index, new Double(value)); + this.put(index, Double.valueOf(value)); return this; } @@ -805,7 +805,7 @@ public class JSONArray implements Iterable { * @throws JSONException If the index is negative. */ public JSONArray put(int index, int value) throws JSONException { - this.put(index, new Integer(value)); + this.put(index, Integer.valueOf(value)); return this; } @@ -820,7 +820,7 @@ public class JSONArray implements Iterable { * @throws JSONException If the index is negative. */ public JSONArray put(int index, long value) throws JSONException { - this.put(index, new Long(value)); + this.put(index, Long.valueOf(value)); return this; } diff --git a/src/main/java/com/volmit/iris/util/json/JSONObject.java b/src/main/java/com/volmit/iris/util/json/JSONObject.java index 9d4501245..440a36a28 100644 --- a/src/main/java/com/volmit/iris/util/json/JSONObject.java +++ b/src/main/java/com/volmit/iris/util/json/JSONObject.java @@ -1115,7 +1115,7 @@ public class JSONObject { * @throws JSONException If the key is null or if the number is invalid. */ public JSONObject put(String key, double value) throws JSONException { - this.put(key, new Double(value)); + this.put(key, Double.valueOf(value)); return this; } @@ -1128,7 +1128,7 @@ public class JSONObject { * @throws JSONException If the key is null. */ public JSONObject put(String key, int value) throws JSONException { - this.put(key, new Integer(value)); + this.put(key, Integer.valueOf(value)); return this; } @@ -1141,7 +1141,7 @@ public class JSONObject { * @throws JSONException If the key is null. */ public JSONObject put(String key, long value) throws JSONException { - this.put(key, new Long(value)); + this.put(key, Long.valueOf(value)); return this; } @@ -1389,7 +1389,7 @@ public class JSONObject { return d; } } else { - Long myLong = new Long(string); + Long myLong = Long.valueOf(string); if (string.equals(myLong.toString())) { if (myLong == myLong.intValue()) { return myLong.intValue(); diff --git a/src/main/java/com/volmit/iris/util/json/JSONWriter.java b/src/main/java/com/volmit/iris/util/json/JSONWriter.java index e359c3854..b45cceb46 100644 --- a/src/main/java/com/volmit/iris/util/json/JSONWriter.java +++ b/src/main/java/com/volmit/iris/util/json/JSONWriter.java @@ -301,7 +301,7 @@ public class JSONWriter { * @throws JSONException If the number is not finite. */ public JSONWriter value(double d) throws JSONException { - return this.value(new Double(d)); + return this.value(Double.valueOf(d)); } /** diff --git a/src/main/java/com/volmit/iris/util/json/XML.java b/src/main/java/com/volmit/iris/util/json/XML.java index 8b4b057cc..50be36dc8 100644 --- a/src/main/java/com/volmit/iris/util/json/XML.java +++ b/src/main/java/com/volmit/iris/util/json/XML.java @@ -318,7 +318,7 @@ public class XML { try { char initial = string.charAt(0); if (initial == '-' || (initial >= '0' && initial <= '9')) { - Long value = new Long(string); + Long value = Long.valueOf(string); if (value.toString().equals(string)) { return value; } @@ -326,7 +326,7 @@ public class XML { } catch (Exception ignore) { Iris.reportError(ignore); try { - Double value = new Double(string); + Double value = Double.valueOf(string); if (value.toString().equals(string)) { return value; } diff --git a/src/main/java/com/volmit/iris/util/math/BlockPosition.java b/src/main/java/com/volmit/iris/util/math/BlockPosition.java index 2729714e5..96415a2e4 100644 --- a/src/main/java/com/volmit/iris/util/math/BlockPosition.java +++ b/src/main/java/com/volmit/iris/util/math/BlockPosition.java @@ -19,6 +19,8 @@ package com.volmit.iris.util.math; import lombok.Data; +import org.bukkit.World; +import org.bukkit.block.Block; import java.util.Objects; @@ -28,6 +30,7 @@ public class BlockPosition { private int y; private int z; + //Magic numbers private static final int m1 = 1 + MathHelper.f(MathHelper.c(30000000)); private static final int m2 = 64 - (m1 * 2); @@ -88,4 +91,25 @@ public class BlockPosition { var3 |= (z & m6) << m2; return var3; } + + public Block toBlock(World world) + { + return world.getBlockAt(x,y,z); + } + + public BlockPosition add(int x, int y, int z) { + return new BlockPosition(x,y,z); + } + + public void min(BlockPosition i) { + setX(Math.min(i.getX(), getX())); + setY(Math.min(i.getY(), getY())); + setZ(Math.min(i.getZ(), getZ())); + } + + public void max(BlockPosition i) { + setX(Math.max(i.getX(), getX())); + setY(Math.max(i.getY(), getY())); + setZ(Math.max(i.getZ(), getZ())); + } } diff --git a/src/main/java/com/volmit/iris/util/math/ChunkPosition.java b/src/main/java/com/volmit/iris/util/math/Position2.java similarity index 73% rename from src/main/java/com/volmit/iris/util/math/ChunkPosition.java rename to src/main/java/com/volmit/iris/util/math/Position2.java index 65098093f..835f1e448 100644 --- a/src/main/java/com/volmit/iris/util/math/ChunkPosition.java +++ b/src/main/java/com/volmit/iris/util/math/Position2.java @@ -18,11 +18,16 @@ package com.volmit.iris.util.math; -public class ChunkPosition { +import com.volmit.iris.engine.object.IrisBiomePaletteLayer; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Block; + +public class Position2 { private int x; private int z; - public ChunkPosition(int x, int z) { + public Position2(int x, int z) { this.x = x; this.z = z; } @@ -43,6 +48,10 @@ public class ChunkPosition { this.z = z; } + public String toString() { + return "[" + x + "," + z + "]"; + } + @Override public int hashCode() { final int prime = 31; @@ -52,18 +61,26 @@ public class ChunkPosition { return result; } + public Position2 regionToChunk() { + return new Position2(x << 5, z << 5); + } + @Override public boolean equals(Object obj) { if (this == obj) { return true; } - if (!(obj instanceof ChunkPosition other)) { + if (!(obj instanceof Position2 other)) { return false; } return x == other.x && z == other.z; } - public double distance(ChunkPosition center) { + public double distance(Position2 center) { return Math.pow(center.getX() - x, 2) + Math.pow(center.getZ() - z, 2); } + + public Position2 add(int x, int z) { + return new Position2(this.x + x, this.z + z); + } } diff --git a/src/main/java/com/volmit/iris/util/math/Tuple3d.java b/src/main/java/com/volmit/iris/util/math/Tuple3d.java index e3c4456fa..3138e1d7c 100644 --- a/src/main/java/com/volmit/iris/util/math/Tuple3d.java +++ b/src/main/java/com/volmit/iris/util/math/Tuple3d.java @@ -288,6 +288,7 @@ public abstract class Tuple3d implements java.io.Serializable, Cloneable { /** * @deprecated Use scaleAdd(double,Tuple3d) instead */ + @Deprecated public final void scaleAdd(double s, Tuple3f t1) { scaleAdd(s, new Point3d(t1)); } @@ -402,6 +403,7 @@ public abstract class Tuple3d implements java.io.Serializable, Cloneable { /** * @deprecated Use clamp(double,double,Tuple3d) instead */ + @Deprecated public final void clamp(float min, float max, Tuple3d t) { clamp(min, (double) max, t); } @@ -434,6 +436,7 @@ public abstract class Tuple3d implements java.io.Serializable, Cloneable { /** * @deprecated Use clampMin(double,Tuple3d) instead */ + @Deprecated public final void clampMin(float min, Tuple3d t) { clampMin((double) min, t); } @@ -459,6 +462,7 @@ public abstract class Tuple3d implements java.io.Serializable, Cloneable { /** * @deprecated Use clampMax(double,Tuple3d) instead */ + @Deprecated public final void clampMax(float max, Tuple3d t) { clampMax((double) max, t); } @@ -498,6 +502,7 @@ public abstract class Tuple3d implements java.io.Serializable, Cloneable { /** * @deprecated Use clamp(double,double) instead */ + @Deprecated public final void clamp(float min, float max) { clamp(min, (double) max); } @@ -534,6 +539,7 @@ public abstract class Tuple3d implements java.io.Serializable, Cloneable { /** * @deprecated Use clampMin(double) instead */ + @Deprecated public final void clampMin(float min) { clampMin((double) min); } @@ -548,13 +554,13 @@ public abstract class Tuple3d implements java.io.Serializable, Cloneable { if (x < min) x = min; if (y < min) y = min; if (z < min) z = min; - } /** * @deprecated Use clampMax(double) instead */ + @Deprecated public final void clampMax(float max) { clampMax((double) max); } @@ -585,6 +591,7 @@ public abstract class Tuple3d implements java.io.Serializable, Cloneable { /** * @deprecated Use interpolate(Tuple3d,Tuple3d,double) instead */ + @Deprecated public final void interpolate(Tuple3d t1, Tuple3d t2, float alpha) { interpolate(t1, t2, (double) alpha); } @@ -608,6 +615,7 @@ public abstract class Tuple3d implements java.io.Serializable, Cloneable { /** * @deprecated Use interpolate(Tuple3d,double) instead */ + @Deprecated public final void interpolate(Tuple3d t1, float alpha) { interpolate(t1, (double) alpha); } diff --git a/src/main/java/com/volmit/iris/util/math/Tuple4d.java b/src/main/java/com/volmit/iris/util/math/Tuple4d.java index 437f85689..16d288205 100644 --- a/src/main/java/com/volmit/iris/util/math/Tuple4d.java +++ b/src/main/java/com/volmit/iris/util/math/Tuple4d.java @@ -328,6 +328,7 @@ public abstract class Tuple4d implements java.io.Serializable, Cloneable { /** * @deprecated Use scaleAdd(double,Tuple4d) instead */ + @Deprecated public final void scaleAdd(float s, Tuple4d t1) { scaleAdd((double) s, t1); } @@ -452,6 +453,7 @@ public abstract class Tuple4d implements java.io.Serializable, Cloneable { /** * @deprecated Use clamp(double,double,Tuple4d) instead */ + @Deprecated public final void clamp(float min, float max, Tuple4d t) { clamp(min, (double) max, t); } @@ -488,6 +490,7 @@ public abstract class Tuple4d implements java.io.Serializable, Cloneable { /** * @deprecated Use clampMin(double,Tuple4d) instead */ + @Deprecated public final void clampMin(float min, Tuple4d t) { clampMin((double) min, t); } @@ -515,6 +518,7 @@ public abstract class Tuple4d implements java.io.Serializable, Cloneable { /** * @deprecated Use clampMax(double,Tuple4d) instead */ + @Deprecated public final void clampMax(float max, Tuple4d t) { clampMax((double) max, t); } @@ -561,6 +565,7 @@ public abstract class Tuple4d implements java.io.Serializable, Cloneable { /** * @deprecated Use clamp(double,double) instead */ + @Deprecated public final void clamp(float min, float max) { clamp(min, (double) max); } @@ -603,6 +608,7 @@ public abstract class Tuple4d implements java.io.Serializable, Cloneable { /** * @deprecated Use clampMin(double) instead */ + @Deprecated public final void clampMin(float min) { clampMin((double) min); } @@ -624,6 +630,7 @@ public abstract class Tuple4d implements java.io.Serializable, Cloneable { /** * @deprecated Use clampMax(double) instead */ + @Deprecated public final void clampMax(float max) { clampMax((double) max); } @@ -658,6 +665,7 @@ public abstract class Tuple4d implements java.io.Serializable, Cloneable { /** * @deprecated Use interpolate(Tuple4d,Tuple4d,double) instead */ + @Deprecated public void interpolate(Tuple4d t1, Tuple4d t2, float alpha) { interpolate(t1, t2, (double) alpha); } @@ -682,6 +690,7 @@ public abstract class Tuple4d implements java.io.Serializable, Cloneable { /** * @deprecated Use interpolate(Tuple4d,double) instead */ + @Deprecated public void interpolate(Tuple4d t1, float alpha) { interpolate(t1, (double) alpha); } diff --git a/src/main/java/com/volmit/iris/util/scheduling/IrisLock.java b/src/main/java/com/volmit/iris/util/scheduling/IrisLock.java index bfc1cf36a..179ca93ed 100644 --- a/src/main/java/com/volmit/iris/util/scheduling/IrisLock.java +++ b/src/main/java/com/volmit/iris/util/scheduling/IrisLock.java @@ -20,10 +20,14 @@ package com.volmit.iris.util.scheduling; import com.volmit.iris.Iris; import lombok.Data; +import lombok.experimental.Accessors; import java.util.concurrent.locks.ReentrantLock; @Data +@Accessors( + chain = true +) public class IrisLock { private transient final ReentrantLock lock; private transient final String name; diff --git a/src/main/java/com/volmit/iris/util/scheduling/J.java b/src/main/java/com/volmit/iris/util/scheduling/J.java index a9706c505..614e4ebdf 100644 --- a/src/main/java/com/volmit/iris/util/scheduling/J.java +++ b/src/main/java/com/volmit/iris/util/scheduling/J.java @@ -27,7 +27,9 @@ import com.volmit.iris.util.function.NastyRunnable; import com.volmit.iris.util.math.FinalInteger; import org.bukkit.Bukkit; -import java.util.concurrent.*; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; @@ -208,6 +210,15 @@ public class J { Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, r); } + public static CompletableFuture sfut(Runnable r) { + CompletableFuture f = new CompletableFuture(); + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> { + r.run(); + f.complete(null); + }); + return f; + } + /** * Queue a sync task * diff --git a/src/main/java/com/volmit/iris/util/scheduling/Looper.java b/src/main/java/com/volmit/iris/util/scheduling/Looper.java index 6cc9cbcc5..18ac78649 100644 --- a/src/main/java/com/volmit/iris/util/scheduling/Looper.java +++ b/src/main/java/com/volmit/iris/util/scheduling/Looper.java @@ -42,7 +42,7 @@ public abstract class Looper extends Thread { } } - Iris.info("Thread " + getName() + " Shutdown."); + Iris.info("Thread " + getName() + " Shutdown. Pregen stopped / finished."); } protected abstract long loop();