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

- Added Lazy pregen as an option

This commit is contained in:
RePixelatedMC
2023-11-06 15:03:40 +01:00
parent 5004481685
commit 7afdbc2a53
5 changed files with 105 additions and 31 deletions

View File

@@ -20,6 +20,7 @@ package com.volmit.iris.core.commands;
import com.volmit.iris.Iris;
import com.volmit.iris.core.gui.PregeneratorJob;
import com.volmit.iris.core.pregenerator.LazyPregenerator;
import com.volmit.iris.core.pregenerator.PregenTask;
import com.volmit.iris.core.tools.IrisToolbelt;
import com.volmit.iris.util.decree.DecreeExecutor;
@@ -27,9 +28,12 @@ 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;
@Decree(name = "pregen", aliases = "pregenerate", description = "Pregenerate your Iris worlds!")
public class CommandPregen implements DecreeExecutor {
@Decree(description = "Pregenerate a world")
@@ -39,29 +43,68 @@ public class CommandPregen implements DecreeExecutor {
@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
Vector center,
@Param(aliases = "method", description = "The pregen method that will get used. Lazy or Async", defaultValue = "async")
String method
) {
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.");
if(method.equals("async") || method.equals("lazy")){
if (method.equalsIgnoreCase("async")) {
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.");
}
radius = Math.max(radius, 1024);
int w = (radius >> 9 + 1) * 2;
IrisToolbelt.pregenerate(PregenTask
.builder()
.center(new Position2(center.getBlockX() >> 9, center.getBlockZ() >> 9))
.width(w)
.height(w)
.build(), world);
String msg = C.GREEN + "Pregen started in " + C.GOLD + world.getName() + 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();
}
}
radius = Math.max(radius, 1024);
int w = (radius >> 9 + 1) * 2;
IrisToolbelt.pregenerate(PregenTask
.builder()
.center(new Position2(center.getBlockX() >> 9, center.getBlockZ() >> 9))
.width(w)
.height(w)
.build(), world);
String msg = C.GREEN + "Pregen started in " + C.GOLD + world.getName() + 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();
if (method.equalsIgnoreCase("lazy")) {
String worldName = world.getName();
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.");
}
LazyPregenerator.LazyPregenJob pregenJob = LazyPregenerator.LazyPregenJob.builder()
.world(worldName)
.healingPosition(0)
.healing(false)
.chunksPerMinute(999999999)
.radiusBlocks(radius)
.position(0)
.build();
LazyPregenerator pregenerator = new LazyPregenerator(pregenJob, new File("plugins/Iris/lazygen.json"));
pregenerator.start();
String msg = C.GREEN + "Pregen 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();
}
}
} else {
sender().sendMessage(C.RED + "Please use a valid method.");
}
}
@Decree(description = "Stop the active pregeneration task", aliases = "x")

View File

@@ -132,11 +132,6 @@ public class IrisPregenerator {
);
}
public static void shareData(){
long_generatedChunks = generated.get();
long_totalChunks = totalChunks.get();
}
public static long getLongGeneratedChunks() {
return long_generatedChunks;
}

View File

