mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-04-07 08:16:31 +00:00
backup
This commit is contained in:
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user