From a8a87e7f79f95949d168353af7b690a50489b8f1 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sun, 8 Aug 2021 07:50:15 -0400 Subject: [PATCH] Can you smell the rot? --- .../volmit/iris/core/tools/IrisWorlds.java | 91 -- .../iris/engine/IrisEngineCompound.java | 288 ------- .../framework/EngineCompositeGenerator.java | 810 ------------------ .../iris/engine/framework/EngineCompound.java | 169 ---- .../iris/engine/framework/IrisAccess.java | 287 ------- .../framework/headless/HeadlessGenerator.java | 93 -- .../framework/headless/HeadlessWorld.java | 88 -- 7 files changed, 1826 deletions(-) delete mode 100644 src/main/java/com/volmit/iris/core/tools/IrisWorlds.java delete mode 100644 src/main/java/com/volmit/iris/engine/IrisEngineCompound.java delete mode 100644 src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java delete mode 100644 src/main/java/com/volmit/iris/engine/framework/EngineCompound.java delete mode 100644 src/main/java/com/volmit/iris/engine/framework/IrisAccess.java delete mode 100644 src/main/java/com/volmit/iris/engine/framework/headless/HeadlessGenerator.java delete mode 100644 src/main/java/com/volmit/iris/engine/framework/headless/HeadlessWorld.java diff --git a/src/main/java/com/volmit/iris/core/tools/IrisWorlds.java b/src/main/java/com/volmit/iris/core/tools/IrisWorlds.java deleted file mode 100644 index 505ae581a..000000000 --- a/src/main/java/com/volmit/iris/core/tools/IrisWorlds.java +++ /dev/null @@ -1,91 +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.tools; - -import com.volmit.iris.Iris; -import com.volmit.iris.engine.framework.IrisAccess; -import com.volmit.iris.engine.framework.IrisAccessProvider; -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.plugin.VolmitSender; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.entity.Player; - -@SuppressWarnings("ALL") -public class IrisWorlds { - private static final KMap provisioned = new KMap<>(); - - public static void register(World w, IrisAccess p) { - provisioned.put(w.getUID().toString(), p); - } - - public static boolean isIrisWorld(World world) { - if (world == null) { - return false; - } - - if (provisioned.containsKey(world.getUID().toString())) { - return true; - } - - return world.getGenerator() instanceof IrisAccess || world.getGenerator() instanceof IrisAccessProvider; - } - - public static IrisAccess access(World world) { - if (isIrisWorld(world)) { - if (provisioned.containsKey(world.getUID().toString())) { - return provisioned.get(world.getUID().toString()); - } - - return world.getGenerator() instanceof IrisAccessProvider ? (((IrisAccessProvider) world.getGenerator()).getAccess()) : ((IrisAccess) world.getGenerator()); - } - - return null; - } - - public static boolean evacuate(World world) { - for (World i : Bukkit.getWorlds()) { - if (!i.getName().equals(world.getName())) { - for (Player j : world.getPlayers()) { - new VolmitSender(j, Iris.instance.getTag()).sendMessage("You have been evacuated from this world."); - j.teleport(i.getSpawnLocation()); - } - - return true; - } - } - - return false; - } - - public static boolean evacuate(World world, String m) { - for (World i : Bukkit.getWorlds()) { - if (!i.getName().equals(world.getName())) { - for (Player j : world.getPlayers()) { - new VolmitSender(j, Iris.instance.getTag()).sendMessage("You have been evacuated from this world. " + m); - j.teleport(i.getSpawnLocation()); - } - - return true; - } - } - - return false; - } -} diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineCompound.java b/src/main/java/com/volmit/iris/engine/IrisEngineCompound.java deleted file mode 100644 index 63256bc7c..000000000 --- a/src/main/java/com/volmit/iris/engine/IrisEngineCompound.java +++ /dev/null @@ -1,288 +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.engine; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.framework.EngineCompound; -import com.volmit.iris.engine.framework.EngineData; -import com.volmit.iris.engine.framework.EngineTarget; -import com.volmit.iris.engine.object.basic.IrisPosition; -import com.volmit.iris.engine.object.common.IrisWorld; -import com.volmit.iris.engine.object.dimensional.IrisDimension; -import com.volmit.iris.engine.object.dimensional.IrisDimensionIndex; -import com.volmit.iris.util.atomics.AtomicRollingSequence; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.documentation.BlockCoordinates; -import com.volmit.iris.util.documentation.ChunkCoordinates; -import com.volmit.iris.util.format.C; -import com.volmit.iris.util.format.Form; -import com.volmit.iris.util.hunk.Hunk; -import com.volmit.iris.util.parallel.MultiBurst; -import com.volmit.iris.util.scheduling.PrecisionStopwatch; -import lombok.Getter; -import lombok.Setter; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; -import org.bukkit.command.CommandSender; -import org.bukkit.event.EventHandler; -import org.bukkit.event.world.WorldSaveEvent; -import org.bukkit.generator.BlockPopulator; - -import java.io.File; -import java.util.List; - -public class IrisEngineCompound implements EngineCompound { - @Getter - private final IrisWorld world; - - private final AtomicRollingSequence wallClock; - - private Engine defaultEngine; - - @Getter - private final EngineData engineMetadata; - - private final Engine[] engines; - - @Getter - private final MultiBurst burster; - - @Getter - private final KList populators; - - @Getter - private final IrisDimension rootDimension; - - @Getter - private final int threadCount = -1; - - @Getter - @Setter - private boolean studio; - - public IrisEngineCompound(IrisWorld world, IrisDimension rootDimension, IrisData data, int maximumThreads) { - wallClock = new AtomicRollingSequence(32); - this.rootDimension = rootDimension; - Iris.info("Initializing Engine Composite for " + world.name()); - this.world = world; - engineMetadata = EngineData.load(getEngineMetadataFile()); - engineMetadata.setDimension(rootDimension.getLoadKey()); - engineMetadata.setLastVersion(Iris.instance.getDescription().getVersion()); - - saveEngineMetadata(); - populators = new KList<>(); - - if (rootDimension.getDimensionalComposite().isEmpty()) { - burster = null; - // TODO: WARNING HEIGHT - engines = new Engine[]{new IrisEngine(new EngineTarget(world, rootDimension, data, 256, maximumThreads), this, 0)}; - defaultEngine = engines[0]; - } else { - double totalWeight = 0D; - engines = new Engine[rootDimension.getDimensionalComposite().size()]; - 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) { - Iris.warn("Using " + ((threadDist * engines.length) + engines.length) + " threads instead of the configured " + maximumThreads + " maximum thread count due to the requirements of this dimension!"); - } - - for (IrisDimensionIndex i : rootDimension.getDimensionalComposite()) { - totalWeight += i.getWeight(); - } - - int buf = 0; - - for (int i = 0; i < engines.length; i++) { - IrisDimensionIndex index = rootDimension.getDimensionalComposite().get(i); - IrisDimension dimension = data.getDimensionLoader().load(index.getDimension()); - // TODO: WARNING HEIGHT - engines[i] = new IrisEngine(new EngineTarget(world, dimension, data.copy(), (int) Math.floor(256D * (index.getWeight() / totalWeight)), index.isInverted(), threadDist), this, i); - engines[i].setMinHeight(buf); - buf += engines[i].getHeight(); - - if (index.isPrimary()) { - defaultEngine = engines[i]; - } - } - - if (defaultEngine == null) { - defaultEngine = engines[0]; - } - } - - for (Engine i : engines) { - if (i instanceof BlockPopulator) { - populators.add((BlockPopulator) i); - } - } - - Iris.instance.registerListener(this); - } - - public List getStrongholdPositions() { - return engineMetadata.getStrongholdPositions(); - } - - @EventHandler - public void on(WorldSaveEvent e) { - if (world != null && e.getWorld().equals(world)) { - save(); - } - } - - public void printMetrics(CommandSender sender) { - KMap totals = new KMap<>(); - KMap weights = new KMap<>(); - double masterWallClock = wallClock.getAverage(); - - for (int i = 0; i < getSize(); i++) { - Engine e = getEngine(i); - KMap timings = e.getMetrics().pull(); - double totalWeight = 0; - double wallClock = e.getMetrics().getTotal().getAverage(); - - for (double j : timings.values()) { - totalWeight += j; - } - - for (String j : timings.k()) { - weights.put(e.getName() + "[" + e.getIndex() + "]." + j, (wallClock / totalWeight) * timings.get(j)); - } - - totals.put(e.getName() + "[" + e.getIndex() + "]", wallClock); - } - - double mtotals = 0; - - for (double i : totals.values()) { - mtotals += i; - } - - for (String i : totals.k()) { - totals.put(i, (masterWallClock / mtotals) * totals.get(i)); - } - - double v = 0; - - for (double i : weights.values()) { - v += i; - } - - for (String i : weights.k()) { - weights.put(i, weights.get(i) / v); - } - - sender.sendMessage("Total: " + C.BOLD + C.WHITE + Form.duration(masterWallClock, 0)); - - for (String i : totals.k()) { - sender.sendMessage(" Engine " + C.UNDERLINE + C.GREEN + i + C.RESET + ": " + C.BOLD + C.WHITE + Form.duration(totals.get(i), 0)); - } - - sender.sendMessage("Details: "); - - for (String i : weights.sortKNumber().reverse()) { - String befb = C.UNDERLINE + "" + C.GREEN + "" + i.split("\\Q[\\E")[0] + C.RESET + C.GRAY + "["; - String num = C.GOLD + i.split("\\Q[\\E")[1].split("]")[0] + C.RESET + C.GRAY + "]."; - String afb = C.ITALIC + "" + C.AQUA + i.split("\\Q]\\E")[1].substring(1) + C.RESET + C.GRAY; - - sender.sendMessage(" " + befb + num + afb + ": " + C.BOLD + C.WHITE + Form.pc(weights.get(i), 0)); - } - } - - private File getEngineMetadataFile() { - return new File(world.worldFolder(), "iris/engine-metadata.json"); - } - - @ChunkCoordinates - @Override - public void generate(int x, int z, Hunk blocks, Hunk postblocks, Hunk biomes, boolean multicore) { - recycle(); - PrecisionStopwatch p = PrecisionStopwatch.start(); - if (engines.length == 1 && !getEngine(0).getTarget().isInverted()) { - engines[0].generate(x, z, blocks, biomes, multicore); - } else { - int i; - int offset = 0; - - for (i = 0; i < engines.length; i++) { - Engine engine = engines[i]; - int doffset = offset; - int height = engine.getTarget().getHeight(); - Hunk cblock = Hunk.newArrayHunk(16, height, 16); - Hunk cbiome = Hunk.newArrayHunk(16, height, 16); - - if (engine.getTarget().isInverted()) { - cblock = cblock.invertY(); - cbiome = cbiome.invertY(); - } - - engine.generate(x, z, cblock, cbiome, multicore); - blocks.insert(0, doffset, 0, cblock); - biomes.insert(0, doffset, 0, cbiome); - offset += height; - } - } - - wallClock.put(p.getMilliseconds()); - } - - @Override - public int getSize() { - return engines.length; - } - - @Override - public Engine getEngine(int index) { - return engines[index]; - } - - @Override - public void saveEngineMetadata() { - engineMetadata.save(getEngineMetadataFile()); - } - - @BlockCoordinates - @Override - public IrisData getData(int height) { - return getEngineForHeight(height).getData(); - } - - //TODO: FAIL - @Override - public boolean isFailing() { - return false; - } - - @Override - public Engine getDefaultEngine() { - return defaultEngine; - } - - @Override - public void hotload() { - for (int i = 0; i < getSize(); i++) { - getEngine(i).hotload(); - } - } -} diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java b/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java deleted file mode 100644 index d41bb377b..000000000 --- a/src/main/java/com/volmit/iris/engine/framework/EngineCompositeGenerator.java +++ /dev/null @@ -1,810 +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.engine.framework; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; -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.core.project.loader.IrisData; -import com.volmit.iris.engine.IrisEngineCompound; -import com.volmit.iris.engine.data.chunk.MCATerrainChunk; -import com.volmit.iris.engine.data.chunk.TerrainChunk; -import com.volmit.iris.engine.framework.headless.HeadlessGenerator; -import com.volmit.iris.engine.object.basic.IrisPosition; -import com.volmit.iris.engine.object.biome.IrisBiome; -import com.volmit.iris.engine.object.common.IrisWorld; -import com.volmit.iris.engine.object.dimensional.IrisDimension; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.data.B; -import com.volmit.iris.util.format.C; -import com.volmit.iris.util.format.Form; -import com.volmit.iris.util.hunk.Hunk; -import com.volmit.iris.util.io.ReactiveFolder; -import com.volmit.iris.util.math.M; -import com.volmit.iris.util.nbt.mca.NBTWorld; -import com.volmit.iris.util.nbt.tag.CompoundTag; -import com.volmit.iris.util.parallel.BurstExecutor; -import com.volmit.iris.util.parallel.MultiBurst; -import com.volmit.iris.util.plugin.VolmitSender; -import com.volmit.iris.util.reflect.V; -import com.volmit.iris.util.scheduling.ChronoLatch; -import com.volmit.iris.util.scheduling.J; -import com.volmit.iris.util.scheduling.Looper; -import com.volmit.iris.util.scheduling.PrecisionStopwatch; -import io.netty.util.internal.ConcurrentSet; -import lombok.Getter; -import org.bukkit.*; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.generator.BlockPopulator; -import org.bukkit.generator.ChunkGenerator; - -import java.io.File; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; - -public class EngineCompositeGenerator extends ChunkGenerator implements IrisAccess { - private static final BlockData ERROR_BLOCK = Material.RED_GLAZED_TERRACOTTA.createBlockData(); - private final AtomicReference compound = new AtomicReference<>(); - private final AtomicBoolean initialized; - private final String dimensionQuery; - 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 ChronoLatch hotloadcd; - @Getter - private double generatedPerSecond = 0; - private ReactiveFolder hotloader = null; - private IrisWorld cworld = null; - private final Looper ticker; - private final Looper cleaner; - private int hotloaderMisses = 0; - private long lastHotloadTime = 100; - - public EngineCompositeGenerator() { - this(null, true); - } - - public EngineCompositeGenerator(String query, boolean production) { - super(); - ticker = new Looper() { - @Override - protected long loop() { - PrecisionStopwatch p = PrecisionStopwatch.start(); - if (!tickHotloader()) { - hotloaderMisses++; - } else { - hotloaderMisses = 0; - } - lastHotloadTime += p.getMilliseconds(); - lastHotloadTime /= 2; - - return 120 + (lastHotloadTime / 2) + Math.min(hotloaderMisses * 125, 1375); - } - }; - ticker.setPriority(Thread.MIN_PRIORITY); - ticker.setName("Iris Project Manager"); - - cleaner = new Looper() { - @Override - protected long loop() { - if (getComposite() != null) { - getComposite().clean(); - } - - return 10000; - } - }; - cleaner.setPriority(Thread.MIN_PRIORITY); - cleaner.setName("Iris Parallax Manager"); - cleaner.start(); - - if (isStudio()) { - ticker.start(); - } - - hotloadcd = new ChronoLatch(3500); - mst = M.ms(); - this.production = production; - this.dimensionQuery = query; - initialized = new AtomicBoolean(false); - populators = new KList().qadd(new BlockPopulator() { - @Override - public void populate(World world, Random random, Chunk chunk) { - if (compound.get() != null) { - for (BlockPopulator i : compound.get().getPopulators()) { - i.populate(world, random, chunk); - } - } - } - }); - } - - @Override - public void hotload() { - if (isStudio()) { - Iris.proj.updateWorkspace(); - getData().dump(); - J.s(() -> { - try { - for (Player i : getTarget().getWorld().getPlayers()) { - new VolmitSender(i, Iris.instance.getTag()).sendMessage("Dimension Hotloaded"); - i.playSound(i.getLocation(), Sound.BLOCK_COPPER_PLACE, 1f, 1.25f); - } - } catch (Throwable e) { - Iris.reportError(e); - - } - }); - - getComposite().close(); - initialized.lazySet(false); - - if (cworld != null) { - initialize(cworld); - } - } - } - - public boolean tickHotloader() { - if (getComposite() == null || isClosed()) { - return false; - } - - if (!initialized.get()) { - return false; - } - - try { - if (hotloader != null) { - return hotloader.check(); - } - } catch (Throwable e) { - Iris.reportError(e); - } - - return false; - } - - private synchronized IrisDimension getDimension(IrisWorld world) { - String query = dimensionQuery; - query = Iris.linkMultiverseCore.getWorldNameType(world.name(), query); - - IrisDimension dim = null; - - if (query == null) { - File iris = new File(world.worldFolder(), "iris"); - - if (iris.exists() && iris.isDirectory()) { - for (File i : iris.listFiles()) { - // Look for v1 location - if (i.isDirectory() && i.getName().equals("dimensions")) { - for (File j : i.listFiles()) { - if (j.isFile() && j.getName().endsWith(".json")) { - query = j.getName().replaceAll("\\Q.json\\E", ""); - Iris.error("Found v1 install. Please create a new world, this will cause chunks to change in your existing iris worlds!"); - throw new RuntimeException(); - } - } - } - - // Look for v2 location - else if (i.isFile() && i.getName().equals("engine-metadata.json")) { - EngineData metadata = EngineData.load(i); - query = metadata.getDimension(); - break; - } - } - } - } - - if (query == null) { - Iris.error("Cannot find iris dimension data for world: " + world.name() + "! Assuming " + IrisSettings.get().getGenerator().getDefaultWorldType() + "!"); - query = IrisSettings.get().getGenerator().getDefaultWorldType(); - } - - dim = IrisData.loadAnyDimension(query); - - if (dim == null) { - Iris.proj.downloadSearch(new VolmitSender(Bukkit.getConsoleSender(), Iris.instance.getTag()), query, false); - dim = IrisData.loadAnyDimension(query); - - if (dim == null) { - throw new RuntimeException("Cannot find dimension: " + query); - } else { - Iris.info("Download pack: " + query); - } - } - - if (production) { - IrisDimension od = dim; - dim = new IrisData(getDataFolder(world)).getDimensionLoader().load(od.getLoadKey()); - - if (dim == null) { - 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 IrisData(getDataFolder(world)).getDimensionLoader().load(od.getLoadKey()); - - if (dim == null) { - throw new RuntimeException("Cannot find dimension: " + query); - } - } - } - - return dim; - } - - private synchronized IrisDimension getDimension(String world) { - String query = dimensionQuery; - IrisDimension dim = null; - - if (query == null) { - File iris = new File(world + "/iris"); - - if (iris.exists() && iris.isDirectory()) { - for (File i : Objects.requireNonNull(iris.listFiles())) { - // Look for v1 location - if (i.isDirectory() && i.getName().equals("dimensions")) { - for (File j : Objects.requireNonNull(i.listFiles())) { - if (j.isFile() && j.getName().endsWith(".json")) { - query = j.getName().replaceAll("\\Q.json\\E", ""); - Iris.error("Found v1 install. Please create a new world, this will cause chunks to change in your existing iris worlds!"); - throw new RuntimeException(); - } - } - } - - // Look for v2 location - else if (i.isFile() && i.getName().equals("engine-metadata.json")) { - EngineData metadata = EngineData.load(i); - query = metadata.getDimension(); - break; - } - } - } - } - - if (query == null) { - Iris.error("Cannot find iris dimension data for world: " + world + "! Assuming " + IrisSettings.get().getGenerator().getDefaultWorldType() + "!"); - query = IrisSettings.get().getGenerator().getDefaultWorldType(); - } - - dim = IrisData.loadAnyDimension(query); - - if (dim == null) { - Iris.proj.downloadSearch(new VolmitSender(Bukkit.getConsoleSender(), Iris.instance.getTag()), query, false); - dim = IrisData.loadAnyDimension(query); - - if (dim == null) { - throw new RuntimeException("Cannot find dimension: " + query); - } else { - Iris.info("Download pack: " + query); - } - } - - if (production) { - IrisDimension od = dim; - dim = new IrisData(getDataFolder(world)).getDimensionLoader().load(od.getLoadKey()); - - if (dim == null) { - Iris.info("Installing Iris pack " + od.getName() + " into world " + world + "..."); - Iris.proj.installIntoWorld(new VolmitSender(Bukkit.getConsoleSender(), Iris.instance.getTag()), od.getLoadKey(), new File(world)); - dim = new IrisData(getDataFolder(world)).getDimensionLoader().load(od.getLoadKey()); - - if (dim == null) { - throw new RuntimeException("Cannot find dimension: " + query); - } - } - } - - Iris.info(world + " is configured to generate " + dim.getName() + "!"); - - return dim; - } - - public synchronized void initialize(IrisWorld world) { - if (initialized.get()) { - return; - } - - try { - initialized.set(true); - IrisDimension dim = getDimension(world); - IrisData data = production ? new IrisData(getDataFolder(world)) : dim.getLoader().copy(); - 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()); - cworld = world; - - if (isStudio()) { - dim.installDataPack(() -> data, Iris.instance.getDatapacksFolder()); - } - } catch (Throwable e) { - Iris.reportError(e); - e.printStackTrace(); - Iris.error("FAILED TO INITIALIZE DIMENSION FROM " + world.toString()); - } - } - - /** - * Place strongholds in the world - */ - public void placeStrongholds(World world) { - EngineData metadata = getComposite().getEngineMetadata(); - // TODO: In nms class, not here. Also it doesnt work - if (metadata.getStrongholdPositions() == null || metadata.getStrongholdPositions().size() == 0) { - - List strongholds = new ArrayList<>(); - Object nmsWorld = new V(world).invoke("getHandle"); - Object chunkProvider = new V(nmsWorld).invoke("getChunkProvider"); - Object chunkGenerator = new V(chunkProvider).invoke("getChunkGenerator"); - try { - Class clazz = Class.forName("net.minecraft.world.level.chunk.ChunkGenerator"); - Class clazzSG = Class.forName("net.minecraft.world.level.levelgen.feature.StructureGenerator"); - Class clazzBP = Class.forName("net.minecraft.core.BlockPosition"); - @SuppressWarnings("rawtypes") Constructor bpCon = clazzBP.getConstructor(int.class, int.class, int.class); - - //By default, we place 9 strongholds. One near 0,0 and 8 all around it at about 10_000 blocks out - int[][] coords = {{0, 0}, {7000, -7000}, {10000, 0}, {7000, 7000}, {0, 10000}, {-7000, 7000}, {-10000, 0}, {-7000, -7000}, {0, -10000}}; - - //Set of stronghold locations so we don't place 2 strongholds at the same location - Set existing = new ConcurrentSet<>(); - Set> futures = new HashSet<>(); - for (int[] currCoords : coords) { - //Create a NMS BlockPosition - Object blockPosToTest = bpCon.newInstance(currCoords[0], 0, currCoords[1]); - //Create a CompletableFuture so we can track once the sync code is complete - - CompletableFuture future = new CompletableFuture<>(); - futures.add(future); - - //We have to run this code synchronously because it uses NMS - J.s(() -> { - try { - Object o = getBP(clazz, clazzSG, clazzBP, nmsWorld, blockPosToTest, chunkGenerator); - future.complete(o); - } catch (Exception e) { - Iris.reportError(e); - e.printStackTrace(); - future.complete(e); - } - }); - } - - CompletableFuture all = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); - all.thenAccept((_void) -> { //Once all futures for all 9 strongholds have completed - for (CompletableFuture future : futures) { - try { - Object pos = future.getNow(null); - if (pos != null) { - IrisPosition ipos = new IrisPosition((int) new V(pos, false).invoke("getX"), (int) new V(pos, - false).invoke("getY"), (int) new V(pos, false).invoke("getZ")); - long xz = (((long) ipos.getX()) << 32) | (ipos.getZ() & 0xffffffffL); - if (existing.contains(xz)) return; //Make sure we don't double up on stronghold locs - existing.add(xz); - strongholds.add(ipos); - - } - } catch (Exception e) { - Iris.reportError(e); - e.printStackTrace(); - } - } - - StringBuilder positions = new StringBuilder(); - for (IrisPosition pos : strongholds) { - positions.append("(").append(pos.getX()).append(",").append(pos.getY()).append(",").append(pos.getZ()).append(") "); - } - Iris.info("Strongholds (" + strongholds.size() + ") found at [" + positions + "]"); - - metadata.setStrongholdPositions(strongholds); - getComposite().saveEngineMetadata(); - }); - - } catch (Exception e) { - Iris.reportError(e); - strongholds.add(new IrisPosition(1337, 32, -1337)); - metadata.setStrongholdPositions(strongholds); - Iris.warn("Couldn't properly find the stronghold position for this world. Is this headless mode? Are you not using 1.16 or higher?"); - Iris.warn(" -> Setting default stronghold position"); - e.printStackTrace(); - StringBuilder positions = new StringBuilder(); - for (IrisPosition pos : strongholds) { - positions.append("(").append(pos.getX()).append(",").append(pos.getY()).append(",").append(pos.getZ()).append(") "); - } - Iris.info("Strongholds (" + metadata.getStrongholdPositions().size() + ") found at [" + positions + "]"); - } - - } - } - - - /** - * Get BlockPosition for nearest stronghold from the provided position - */ - private Object getBP(Class clazz, Class clazzSG, Class clazzBP, Object nmsWorld, Object pos, Object chunkGenerator) throws NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { - final String stronghold = "k"; //1.17_01 mapping - - Object structureGeneratorStronghold = clazzSG.getDeclaredField(stronghold).get(null); - Method getNearestGeneratedFeature = clazz.getDeclaredMethod("findNearestMapFeature", - nmsWorld.getClass(), - clazzSG, - clazzBP, - int.class, - boolean.class - ); - return getNearestGeneratedFeature.invoke(chunkGenerator, - nmsWorld, - structureGeneratorStronghold, - pos, - 100, - false - ); - } - - private File getDataFolder(IrisWorld world) { - return new File(world.worldFolder(), "iris/pack"); - } - - private File getDataFolder(String world) { - return new File(world + "/iris/pack"); - } - - - @Override - public ChunkData generateChunkData(World world, Random ignored, int x, int z, BiomeGrid biome) { - try { - PrecisionStopwatch ps = PrecisionStopwatch.start(); - TerrainChunk tc = TerrainChunk.create(world, biome); - IrisWorld ww = (getComposite() == null || getComposite().getWorld() == null) ? IrisWorld.fromWorld(world) : getComposite().getWorld(); - generateChunkRawData(ww, x, z, tc, true).run(); - - if (!getComposite().getWorld().hasRealWorld()) { - getComposite().getWorld().bind(world); - } - - generated++; - ps.end(); - - if (IrisSettings.get().getGeneral().isDebug()) { - Iris.debug("Chunk " + C.GREEN + x + "," + z + C.LIGHT_PURPLE + " in " + C.YELLOW + Form.duration(ps.getMillis(), 2) + C.LIGHT_PURPLE + " Rate: " + C.BLUE + Form.f(getGeneratedPerSecond(), 0) + "/s"); - } - - return tc.getRaw(); - } catch (Throwable e) { - Iris.error("======================================"); - e.printStackTrace(); - Iris.reportErrorChunk(x, z, e, "CHUNK"); - Iris.error("======================================"); - - ChunkData d = Bukkit.createChunkData(world); - - for (int i = 0; i < 16; i++) { - for (int j = 0; j < 16; j++) { - d.setBlock(i, 0, j, ERROR_BLOCK); - } - } - - return d; - } - } - - public void assignHeadlessGenerator(HeadlessGenerator headlessGenerator) { - this.headlessGenerator = headlessGenerator; - } - - @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(); - } - - @Override - public void directWriteChunk(IrisWorld w, int x, int z, NBTWorld writer) { - try { - int ox = x << 4; - int oz = z << 4; - com.volmit.iris.util.nbt.mca.Chunk chunk = writer.getChunk(x, z); - generateChunkRawData(w, x, z, MCATerrainChunk.builder() - .writer(writer).ox(ox).oz(oz).mcaChunk(chunk) - .minHeight(w.minHeight()).maxHeight(w.maxHeight()) - .injector((xx, yy, zz, biomeBase) -> chunk.setBiomeAt(ox + xx, yy, oz + zz, - INMS.get().getTrueBiomeBaseId(biomeBase))) - .build(), false).run(); - } catch (Throwable e) { - Iris.error("======================================"); - e.printStackTrace(); - Iris.reportErrorChunk(x, z, e, "MCA"); - Iris.error("======================================"); - com.volmit.iris.util.nbt.mca.Chunk chunk = writer.getChunk(x, z); - CompoundTag c = NBTWorld.getCompound(ERROR_BLOCK); - for (int i = 0; i < 16; i++) { - for (int j = 0; j < 16; j++) { - chunk.setBlockStateAt(i, 0, j, c, false); - } - } - } - } - - public Runnable generateChunkRawData(IrisWorld world, int x, int z, TerrainChunk tc, boolean multicore) { - initialize(world); - tickMetrics(); - - Hunk blocks = Hunk.view((ChunkData) tc); - Hunk biomes = Hunk.view((BiomeGrid) tc); - Hunk post = Hunk.newAtomicHunk(biomes.getWidth(), biomes.getHeight(), biomes.getDepth()); - compound.get().generate(x * 16, z * 16, blocks, post, biomes, multicore); - - return () -> blocks.insertSoftly(0, 0, 0, post, (b) -> b == null || B.isAirOrFluid(b)); - } - - private void tickMetrics() { - if (M.ms() - mst > 1000) { - generatedPerSecond = (double) (generated - lgenerated) / ((double) (M.ms() - mst) / 1000D); - mst = M.ms(); - lgenerated = generated; - } - } - - @Override - public boolean canSpawn(World world, int x, int z) { - return super.canSpawn(world, x, z); - } - - - @Override - public List getDefaultPopulators(World world) { - return populators; - } - - - @Override - public Location getFixedSpawnLocation(World world, Random random) { - return super.getFixedSpawnLocation(world, random); - } - - @Override - public boolean isParallelCapable() { - return true; - } - - @Override - public boolean shouldGenerateCaves() { - return false; - } - - @Override - public boolean shouldGenerateDecorations() { - return false; - } - - @Override - public boolean shouldGenerateMobs() { - return false; - } - - @Override - public boolean shouldGenerateStructures() { - return false; - } - - public static EngineCompositeGenerator newStudioWorld(String dimension) { - return new EngineCompositeGenerator(dimension, false); - } - - public static EngineCompositeGenerator newProductionWorld(String dimension) { - return new EngineCompositeGenerator(dimension, true); - } - - public static EngineCompositeGenerator newProductionWorld() { - return new EngineCompositeGenerator(null, true); - } - - public EngineCompound getComposite() { - return compound.get(); - } - - @Override - public IrisBiome getBiome(int x, int z) { - return getBiome(x, 0, z); - } - - @Override - public IrisBiome getCaveBiome(int x, int z) { - return getCaveBiome(x, 0, z); - } - - @Override - public int getGenerated() { - return generated; - } - - @Override - public void printMetrics(CommandSender sender) { - getComposite().printMetrics(sender); - } - - @Override - public IrisBiome getBiome(int x, int y, int z) { - // TODO: REMOVE GET ABS BIOME OR THIS ONE - return getEngineAccess(y).getBiome(x, y - getComposite().getEngineForHeight(y).getMinHeight(), z); - } - - @Override - public IrisBiome getCaveBiome(int x, int y, int z) { - return getEngineAccess(y).getCaveBiome(x, z); - } - - @Override - public GeneratorAccess getEngineAccess(int y) { - return getComposite().getEngineForHeight(y); - } - - @Override - public IrisData getData() { - if (getCompound() == null) { - return null; - } - return getComposite().getData(); - } - - @Override - public int getHeight(int x, int y, int z) { - return getEngineAccess(y).getHeight(x, z); - } - - @Override - public int getThreadCount() { - return getComposite().getThreadCount(); - } - - @Override - public void changeThreadCount(int m) { - // TODO: DO IT - } - - @Override - public void close() { - if (isStudio()) { - ticker.interrupt(); - } - - cleaner.interrupt(); - - if (getComposite() != null) { - getComposite().close(); - - if (isStudio() && getComposite().getWorld().hasRealWorld()) { - getComposite().getWorld().evacuate(); - Bukkit.unloadWorld(getComposite().getWorld().realWorld(), !isStudio()); - } - } - } - - @Override - public boolean isClosed() { - try { - return getComposite().getEngine(0).isClosed(); - } catch (Throwable e) { - Iris.reportError(e); - return false; - } - } - - @Override - public EngineTarget getTarget() { - try { - return getComposite().getEngine(0).getTarget(); - } catch (NullPointerException e) { - Iris.reportError(e); - Iris.info("Failed to get composite engine. Please re-create the world in case you notice issues"); - return null; - } - } - - @Override - public EngineCompound getCompound() { - return getComposite(); - } - - @Override - public boolean isFailing() { - if (getComposite() == null) { - return false; - } - - return getComposite().isFailing(); - } - - @Override - public boolean isStudio() { - return !production; - } - - public boolean isVanillaCaves() { - return false; - } - - public KList getAllBiomes(String worldName) { - if (getComposite() != null) { - return getComposite().getAllBiomes(); - } else { - KMap v = new KMap<>(); - IrisDimension dim = getDimension(worldName); - dim.getAllAnyBiomes().forEach((i) -> v.put(i.getLoadKey(), i)); - - try { - dim.getDimensionalComposite().forEach((m) -> IrisData.loadAnyDimension(m.getDimension()).getAllAnyBiomes().forEach((i) -> v.put(i.getLoadKey(), i))); - } catch (Throwable ignored) { - Iris.reportError(ignored); - - } - - Iris.info("Injecting " + v.size() + " biomes into the NMS World Chunk Provider (Iris)"); - - return v.v(); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java b/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java deleted file mode 100644 index 77321ccef..000000000 --- a/src/main/java/com/volmit/iris/engine/framework/EngineCompound.java +++ /dev/null @@ -1,169 +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.engine.framework; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator; -import com.volmit.iris.engine.object.basic.IrisPosition; -import com.volmit.iris.engine.object.biome.IrisBiome; -import com.volmit.iris.engine.object.common.IrisWorld; -import com.volmit.iris.engine.object.dimensional.IrisDimension; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.data.DataProvider; -import com.volmit.iris.util.hunk.Hunk; -import com.volmit.iris.util.parallel.MultiBurst; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; -import org.bukkit.command.CommandSender; -import org.bukkit.event.Listener; -import org.bukkit.generator.BlockPopulator; - -import java.util.List; - -public interface EngineCompound extends Listener, Hotloadable, DataProvider { - IrisDimension getRootDimension(); - - void generate(int x, int z, Hunk blocks, Hunk postblocks, Hunk biomes, boolean multicore); - - IrisWorld getWorld(); - - List getStrongholdPositions(); - - void printMetrics(CommandSender sender); - - int getSize(); - - default int getHeight() { - // TODO: WARNING HEIGHT - return 256; - } - - Engine getEngine(int index); - - MultiBurst getBurster(); - - EngineData getEngineMetadata(); - - void saveEngineMetadata(); - - KList getPopulators(); - - default Engine getEngineForHeight(int height) { - if (getSize() == 1) { - return getEngine(0); - } - - int buf = 0; - - for (int i = 0; i < getSize(); i++) { - Engine e = getEngine(i); - buf += e.getHeight(); - - if (buf >= height) { - return e; - } - } - - return getEngine(getSize() - 1); - } - - default void recycle() { - for (int i = 0; i < getSize(); i++) { - getEngine(i).recycle(); - } - } - - default void save() { - saveEngineMetadata(); - for (int i = 0; i < getSize(); i++) { - getEngine(i).save(); - } - } - - default void saveNOW() { - saveEngineMetadata(); - for (int i = 0; i < getSize(); i++) { - getEngine(i).saveNow(); - } - } - - IrisData getData(int height); - - default IrisData getData() { - return getData(0); - } - - default void close() { - for (int i = 0; i < getSize(); i++) { - getEngine(i).close(); - } - } - - boolean isFailing(); - - int getThreadCount(); - - boolean isStudio(); - - void setStudio(boolean std); - - default void clean() { - for (int i = 0; i < getSize(); i++) { - getEngine(i).clean(); - } - } - - Engine getDefaultEngine(); - - default KList getAllBiomes() { - KMap v = new KMap<>(); - - IrisDimension dim = getRootDimension(); - dim.getAllBiomes(this).forEach((i) -> v.put(i.getLoadKey(), i)); - - try { - dim.getDimensionalComposite().forEach((m) -> getData().getDimensionLoader().load(m.getDimension()).getAllBiomes(this).forEach((i) -> v.put(i.getLoadKey(), i))); - } catch (Throwable ignored) { - Iris.reportError(ignored); - - } - - return v.v(); - } - - default int getLowestBedrock() { - int f = Integer.MAX_VALUE; - - for (int i = 0; i < getSize(); i++) { - Engine e = getEngine(i); - - if (e.getDimension().isBedrock()) { - int m = ((IrisTerrainNormalActuator) e.getTerrainActuator()).getLastBedrock(); - - if (f > m) { - f = m; - } - } - } - - return f; - } -} diff --git a/src/main/java/com/volmit/iris/engine/framework/IrisAccess.java b/src/main/java/com/volmit/iris/engine/framework/IrisAccess.java deleted file mode 100644 index 9eb9dcb14..000000000 --- a/src/main/java/com/volmit/iris/engine/framework/IrisAccess.java +++ /dev/null @@ -1,287 +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.engine.framework; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.pregenerator.PregenListener; -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.engine.framework.headless.HeadlessGenerator; -import com.volmit.iris.engine.object.biome.IrisBiome; -import com.volmit.iris.engine.object.common.IrisWorld; -import com.volmit.iris.engine.object.regional.IrisRegion; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.data.DataProvider; -import com.volmit.iris.util.math.M; -import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.nbt.mca.NBTWorld; -import com.volmit.iris.util.parallel.MultiBurst; -import com.volmit.iris.util.scheduling.ChronoLatch; -import com.volmit.iris.util.scheduling.J; -import org.bukkit.Location; -import org.bukkit.command.CommandSender; -import org.bukkit.util.Vector; - -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; - -@SuppressWarnings("EmptyMethod") -public interface IrisAccess extends Hotloadable, DataProvider { - - HeadlessGenerator getHeadlessGenerator(); - - 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(); - - double getGeneratedPerSecond(); - - void printMetrics(CommandSender sender); - - /** - * Ignores the world, just uses the position - * - * @param l the location - * @return the biome - */ - default IrisBiome getBiome(Location l) { - return getBiome(l.toVector()); - } - - default IrisRegion getRegion(int x, int y, int z) { - return getEngineAccess(y).getRegion(x, z); - } - - default IrisRegion getRegion(Location l) { - return getRegion(l.getBlockX(), l.getBlockY(), l.getBlockZ()); - } - - default IrisBiome getBiome(Vector l) { - return getBiome(l.getBlockX(), l.getBlockY(), l.getBlockZ()); - } - - IrisBiome getBiome(int x, int y, int z); - - IrisBiome getCaveBiome(int x, int y, int z); - - IrisBiome getBiome(int x, int z); - - IrisBiome getCaveBiome(int x, int z); - - GeneratorAccess getEngineAccess(int y); - - IrisData getData(); - - int getHeight(int x, int y, int z); - - int getThreadCount(); - - void changeThreadCount(int m); - - void close(); - - boolean isClosed(); - - EngineTarget getTarget(); - - EngineCompound getCompound(); - - boolean isFailing(); - - 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; - } - - ChronoLatch cl = new ChronoLatch(250, false); - long s = M.ms(); - int cpus = (Runtime.getRuntime().availableProcessors()); - KList engines = new KList<>(); - for (int i = 0; i < getCompound().getSize(); i++) { - Engine e = getCompound().getEngine(i); - if (e.getDimension().getAllBiomes(e).contains(biome)) { - engines.add(e); - } - } - - if (engines.isEmpty()) { - return null; - } - - AtomicInteger tries = new AtomicInteger(0); - AtomicBoolean found = new AtomicBoolean(false); - AtomicBoolean running = new AtomicBoolean(true); - AtomicReference location = new AtomicReference<>(); - for (int i = 0; i < cpus; i++) { - J.a(() -> { - try { - Engine e; - IrisBiome b; - int x, z; - - while (!found.get() && running.get()) { - try { - synchronized (engines) { - e = engines.getRandom(); - x = RNG.r.i(-29999970, 29999970); - z = RNG.r.i(-29999970, 29999970); - b = e.getSurfaceBiome(x, z); - } - - if (b != null && b.getLoadKey() == null) { - continue; - } - - if (b != null && b.getLoadKey().equals(biome.getLoadKey())) { - found.lazySet(true); - location.lazySet(new Location(e.getWorld().realWorld(), x, e.getHeight(x, z), z)); - } - - tries.getAndIncrement(); - } catch (Throwable ex) { - Iris.reportError(ex); - ex.printStackTrace(); - return; - } - } - } catch (Throwable e) { - Iris.reportError(e); - e.printStackTrace(); - } - }); - } - - while (!found.get() || location.get() == null) { - J.sleep(50); - - if (cl.flip()) { - triesc.accept(tries.get()); - } - - if (M.ms() - s > timeout) { - running.set(false); - return null; - } - } - - running.set(false); - return location.get(); - } - - 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; - } - - ChronoLatch cl = new ChronoLatch(3000, false); - long s = M.ms(); - int cpus = (Runtime.getRuntime().availableProcessors()); - KList engines = new KList<>(); - for (int i = 0; i < getCompound().getSize(); i++) { - Engine e = getCompound().getEngine(i); - if (e.getDimension().getRegions().contains(reg.getLoadKey())) { - engines.add(e); - } - } - - if (engines.isEmpty()) { - return null; - } - - AtomicInteger tries = new AtomicInteger(0); - AtomicBoolean found = new AtomicBoolean(false); - AtomicBoolean running = new AtomicBoolean(true); - AtomicReference location = new AtomicReference<>(); - - for (int i = 0; i < cpus; i++) { - J.a(() -> { - Engine e; - IrisRegion b; - int x, z; - - while (!found.get() && running.get()) { - try { - e = engines.getRandom(); - x = RNG.r.i(-29999970, 29999970); - z = RNG.r.i(-29999970, 29999970); - b = e.getRegion(x, z); - - if (b != null && b.getLoadKey() != null && b.getLoadKey().equals(reg.getLoadKey())) { - found.lazySet(true); - location.lazySet(new Location(e.getWorld().realWorld(), x, e.getHeight(x, z) + e.getMinHeight(), z)); - } - - tries.getAndIncrement(); - } catch (Throwable xe) { - Iris.reportError(xe); - xe.printStackTrace(); - return; - } - } - }); - } - - while (!found.get() || location.get() != null) { - J.sleep(50); - - if (cl.flip()) { - triesc.accept(tries.get()); - } - - if (M.ms() - s > timeout) { - triesc.accept(tries.get()); - running.set(false); - return null; - } - } - - triesc.accept(tries.get()); - running.set(false); - return location.get(); - } - - default int getParallaxChunkCount() { - int v = 0; - - for (int i = 0; i < getCompound().getSize(); i++) { - v += getCompound().getEngine(i).getParallax().getChunkCount(); - } - - return v; - } - - default double getHeight(Location l) { - return getHeight(l.getBlockX(), l.getBlockY(), l.getBlockZ()); - } -} diff --git a/src/main/java/com/volmit/iris/engine/framework/headless/HeadlessGenerator.java b/src/main/java/com/volmit/iris/engine/framework/headless/HeadlessGenerator.java deleted file mode 100644 index 33078370e..000000000 --- a/src/main/java/com/volmit/iris/engine/framework/headless/HeadlessGenerator.java +++ /dev/null @@ -1,93 +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.engine.framework.headless; - -import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.pregenerator.PregenListener; -import com.volmit.iris.engine.framework.EngineCompositeGenerator; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.math.Position2; -import com.volmit.iris.util.nbt.mca.MCAUtil; -import com.volmit.iris.util.nbt.mca.NBTWorld; -import com.volmit.iris.util.parallel.MultiBurst; -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/framework/headless/HeadlessWorld.java b/src/main/java/com/volmit/iris/engine/framework/headless/HeadlessWorld.java deleted file mode 100644 index 401e83bc8..000000000 --- a/src/main/java/com/volmit/iris/engine/framework/headless/HeadlessWorld.java +++ /dev/null @@ -1,88 +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.engine.framework.headless; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.core.tools.IrisWorlds; -import com.volmit.iris.engine.framework.EngineCompositeGenerator; -import com.volmit.iris.engine.object.common.IrisWorld; -import com.volmit.iris.engine.object.dimensional.IrisDimension; -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() { - World w = new WorldCreator(worldName) - .environment(dimension.getEnvironment()) - .seed(world.seed()) - .generator(new EngineCompositeGenerator(dimension.getLoadKey(), !studio)) - .createWorld(); - world.realWorld(w); - return w; - } - - 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, IrisData.loadAnyDimension(dimension), seed); - } -}