This commit is contained in:
RePixelatedMC
2024-10-19 17:16:29 +02:00
parent 8755449c13
commit 2133a03c21
6 changed files with 37 additions and 514 deletions

View File

@@ -23,20 +23,11 @@ import com.volmit.iris.core.ServerConfigurator;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.core.nms.INMS;
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;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.mantle.components.MantleObjectComponent;
import com.volmit.iris.engine.object.IrisBiome;
import com.volmit.iris.engine.object.IrisCave;
import com.volmit.iris.engine.object.IrisDimension;
import com.volmit.iris.engine.object.IrisEntity;
import com.volmit.iris.util.data.Dimension;
import com.volmit.iris.util.decree.DecreeExecutor;
import com.volmit.iris.util.decree.DecreeOrigin;
import com.volmit.iris.util.decree.annotations.Decree;
@@ -45,21 +36,16 @@ 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.mantle.TectonicPlate;
import com.volmit.iris.util.math.Spiraler;
import com.volmit.iris.util.math.Vector3d;
import com.volmit.iris.util.nbt.mca.MCAFile;
import com.volmit.iris.util.nbt.mca.MCAUtil;
import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.plugin.VolmitSender;
import io.lumine.mythic.bukkit.adapters.BukkitEntity;
import net.jpountz.lz4.LZ4BlockInputStream;
import net.jpountz.lz4.LZ4BlockOutputStream;
import net.jpountz.lz4.LZ4FrameInputStream;
import net.jpountz.lz4.LZ4FrameOutputStream;
import org.apache.commons.lang.RandomStringUtils;
import org.bukkit.*;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.EntityType;
import java.io.*;
import java.net.InetAddress;
@@ -73,7 +59,6 @@ import java.util.zip.GZIPOutputStream;
@Decree(name = "Developer", origin = DecreeOrigin.BOTH, description = "Iris World Manager", aliases = {"dev"})
public class CommandDeveloper implements DecreeExecutor {
private CommandTurboPregen turboPregen;
private CommandUpdater updater;
@Decree(description = "Get Loaded TectonicPlates Count", origin = DecreeOrigin.BOTH, sync = true)
@@ -164,16 +149,6 @@ public class CommandDeveloper implements DecreeExecutor {
sender().sendMessage("Height: " + player().getWorld().getHighestBlockAt(player().getLocation(), HeightMap.MOTION_BLOCKING).getY());
}
@Decree(description = "Fix biomes in a iris world", aliases = {"fb"} )
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 = "check", aliases = {"ck"} )
public void check() {
sender().sendMessage("Data Pack Biome: " + INMS.get().getTrueBiomeBaseKey(player().getLocation()) + " (ID: " + INMS.get().getTrueBiomeBaseId(INMS.get().getTrueBiomeBase(player().getLocation())) + ")");

View File

@@ -79,7 +79,6 @@ public class CommandIris implements DecreeExecutor {
private CommandWhat what;
private CommandEdit edit;
private CommandFind find;
private CommandSupport support;
private CommandDeveloper developer;
public static boolean worldCreation = false;
String WorldEngine;

View File

@@ -1,82 +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.loader.IrisData;
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.engine.framework.Engine;
import com.volmit.iris.engine.object.IrisDimension;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.decree.DecreeExecutor;
import com.volmit.iris.util.decree.DecreeOrigin;
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.format.Form;
import com.volmit.iris.util.io.IO;
import com.volmit.iris.util.mantle.TectonicPlate;
import com.volmit.iris.util.misc.Hastebin;
import com.volmit.iris.util.misc.Platform;
import com.volmit.iris.util.misc.getHardware;
import com.volmit.iris.util.nbt.mca.MCAFile;
import com.volmit.iris.util.nbt.mca.MCAUtil;
import com.volmit.iris.util.plugin.VolmitSender;
import net.jpountz.lz4.LZ4BlockInputStream;
import net.jpountz.lz4.LZ4BlockOutputStream;
import net.jpountz.lz4.LZ4FrameInputStream;
import net.jpountz.lz4.LZ4FrameOutputStream;
import org.apache.commons.lang.RandomStringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import oshi.SystemInfo;
import java.io.*;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
@Decree(name = "Support", origin = DecreeOrigin.BOTH, description = "Iris World Manager", aliases = {"support"})
public class CommandSupport implements DecreeExecutor {
@Decree(description = "report")
public void report() {
try {
if (sender().isPlayer()) sender().sendMessage(C.GOLD + "Creating report..");
if (!sender().isPlayer()) Iris.info(C.GOLD + "Creating report..");
Hastebin.enviornment(sender());
} catch (Exception e) {
Iris.info(C.RED + "Something went wrong: ");
e.printStackTrace();
}
}
}

View File

@@ -1,131 +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.LazyPregenerator;
import com.volmit.iris.core.pregenerator.TurboPregenerator;
import com.volmit.iris.core.pregenerator.TurboPregenerator;
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 org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.util.Vector;
import java.io.File;
import java.io.IOException;
@Decree(name = "turbopregen", aliases = "turbo", description = "Pregenerate your Iris worlds!")
public class CommandTurboPregen implements DecreeExecutor {
public String worldName;
@Decree(description = "Pregenerate 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, "turbogen.json");
if (TurboFile.exists()) {
if (TurboPregenerator.getInstance() != null) {
sender().sendMessage(C.BLUE + "Turbo pregen is already in progress");
Iris.info(C.YELLOW + "Turbo pregen is already in progress");
return;
} else {
try {
TurboFile.delete();
} catch (Exception e){
Iris.error("Failed to delete the old instance file of Turbo Pregen!");
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.");
}
TurboPregenerator.TurboPregenJob pregenJob = TurboPregenerator.TurboPregenJob.builder()
.world(worldName)
.radiusBlocks(radius)
.position(0)
.build();
File TurboGenFile = new File(worldDirectory, "turbogen.json");
TurboPregenerator pregenerator = new TurboPregenerator(pregenJob, TurboGenFile);
pregenerator.start();
String msg = C.GREEN + "TurboPregen 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 pregeneration task", aliases = "x")
public void stop(@Param(aliases = "world", description = "The world to pause") World world) throws IOException {
TurboPregenerator turboPregenInstance = TurboPregenerator.getInstance();
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
File turboFile = new File(worldDirectory, "turbogen.json");
if (turboPregenInstance != null) {
turboPregenInstance.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, "turbogen.json");
if (TurboFile.exists()){
TurboPregenerator.loadTurboGenerator(world.getName());
sender().sendMessage(C.YELLOW + "Started Turbo Pregen back up!");
} else {
sender().sendMessage(C.YELLOW + "No active Turbo Pregen tasks to pause/unpause.");
}
}
}
}

View File

@@ -1,233 +0,0 @@
package com.volmit.iris.core.tools;
import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.IrisBiome;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.math.RollingSequence;
import com.volmit.iris.util.scheduling.ChronoLatch;
import org.bukkit.World;
import org.bukkit.plugin.Plugin;
import org.bukkit.block.Biome;
import java.io.File;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
public class IrisBiomeFixer {
private World world;
private Engine engine;
private ChronoLatch latch;
private RollingSequence chunksPerSecond;
private RollingSequence chunksPerMinute;
private AtomicLong startTime;
private AtomicLong lastLogTime;
private AtomicInteger generated = new AtomicInteger(0);
private AtomicInteger generatedLast = new AtomicInteger(0);
private AtomicInteger generatedLastMinute = new AtomicInteger(0);
private AtomicInteger totalChunks = new AtomicInteger(0);
private ChronoLatch progressLatch = new ChronoLatch(5000); // Update every 5 seconds
private ChronoLatch minuteLatch = new ChronoLatch(60000, false);
private File unregisteredBiomesFile;
private Plugin plugin;
private ScheduledExecutorService progressUpdater;
public IrisBiomeFixer(World world) {
if (!IrisToolbelt.isIrisWorld(world)) {
Iris.info("This is not an Iris world!");
return;
}
this.chunksPerSecond = new RollingSequence(10);
this.chunksPerMinute = new RollingSequence(10);
this.startTime = new AtomicLong(M.ms());
this.lastLogTime = new AtomicLong(M.ms());
this.world = world;
this.latch = new ChronoLatch(3000);
this.engine = IrisToolbelt.access(world).getEngine();
this.plugin = Iris.instance;
// Initialize the file for storing unregistered biome IDs
this.unregisteredBiomesFile = new File(world.getWorldFolder(), "unregistered_biomes.txt");
// Initialize the progress updater executor
this.progressUpdater = Executors.newSingleThreadScheduledExecutor();
}
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);
}
// Start the progress updater
progressUpdater.scheduleAtFixedRate(this::updateProgress, 1, 1, TimeUnit.SECONDS);
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;
}
int minY = world.getMinHeight();
int maxY = world.getMaxHeight();
int height = maxY - minY; // Correct height calculation
Hunk<Object> biomes = Hunk.newHunk(16, height, 16);
for (int x = 0; x < 16; x += 4) {
for (int z = 0; z < 16; z += 4) {
for (int y = minY; y < maxY; y += 4) {
int realX = chunkX * 16 + x;
int realZ = chunkZ * 16 + z;
int realY = y;
IrisBiome biome = engine.getBiome(realX, realY, realZ);
Object biomeHolder = null;
if (biome.isCustom()) {
biomeHolder = INMS.get().getCustomBiomeBaseHolderFor(
engine.getDimension().getLoadKey() + ":" + biome.getCustomBiome(rng, realX, realY, realZ).getId());
} else {
Biome bukkitBiome = biome.getDerivative();
if (bukkitBiome != null) {
biomeHolder = INMS.get().getBiomeBase(world, bukkitBiome);
}
}
if (biomeHolder == null) {
Iris.warn("Biomeholder null! Unsure what to do.");
}
// Now fill the 4x4x4 block in the hunk
for (int subX = x; subX < x + 4 && subX < 16; subX++) {
for (int subZ = z; subZ < z + 4 && subZ < 16; subZ++) {
for (int subY = y; subY < y + 4 && subY < maxY; subY++) {
int relativeY = subY - minY; // Offset Y-coordinate
biomes.set(subX, relativeY, subZ, biomeHolder);
}
}
}
}
}
}
// Set biomes to the chunk using NMS
//INMS.get().setBiomes(cx, cz, engine.getWorld().realWorld(), biomes);
generated.incrementAndGet();
}
}
}
// Shut down the progress updater
progressUpdater.shutdown();
try {
if (!progressUpdater.awaitTermination(1, TimeUnit.MINUTES)) {
Iris.warn("Progress updater did not terminate in time.");
progressUpdater.shutdownNow();
}
} catch (InterruptedException e) {
Iris.warn("Progress updater interrupted during shutdown.");
progressUpdater.shutdownNow();
Thread.currentThread().interrupt();
}
Iris.info("Biome Fixing Completed: " + generated.get() + "/" + totalChunks.get() + " chunks processed.");
}
private void updateProgress() {
long currentTime = M.ms();
int currentGenerated = generated.get();
int last = generatedLast.getAndSet(currentGenerated);
int chunksProcessed = currentGenerated - last;
chunksPerSecond.put(chunksProcessed);
// Update chunks per minute
if (minuteLatch.flip()) {
int lastMinuteGenerated = generatedLastMinute.getAndSet(currentGenerated);
int minuteProcessed = currentGenerated - lastMinuteGenerated;
chunksPerMinute.put(minuteProcessed);
}
long eta = computeETA();
double percentage = ((double) currentGenerated / totalChunks.get()) * 100;
if (progressLatch.flip()) {
Iris.info("Biome Fixer Progress: " + currentGenerated + "/" + totalChunks.get() +
" chunks (" + Form.f(percentage) + "%%) - " +
chunksPerSecond.getAverage() + " chunks/s ETA: " + formatETA(eta));
}
}
private long computeETA() {
if (generated.get() > totalChunks.get() / 8) {
// Use smooth function
double elapsedTime = (double) (M.ms() - startTime.get());
double rate = generated.get() / elapsedTime; // chunks per millisecond
int remaining = totalChunks.get() - generated.get();
return (long) (remaining / rate);
} else {
// Use quick function
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 hours + "h:" + minutes + "m:" + seconds + "s";
}
}

