From 9a24627ceb822eb3b7e41f3890ffe8ba32987d59 Mon Sep 17 00:00:00 2001 From: RePixelatedMC <107539181+RePixelatedMC@users.noreply.github.com> Date: Fri, 27 Sep 2024 17:07:01 +0200 Subject: [PATCH] backup --- .../iris/core/commands/CommandDeepSearch.java | 134 ------------- .../iris/core/commands/CommandDeveloper.java | 11 ++ .../iris/core/tools/IrisBiomeFixer.java | 176 ++++++++++++++++-- 3 files changed, 168 insertions(+), 153 deletions(-) delete mode 100644 core/src/main/java/com/volmit/iris/core/commands/CommandDeepSearch.java 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 cb43a29d2..a65d2c680 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.nms.datapack.DataVersion; import com.volmit.iris.core.nms.v1X.NMSBinding1X; import com.volmit.iris.core.pregenerator.ChunkUpdater; import com.volmit.iris.core.service.IrisEngineSVC; +import com.volmit.iris.core.tools.IrisBiomeFixer; import com.volmit.iris.core.tools.IrisConverter; import com.volmit.iris.core.tools.IrisPackBenchmarking; import com.volmit.iris.core.tools.IrisToolbelt; @@ -160,6 +161,16 @@ public class CommandDeveloper implements DecreeExecutor { } + @Decree(description = "Fix biomes in a iris world") + public void fixBiomes( + @Param(description = "The IrisWorld to fix biomes at") World world) { + + IrisBiomeFixer biomeFixer = new IrisBiomeFixer(world); + Iris.info("Fixing biomes."); + biomeFixer.fixBiomes(); + Iris.info("Done fixing biomes!"); + } + @Decree(description = "Upgrade to another Minecraft version") public void upgrade( @Param(description = "The version to upgrade to", defaultValue = "latest") DataVersion version) { diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisBiomeFixer.java b/core/src/main/java/com/volmit/iris/core/tools/IrisBiomeFixer.java index f202d2a11..424489f4f 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisBiomeFixer.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisBiomeFixer.java @@ -1,46 +1,184 @@ package com.volmit.iris.core.tools; import com.volmit.iris.Iris; -import com.volmit.iris.util.format.C; -import com.volmit.iris.util.format.Form; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.object.IrisBiome; +import com.volmit.iris.engine.object.IrisBiomeCustom; import com.volmit.iris.util.math.M; -import com.volmit.iris.util.math.Position2; -import com.volmit.iris.util.math.Spiraler; -import com.volmit.iris.util.misc.E; -import com.volmit.iris.util.nbt.mca.MCAFile; -import com.volmit.iris.util.nbt.mca.MCAUtil; -import com.volmit.iris.util.parallel.BurstExecutor; -import com.volmit.iris.util.parallel.MultiBurst; +import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.math.RollingSequence; import com.volmit.iris.util.scheduling.ChronoLatch; -import org.bukkit.Chunk; +import com.volmit.iris.util.scheduling.J; import org.bukkit.World; import java.io.File; -import java.io.FileNotFoundException; -import java.util.ArrayList; + +import org.bukkit.Chunk; +import org.bukkit.block.Biome; +import org.bukkit.block.Block; + import java.util.concurrent.atomic.AtomicInteger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.util.concurrent.atomic.AtomicLong; public class IrisBiomeFixer { /** - * Do a pregen style approach irritate across a certain region and set everything to the correct biome again. + * Do a pregen style approach iterate across a certain region and set everything to the correct biome again. * Have 2 modes ( all, surface-only ) surface-only gets the underground caves from a different world */ private World world; + private Engine engine; private int radius; private ChronoLatch latch; + private RollingSequence chunksPerSecond; + private AtomicLong startTime; + private AtomicLong lastLogTime; - public IrisBiomeFixer(World world, int radius) { + private AtomicInteger generated = new AtomicInteger(0); + private AtomicInteger lastGenerated = new AtomicInteger(0); + private AtomicInteger totalChunks = new AtomicInteger(0); + private ChronoLatch progressLatch = new ChronoLatch(5000); // Update every 5 seconds + + public IrisBiomeFixer(World world) { + if (!IrisToolbelt.isIrisWorld(world)) { + Iris.info("This is not an Iris world!"); + return; + } + + this.chunksPerSecond = new RollingSequence(32); + this.startTime = new AtomicLong(M.ms()); + this.lastLogTime = new AtomicLong(M.ms()); this.world = world; - this.radius = radius; this.latch = new ChronoLatch(3000); - - + this.engine = IrisToolbelt.access(world).getEngine(); } + public void fixBiomes() { + File regionFolder = new File(world.getWorldFolder(), "region"); + File[] regionFiles = regionFolder.listFiles((dir, name) -> name.endsWith(".mca")); + + if (regionFiles == null || regionFiles.length == 0) { + Iris.info("No region files found in " + regionFolder.getAbsolutePath()); + return; + } + + RNG rng = new RNG(engine.getSeedManager().getBiome()); + + // Calculate total chunks + for (File regionFile : regionFiles) { + String filename = regionFile.getName(); // e.g., "r.0.0.mca" + String[] parts = filename.split("\\."); + + if (parts.length != 4) { + continue; + } + + totalChunks.addAndGet(1024); // Each region has 32x32 chunks = 1024 + } + + for (File regionFile : regionFiles) { + String filename = regionFile.getName(); // e.g., "r.0.0.mca" + String[] parts = filename.split("\\."); + + if (parts.length != 4) { + continue; + } + + int regionX = Integer.parseInt(parts[1]); + int regionZ = Integer.parseInt(parts[2]); + + for (int cx = 0; cx < 32; cx++) { + for (int cz = 0; cz < 32; cz++) { + int chunkX = regionX * 32 + cx; + int chunkZ = regionZ * 32 + cz; + + if (!world.isChunkGenerated(chunkX, chunkZ)) { + continue; + } + + J.s(() -> { + world.loadChunk(chunkX, chunkZ); + }); + Chunk chunk = world.getChunkAt(chunkX, chunkZ); + + int minY = world.getMinHeight(); + int maxY = world.getMaxHeight(); + + for (int x = 0; x < 16; x++) { + for (int y = minY; y < maxY; y++) { + for (int z = 0; z < 16; z++) { + Block block = chunk.getBlock(x, y, z); + Biome bukkitBiome = null; + IrisBiome irisBiome = engine.getBiome(x, y, z); + IrisBiomeCustom custom = irisBiome.getCustomBiome(rng, x, y, z); + if (custom != null) { + bukkitBiome = Biome.valueOf(custom.getId().toUpperCase()); + } else { + } + + world.setBiome(block.getX(), block.getY(), block.getZ(), bukkitBiome); + } + } + } + + generated.incrementAndGet(); + + // Progress Logging + if (progressLatch.flip()) { + long currentTime = M.ms(); + long elapsedTime = currentTime - lastLogTime.get(); + int currentGenerated = generated.get(); + int last = lastGenerated.getAndSet(currentGenerated); + int chunksProcessed = currentGenerated - last; + + double seconds = elapsedTime / 1000.0; + int cps = seconds > 0 ? (int) (chunksProcessed / seconds) : 0; + chunksPerSecond.put(cps); + + long eta = computeETA(cps); + double percentage = ((double) currentGenerated / totalChunks.get()) * 100; + + Iris.info(String.format("Biome Fixer Progress: %d/%d chunks (%.2f%%) - %d chunks/s ETA: %s", + currentGenerated, totalChunks.get(), percentage, cps, formatETA(eta))); + + lastLogTime.set(currentTime); + } + + world.unloadChunk(chunkX, chunkZ); + } + } + } + + // Final Progress Update + Iris.info(String.format("Biome Fixing Completed: %d/%d chunks processed.", generated.get(), totalChunks.get())); + } + + private long computeETA(int cps) { + if (chunksPerSecond.size() < chunksPerSecond.getMax()) { + if (cps == 0) return Long.MAX_VALUE; + int remaining = totalChunks.get() - generated.get(); + return (long) ((double) remaining / cps) * 1000; + } else { + double averageCps = chunksPerSecond.getAverage(); + if (averageCps == 0) return Long.MAX_VALUE; + int remaining = totalChunks.get() - generated.get(); + return (long) ((double) remaining / averageCps) * 1000; + } + } + + private String formatETA(long millis) { + if (millis == Long.MAX_VALUE) { + return "Unknown"; + } + long seconds = millis / 1000; + long minutes = seconds / 60; + seconds %= 60; + long hours = minutes / 60; + minutes %= 60; + return String.format("%02dh:%02dm:%02ds", hours, minutes, seconds); + } } +