diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandDeepSearch.java b/core/src/main/java/com/volmit/iris/core/commands/CommandDeepSearch.java deleted file mode 100644 index d8cd6a260..000000000 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandDeepSearch.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2022 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.commands; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.pregenerator.DeepSearchPregenerator; -import com.volmit.iris.core.pregenerator.PregenTask; -import com.volmit.iris.core.pregenerator.TurboPregenerator; -import com.volmit.iris.core.tools.IrisToolbelt; -import com.volmit.iris.util.data.Dimension; -import com.volmit.iris.util.decree.DecreeExecutor; -import com.volmit.iris.util.decree.annotations.Decree; -import com.volmit.iris.util.decree.annotations.Param; -import com.volmit.iris.util.format.C; -import com.volmit.iris.util.math.Position2; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.util.Vector; - -import java.io.File; -import java.io.IOException; - -@Decree(name = "DeepSearch", aliases = "search", description = "Pregenerate your Iris worlds!") -public class CommandDeepSearch implements DecreeExecutor { - public String worldName; - @Decree(description = "DeepSearch a world") - public void start( - @Param(description = "The radius of the pregen in blocks", aliases = "size") - int radius, - @Param(description = "The world to pregen", contextual = true) - World world, - @Param(aliases = "middle", description = "The center location of the pregen. Use \"me\" for your current location", defaultValue = "0,0") - Vector center - ) { - - worldName = world.getName(); - File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName()); - File TurboFile = new File(worldDirectory, "DeepSearch.json"); - if (TurboFile.exists()) { - if (DeepSearchPregenerator.getInstance() != null) { - sender().sendMessage(C.BLUE + "DeepSearch is already in progress"); - Iris.info(C.YELLOW + "DeepSearch is already in progress"); - return; - } else { - try { - TurboFile.delete(); - } catch (Exception e){ - Iris.error("Failed to delete the old instance file of DeepSearch!"); - return; - } - } - } - - try { - if (sender().isPlayer() && access() == null) { - sender().sendMessage(C.RED + "The engine access for this world is null!"); - sender().sendMessage(C.RED + "Please make sure the world is loaded & the engine is initialized. Generate a new chunk, for example."); - } - - DeepSearchPregenerator.DeepSearchJob DeepSearchJob = DeepSearchPregenerator.DeepSearchJob.builder() - .world(world) - .radiusBlocks(radius) - .position(0) - .build(); - - File SearchGenFile = new File(worldDirectory, "DeepSearch.json"); - DeepSearchPregenerator pregenerator = new DeepSearchPregenerator(DeepSearchJob, SearchGenFile); - pregenerator.start(); - - String msg = C.GREEN + "DeepSearch started in " + C.GOLD + worldName + C.GREEN + " of " + C.GOLD + (radius * 2) + C.GREEN + " by " + C.GOLD + (radius * 2) + C.GREEN + " blocks from " + C.GOLD + center.getX() + "," + center.getZ(); - sender().sendMessage(msg); - Iris.info(msg); - } catch (Throwable e) { - sender().sendMessage(C.RED + "Epic fail. See console."); - Iris.reportError(e); - e.printStackTrace(); - } - } - - @Decree(description = "Stop the active DeepSearch task", aliases = "x") - public void stop(@Param(aliases = "world", description = "The world to pause") World world) throws IOException { - DeepSearchPregenerator DeepSearchInstance = DeepSearchPregenerator.getInstance(); - File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName()); - File turboFile = new File(worldDirectory, "DeepSearch.json"); - - if (DeepSearchInstance != null) { - DeepSearchInstance.shutdownInstance(world); - sender().sendMessage(C.LIGHT_PURPLE + "Closed Turbogen instance for " + world.getName()); - } else if (turboFile.exists() && turboFile.delete()) { - sender().sendMessage(C.LIGHT_PURPLE + "Closed Turbogen instance for " + world.getName()); - } else if (turboFile.exists()) { - Iris.error("Failed to delete the old instance file of Turbo Pregen!"); - } else { - sender().sendMessage(C.YELLOW + "No active pregeneration tasks to stop"); - } - } - - @Decree(description = "Pause / continue the active pregeneration task", aliases = {"t", "resume", "unpause"}) - public void pause( - @Param(aliases = "world", description = "The world to pause") - World world - ) { - if (TurboPregenerator.getInstance() != null) { - TurboPregenerator.setPausedTurbo(world); - sender().sendMessage(C.GREEN + "Paused/unpaused Turbo Pregen, now: " + (TurboPregenerator.isPausedTurbo(world) ? "Paused" : "Running") + "."); - } else { - File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName()); - File TurboFile = new File(worldDirectory, "DeepSearch.json"); - if (TurboFile.exists()){ - TurboPregenerator.loadTurboGenerator(world.getName()); - sender().sendMessage(C.YELLOW + "Started DeepSearch back up!"); - } else { - sender().sendMessage(C.YELLOW + "No active DeepSearch tasks to pause/unpause."); - } - - } - } -} diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java index 4bb6d9e52..2f67233b3 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java @@ -26,6 +26,7 @@ import com.volmit.iris.core.pregenerator.ChunkUpdater; import com.volmit.iris.core.service.IrisEngineSVC; import com.volmit.iris.core.tools.IrisPackBenchmarking; import com.volmit.iris.core.tools.IrisToolbelt; +import com.volmit.iris.core.tools.IrisWorldDump; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.mantle.components.MantleObjectComponent; import com.volmit.iris.engine.object.IrisBiome; @@ -169,11 +170,12 @@ public class CommandDeveloper implements DecreeExecutor { @Decree(description = "test") public void mca ( - @Param(description = "String") String world) { + @Param(description = "String") World world) { try { - File[] McaFiles = new File(world, "region").listFiles((dir, name) -> name.endsWith(".mca")); + File[] McaFiles = new File(world.getName(), "region").listFiles((dir, name) -> name.endsWith(".mca")); for (File mca : McaFiles) { - MCAFile MCARegion = MCAUtil.read(mca); + IrisWorldDump dump = new IrisWorldDump(world, sender()); + dump.dump(); } } catch (Exception e) { e.printStackTrace(); diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java index bea1dcd2b..71e5b89dd 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java @@ -85,7 +85,6 @@ import java.util.function.Supplier; public class CommandStudio implements DecreeExecutor { private CommandFind find; private CommandEdit edit; - //private CommandDeepSearch deepSearch; public static String hrf(Duration duration) { return duration.toString().substring(2).replaceAll("(\\d[HMS])(?!$)", "$1 ").toLowerCase(); diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/DeepSearchPregenerator.java b/core/src/main/java/com/volmit/iris/core/pregenerator/DeepSearchPregenerator.java deleted file mode 100644 index c60724d2a..000000000 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/DeepSearchPregenerator.java +++ /dev/null @@ -1,275 +0,0 @@ -package com.volmit.iris.core.pregenerator; - -import com.google.gson.Gson; -import com.volmit.iris.Iris; -import com.volmit.iris.core.tools.IrisToolbelt; -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.object.IrisBiome; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.format.C; -import com.volmit.iris.util.format.Form; -import com.volmit.iris.util.io.IO; -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.math.Spiraler; -import com.volmit.iris.util.scheduling.ChronoLatch; -import com.volmit.iris.util.scheduling.J; -import lombok.Builder; -import lombok.Data; -import lombok.Getter; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.world.WorldUnloadEvent; -import org.bukkit.scheduler.BukkitRunnable; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.locks.ReentrantLock; - -public class DeepSearchPregenerator extends Thread implements Listener { - @Getter - private static DeepSearchPregenerator instance; - private final DeepSearchJob job; - private final File destination; - private final int maxPosition; - private World world; - private final ChronoLatch latch; - private static AtomicInteger foundChunks; - private final AtomicInteger foundLast; - private final AtomicInteger foundTotalChunks; - private final AtomicLong startTime; - private final RollingSequence chunksPerSecond; - private final RollingSequence chunksPerMinute; - private final AtomicInteger chunkCachePos; - private final AtomicInteger chunkCacheSize; - private int pos; - private final AtomicInteger foundCacheLast; - private final AtomicInteger foundCache; - private LinkedHashMap chunkCache; - private KList chunkQueue; - private final ReentrantLock cacheLock; - - private static final Map jobs = new HashMap<>(); - - public DeepSearchPregenerator(DeepSearchJob job, File destination) { - this.job = job; - this.chunkCacheSize = new AtomicInteger(); // todo - this.chunkCachePos = new AtomicInteger(1000); - this.foundCacheLast = new AtomicInteger(); - this.foundCache = new AtomicInteger(); - this.cacheLock = new ReentrantLock(); - this.destination = destination; - this.chunkCache = new LinkedHashMap<>(); - this.maxPosition = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> { - }).count(); - this.world = Bukkit.getWorld(job.getWorld().getUID()); - this.chunkQueue = new KList<>(); - this.latch = new ChronoLatch(3000); - this.startTime = new AtomicLong(M.ms()); - this.chunksPerSecond = new RollingSequence(10); - this.chunksPerMinute = new RollingSequence(10); - foundChunks = new AtomicInteger(0); - this.foundLast = new AtomicInteger(0); - this.foundTotalChunks = new AtomicInteger((int) Math.ceil(Math.pow((2.0 * job.getRadiusBlocks()) / 16, 2))); - - this.pos = 0; - jobs.put(job.getWorld().getName(), job); - DeepSearchPregenerator.instance = this; - } - - @EventHandler - public void on(WorldUnloadEvent e) { - if (e.getWorld().equals(world)) { - interrupt(); - } - } - - public void run() { - while (!interrupted()) { - tick(); - } - try { - saveNow(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public void tick() { - DeepSearchJob job = jobs.get(world.getName()); - // chunkCache(); //todo finish this - if (latch.flip() && !job.paused) { - if (cacheLock.isLocked()) { - Iris.info("DeepFinder: Caching: " + chunkCachePos.get() + " Of " + chunkCacheSize.get()); - } else { - long eta = computeETA(); - save(); - int secondGenerated = foundChunks.get() - foundLast.get(); - foundLast.set(foundChunks.get()); - secondGenerated = secondGenerated / 3; - chunksPerSecond.put(secondGenerated); - chunksPerMinute.put(secondGenerated * 60); - Iris.info("DeepFinder: " + C.IRIS + world.getName() + C.RESET + " Searching: " + Form.f(foundChunks.get()) + " of " + Form.f(foundTotalChunks.get()) + " " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2)); - } - - } - if (foundChunks.get() >= foundTotalChunks.get()) { - Iris.info("Completed DeepSearch!"); - interrupt(); - } - } - - private long computeETA() { - return (long) ((foundTotalChunks.get() - foundChunks.get()) / chunksPerSecond.getAverage()) * 1000; - // todo broken - } - - private final ExecutorService executorService = Executors.newSingleThreadExecutor(); - - private void queueSystem(Position2 chunk) { - if (chunkQueue.isEmpty()) { - for (int limit = 512; limit != 0; limit--) { - pos = job.getPosition() + 1; - chunkQueue.add(getChunk(pos)); - } - } else { - //MCAUtil.read(); - - } - - - } - - private void findInChunk(World world, int x, int z) throws IOException { - int xx = x * 16; - int zz = z * 16; - Engine engine = IrisToolbelt.access(world).getEngine(); - for (int i = 0; i < 16; i++) { - for (int j = 0; j < 16; j++) { - int height = engine.getHeight(xx + i, zz + j); - if (height > 300) { - File found = new File("plugins" + "iris" + "found.txt"); - FileWriter writer = new FileWriter(found); - if (!found.exists()) { - found.createNewFile(); - } - IrisBiome biome = engine.getBiome(xx, engine.getHeight(), zz); - Iris.info("Found at! " + xx + ", " + zz + "Biome ID: " + biome.getName() + ", "); - writer.write("Biome at: X: " + xx + " Z: " + zz + "Biome ID: " + biome.getName() + ", "); - return; - } - } - } - } - - public Position2 getChunk(int position) { - int p = -1; - AtomicInteger xx = new AtomicInteger(); - AtomicInteger zz = new AtomicInteger(); - Spiraler s = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> { - xx.set(x); - zz.set(z); - }); - - while (s.hasNext() && p++ < position) { - s.next(); - } - - return new Position2(xx.get(), zz.get()); - } - - public void save() { - J.a(() -> { - try { - saveNow(); - } catch (Throwable e) { - e.printStackTrace(); - } - }); - } - - public static void setPausedDeep(World world) { - DeepSearchJob job = jobs.get(world.getName()); - if (isPausedDeep(world)){ - job.paused = false; - } else { - job.paused = true; - } - - if ( job.paused) { - Iris.info(C.BLUE + "DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " Paused"); - } else { - Iris.info(C.BLUE + "DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " Resumed"); - } - } - - public static boolean isPausedDeep(World world) { - DeepSearchJob job = jobs.get(world.getName()); - return job != null && job.isPaused(); - } - - public void shutdownInstance(World world) throws IOException { - Iris.info("DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " Shutting down.."); - DeepSearchJob job = jobs.get(world.getName()); - File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName()); - File deepFile = new File(worldDirectory, "DeepSearch.json"); - - if (job == null) { - Iris.error("No DeepSearch job found for world: " + world.getName()); - return; - } - - try { - if (!job.isPaused()) { - job.setPaused(true); - } - save(); - jobs.remove(world.getName()); - new BukkitRunnable() { - @Override - public void run() { - while (deepFile.exists()){ - deepFile.delete(); - J.sleep(1000); - } - Iris.info("DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " File deleted and instance closed."); - } - }.runTaskLater(Iris.instance, 20L); - } catch (Exception e) { - Iris.error("Failed to shutdown DeepSearch for " + world.getName()); - e.printStackTrace(); - } finally { - saveNow(); - interrupt(); - } - } - - - public void saveNow() throws IOException { - IO.writeAll(this.destination, new Gson().toJson(job)); - } - - @Data - @Builder - public static class DeepSearchJob { - private World world; - @Builder.Default - private int radiusBlocks = 5000; - @Builder.Default - private int position = 0; - @Builder.Default - boolean paused = false; - } -} - diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisWorldDump.java b/core/src/main/java/com/volmit/iris/core/tools/IrisWorldDump.java new file mode 100644 index 000000000..47c40528b --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisWorldDump.java @@ -0,0 +1,114 @@ +package com.volmit.iris.core.tools; + +import com.volmit.iris.Iris; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.format.C; +import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.nbt.mca.Chunk; +import com.volmit.iris.util.nbt.mca.MCAFile; +import com.volmit.iris.util.nbt.mca.MCAUtil; +import com.volmit.iris.util.nbt.tag.CompoundTag; +import com.volmit.iris.util.plugin.VolmitSender; +import org.bukkit.World; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReferenceArray; + +public class IrisWorldDump { + private KList mcaList; + private World world; + private File MCADirectory; + private AtomicInteger processed; + private AtomicInteger totalToProcess; + private Engine engine = null; + private Boolean IrisWorld; + private VolmitSender sender; + + public IrisWorldDump(World world, VolmitSender sender) { + this.world = world; + this.sender = sender; + this.MCADirectory = new File(world.getWorldFolder(), "region"); + if (Runtime.getRuntime().maxMemory() < 1.5 * estimateMemoryUsage()) { + sender.sendMessage(C.YELLOW + "Not enough memory!"); + sender.sendMessage(C.YELLOW + "- Process amount: " + Form.memSize(Runtime.getRuntime().maxMemory())); + sender.sendMessage(C.YELLOW + "- Required amount: " + Form.memSize(estimateMemoryUsage())); + //return; + } + sender.sendMessage("Initializing IrisWorldDump..."); + + this.mcaList = new KList<>(getMcaFiles()); + this.processed = new AtomicInteger(0); + this.totalToProcess = new AtomicInteger(0); + + try { + this.engine = IrisToolbelt.access(world).getEngine(); + this.IrisWorld = true; + } catch (Exception e) { + this.IrisWorld = false; + } + } + + public void dump() { + for (MCAFile mca : mcaList) { + AtomicReferenceArray chunks = new AtomicReferenceArray<>(1024); + for (int i = 0; i < chunks.length(); i++) { + chunks.set(i, mca.getChunks().get(i)); + } + for (int i = 0; i < chunks.length(); i++) { + Chunk chunk = chunks.get(i); + if (chunk != null) { + int CHUNK_HEIGHT = (world.getMaxHeight() - world.getMinHeight()); + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + for (int y = 0; y < CHUNK_HEIGHT; y++) { + CompoundTag tag = chunk.getBlockStateAt(x,y,z); + int i1 = 0; + } + } + } + } + + } + + } + + + } + + + private long estimateMemoryUsage() { + long size = 0; + for (File mca : MCADirectory.listFiles()) { + size =+ mca.length(); + } + return size; + } + + private List getMcaFiles() { + List mcaFiles = new ArrayList<>(); + int l = 0; + int f = 0; + for (File mca : MCADirectory.listFiles()) { + if (mca.getName().endsWith(".mca")) { + try { + mcaFiles.add(MCAUtil.read(mca)); + l++; + } catch (Exception e) { + f++; + Iris.error("Failed to read mca file: " + mca.getName(), e); + e.printStackTrace(); // todo: debug line + } + } + } + sender.sendMessage("Loaded: " + l + " MCA Regions"); + if (f > 0) { + sender.sendMessage(C.RED +"Failed " + C.GRAY + "to load: " + f + " MCA Regions"); + } + return mcaFiles; + } + +} diff --git a/core/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java b/core/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java index f74cdcf7f..044f0ccd1 100644 --- a/core/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java +++ b/core/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java @@ -150,8 +150,8 @@ public class Chunk { if ((loadFlags & STRUCTURES) != 0) { structures = level.getCompoundTag("Structures"); } - if ((loadFlags & (BLOCK_LIGHTS | BLOCK_STATES | SKY_LIGHT)) != 0 && level.containsKey("Sections")) { - for (CompoundTag section : level.getListTag("Sections").asCompoundTagList()) { + if ((loadFlags & (BLOCK_LIGHTS | BLOCK_STATES | SKY_LIGHT)) != 0 && level.containsKey("sections")) { + for (CompoundTag section : level.getListTag("sections").asCompoundTagList()) { int sectionIndex = section.getByte("Y"); if (sectionIndex > 15 || sectionIndex < 0) { continue; diff --git a/core/src/main/java/com/volmit/iris/util/nbt/mca/Section.java b/core/src/main/java/com/volmit/iris/util/nbt/mca/Section.java index f58f74faf..0b8ea71b2 100644 --- a/core/src/main/java/com/volmit/iris/util/nbt/mca/Section.java +++ b/core/src/main/java/com/volmit/iris/util/nbt/mca/Section.java @@ -37,7 +37,8 @@ public class Section { public Section(CompoundTag sectionRoot, int dataVersion, long loadFlags) { data = sectionRoot; - ListTag rawPalette = sectionRoot.getListTag("Palette"); + //ListTag rawPalette = sectionRoot.getListTag("palette"); + ListTag rawPalette = sectionRoot.getCompoundTag("biomes").getListTag("palette"); if (rawPalette == null) { return; } diff --git a/core/src/main/java/com/volmit/iris/util/nbt/mca/palette/MCAWrappedPalettedContainer.java b/core/src/main/java/com/volmit/iris/util/nbt/mca/palette/MCAWrappedPalettedContainer.java index fcd7edd5c..3749e74f3 100644 --- a/core/src/main/java/com/volmit/iris/util/nbt/mca/palette/MCAWrappedPalettedContainer.java +++ b/core/src/main/java/com/volmit/iris/util/nbt/mca/palette/MCAWrappedPalettedContainer.java @@ -42,6 +42,7 @@ public class MCAWrappedPalettedContainer implements MCAPaletteAccess { } public void readFromSection(CompoundTag tag) { - container.read(tag.getListTag("Palette"), tag.getLongArrayTag("BlockStates").getValue()); + //container.read(tag.getListTag("palette"), tag.getLongArrayTag("block_states").getValue()); + container.read(tag.getCompoundTag("block_states").getListTag("palette"), tag.getCompoundTag("block_states").getLongArrayTag("data").getValue()); } }