View File

@@ -140,48 +140,43 @@ public class IrisConverter {
});
}
/**
*
* @param sender
*/
public static void convertJigsawStructure(File in, File out, VolmitSender sender) {
File dataFolder = Iris.instance.getDataFolder("convert");
try {
KMap<String, IrisJigsawPool> pools = new KMap<>();
KList<File> roots = new KList<>();
AtomicInteger total = new AtomicInteger(0);
AtomicInteger at = new AtomicInteger(0);
File destPools = new File(out.getAbsolutePath() + "/jigsaw-pools");
destPools.mkdirs();
findAllNBT(in, (folder, file) -> {
total.getAndIncrement();
if (roots.addIfMissing(folder)) {
String b = in.toURI().relativize(folder.toURI()).getPath();
if (b.startsWith("/")) {
b = b.substring(1);
}
if (b.endsWith("/")) {
b = b.substring(0, b.length() - 1);
}
pools.put(b, new IrisJigsawPool());
}
});
} catch (Exception e) {
Iris.error(C.RED + "Failed to convert: " + in.getPath());
e.printStackTrace();
}
}
// /**
// *
// * @param sender
// */
// public static void convertJigsawStructure(File in, File out, VolmitSender sender) {
// File dataFolder = Iris.instance.getDataFolder("convert");
// try {
// KMap<String, IrisJigsawPool> pools = new KMap<>();
// KList<File> roots = new KList<>();
// AtomicInteger total = new AtomicInteger(0);
// AtomicInteger at = new AtomicInteger(0);
// File destPools = new File(out.getAbsolutePath() + "/jigsaw-pools");
// destPools.mkdirs();
// findAllNBT(in, (folder, file) -> {
// total.getAndIncrement();
// if (roots.addIfMissing(folder)) {
// String b = in.toURI().relativize(folder.toURI()).getPath();
// if (b.startsWith("/")) {
// b = b.substring(1);
// }
//
// if (b.endsWith("/")) {
// b = b.substring(0, b.length() - 1);
// }
//
// pools.put(b, new IrisJigsawPool());
// }
// });
//
// } catch (Exception e) {
// Iris.error(C.RED + "Failed to convert: " + in.getPath());
// e.printStackTrace();
// }
//
//
//
// }
private static void findAllNBT(File path, Consumer2<File, File> inFile) {
if (path == null) {