- Fixed caves breaksurface

- changes
This commit is contained in:
RePixelatedMC
2024-03-31 17:53:10 +02:00
parent 50686795d0
commit eb94d97ea4
17 changed files with 320 additions and 194 deletions
+8 -1
View File
@@ -364,6 +364,13 @@ public class Iris extends VolmitPlugin implements Listener {
return Integer.parseInt(version); return Integer.parseInt(version);
} }
public static String getJava() {
String javaRuntimeName = System.getProperty("java.vm.name");
String javaRuntimeVendor = System.getProperty("java.vendor");
String javaRuntimeVersion = System.getProperty("java.vm.version");
return String.format("%s %s (build %s)", javaRuntimeName, javaRuntimeVendor, javaRuntimeVersion);
}
public static void reportErrorChunk(int x, int z, Throwable e, String extra) { public static void reportErrorChunk(int x, int z, Throwable e, String extra) {
if (IrisSettings.get().getGeneral().isDebug()) { if (IrisSettings.get().getGeneral().isDebug()) {
File f = instance.getDataFile("debug", "chunk-errors", "chunk." + x + "." + z + ".txt"); File f = instance.getDataFile("debug", "chunk-errors", "chunk." + x + "." + z + ".txt");
@@ -804,6 +811,7 @@ public class Iris extends VolmitPlugin implements Listener {
if (!passedserversoftware) { if (!passedserversoftware) {
Iris.info("Server type & version: " + C.RED + Bukkit.getVersion()); Iris.info("Server type & version: " + C.RED + Bukkit.getVersion());
} else { Iris.info("Server type & version: " + Bukkit.getVersion()); } } else { Iris.info("Server type & version: " + Bukkit.getVersion()); }
Iris.info("Java: " + getJava());
if (!instance.getServer().getVersion().contains("Purpur")) { if (!instance.getServer().getVersion().contains("Purpur")) {
if (instance.getServer().getVersion().contains("Spigot") && instance.getServer().getVersion().contains("Bukkit")) { if (instance.getServer().getVersion().contains("Spigot") && instance.getServer().getVersion().contains("Bukkit")) {
Iris.info(C.RED + " Iris requires paper or above to function properly.."); Iris.info(C.RED + " Iris requires paper or above to function properly..");
@@ -842,7 +850,6 @@ public class Iris extends VolmitPlugin implements Listener {
Iris.warn("6GB+ Ram is recommended"); Iris.warn("6GB+ Ram is recommended");
} }
Iris.info("Bukkit version: " + Bukkit.getBukkitVersion()); Iris.info("Bukkit version: " + Bukkit.getBukkitVersion());
Iris.info("Java version: " + getJavaVersion());
Iris.info("Custom Biomes: " + INMS.get().countCustomBiomes()); Iris.info("Custom Biomes: " + INMS.get().countCustomBiomes());
setupChecks(); setupChecks();
printPacks(); printPacks();
@@ -177,6 +177,7 @@ public class IrisSettings {
public static class IrisSettingsGenerator { public static class IrisSettingsGenerator {
public String defaultWorldType = "overworld"; public String defaultWorldType = "overworld";
public int maxBiomeChildDepth = 4; public int maxBiomeChildDepth = 4;
// public boolean forceConvertTo320Height = false;
public boolean preventLeafDecay = true; public boolean preventLeafDecay = true;
} }
@@ -74,7 +74,7 @@ public class CommandDeepSearch implements DecreeExecutor {
} }
DeepSearchPregenerator.DeepSearchJob DeepSearchJob = DeepSearchPregenerator.DeepSearchJob.builder() DeepSearchPregenerator.DeepSearchJob DeepSearchJob = DeepSearchPregenerator.DeepSearchJob.builder()
.world(worldName) .world(world)
.radiusBlocks(radius) .radiusBlocks(radius)
.position(0) .position(0)
.build(); .build();
@@ -23,12 +23,15 @@ import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.core.nms.v1X.NMSBinding1X; import com.volmit.iris.core.nms.v1X.NMSBinding1X;
import com.volmit.iris.core.service.IrisEngineSVC; 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.core.tools.IrisToolbelt;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.mantle.components.MantleObjectComponent; import com.volmit.iris.engine.mantle.components.MantleObjectComponent;
import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisBiome;
import com.volmit.iris.engine.object.IrisCave; 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.engine.object.IrisEntity;
import com.volmit.iris.util.data.Dimension;
import com.volmit.iris.util.decree.DecreeExecutor; import com.volmit.iris.util.decree.DecreeExecutor;
import com.volmit.iris.util.decree.DecreeOrigin; import com.volmit.iris.util.decree.DecreeOrigin;
import com.volmit.iris.util.decree.annotations.Decree; import com.volmit.iris.util.decree.annotations.Decree;
@@ -137,15 +140,19 @@ public class CommandDeveloper implements DecreeExecutor {
} }
@Decree(description = "Test")
public void packBenchmark(
@Param(description = "The pack to bench", aliases = {"pack"})
IrisDimension dimension
) {
Iris.info("test");
IrisPackBenchmarking benchmark = new IrisPackBenchmarking(dimension, 1);
}
@Decree(description = "test") @Decree(description = "test")
public void test() throws NoSuchFieldException, IllegalAccessException { public void test() throws NoSuchFieldException, IllegalAccessException {
Iris.info("CMD Executed"); IrisEngineSVC.instance.engineStatus();
Engine engine = IrisToolbelt.access(player().getWorld()).getEngine();
Location at = player().getLocation();
IrisBiome caveBiome = engine.getMantle().getComplex().getCaveBiomeStream().get(at.getBlockX(), at.getBlockZ());
if (!caveBiome.getName().contains("Subterranean Land")) {
sender().sendMessage("Cool cave?: " + caveBiome.getName());
}
} }
@@ -76,8 +76,6 @@ public class CommandIris implements DecreeExecutor {
private CommandEdit edit; private CommandEdit edit;
private CommandFind find; private CommandFind find;
private CommandDeveloper developer; private CommandDeveloper developer;
public static @Getter String BenchDimension;
public static boolean worldCreation = false; public static boolean worldCreation = false;
String WorldToLoad; String WorldToLoad;
String WorldEngine; String WorldEngine;
@@ -56,6 +56,7 @@ public class CommandPregen implements DecreeExecutor {
IrisToolbelt.pregenerate(PregenTask IrisToolbelt.pregenerate(PregenTask
.builder() .builder()
.center(new Position2(center.getBlockX() >> 9, center.getBlockZ() >> 9)) .center(new Position2(center.getBlockX() >> 9, center.getBlockZ() >> 9))
.gui(true)
.width(w) .width(w)
.height(w) .height(w)
.build(), world); .build(), world);
@@ -24,6 +24,7 @@ import com.volmit.iris.core.pregenerator.IrisPregenerator;
import com.volmit.iris.core.pregenerator.PregenListener; import com.volmit.iris.core.pregenerator.PregenListener;
import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.core.pregenerator.PregenTask;
import com.volmit.iris.core.pregenerator.PregeneratorMethod; import com.volmit.iris.core.pregenerator.PregeneratorMethod;
import com.volmit.iris.core.tools.IrisPackBenchmarking;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.format.Form; import com.volmit.iris.util.format.Form;
@@ -44,6 +45,8 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer; import java.util.function.Consumer;
import static com.volmit.iris.core.tools.IrisPackBenchmarking.benchmarkInProgress;
public class PregeneratorJob implements PregenListener { public class PregeneratorJob implements PregenListener {
private static final Color COLOR_EXISTS = parseColor("#4d7d5b"); private static final Color COLOR_EXISTS = parseColor("#4d7d5b");
private static final Color COLOR_BLACK = parseColor("#4d7d5b"); private static final Color COLOR_BLACK = parseColor("#4d7d5b");
@@ -86,7 +89,7 @@ public class PregeneratorJob implements PregenListener {
max.setZ(Math.max((zz << 5) + 31, max.getZ())); max.setZ(Math.max((zz << 5) + 31, max.getZ()));
}); });
if (IrisSettings.get().getGui().isUseServerLaunchedGuis()) { if (IrisSettings.get().getGui().isUseServerLaunchedGuis() && task.isGui()) {
open(); open();
} }
@@ -5,18 +5,16 @@ import com.volmit.iris.Iris;
import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.core.tools.IrisToolbelt;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisBiome;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form; import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.io.IO; import com.volmit.iris.util.io.IO;
import com.volmit.iris.util.mantle.MantleFlag;
import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.M;
import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.RollingSequence; import com.volmit.iris.util.math.RollingSequence;
import com.volmit.iris.util.math.Spiraler; import com.volmit.iris.util.math.Spiraler;
import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import io.papermc.lib.PaperLib;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.Getter; import lombok.Getter;
@@ -33,7 +31,6 @@ import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@@ -56,10 +53,12 @@ public class DeepSearchPregenerator extends Thread implements Listener {
private final RollingSequence chunksPerMinute; private final RollingSequence chunksPerMinute;
private final AtomicInteger chunkCachePos; private final AtomicInteger chunkCachePos;
private final AtomicInteger chunkCacheSize; private final AtomicInteger chunkCacheSize;
private int pos;
private final AtomicInteger foundCacheLast; private final AtomicInteger foundCacheLast;
private final AtomicInteger foundCache; private final AtomicInteger foundCache;
private LinkedHashMap<Integer, Position2> chunkCache; private LinkedHashMap<Integer, Position2> chunkCache;
private final ReentrantLock cacheLock = new ReentrantLock(); private KList<Position2> chunkQueue;
private final ReentrantLock cacheLock;
private static final Map<String, DeepSearchJob> jobs = new HashMap<>(); private static final Map<String, DeepSearchJob> jobs = new HashMap<>();
@@ -69,11 +68,13 @@ public class DeepSearchPregenerator extends Thread implements Listener {
this.chunkCachePos = new AtomicInteger(1000); this.chunkCachePos = new AtomicInteger(1000);
this.foundCacheLast = new AtomicInteger(); this.foundCacheLast = new AtomicInteger();
this.foundCache = new AtomicInteger(); this.foundCache = new AtomicInteger();
this.cacheLock = new ReentrantLock();
this.destination = destination; this.destination = destination;
this.chunkCache = new LinkedHashMap(); this.chunkCache = new LinkedHashMap<>();
this.maxPosition = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> { this.maxPosition = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> {
}).count(); }).count();
this.world = Bukkit.getWorld(job.getWorld()); this.world = Bukkit.getWorld(job.getWorld().getUID());
this.chunkQueue = new KList<>();
this.latch = new ChronoLatch(3000); this.latch = new ChronoLatch(3000);
this.startTime = new AtomicLong(M.ms()); this.startTime = new AtomicLong(M.ms());
this.chunksPerSecond = new RollingSequence(10); this.chunksPerSecond = new RollingSequence(10);
@@ -81,7 +82,9 @@ public class DeepSearchPregenerator extends Thread implements Listener {
foundChunks = new AtomicInteger(0); foundChunks = new AtomicInteger(0);
this.foundLast = new AtomicInteger(0); this.foundLast = new AtomicInteger(0);
this.foundTotalChunks = new AtomicInteger((int) Math.ceil(Math.pow((2.0 * job.getRadiusBlocks()) / 16, 2))); this.foundTotalChunks = new AtomicInteger((int) Math.ceil(Math.pow((2.0 * job.getRadiusBlocks()) / 16, 2)));
jobs.put(job.getWorld(), job);
this.pos = 0;
jobs.put(job.getWorld().getName(), job);
DeepSearchPregenerator.instance = this; DeepSearchPregenerator.instance = this;
} }
@@ -108,9 +111,8 @@ public class DeepSearchPregenerator extends Thread implements Listener {
// chunkCache(); //todo finish this // chunkCache(); //todo finish this
if (latch.flip() && !job.paused) { if (latch.flip() && !job.paused) {
if (cacheLock.isLocked()) { if (cacheLock.isLocked()) {
Iris.info("DeepFinder: Caching: " + chunkCachePos.get() + " Of " + chunkCacheSize.get()); Iris.info("DeepFinder: Caching: " + chunkCachePos.get() + " Of " + chunkCacheSize.get());
} } else {
long eta = computeETA(); long eta = computeETA();
save(); save();
int secondGenerated = foundChunks.get() - foundLast.get(); int secondGenerated = foundChunks.get() - foundLast.get();
@@ -118,19 +120,13 @@ public class DeepSearchPregenerator extends Thread implements Listener {
secondGenerated = secondGenerated / 3; secondGenerated = secondGenerated / 3;
chunksPerSecond.put(secondGenerated); chunksPerSecond.put(secondGenerated);
chunksPerMinute.put(secondGenerated * 60); chunksPerMinute.put(secondGenerated * 60);
Iris.info("deepFinder: " + C.IRIS + world.getName() + C.RESET + " RTT: " + Form.f(foundChunks.get()) + " of " + Form.f(foundTotalChunks.get()) + " " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2)); Iris.info("DeepFinder: " + C.IRIS + world.getName() + C.RESET + " Searching: " + Form.f(foundChunks.get()) + " of " + Form.f(foundTotalChunks.get()) + " " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2));
} }
}
if (foundChunks.get() >= foundTotalChunks.get()) { if (foundChunks.get() >= foundTotalChunks.get()) {
Iris.info("Completed DeepSearch!"); Iris.info("Completed DeepSearch!");
interrupt(); interrupt();
} else {
int pos = job.getPosition() + 1;
job.setPosition(pos);
if (!job.paused) {
tickSearch(getChunk(pos));
}
} }
} }
@@ -141,22 +137,18 @@ public class DeepSearchPregenerator extends Thread implements Listener {
private final ExecutorService executorService = Executors.newSingleThreadExecutor(); private final ExecutorService executorService = Executors.newSingleThreadExecutor();
private void tickSearch(Position2 chunk) { private void queueSystem(Position2 chunk) {
executorService.submit(() -> { if (chunkQueue.isEmpty()) {
CountDownLatch latch = new CountDownLatch(1); for (int limit = 512; limit != 0; limit--) {
try { pos = job.getPosition() + 1;
findInChunk(world, chunk.getX(), chunk.getZ()); chunkQueue.add(getChunk(pos));
} catch (IOException e) {
throw new RuntimeException(e);
} }
Iris.verbose("Generated Async " + chunk); } else {
latch.countDown(); //MCAUtil.read();
}
try {
latch.await();
} catch (InterruptedException ignored) {}
foundChunks.addAndGet(1);
});
} }
private void findInChunk(World world, int x, int z) throws IOException { private void findInChunk(World world, int x, int z) throws IOException {
@@ -271,7 +263,7 @@ public class DeepSearchPregenerator extends Thread implements Listener {
@Data @Data
@Builder @Builder
public static class DeepSearchJob { public static class DeepSearchJob {
private String world; private World world;
@Builder.Default @Builder.Default
private int radiusBlocks = 5000; private int radiusBlocks = 5000;
@Builder.Default @Builder.Default
@@ -19,7 +19,11 @@
package com.volmit.iris.core.pregenerator; package com.volmit.iris.core.pregenerator;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.pack.IrisPack;
import com.volmit.iris.core.tools.IrisPackBenchmarking;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form; import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.mantle.Mantle;
import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.M;
@@ -45,6 +49,7 @@ public class IrisPregenerator {
private final RollingSequence chunksPerSecond; private final RollingSequence chunksPerSecond;
private final RollingSequence chunksPerMinute; private final RollingSequence chunksPerMinute;
private final RollingSequence regionsPerMinute; private final RollingSequence regionsPerMinute;
private final KList<Integer> chunksPerSecondHistory;
private static AtomicInteger generated; private static AtomicInteger generated;
private final AtomicInteger generatedLast; private final AtomicInteger generatedLast;
private final AtomicInteger generatedLastMinute; private final AtomicInteger generatedLastMinute;
@@ -57,8 +62,6 @@ public class IrisPregenerator {
private final KSet<Position2> net; private final KSet<Position2> net;
private final ChronoLatch cl; private final ChronoLatch cl;
private final ChronoLatch saveLatch = new ChronoLatch(30000); private final ChronoLatch saveLatch = new ChronoLatch(30000);
static long long_generatedChunks = 0;
static long long_totalChunks = 0;
public IrisPregenerator(PregenTask task, PregeneratorMethod generator, PregenListener listener) { public IrisPregenerator(PregenTask task, PregeneratorMethod generator, PregenListener listener) {
this.listener = listenify(listener); this.listener = listenify(listener);
@@ -75,6 +78,7 @@ public class IrisPregenerator {
chunksPerSecond = new RollingSequence(10); chunksPerSecond = new RollingSequence(10);
chunksPerMinute = new RollingSequence(10); chunksPerMinute = new RollingSequence(10);
regionsPerMinute = new RollingSequence(10); regionsPerMinute = new RollingSequence(10);
chunksPerSecondHistory = new KList<>();
generated = new AtomicInteger(0); generated = new AtomicInteger(0);
generatedLast = new AtomicInteger(0); generatedLast = new AtomicInteger(0);
generatedLastMinute = new AtomicInteger(0); generatedLastMinute = new AtomicInteger(0);
@@ -88,6 +92,7 @@ public class IrisPregenerator {
int secondGenerated = generated.get() - generatedLast.get(); int secondGenerated = generated.get() - generatedLast.get();
generatedLast.set(generated.get()); generatedLast.set(generated.get());
chunksPerSecond.put(secondGenerated); chunksPerSecond.put(secondGenerated);
chunksPerSecondHistory.add(secondGenerated);
if (minuteLatch.flip()) { if (minuteLatch.flip()) {
int minuteGenerated = generated.get() - generatedLastMinute.get(); int minuteGenerated = generated.get() - generatedLastMinute.get();
@@ -95,8 +100,6 @@ public class IrisPregenerator {
chunksPerMinute.put(minuteGenerated); chunksPerMinute.put(minuteGenerated);
regionsPerMinute.put((double) minuteGenerated / 1024D); regionsPerMinute.put((double) minuteGenerated / 1024D);
} }
long_generatedChunks = generated.get();
long_totalChunks = totalChunks.get();
listener.onTick(chunksPerSecond.getAverage(), chunksPerMinute.getAverage(), listener.onTick(chunksPerSecond.getAverage(), chunksPerMinute.getAverage(),
regionsPerMinute.getAverage(), regionsPerMinute.getAverage(),
@@ -107,7 +110,11 @@ public class IrisPregenerator {
if (cl.flip()) { if (cl.flip()) {
double percentage = ((double) generated.get() / (double) totalChunks.get()) * 100; double percentage = ((double) generated.get() / (double) totalChunks.get()) * 100;
if (!IrisPackBenchmarking.benchmarkInProgress) {
Iris.info("Pregen: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration(eta, 2), percentage); Iris.info("Pregen: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration(eta, 2), percentage);
} else {
Iris.info("Benchmarking: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration(eta, 2), percentage);
}
} }
return 1000; return 1000;
} }
@@ -123,13 +130,6 @@ public class IrisPregenerator {
); );
} }
public static long getLongGeneratedChunks() {
return long_generatedChunks;
}
public static long getLongTotalChunks() {
return long_totalChunks;
}
public void close() { public void close() {
shutdown.set(true); shutdown.set(true);
@@ -142,6 +142,11 @@ public class IrisPregenerator {
task.iterateRegions((x, z) -> visitRegion(x, z, true)); task.iterateRegions((x, z) -> visitRegion(x, z, true));
task.iterateRegions((x, z) -> visitRegion(x, z, false)); task.iterateRegions((x, z) -> visitRegion(x, z, false));
shutdown(); shutdown();
if (!IrisPackBenchmarking.benchmarkInProgress) {
Iris.info(C.IRIS + "Pregen stopped.");
} else {
IrisPackBenchmarking.instance.finishedBenchmark(chunksPerSecondHistory);
}
} }
private void checkRegions() { private void checkRegions() {
@@ -35,6 +35,8 @@ public class PregenTask {
private static final KList<Position2> ORDER_CENTER = computeChunkOrder(); private static final KList<Position2> ORDER_CENTER = computeChunkOrder();
private static final KMap<Position2, KList<Position2>> ORDERS = new KMap<>(); private static final KMap<Position2, KList<Position2>> ORDERS = new KMap<>();
@Builder.Default
private boolean gui = false;
@Builder.Default @Builder.Default
private Position2 center = new Position2(0, 0); private Position2 center = new Position2(0, 0);
@Builder.Default @Builder.Default
@@ -3,11 +3,11 @@ package com.volmit.iris.core.safeguard;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.core.nms.v1X.NMSBinding1X; import com.volmit.iris.core.nms.v1X.NMSBinding1X;
import org.apache.logging.log4j.core.util.ExecutorServices;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import javax.print.attribute.standard.Severity; import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import java.io.File; import java.io.File;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.file.Files; import java.nio.file.Files;
@@ -17,9 +17,6 @@ import java.nio.file.StandardOpenOption;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.StringJoiner; import java.util.StringJoiner;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static com.volmit.iris.Iris.getJavaVersion; import static com.volmit.iris.Iris.getJavaVersion;
import static com.volmit.iris.Iris.instance; import static com.volmit.iris.Iris.instance;
@@ -128,25 +125,15 @@ public class ServerBootSFG {
} }
} }
public static boolean isJDK() {
String path = System.getProperty("sun.boot.library.path");
if (path != null) {
String javacPath = "";
if (path.endsWith(File.separator + "bin")) {
javacPath = path;
} else {
int libIndex = path.lastIndexOf(File.separator + "lib");
if (libIndex > 0) {
javacPath = path.substring(0, libIndex) + File.separator + "bin";
}
}
if (checkJavac(javacPath))
return true;
}
path = System.getProperty("java.home");
return path != null && checkJavac(path + File.separator + "bin");
}
public static boolean isJDK() {
try {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
// If the compiler is null, it means this is a JRE environment, not a JDK.
return compiler != null;
} catch (Exception ignored) {}
return false;
}
public static boolean hasPrivileges() { public static boolean hasPrivileges() {
Path pv = Paths.get(Bukkit.getWorldContainer() + "iristest.json"); Path pv = Paths.get(Bukkit.getWorldContainer() + "iristest.json");
try (FileChannel fc = FileChannel.open(pv, StandardOpenOption.CREATE, StandardOpenOption.DELETE_ON_CLOSE, StandardOpenOption.READ, StandardOpenOption.WRITE)) { try (FileChannel fc = FileChannel.open(pv, StandardOpenOption.CREATE, StandardOpenOption.DELETE_ON_CLOSE, StandardOpenOption.READ, StandardOpenOption.WRITE)) {
@@ -1,6 +1,7 @@
package com.volmit.iris.core.service; package com.volmit.iris.core.service;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.core.tools.IrisToolbelt;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.platform.PlatformChunkGenerator; import com.volmit.iris.engine.platform.PlatformChunkGenerator;
@@ -17,6 +18,8 @@ import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.ServerLoadEvent;
import org.bukkit.event.world.WorldLoadEvent; import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.event.world.WorldUnloadEvent; import org.bukkit.event.world.WorldUnloadEvent;
import org.checkerframework.checker.units.qual.A; import org.checkerframework.checker.units.qual.A;
@@ -30,12 +33,13 @@ import java.util.function.Supplier;
public class IrisEngineSVC implements IrisService { public class IrisEngineSVC implements IrisService {
public static IrisEngineSVC instance; public static IrisEngineSVC instance;
public boolean isServerShuttingDown = false;
public boolean isServerLoaded = false;
private static final AtomicInteger tectonicLimit = new AtomicInteger(30); private static final AtomicInteger tectonicLimit = new AtomicInteger(30);
private final ReentrantLock lastUseLock = new ReentrantLock(); private ReentrantLock lastUseLock;
private final KMap<World, Long> lastUse = new KMap<>(); private KMap<World, Long> lastUse;
private List<World> IrisWorlds; private List<World> IrisWorlds;
private Looper cacheTicker; private Looper cacheTicker;
private Looper freezeTicker;
private Looper trimTicker; private Looper trimTicker;
private Looper unloadTicker; private Looper unloadTicker;
private Looper updateTicker; private Looper updateTicker;
@@ -55,6 +59,8 @@ public class IrisEngineSVC implements IrisService {
@Override @Override
public void onEnable() { public void onEnable() {
this.cl = new ChronoLatch(5000); this.cl = new ChronoLatch(5000);
lastUse = new KMap<>();
lastUseLock = new ReentrantLock();
IrisWorlds = new ArrayList<>(); IrisWorlds = new ArrayList<>();
IsUnloadAlive = new AtomicBoolean(true); IsUnloadAlive = new AtomicBoolean(true);
IsTrimAlive = new AtomicBoolean(true); IsTrimAlive = new AtomicBoolean(true);
@@ -81,11 +87,19 @@ public class IrisEngineSVC implements IrisService {
cacheTicker.start(); cacheTicker.start();
trimTicker.start(); trimTicker.start();
unloadTicker.start(); unloadTicker.start();
freezeTicker.start();
instance = this; instance = this;
} }
public void engineStatus() {
boolean trimAlive = trimTicker.isAlive();
boolean unloadAlive = unloadTicker.isAlive();
Iris.info("Status:");
Iris.info("- Trim: " + trimAlive);
Iris.info("- Unload: " + unloadAlive);
}
public static int getTectonicLimit() { public static int getTectonicLimit() {
return tectonicLimit.get(); return tectonicLimit.get();
} }
@@ -104,6 +118,18 @@ public class IrisEngineSVC implements IrisService {
updateWorlds(); updateWorlds();
} }
@EventHandler
public void onServerBoot(ServerLoadEvent event) {
isServerLoaded = true;
}
@EventHandler
public void onPluginDisable(PluginDisableEvent event) {
if (event.getPlugin().equals(Iris.instance)) {
isServerShuttingDown = true;
}
}
public void updateWorlds() { public void updateWorlds() {
for (World world : Bukkit.getWorlds()) { for (World world : Bukkit.getWorlds()) {
try { try {
@@ -146,11 +172,33 @@ public class IrisEngineSVC implements IrisService {
TotalNotQueuedTectonicPlates.set(0); TotalNotQueuedTectonicPlates.set(0);
TotalTectonicPlates.set(0); TotalTectonicPlates.set(0);
for (World world : IrisWorlds) { for (World world : IrisWorlds) {
Engine engine = IrisToolbelt.access(world).getEngine(); Engine engine = Objects.requireNonNull(IrisToolbelt.access(world)).getEngine();
TotalQueuedTectonicPlates.addAndGet((int) engine.getMantle().getToUnload()); TotalQueuedTectonicPlates.addAndGet((int) engine.getMantle().getToUnload());
TotalNotQueuedTectonicPlates.addAndGet((int) engine.getMantle().getNotQueuedLoadedRegions()); TotalNotQueuedTectonicPlates.addAndGet((int) engine.getMantle().getNotQueuedLoadedRegions());
TotalTectonicPlates.addAndGet(engine.getMantle().getLoadedRegionCount()); TotalTectonicPlates.addAndGet(engine.getMantle().getLoadedRegionCount());
} }
if (!isServerShuttingDown && isServerLoaded) {
if (!trimTicker.isAlive()) {
Iris.info(C.IRIS + "TrimTicker found dead! Booting it up!");
try {
trimTicker.start();
} catch (Exception e) {
Iris.error("What happened?");
e.printStackTrace();
}
}
if (!unloadTicker.isAlive()) {
Iris.info(C.IRIS + "UnloadTicker found dead! Booting it up!");
try {
unloadTicker.start();
} catch (Exception e) {
Iris.error("What happened?");
e.printStackTrace();
}
}
}
} catch (Exception e) { } catch (Exception e) {
return -1; return -1;
} }
@@ -158,54 +206,6 @@ public class IrisEngineSVC implements IrisService {
} }
}; };
freezeTicker = new Looper() {
@Override
protected long loop() {
if (cl.flip()) {
if (!unloadTicker.isAlive()) {
Iris.debug(C.YELLOW + "UnloadTicker Found dead?");
}
if (!trimTicker.isAlive()) {
Iris.debug(C.YELLOW + "UnloadTicker Found dead?");
}
Runtime runtime = Runtime.getRuntime();
long usedMemory = runtime.totalMemory() - runtime.freeMemory();
long maxMemory = runtime.maxMemory();
double memoryUsagePercentage = ((double) usedMemory / (double) maxMemory);
double externalTrim = trimActiveAlive.getMillis();
double externalUnload = unloadActiveAlive.getMillis();
double localTrim = trimAlive.getMillis();
double localUnload = unloadAlive.getMillis();
if (localTrim > 120000) {
Iris.info(C.YELLOW + "EngineSVC Alert! The Trim subsystem has exceeded its expected response time: " + Form.duration(trimAlive.getMillis()) + ".");
}
if (localUnload > 120000) {
Iris.info(C.YELLOW + "EngineSVC Alert! The Tectonic subsystem has exceeded its expected response time: " + Form.duration(trimAlive.getMillis()) + ".");
}
if (memoryUsagePercentage > 0.9 && tectonicLimit.get() < TotalTectonicPlates.get()) {
if (localTrim > 30000 && externalTrim > 10000) {
Iris.info(C.RED + "CRITICAL EngineSVC FAILURE! The Tectonic Trim subsystem has not trimmed for: " + Form.duration(trimAlive.getMillis()) + ".");
IsTrimAlive.set(false);
} else {
Iris.info(C.IRIS + "EngineSVC reports activity within the Trim subsystem system!");
IsTrimAlive.set(true);
}
if (localUnload > 30000 && externalUnload > 12000 && TotalQueuedTectonicPlates.get() != 0) {
Iris.info(C.RED + "CRITICAL EngineSVC FAILURE! The Tectonic Unload subsystem has not unloaded for: " + Form.duration(trimAlive.getMillis()) + ".");
IsUnloadAlive.set(false);
} else {
Iris.info(C.IRIS + "EngineSVC reports activity within the Unload subsystem system!");
IsUnloadAlive.set(true);
}
}
}
return 1;
}
};
trimTicker = new Looper() { trimTicker = new Looper() {
private final Supplier<Engine> supplier = createSupplier(); private final Supplier<Engine> supplier = createSupplier();
@Override @Override
@@ -250,7 +250,7 @@ public class IrisEngineSVC implements IrisService {
} }
} catch (Throwable e) { } catch (Throwable e) {
Iris.reportError(e); Iris.reportError(e);
Iris.info(C.RED + "EngineSVC: Failed to unload. Please contact support!"); Iris.info(C.RED + "EngineSVC: Failed to unload.");
e.printStackTrace(); e.printStackTrace();
return -1; return -1;
} }
@@ -1,31 +0,0 @@
package com.volmit.iris.core.service;
import com.volmit.iris.Iris;
import com.volmit.iris.util.plugin.IrisService;
import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.plugin.java.JavaPlugin;
import static java.lang.System.getLogger;
public class WorldLoadSFG implements IrisService {
private JavaPlugin plugin;
@EventHandler
public void onWorldLoad(WorldLoadEvent event) {
World world = event.getWorld();
}
@Override
public void onEnable() {
this.plugin = Iris.instance;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@Override
public void onDisable() {
}
}
@@ -2,38 +2,132 @@ package com.volmit.iris.core.tools;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.pregenerator.IrisPregenerator;
import com.volmit.iris.core.pregenerator.LazyPregenerator;
import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.core.pregenerator.PregenTask;
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.collection.KMap;
import com.volmit.iris.util.exceptions.IrisException; import com.volmit.iris.util.exceptions.IrisException;
import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.J;
import org.apache.commons.io.FileUtils; import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import lombok.Getter;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import java.io.File; import java.io.File;
import java.util.concurrent.CompletableFuture; import java.io.FileWriter;
import java.util.concurrent.ExecutionException; import java.io.IOException;
import java.nio.file.FileVisitResult;
import static com.volmit.iris.core.commands.CommandIris.BenchDimension; import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.Clock;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.concurrent.*;
public class IrisPackBenchmarking { public class IrisPackBenchmarking {
@Getter
public static IrisPackBenchmarking instance; public static IrisPackBenchmarking instance;
long totalChunks; public static boolean benchmarkInProgress = false;
long generatedChunks; private IrisDimension IrisDimension;
double elapsedTimeNs; private int radius;
private boolean finished = false;
PrecisionStopwatch stopwatch;
public void runBenchmark() { public IrisPackBenchmarking(IrisDimension dimension, int r) {
instance = this;
this.IrisDimension = dimension;
this.radius = r;
runBenchmark();
}
private void runBenchmark() {
this.stopwatch = new PrecisionStopwatch();
ExecutorService service = Executors.newSingleThreadExecutor();
service.submit(() -> {
Iris.info("Setting up benchmark environment ");
benchmarkInProgress = true;
File file = new File("benchmark");
if (file.exists()) {
deleteDirectory(file.toPath());
}
createBenchmark();
while (!IrisToolbelt.isIrisWorld(Bukkit.getWorld("benchmark"))) {
J.sleep(1000);
Iris.debug("Iris PackBenchmark: Waiting...");
}
Iris.info("Starting Benchmark!");
stopwatch.begin();
startBenchmark();
});
} }
public void createBenchmark(){
public boolean getBenchmarkInProgress() {
return benchmarkInProgress;
}
public void finishedBenchmark(KList<Integer> cps) {
try {
String time = Form.duration(stopwatch.getMillis());
Engine engine = IrisToolbelt.access(Bukkit.getWorld("benchmark")).getEngine();
Iris.info("-----------------");
Iris.info("Results:");
Iris.info("- Total time: " + time);
Iris.info("- Average CPS: " + calculateAverage(cps));
Iris.info(" - Median CPS: " + calculateMedian(cps));
Iris.info(" - Highest CPS: " + findHighest(cps));
Iris.info(" - Lowest CPS: " + findLowest(cps));
Iris.info("-----------------");
Iris.info("Creating a report..");
File profilers = new File("plugins" + File.separator + "Iris" + File.separator + "packbenchmarks");
profilers.mkdir();
File results = new File("plugins " + File.separator + "Iris", IrisDimension.getName() + LocalDateTime.now(Clock.systemDefaultZone()) + ".txt");
results.createNewFile();
KMap<String, Double> metrics = engine.getMetrics().pull();
try (FileWriter writer = new FileWriter(results)) {
writer.write("-----------------\n");
writer.write("Results:\n");
writer.write("Dimension: " + IrisDimension.getName() + "\n");
writer.write("- Date of Benchmark: " + LocalDateTime.now(Clock.systemDefaultZone()) + "\n");
writer.write("\n");
writer.write("Metrics");
for (String m : metrics.k()) {
double i = metrics.get(m);
writer.write("- " + m + ": " + i);
}
writer.write("- " + metrics);
writer.write("Benchmark: " + LocalDateTime.now(Clock.systemDefaultZone()) + "\n");
writer.write("- Total time: " + time + "\n");
writer.write("- Average CPS: " + calculateAverage(cps) + "\n");
writer.write(" - Median CPS: " + calculateMedian(cps) + "\n");
writer.write(" - Highest CPS: " + findHighest(cps) + "\n");
writer.write(" - Lowest CPS: " + findLowest(cps) + "\n");
writer.write("-----------------\n");
Iris.info("Finished generating a report!");
} catch (IOException e) {
Iris.error("An error occurred writing to the file.");
e.printStackTrace();
}
Bukkit.getServer().unloadWorld("benchmark", true);
stopwatch.end();
} catch (Exception e) {
Iris.error("Something has gone wrong!");
e.printStackTrace();
}
}
private void createBenchmark(){
try { try {
IrisToolbelt.createWorld() IrisToolbelt.createWorld()
.dimension(BenchDimension) .dimension(IrisDimension.getName())
.name("Benchmark") .name("benchmark")
.seed(1337) .seed(1337)
.studio(false) .studio(false)
.benchmark(true) .benchmark(true)
@@ -42,15 +136,66 @@ public class IrisPackBenchmarking {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
public void startBenchmark(){
private void startBenchmark(){
int x = 0; int x = 0;
int z = 0; int z = 0;
IrisToolbelt.pregenerate(PregenTask IrisToolbelt.pregenerate(PregenTask
.builder() .builder()
.gui(false)
.center(new Position2(x, z)) .center(new Position2(x, z))
.width(5) .width(5)
.height(5) .height(5)
.build(), Bukkit.getWorld("Benchmark") .build(), Bukkit.getWorld("benchmark")
); );
} }
private double calculateAverage(KList<Integer> list) {
double sum = 0;
for (int num : list) {
sum += num;
}
return sum / list.size();
}
private double calculateMedian(KList<Integer> list) {
Collections.sort(list);
int middle = list.size() / 2;
if (list.size() % 2 == 1) {
return list.get(middle);
} else {
return (list.get(middle - 1) + list.get(middle)) / 2.0;
}
}
private int findLowest(KList<Integer> list) {
return Collections.min(list);
}
private int findHighest(KList<Integer> list) {
return Collections.max(list);
}
private boolean deleteDirectory(Path dir) {
try {
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
} }
@@ -23,6 +23,7 @@ import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.IrisComplex;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineTarget; import com.volmit.iris.engine.framework.EngineTarget;
import com.volmit.iris.engine.framework.SeedManager;
import com.volmit.iris.engine.mantle.components.MantleJigsawComponent; import com.volmit.iris.engine.mantle.components.MantleJigsawComponent;
import com.volmit.iris.engine.mantle.components.MantleObjectComponent; import com.volmit.iris.engine.mantle.components.MantleObjectComponent;
import com.volmit.iris.engine.object.IObjectPlacer; import com.volmit.iris.engine.object.IObjectPlacer;
@@ -18,6 +18,7 @@
package com.volmit.iris.engine.object; package com.volmit.iris.engine.object;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.data.DataProvider; import com.volmit.iris.util.data.DataProvider;
@@ -69,6 +70,17 @@ public class IrisBiomeGeneratorLink {
double g = getCachedGenerator(xg).getHeight(x, z, seed); double g = getCachedGenerator(xg).getHeight(x, z, seed);
g = g < 0 ? 0 : g; g = g < 0 ? 0 : g;
g = g > 1 ? 1 : g; g = g > 1 ? 1 : g;
// if (IrisSettings.get().getGenerator().forceConvertTo320Height) {
// if (max > 320 || min > 320) {
// double scaleFactor = 320.0 / Math.max(max, min);
// min *= (int) scaleFactor;
// max *= (int) scaleFactor;
// if (min < 0) {
//
// }
// }
// }
// todo This
return IrisInterpolation.lerp(min, max, g); return IrisInterpolation.lerp(min, max, g);
} }
@@ -52,8 +52,6 @@ public class IrisCavePlacer implements IRare {
private String cave; private String cave;
@Desc("If set to true, this cave is allowed to break the surface") @Desc("If set to true, this cave is allowed to break the surface")
private boolean breakSurface = true; private boolean breakSurface = true;
@Desc("If set to true, this cave is allowed to get placed above the terrain level")
private boolean ignoreHeightLimit = false;
@Desc("The height range this cave can spawn at. If breakSurface is false, the output of this range will be clamped by the current world height to prevent surface breaking.") @Desc("The height range this cave can spawn at. If breakSurface is false, the output of this range will be clamped by the current world height to prevent surface breaking.")
private IrisStyledRange caveStartHeight = new IrisStyledRange(13, 120, new IrisGeneratorStyle(NoiseStyle.STATIC)); private IrisStyledRange caveStartHeight = new IrisStyledRange(13, 120, new IrisGeneratorStyle(NoiseStyle.STATIC));
@@ -84,15 +82,13 @@ public class IrisCavePlacer implements IRare {
} }
if (y == -1) { if (y == -1) {
if(!ignoreHeightLimit) { if(!breakSurface) {
int eH = engine.getHeight(x, z); int eH = engine.getHeight(x, z);
if (caveStartHeight.getMax() > eH) { if (caveStartHeight.getMax() > eH) {
caveStartHeight.setMax(eH); caveStartHeight.setMax(eH);
} }
} }
int h = (int) caveStartHeight.get(rng, x, z, data); y = (int) caveStartHeight.get(rng, x, z, data);
int ma = breakSurface ? h : (int) (engine.getComplex().getHeightStream().get(x, z) - 9);
y = Math.min(h, ma);
} }
try { try {