9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2025-12-29 20:19:06 +00:00

Sync / Progress on dump

This commit is contained in:
RePixelatedMC
2024-05-01 12:21:48 +02:00
parent a919b91efb
commit bb78f412e0
17 changed files with 683 additions and 65 deletions

View File

@@ -42,6 +42,7 @@ public class IrisSettings {
private IrisSettingsConcurrency concurrency = new IrisSettingsConcurrency();
private IrisSettingsStudio studio = new IrisSettingsStudio();
private IrisSettingsPerformance performance = new IrisSettingsPerformance();
private IrisWorldDump worldDump = new IrisWorldDump();
public static int getThreadCount(int c) {
return switch (c) {
@@ -187,4 +188,8 @@ public class IrisSettings {
public boolean disableTimeAndWeather = true;
public boolean autoStartDefaultStudio = false;
}
@Data
public static class IrisWorldDump {
public int mcaCacheSize = 3;
}
}

View File

@@ -28,6 +28,7 @@ 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.jvm.VMJavaFX;
import com.volmit.iris.engine.mantle.components.MantleObjectComponent;
import com.volmit.iris.engine.object.IrisBiome;
import com.volmit.iris.engine.object.IrisCave;
@@ -172,11 +173,20 @@ public class CommandDeveloper implements DecreeExecutor {
public void mca (
@Param(description = "String") World world) {
try {
File[] McaFiles = new File(world.getName(), "region").listFiles((dir, name) -> name.endsWith(".mca"));
for (File mca : McaFiles) {
IrisWorldDump dump = new IrisWorldDump(world, sender(), IrisWorldDump.mode.RAW);
dump.dump();
}
IrisWorldDump dump = new IrisWorldDump(world, sender(), IrisWorldDump.mode.PACKED);
dump.start();
} catch (Exception e) {
e.printStackTrace();
}
}
@Decree(description = "test")
public void javafx () {
try {
VMJavaFX javaFX = new VMJavaFX(sender());
javaFX.start();
} catch (Exception e) {
e.printStackTrace();
}

View File

@@ -106,7 +106,7 @@ public class ChunkUpdater {
try {
if (!paused.get()) {
long eta = computeETA();
long elapsedSeconds = (System.currentTimeMillis() - startTime.get()) / 1000;
long elapsedSeconds = (System.currentTimeMillis() - startTime.get()) / 3000;
int processed = chunksProcessed.get();
double cps = elapsedSeconds > 0 ? processed / (double) elapsedSeconds : 0;
chunksPerSecond.put(cps);

View File

@@ -1,50 +1,77 @@
package com.volmit.iris.core.tools;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.math.RollingSequence;
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.nbt.tag.StringTag;
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.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReferenceArray;
public class IrisWorldDump {
private KList<MCAFile> mcaList;
private KMap<String, Long> storage;
private AtomicLong airStorage;
private World world;
private File MCADirectory;
private AtomicInteger processed;
private AtomicInteger regionsProcessed;
private AtomicInteger chunksProcessed;
private AtomicInteger totalToProcess;
private AtomicInteger totalMaxChunks;
private AtomicInteger totalMCAFiles;
private RollingSequence chunksPerSecond;
private Engine engine = null;
private Boolean IrisWorld;
private VolmitSender sender;
private ExecutorService executor;
private ScheduledExecutorService scheduler;
private AtomicLong startTime;
private mode mode;
private File dumps;
private File worldDump;
private int mcaCacheSize;
private File temp;
private File blocks;
private File structures;
public IrisWorldDump(World world, VolmitSender sender, mode mode) {
sender.sendMessage("Initializing IrisWorldDump...");
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.totalMCAFiles = new AtomicInteger(MCACount());
this.dumps = new File("plugins" + File.separator + "iris", "dumps");
this.worldDump = new File(dumps, world.getName());
this.mcaCacheSize = IrisSettings.get().getWorldDump().mcaCacheSize;
this.regionsProcessed = new AtomicInteger(0);
this.chunksProcessed = new AtomicInteger(0);
this.totalToProcess = new AtomicInteger(0);
this.totalMaxChunks = new AtomicInteger(totalMCAFiles.get() * 1024);
this.chunksPerSecond = new RollingSequence(10);
this.temp = new File(worldDump, "temp");
this.executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() - 1);
this.scheduler = Executors.newSingleThreadScheduledExecutor();
this.startTime = new AtomicLong();
this.storage = new KMap<>();
this.airStorage = new AtomicLong(0);
this.blocks = new File(worldDump, "blocks");
this.structures = new File(worldDump, "structures");
initialize();
try {
this.engine = IrisToolbelt.access(world).getEngine();
this.IrisWorld = true;
@@ -53,6 +80,45 @@ public class IrisWorldDump {
}
}
private void initialize() {
if (!dumps.exists()) {
if (!dumps.mkdirs()) {
System.err.println("Failed to create dump directory.");
return;
}
}
if (worldDump.exists() && !worldDump.delete()) {
System.err.println("Failed to delete existing world dump directory.");
return;
}
if (!worldDump.mkdir()) {
System.err.println("Failed to create world dump directory.");
return;
}
if (!blocks.mkdir()) {
System.err.println("Failed to create blocks directory.");
return;
}
if (!structures.mkdir()) {
System.err.println("Failed to create structures directory.");
return;
}
for (File mcaFile : MCADirectory.listFiles()) {
if (mcaFile.getName().endsWith(".mca")) {
totalToProcess.getAndIncrement();
}
}
}
public void start() {
dump();
updater();
}
public enum mode {
RAW {
@Override
@@ -64,69 +130,102 @@ public class IrisWorldDump {
@Override
public void methodDump() {
}
},
PACKED {
@Override
public void methodDump() {
}
};
public abstract void methodDump();
}
private void updater() {
startTime.set(System.currentTimeMillis());
scheduler.scheduleAtFixedRate(() -> {
long eta = computeETA();
long elapsedSeconds = (System.currentTimeMillis() - startTime.get()) / 3000;
int processed = chunksProcessed.get();
double cps = elapsedSeconds > 0 ? processed / (double) elapsedSeconds : 0;
chunksPerSecond.put(cps);
double percentage = ((double) chunksProcessed.get() / (double) totalMaxChunks.get()) * 100;
Iris.info("Processed: " + Form.f(processed) + " of " + Form.f(totalMaxChunks.get()) + " (%.0f%%) " + Form.f(chunksPerSecond.getAverage()) + "/s, ETA: " + Form.duration(eta, 2), percentage);
public void dump() {
for (MCAFile mca : mcaList) {
AtomicReferenceArray<Chunk> chunks = new AtomicReferenceArray<>(1024);
for (int i = 0; i < chunks.length(); i++) {
chunks.set(i, mca.getChunks().get(i));
}, 1, 3, TimeUnit.SECONDS);
}
private void dump() {
Iris.info("Starting the dump process.");
int threads = Runtime.getRuntime().availableProcessors();
AtomicInteger f = new AtomicInteger();
for (File mcaFile : MCADirectory.listFiles()) {
if (mcaFile.getName().endsWith(".mca")) {
executor.submit(() -> {
try {
processMCARegion( MCAUtil.read(mcaFile));
} catch (Exception e) {
f.getAndIncrement();
Iris.error("Failed to read mca file");
e.printStackTrace();
}
});
}
}
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);
//net.minecraft.world.level.chunk.PalettedContainer;
//net.minecraft.world.level.chunk.storage.ChunkSerializer;
}
private void processMCARegion(MCAFile mca) {
AtomicReferenceArray<Chunk> 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);
if (tag == null) {
String blockName = "minecraft:air";
//storage.compute(blockName, (key, count) -> (count == null) ? 1 : count + 1);
airStorage.getAndIncrement();
int ii = 0;
} else {
StringTag nameTag = tag.getStringTag("Name");
String blockName = nameTag.getValue();
storage.compute(blockName, (key, count) -> (count == null) ? 1 : count + 1);
int ii = 0;
}
}
}
}
chunksProcessed.getAndIncrement();
}
}
regionsProcessed.getAndIncrement();
}
private long estimateMemoryUsage() {
long size = 0;
private int MCACount() {
int size = 0;
for (File mca : MCADirectory.listFiles()) {
size =+ mca.length();
if (mca.getName().endsWith(".mca")) {
size++;
}
}
return size;
}
private List<MCAFile> getMcaFiles() {
List<MCAFile> mcaFiles = new ArrayList<>();
int l = 0;
int f = 0;
for (File mca : MCADirectory.listFiles()) {
// net.minecraft.world.level.chunk.PalettedContainer
// take a look at the classes `net.minecraft.world.level.chunk.PalettedContainer` and `net.minecraft.world.level.chunk.storage.ChunkSerializer`
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");
}
Iris.info("Successfull: " + Form.f(l));
Iris.info("Failed: " + Form.f(f));
return mcaFiles;
private long computeETA() {
return (long) (totalMaxChunks.get() > 1024 ? // Generated chunks exceed 1/8th of total?
// If yes, use smooth function (which gets more accurate over time since its less sensitive to outliers)
((totalMaxChunks.get() - chunksProcessed.get()) * ((double) (M.ms() - startTime.get()) / (double) chunksProcessed.get())) :
// If no, use quick function (which is less accurate over time but responds better to the initial delay)
((totalMaxChunks.get() - chunksProcessed.get()) / chunksPerSecond.getAverage()) * 1000
);
}
}

View File

@@ -0,0 +1,32 @@
package com.volmit.iris.engine.jvm;
import com.volmit.iris.util.plugin.VolmitSender;
public class VMJavaFX {
private VolmitSender sender;
public VMJavaFX(VolmitSender user) {
this.sender = user;
}
public void start() {
try {
// Start JavaFX in a new JVM
ProcessBuilder processBuilder = new ProcessBuilder(
"java",
"--module-path", "path/to/javafx-sdk/lib", // Set path to JavaFX SDK
"--add-modules", "javafx.controls,javafx.fxml",
"-jar", "path/to/javafx-application.jar"
);
processBuilder.inheritIO();
processBuilder.start();
sender.sendMessage("JavaFX application is launched!");
} catch (Exception e) {
sender.sendMessage("Failed to launch JavaFX application.");
e.printStackTrace();
}
}
}