@@ -2,9 +2,12 @@ package com.volmit.iris.core.pregenerator;
import com.google.gson.Gson;
import com.volmit.iris.Iris;
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.math.M;
import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.RollingSequence;
import com.volmit.iris.util.math.Spiraler;
import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
@@ -20,6 +23,7 @@ import org.bukkit.event.world.WorldUnloadEvent;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
public class LazyPregenerator extends Thread implements Listener {
private final LazyPregenJob job;
@@ -28,6 +32,11 @@ public class LazyPregenerator extends Thread implements Listener {
private final World world;
private final long rate;
private final ChronoLatch latch;
private static AtomicInteger lazyGeneratedChunks;
private final AtomicInteger generatedLast;
private final AtomicInteger lazyTotalChunks;
private final AtomicLong startTime;
private final RollingSequence chunksPerSecond;
public LazyPregenerator(LazyPregenJob job, File destination) {
this.job = job;
@@ -36,7 +45,15 @@ public class LazyPregenerator extends Thread implements Listener {
}).count();
this.world = Bukkit.getWorld(job.getWorld());
this.rate = Math.round((1D / (job.chunksPerMinute / 60D)) * 1000D);
this.latch = new ChronoLatch(60000);
this.latch = new ChronoLatch(6000);
startTime = new AtomicLong(M.ms());
chunksPerSecond = new RollingSequence(10);
lazyGeneratedChunks = new AtomicInteger(0);
generatedLast = new AtomicInteger(0);
lazyTotalChunks = new AtomicInteger();
int radius = job.getRadiusBlocks();
lazyTotalChunks.set((int) Math.ceil(Math.pow((2.0 * radius) / 16, 2)));
}
public LazyPregenerator(File file) throws IOException {
@@ -81,17 +98,26 @@ public class LazyPregenerator extends Thread implements Listener {
public void tick() {
if (latch.flip()) {
long eta = computeETA();
save();
Iris.info("LazyGen: " + world.getName() + " RTT: " + Form.duration((Math.pow((job.radiusBlocks / 16D), 2) / job.chunksPerMinute) * 60 * 1000, 2));
int secondGenerated = lazyGeneratedChunks.get() - generatedLast.get();
generatedLast.set(lazyGeneratedChunks.get());
secondGenerated = secondGenerated / 6;
chunksPerSecond.put(secondGenerated);
Iris.info("LazyGen: " + C.IRIS + world.getName() + C.RESET + " RTT: " + Form.f(lazyGeneratedChunks.get()) + " of " + Form.f(lazyTotalChunks.get()) + " " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2));
//Iris.info("Debug: " + maxPosition);
//Iris.info("Debug1: " + job.getPosition());
// todo: Maxpos borked
}
if (job.getPosition() >= maxPosition) {
if (lazyGeneratedChunks.get() >= lazyTotalChunks.get()) {
if (job.isHealing()) {
int pos = (job.getHealingPosition() + 1) % maxPosition;
job.setHealingPosition(pos);
tickRegenerate(getChunk(pos));
} else {
Iris.verbose("Completed Lazy Gen!");
Iris.info("Completed Lazy Gen!");
interrupt();
}
} else {
@@ -101,6 +127,15 @@ public class LazyPregenerator extends Thread implements Listener {
}
}
private long computeETA() {
return (long) (lazyTotalChunks.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)
((lazyTotalChunks.get() - lazyGeneratedChunks.get()) * ((double) (M.ms() - startTime.get()) / (double) lazyGeneratedChunks.get())) :
// If no, use quick function (which is less accurate over time but responds better to the initial delay)
((lazyTotalChunks.get() - lazyGeneratedChunks.get()) / chunksPerSecond.getAverage()) * 1000 //
);
}
private void tickGenerate(Position2 chunk) {
if (PaperLib.isPaper()) {
PaperLib.getChunkAtAsync(world, chunk.getX(), chunk.getZ(), true).thenAccept((i) -> Iris.verbose("Generated Async " + chunk));
@@ -108,6 +143,7 @@ public class LazyPregenerator extends Thread implements Listener {
J.s(() -> world.getChunkAt(chunk.getX(), chunk.getZ()));
Iris.verbose("Generated " + chunk);
}
lazyGeneratedChunks.addAndGet(1);
}
private void tickRegenerate(Position2 chunk) {

View File

@@ -126,7 +126,7 @@ public class IrisPackBenchmarking {
int x = 0;
int z = 0;
LazyPregenerator.LazyPregenJob pregenJob = LazyPregenerator.LazyPregenJob.builder()
.world("Benchmark")
//.world("Benchmark")
.healingPosition(0)
.healing(false)
.chunksPerMinute(3200)

View File

@@ -38,7 +38,7 @@ public class UtilsSFG {
if (incompatiblePlugins.get("Dynmap")) {
Iris.safeguard(C.RED + "Dynmap");
Iris.safeguard(C.RED + "- The plugin Dynmap is not compatible with the server.");
Iris.safeguard(C.RED + "- If you want to have a map plugin like Dynmap, consider Bluemap or LiveAtlas.");
Iris.safeguard(C.RED + "- If you want to have a map plugin like Dynmap, consider Bluemap.");
}
if (incompatiblePlugins.get("TerraformGenerator") || incompatiblePlugins.get("Stratos")) {
Iris.safeguard(C.YELLOW + "Terraform Generator / Stratos");