mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-01-03 22:26:25 +00:00
- Iris Updater
Updates chunks thats it/
This commit is contained in:
@@ -21,6 +21,7 @@ package com.volmit.iris.core.commands;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.loader.IrisData;
|
||||
import com.volmit.iris.core.pregenerator.ChunkUpdater;
|
||||
import com.volmit.iris.core.service.StudioSVC;
|
||||
import com.volmit.iris.core.tools.IrisBenchmarking;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
@@ -37,6 +38,7 @@ import com.volmit.iris.util.decree.annotations.Decree;
|
||||
import com.volmit.iris.util.decree.annotations.Param;
|
||||
import com.volmit.iris.util.decree.specialhandlers.NullablePlayerHandler;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.plugin.VolmitSender;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import lombok.Getter;
|
||||
@@ -317,6 +319,24 @@ public class CommandIris implements DecreeExecutor {
|
||||
return dir.delete();
|
||||
}
|
||||
|
||||
@Decree(description = "Updates all chunk in the specified world")
|
||||
public void updater(
|
||||
@Param(description = "World to update chunks at")
|
||||
World world
|
||||
) {
|
||||
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||
sender().sendMessage(C.GOLD + "This is not an Iris world");
|
||||
return;
|
||||
}
|
||||
ChunkUpdater updater = new ChunkUpdater(world);
|
||||
if (sender().isPlayer()) {
|
||||
sender().sendMessage(C.GREEN + "Updating " + world.getName() + " Total chunks: " + Form.f(updater.getChunks()));
|
||||
} else {
|
||||
Iris.info(C.GREEN + "Updating " + world.getName() + " Total chunks: " + Form.f(updater.getChunks()));
|
||||
}
|
||||
updater.start();
|
||||
}
|
||||
|
||||
@Decree(description = "Set aura spins")
|
||||
public void aura(
|
||||
@Param(description = "The h color value", defaultValue = "-20")
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
package com.volmit.iris.core.pregenerator;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
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.math.Spiraler;
|
||||
import com.volmit.iris.util.nbt.mca.MCAFile;
|
||||
import com.volmit.iris.util.nbt.mca.MCAUtil;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public class ChunkUpdater {
|
||||
private AtomicBoolean cancelled;
|
||||
@@ -25,12 +34,19 @@ public class ChunkUpdater {
|
||||
private final AtomicInteger totalMaxChunks;
|
||||
private final AtomicInteger totalMcaregions;
|
||||
private final AtomicInteger position;
|
||||
private AtomicInteger chunksProcessed;
|
||||
private AtomicInteger chunksUpdated;
|
||||
private AtomicLong startTime;
|
||||
private ExecutorService executor;
|
||||
private ScheduledExecutorService scheduler;
|
||||
private final File[] McaFiles;
|
||||
private final Engine engine;
|
||||
private final World world;
|
||||
|
||||
public ChunkUpdater(World world) {
|
||||
File cacheDir = new File("plugins" + File.separator + "iris" + File.separator + "cache");
|
||||
File chunkCacheDir = new File("plugins" + File.separator + "iris" + File.separator + "cache" + File.separator + "spiral");
|
||||
this.engine = IrisToolbelt.access(world).getEngine();
|
||||
this.chunksPerSecond = new RollingSequence(10);
|
||||
this.mcaregionsPerSecond = new RollingSequence(10);
|
||||
this.world = world;
|
||||
@@ -38,33 +54,82 @@ public class ChunkUpdater {
|
||||
this.McaFiles = new File(world.getWorldFolder(), "region").listFiles((dir, name) -> name.endsWith(".mca"));
|
||||
this.worldheightsize = new AtomicInteger(calculateWorldDimensions(new File(world.getWorldFolder(), "region"), 1));
|
||||
this.worldwidthsize = new AtomicInteger(calculateWorldDimensions(new File(world.getWorldFolder(), "region"), 0));
|
||||
this.totalMaxChunks = new AtomicInteger((worldheightsize.get() / 16 ) * (worldwidthsize.get() / 16));
|
||||
int m = Math.max(worldheightsize.get(), worldwidthsize.get());
|
||||
this.executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() - 2);
|
||||
this.scheduler = Executors.newScheduledThreadPool(1);
|
||||
this.startTime = new AtomicLong();
|
||||
this.worldheightsize.set(m);
|
||||
this.worldwidthsize.set(m);
|
||||
this.totalMaxChunks = new AtomicInteger((worldheightsize.get() / 16) * (worldwidthsize.get() / 16));
|
||||
this.chunksProcessed = new AtomicInteger();
|
||||
this.chunksUpdated = new AtomicInteger();
|
||||
this.position = new AtomicInteger(0);
|
||||
this.cancelled = new AtomicBoolean(false);
|
||||
this.totalChunks = new AtomicInteger(0);
|
||||
this.totalMcaregions = new AtomicInteger(0);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
Initialize();
|
||||
public int getChunks() {
|
||||
return totalMaxChunks.get();
|
||||
}
|
||||
|
||||
public void Initialize() {
|
||||
Iris.info("Initializing..");
|
||||
public void start() {
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
private void update() {
|
||||
Iris.info("Updating..");
|
||||
try {
|
||||
for (File mca : McaFiles) {
|
||||
MCAFile MCARegion = MCAUtil.read(mca);
|
||||
for (int pos = 0; pos != totalMaxChunks.get(); pos++) {
|
||||
int[] coords = getChunk(pos);
|
||||
if(MCARegion.hasChunk(coords[0], coords[1])) chunkMap.add(coords);
|
||||
startTime.set(System.currentTimeMillis());
|
||||
scheduler.scheduleAtFixedRate(() -> {
|
||||
try {
|
||||
long eta = computeETA();
|
||||
long elapsedSeconds = (System.currentTimeMillis() - startTime.get()) / 1000;
|
||||
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("Updated: " + Form.f(processed) + " of : " + Form.f(totalMaxChunks.get()) + " (%.0f%%) " + Form.f(chunksPerSecond.getAverage()) + "/s, ETA: " + Form.duration(eta, 2), percentage);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, 0, 3, TimeUnit.SECONDS);
|
||||
|
||||
for (int i = 0; i < totalMaxChunks.get(); i++) {
|
||||
executor.submit(this::processNextChunk);
|
||||
}
|
||||
Iris.info("Finished Initializing..");
|
||||
|
||||
executor.shutdown();
|
||||
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
|
||||
scheduler.shutdownNow();
|
||||
Iris.info("Processed: " + Form.f(chunksProcessed.get()) + " Chunks");
|
||||
Iris.info("Finished Updating: " + Form.f(chunksUpdated.get()) + " Chunks");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void processNextChunk() {
|
||||
int pos = position.getAndIncrement();
|
||||
int[] coords = getChunk(pos);
|
||||
if (PaperLib.isChunkGenerated(world, coords[0], coords[1])) {
|
||||
Chunk chunk = world.getChunkAt(coords[0], coords[1]);
|
||||
engine.updateChunk(chunk);
|
||||
chunksUpdated.getAndIncrement();
|
||||
}
|
||||
chunksProcessed.getAndIncrement();
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
public int calculateWorldDimensions(File regionDir, Integer o) {
|
||||
File[] files = regionDir.listFiles((dir, name) -> name.endsWith(".mca"));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user