mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 10:12:53 +00:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
c0136585e6
@ -25,7 +25,7 @@ plugins {
|
|||||||
id "de.undercouch.download" version "5.0.1"
|
id "de.undercouch.download" version "5.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
version '3.0.0-1.19.2-1.20.2'
|
version '3.0.0-1.19.2-1.20.4'
|
||||||
def specialSourceVersion = '1.11.0' //[NMS]
|
def specialSourceVersion = '1.11.0' //[NMS]
|
||||||
|
|
||||||
// ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED
|
// ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED
|
||||||
@ -44,7 +44,7 @@ registerCustomOutputTaskUnix('PsychoLT', '/Volumes/PRO-G40/Minecraft/MinecraftDe
|
|||||||
// ==============================================================
|
// ==============================================================
|
||||||
|
|
||||||
def NMS_BINDINGS = Map.of(
|
def NMS_BINDINGS = Map.of(
|
||||||
// "v1_20_R3", "1.20.4-R0.1-SNAPSHOT",
|
"v1_20_R3", "1.20.4-R0.1-SNAPSHOT",
|
||||||
"v1_20_R2", "1.20.2-R0.1-SNAPSHOT",
|
"v1_20_R2", "1.20.2-R0.1-SNAPSHOT",
|
||||||
"v1_20_R1", "1.20.1-R0.1-SNAPSHOT",
|
"v1_20_R1", "1.20.1-R0.1-SNAPSHOT",
|
||||||
"v1_19_R3", "1.19.4-R0.1-SNAPSHOT",
|
"v1_19_R3", "1.19.4-R0.1-SNAPSHOT",
|
||||||
@ -344,4 +344,4 @@ def registerCustomOutputTaskUnix(name, path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.build.dependsOn(shadowJar)
|
tasks.build.dependsOn(shadowJar)
|
||||||
|
@ -146,7 +146,6 @@ public class IrisSettings {
|
|||||||
@Data
|
@Data
|
||||||
public static class IrisSettingsGeneral {
|
public static class IrisSettingsGeneral {
|
||||||
public boolean ignoreBootMode = false;
|
public boolean ignoreBootMode = false;
|
||||||
public boolean useIntegratedChunkHandler = false;
|
|
||||||
public boolean commandSounds = true;
|
public boolean commandSounds = true;
|
||||||
public boolean debug = false;
|
public boolean debug = false;
|
||||||
public boolean disableNMS = false;
|
public boolean disableNMS = false;
|
||||||
@ -184,7 +183,6 @@ public class IrisSettings {
|
|||||||
public static class IrisSettingsStudio {
|
public static class IrisSettingsStudio {
|
||||||
public boolean studio = true;
|
public boolean studio = true;
|
||||||
public boolean openVSCode = true;
|
public boolean openVSCode = true;
|
||||||
public boolean displayTrueHeight = false;
|
|
||||||
public boolean disableTimeAndWeather = true;
|
public boolean disableTimeAndWeather = true;
|
||||||
public boolean autoStartDefaultStudio = false;
|
public boolean autoStartDefaultStudio = false;
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ import java.util.zip.GZIPOutputStream;
|
|||||||
|
|
||||||
@Decree(name = "Developer", origin = DecreeOrigin.BOTH, description = "Iris World Manager", aliases = {"dev"})
|
@Decree(name = "Developer", origin = DecreeOrigin.BOTH, description = "Iris World Manager", aliases = {"dev"})
|
||||||
public class CommandDeveloper implements DecreeExecutor {
|
public class CommandDeveloper implements DecreeExecutor {
|
||||||
|
private CommandTurboPregen turboPregen;
|
||||||
|
|
||||||
@Decree(description = "Get Loaded TectonicPlates Count", origin = DecreeOrigin.BOTH, sync = true)
|
@Decree(description = "Get Loaded TectonicPlates Count", origin = DecreeOrigin.BOTH, sync = true)
|
||||||
public void EngineStatus(
|
public void EngineStatus(
|
||||||
|
@ -48,7 +48,7 @@ public class CommandTurboPregen implements DecreeExecutor {
|
|||||||
|
|
||||||
worldName = world.getName();
|
worldName = world.getName();
|
||||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||||
File TurboFile = new File(worldDirectory, "Turbogen.json");
|
File TurboFile = new File(worldDirectory, "turbogen.json");
|
||||||
if (TurboFile.exists()) {
|
if (TurboFile.exists()) {
|
||||||
if (TurboPregenerator.getInstance() != null) {
|
if (TurboPregenerator.getInstance() != null) {
|
||||||
sender().sendMessage(C.BLUE + "Turbo pregen is already in progress");
|
sender().sendMessage(C.BLUE + "Turbo pregen is already in progress");
|
||||||
|
@ -4,6 +4,7 @@ import com.google.gson.Gson;
|
|||||||
import com.volmit.iris.Iris;
|
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.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;
|
||||||
@ -138,23 +139,6 @@ public class DeepSearchPregenerator extends Thread implements Listener {
|
|||||||
// todo broken
|
// todo broken
|
||||||
}
|
}
|
||||||
|
|
||||||
private void chunkCache() {
|
|
||||||
if (chunkCache.isEmpty()) {
|
|
||||||
cacheLock.lock();
|
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
|
||||||
executorService.submit(() -> {
|
|
||||||
for (; chunkCacheSize.get() > chunkCachePos.get(); chunkCacheSize.getAndAdd(-1)) {
|
|
||||||
chunkCache.put(chunkCachePos.get(), getChunk(chunkCachePos.get()));
|
|
||||||
chunkCachePos.getAndAdd(1);
|
|
||||||
}
|
|
||||||
Iris.info("Total Time: " + p.getMinutes());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (cacheLock.isLocked()) {
|
|
||||||
cacheLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
|
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
|
||||||
|
|
||||||
private void tickSearch(Position2 chunk) {
|
private void tickSearch(Position2 chunk) {
|
||||||
@ -188,8 +172,10 @@ public class DeepSearchPregenerator extends Thread implements Listener {
|
|||||||
if (!found.exists()) {
|
if (!found.exists()) {
|
||||||
found.createNewFile();
|
found.createNewFile();
|
||||||
}
|
}
|
||||||
Iris.info("Found at! " + x + ", " + z);
|
IrisBiome biome = engine.getBiome(xx, engine.getHeight(), zz);
|
||||||
writer.write("Found at: X: " + xx + " Z: " + zz + ", ");
|
Iris.info("Found at! " + xx + ", " + zz + "Biome ID: " + biome.getName() + ", ");
|
||||||
|
writer.write("Biome at: X: " + xx + " Z: " + zz + "Biome ID: " + biome.getName() + ", ");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,30 +11,35 @@ 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.parallel.BurstExecutor;
|
||||||
|
import com.volmit.iris.util.parallel.HyperLock;
|
||||||
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
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 io.papermc.lib.PaperLib;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import org.apache.logging.log4j.core.util.ExecutorServices;
|
||||||
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.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.world.WorldUnloadEvent;
|
import org.bukkit.event.world.WorldUnloadEvent;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.checkerframework.checker.units.qual.N;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.lang.reflect.Array;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
public class TurboPregenerator extends Thread implements Listener {
|
public class TurboPregenerator extends Thread implements Listener {
|
||||||
@Getter
|
@Getter
|
||||||
@ -46,12 +51,19 @@ public class TurboPregenerator extends Thread implements Listener {
|
|||||||
private final ChronoLatch latch;
|
private final ChronoLatch latch;
|
||||||
private static AtomicInteger turboGeneratedChunks;
|
private static AtomicInteger turboGeneratedChunks;
|
||||||
private final AtomicInteger generatedLast;
|
private final AtomicInteger generatedLast;
|
||||||
|
private final AtomicLong cachedLast;
|
||||||
|
private final RollingSequence cachePerSecond;
|
||||||
private final AtomicInteger turboTotalChunks;
|
private final AtomicInteger turboTotalChunks;
|
||||||
private final AtomicLong startTime;
|
private final AtomicLong startTime;
|
||||||
private final RollingSequence chunksPerSecond;
|
private final RollingSequence chunksPerSecond;
|
||||||
private final RollingSequence chunksPerMinute;
|
private final RollingSequence chunksPerMinute;
|
||||||
private KList<Position2> queue = new KList<>();
|
private KList<Position2> queue;
|
||||||
|
private ConcurrentHashMap<Integer, Position2> cache;
|
||||||
private AtomicInteger maxWaiting;
|
private AtomicInteger maxWaiting;
|
||||||
|
private ReentrantLock cachinglock;
|
||||||
|
private AtomicBoolean caching;
|
||||||
|
private final HyperLock hyperLock;
|
||||||
|
private MultiBurst burst;
|
||||||
private static final Map<String, TurboPregenJob> jobs = new HashMap<>();
|
private static final Map<String, TurboPregenJob> jobs = new HashMap<>();
|
||||||
|
|
||||||
public TurboPregenerator(TurboPregenJob job, File destination) {
|
public TurboPregenerator(TurboPregenJob job, File destination) {
|
||||||
@ -63,31 +75,39 @@ public class TurboPregenerator extends Thread implements Listener {
|
|||||||
}).count();
|
}).count();
|
||||||
this.world = Bukkit.getWorld(job.getWorld());
|
this.world = Bukkit.getWorld(job.getWorld());
|
||||||
this.latch = new ChronoLatch(3000);
|
this.latch = new ChronoLatch(3000);
|
||||||
|
this.burst = MultiBurst.burst;
|
||||||
|
this.hyperLock = new HyperLock();
|
||||||
this.startTime = new AtomicLong(M.ms());
|
this.startTime = new AtomicLong(M.ms());
|
||||||
|
this.cachePerSecond = new RollingSequence(10);
|
||||||
this.chunksPerSecond = new RollingSequence(10);
|
this.chunksPerSecond = new RollingSequence(10);
|
||||||
this.chunksPerMinute = new RollingSequence(10);
|
this.chunksPerMinute = new RollingSequence(10);
|
||||||
turboGeneratedChunks = new AtomicInteger(0);
|
turboGeneratedChunks = new AtomicInteger(0);
|
||||||
this.generatedLast = new AtomicInteger(0);
|
this.generatedLast = new AtomicInteger(0);
|
||||||
|
this.cachedLast = new AtomicLong(0);
|
||||||
|
this.caching = new AtomicBoolean(false);
|
||||||
this.turboTotalChunks = new AtomicInteger((int) Math.ceil(Math.pow((2.0 * job.getRadiusBlocks()) / 16, 2)));
|
this.turboTotalChunks = new AtomicInteger((int) Math.ceil(Math.pow((2.0 * job.getRadiusBlocks()) / 16, 2)));
|
||||||
|
cache = new ConcurrentHashMap<>(turboTotalChunks.get());
|
||||||
|
this.cachinglock = new ReentrantLock();
|
||||||
jobs.put(job.getWorld(), job);
|
jobs.put(job.getWorld(), job);
|
||||||
TurboPregenerator.instance = this;
|
TurboPregenerator.instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TurboPregenerator(File file) throws IOException {
|
public TurboPregenerator(File file) throws IOException {
|
||||||
this(new Gson().fromJson(IO.readAll(file), TurboPregenerator.TurboPregenJob.class), file);
|
this(new Gson().fromJson(IO.readAll(file), TurboPregenerator.TurboPregenJob.class), file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadTurboGenerator(String i) {
|
public static void loadTurboGenerator(String i) {
|
||||||
World x = Bukkit.getWorld(i);
|
World x = Bukkit.getWorld(i);
|
||||||
File turbogen = new File(x.getWorldFolder(), "turbogen.json");
|
File turbogen = new File(x.getWorldFolder(), "turbogen.json");
|
||||||
if (turbogen.exists()) {
|
if (turbogen.exists()) {
|
||||||
try {
|
try {
|
||||||
TurboPregenerator p = new TurboPregenerator(turbogen);
|
TurboPregenerator p = new TurboPregenerator(turbogen);
|
||||||
p.start();
|
p.start();
|
||||||
Iris.info("Started Turbo Pregenerator: " + p.job);
|
Iris.info("Started Turbo Pregenerator: " + p.job);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +132,20 @@ public class TurboPregenerator extends Thread implements Listener {
|
|||||||
|
|
||||||
public void tick() {
|
public void tick() {
|
||||||
TurboPregenJob job = jobs.get(world.getName());
|
TurboPregenJob job = jobs.get(world.getName());
|
||||||
if (latch.flip() && !job.paused) {
|
if (!cachinglock.isLocked() && cache.isEmpty() && !caching.get()) {
|
||||||
|
ExecutorService cache = Executors.newFixedThreadPool(1);
|
||||||
|
cache.submit(this::cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (latch.flip() && caching.get()) {
|
||||||
|
long secondCached = cache.mappingCount() - cachedLast.get();
|
||||||
|
cachedLast.set(cache.mappingCount());
|
||||||
|
secondCached = secondCached / 3;
|
||||||
|
cachePerSecond.put(secondCached);
|
||||||
|
Iris.info("TurboGen: " + C.IRIS + world.getName() + C.RESET + C.BLUE + " Caching: " + Form.f(cache.mappingCount()) + " of " + Form.f(turboTotalChunks.get()) + " " + Form.f((int) cachePerSecond.getAverage()) + "/s");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (latch.flip() && !job.paused && !cachinglock.isLocked()) {
|
||||||
long eta = computeETA();
|
long eta = computeETA();
|
||||||
save();
|
save();
|
||||||
int secondGenerated = turboGeneratedChunks.get() - generatedLast.get();
|
int secondGenerated = turboGeneratedChunks.get() - generatedLast.get();
|
||||||
@ -127,18 +160,52 @@ public class TurboPregenerator extends Thread implements Listener {
|
|||||||
Iris.info("Completed Turbo Gen!");
|
Iris.info("Completed Turbo Gen!");
|
||||||
interrupt();
|
interrupt();
|
||||||
} else {
|
} else {
|
||||||
int pos = job.getPosition() + 1;
|
if (!cachinglock.isLocked()) {
|
||||||
job.setPosition(pos);
|
int pos = job.getPosition() + 1;
|
||||||
if (!job.paused) {
|
job.setPosition(pos);
|
||||||
if (queue.size() < maxWaiting.get()) {
|
if (!job.paused) {
|
||||||
Position2 chunk = getChunk(pos);
|
if (queue.size() < maxWaiting.get()) {
|
||||||
queue.add(chunk);
|
Position2 chunk = cache.get(pos);
|
||||||
|
queue.add(chunk);
|
||||||
|
}
|
||||||
|
waitForChunksPartial();
|
||||||
}
|
}
|
||||||
waitForChunksPartial();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void cache() {
|
||||||
|
if (!cachinglock.isLocked()) {
|
||||||
|
cachinglock.lock();
|
||||||
|
caching.set(true);
|
||||||
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
|
BurstExecutor b = MultiBurst.burst.burst(turboTotalChunks.get());
|
||||||
|
b.setMulticore(true);
|
||||||
|
int[] list = IntStream.rangeClosed(0, turboTotalChunks.get()).toArray();
|
||||||
|
AtomicInteger order = new AtomicInteger(turboTotalChunks.get());
|
||||||
|
|
||||||
|
int threads = Runtime.getRuntime().availableProcessors();
|
||||||
|
if (threads > 1) threads--;
|
||||||
|
ExecutorService process = Executors.newFixedThreadPool(threads);
|
||||||
|
|
||||||
|
for (int id : list) {
|
||||||
|
b.queue(() -> {
|
||||||
|
cache.put(id, getChunk(id));
|
||||||
|
order.addAndGet(-1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
b.complete();
|
||||||
|
|
||||||
|
if (order.get() < 0) {
|
||||||
|
cachinglock.unlock();
|
||||||
|
caching.set(false);
|
||||||
|
Iris.info("Completed Caching in: " + Form.duration(p.getMilliseconds(), 2));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Iris.error("TurboCache is locked!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void waitForChunksPartial() {
|
private void waitForChunksPartial() {
|
||||||
while (!queue.isEmpty() && maxWaiting.get() > queue.size()) {
|
while (!queue.isEmpty() && maxWaiting.get() > queue.size()) {
|
||||||
try {
|
try {
|
||||||
@ -163,7 +230,6 @@ public class TurboPregenerator extends Thread implements Listener {
|
|||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
PaperLib.getChunkAtAsync(world, chunk.getX(), chunk.getZ(), true)
|
PaperLib.getChunkAtAsync(world, chunk.getX(), chunk.getZ(), true)
|
||||||
.thenAccept((i) -> {
|
.thenAccept((i) -> {
|
||||||
Iris.verbose("Generated Async " + chunk);
|
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
|
@ -23,20 +23,28 @@ import com.volmit.iris.core.pregenerator.PregenListener;
|
|||||||
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
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.parallel.MultiBurst;
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public class AsyncPregenMethod implements PregeneratorMethod {
|
public class AsyncPregenMethod implements PregeneratorMethod {
|
||||||
private final World world;
|
private final World world;
|
||||||
private final MultiBurst burst;
|
private final MultiBurst burst;
|
||||||
private final KList<Future<?>> future;
|
private final KList<Future<?>> future;
|
||||||
|
private final Map<Chunk, Long> lastUse;
|
||||||
|
|
||||||
public AsyncPregenMethod(World world, int threads) {
|
public AsyncPregenMethod(World world, int threads) {
|
||||||
if (!PaperLib.isPaper()) {
|
if (!PaperLib.isPaper()) {
|
||||||
@ -46,6 +54,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
this.world = world;
|
this.world = world;
|
||||||
burst = MultiBurst.burst;
|
burst = MultiBurst.burst;
|
||||||
future = new KList<>(1024);
|
future = new KList<>(1024);
|
||||||
|
this.lastUse = new KMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unloadAndSaveAllChunks() {
|
private void unloadAndSaveAllChunks() {
|
||||||
@ -56,8 +65,12 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Chunk i : world.getLoadedChunks()) {
|
for (Chunk i : new ArrayList<>(lastUse.keySet())) {
|
||||||
i.unload(true);
|
Long lastUseTime = lastUse.get(i);
|
||||||
|
if (lastUseTime != null && M.ms() - lastUseTime >= 10000) {
|
||||||
|
i.unload();
|
||||||
|
lastUse.remove(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
world.save();
|
world.save();
|
||||||
}).get();
|
}).get();
|
||||||
@ -72,7 +85,8 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
if (i == null) {
|
if (i == null) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Chunk c = Bukkit.getWorld(world.getUID()).getChunkAt(x, z);
|
||||||
|
lastUse.put(c, M.ms());
|
||||||
listener.onChunkGenerated(x, z);
|
listener.onChunkGenerated(x, z);
|
||||||
listener.onChunkCleaned(x, z);
|
listener.onChunkCleaned(x, z);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -18,25 +18,33 @@
|
|||||||
|
|
||||||
package com.volmit.iris.core.pregenerator.methods;
|
package com.volmit.iris.core.pregenerator.methods;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.IrisSettings;
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.pregenerator.PregenListener;
|
import com.volmit.iris.core.pregenerator.PregenListener;
|
||||||
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
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.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class MedievalPregenMethod implements PregeneratorMethod {
|
public class MedievalPregenMethod implements PregeneratorMethod {
|
||||||
private final World world;
|
private final World world;
|
||||||
private final KList<CompletableFuture<?>> futures;
|
private final KList<CompletableFuture<?>> futures;
|
||||||
|
private final Map<Chunk, Long> lastUse;
|
||||||
|
|
||||||
public MedievalPregenMethod(World world) {
|
public MedievalPregenMethod(World world) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
futures = new KList<>();
|
futures = new KList<>();
|
||||||
|
this.lastUse = new KMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void waitForChunks() {
|
private void waitForChunks() {
|
||||||
@ -52,11 +60,19 @@ public class MedievalPregenMethod implements PregeneratorMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void unloadAndSaveAllChunks() {
|
private void unloadAndSaveAllChunks() {
|
||||||
waitForChunks();
|
|
||||||
try {
|
try {
|
||||||
J.sfut(() -> {
|
J.sfut(() -> {
|
||||||
for (Chunk i : world.getLoadedChunks()) {
|
if (world == null) {
|
||||||
i.unload(true);
|
Iris.warn("World was null somehow...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Chunk i : new ArrayList<>(lastUse.keySet())) {
|
||||||
|
Long lastUseTime = lastUse.get(i);
|
||||||
|
if (lastUseTime != null && M.ms() - lastUseTime >= 10) {
|
||||||
|
i.unload();
|
||||||
|
lastUse.remove(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
world.save();
|
world.save();
|
||||||
}).get();
|
}).get();
|
||||||
@ -104,6 +120,8 @@ public class MedievalPregenMethod implements PregeneratorMethod {
|
|||||||
listener.onChunkGenerating(x, z);
|
listener.onChunkGenerating(x, z);
|
||||||
futures.add(J.sfut(() -> {
|
futures.add(J.sfut(() -> {
|
||||||
world.getChunkAt(x, z);
|
world.getChunkAt(x, z);
|
||||||
|
Chunk c = Bukkit.getWorld(world.getUID()).getChunkAt(x, z);
|
||||||
|
lastUse.put(c, M.ms());
|
||||||
listener.onChunkGenerated(x, z);
|
listener.onChunkGenerated(x, z);
|
||||||
listener.onChunkCleaned(x, z);
|
listener.onChunkCleaned(x, z);
|
||||||
}));
|
}));
|
||||||
|
@ -73,7 +73,6 @@ public class ModesSFG {
|
|||||||
Iris.info(C.YELLOW + "- Broken worlds");
|
Iris.info(C.YELLOW + "- Broken worlds");
|
||||||
Iris.info(C.YELLOW + "- Unexpected behavior.");
|
Iris.info(C.YELLOW + "- Unexpected behavior.");
|
||||||
Iris.info(C.YELLOW + "- And perhaps further complications.");
|
Iris.info(C.YELLOW + "- And perhaps further complications.");
|
||||||
Iris.info(C.GOLD + "ATTENTION: " + C.YELLOW + "While running Iris in unstable mode, you won't be eligible for support.");
|
|
||||||
Iris.info(C.GOLD + "CAUSE: " + C.YELLOW + UtilsSFG.MSGIncompatibleWarnings());
|
Iris.info(C.GOLD + "CAUSE: " + C.YELLOW + UtilsSFG.MSGIncompatibleWarnings());
|
||||||
Iris.info("");
|
Iris.info("");
|
||||||
}
|
}
|
||||||
|
@ -125,21 +125,32 @@ public class BoardSVC implements IrisService, BoardProvider {
|
|||||||
int y = player.getLocation().getBlockY() - player.getWorld().getMinHeight();
|
int y = player.getLocation().getBlockY() - player.getWorld().getMinHeight();
|
||||||
int z = player.getLocation().getBlockZ();
|
int z = player.getLocation().getBlockZ();
|
||||||
|
|
||||||
lines.add("&7&m ");
|
if(IrisSettings.get().getGeneral().debug){
|
||||||
lines.add(C.GREEN + "Speed" + C.GRAY + ": " + Form.f(engine.getGeneratedPerSecond(), 0) + "/s " + Form.duration(1000D / engine.getGeneratedPerSecond(), 0));
|
lines.add("&7&m ");
|
||||||
lines.add(C.AQUA + "Cache" + C.GRAY + ": " + Form.f(IrisData.cacheSize()));
|
lines.add(C.GREEN + "Speed" + C.GRAY + ": " + Form.f(engine.getGeneratedPerSecond(), 0) + "/s " + Form.duration(1000D / engine.getGeneratedPerSecond(), 0));
|
||||||
lines.add(C.AQUA + "Mantle" + C.GRAY + ": " + engine.getMantle().getLoadedRegionCount());
|
lines.add(C.AQUA + "Cache" + C.GRAY + ": " + Form.f(IrisData.cacheSize()));
|
||||||
lines.add("&7&m ");
|
lines.add(C.AQUA + "Mantle" + C.GRAY + ": " + engine.getMantle().getLoadedRegionCount());
|
||||||
lines.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName());
|
lines.add(C.LIGHT_PURPLE + "Carving" + C.GRAY + ": " + engine.getMantle().isCarved(x,y,z));
|
||||||
lines.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiomeOrMantle(x, y, z).getName());
|
lines.add("&7&m ");
|
||||||
if (!IrisSettings.get().getStudio().displayTrueHeight) {
|
lines.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName());
|
||||||
lines.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z) + player.getWorld().getMinHeight()));
|
lines.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiomeOrMantle(x, y, z).getName());
|
||||||
} else {
|
|
||||||
lines.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z)));
|
lines.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z)));
|
||||||
|
lines.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getComplex().getSlopeStream().get(x, z), 2));
|
||||||
|
lines.add(C.AQUA + "BUD/s" + C.GRAY + ": " + Form.f(engine.getBlockUpdatesPerSecond()));
|
||||||
|
lines.add("&7&m ");
|
||||||
|
} else {
|
||||||
|
lines.add("&7&m ");
|
||||||
|
lines.add(C.GREEN + "Speed" + C.GRAY + ": " + Form.f(engine.getGeneratedPerSecond(), 0) + "/s " + Form.duration(1000D / engine.getGeneratedPerSecond(), 0));
|
||||||
|
lines.add(C.AQUA + "Cache" + C.GRAY + ": " + Form.f(IrisData.cacheSize()));
|
||||||
|
lines.add(C.AQUA + "Mantle" + C.GRAY + ": " + engine.getMantle().getLoadedRegionCount());
|
||||||
|
lines.add("&7&m ");
|
||||||
|
lines.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName());
|
||||||
|
lines.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiomeOrMantle(x, y, z).getName());
|
||||||
|
lines.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z)));
|
||||||
|
lines.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getComplex().getSlopeStream().get(x, z), 2));
|
||||||
|
lines.add(C.AQUA + "BUD/s" + C.GRAY + ": " + Form.f(engine.getBlockUpdatesPerSecond()));
|
||||||
|
lines.add("&7&m ");
|
||||||
}
|
}
|
||||||
lines.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getComplex().getSlopeStream().get(x, z), 2));
|
|
||||||
lines.add(C.AQUA + "BUD/s" + C.GRAY + ": " + Form.f(engine.getBlockUpdatesPerSecond()));
|
|
||||||
lines.add("&7&m ");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,163 +0,0 @@
|
|||||||
package com.volmit.iris.core.service;
|
|
||||||
|
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Chunk;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.player.PlayerMoveEvent;
|
|
||||||
import org.bukkit.event.world.ChunkLoadEvent;
|
|
||||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
|
||||||
import org.bukkit.event.world.WorldLoadEvent;
|
|
||||||
import org.bukkit.event.world.WorldUnloadEvent;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
public class ChunkHandlerSVC implements Listener {
|
|
||||||
// Does nothing for now
|
|
||||||
private final JavaPlugin plugin;
|
|
||||||
private static BukkitTask task;
|
|
||||||
private final Map<World, ChunkUnloader> worlds = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
private static final Map<Chunk, Set<Player>> playersInChunk = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public ChunkHandlerSVC(JavaPlugin plugin) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
|
||||||
|
|
||||||
for (World world : Bukkit.getWorlds()) {
|
|
||||||
if (IrisToolbelt.isIrisWorld(world)) {
|
|
||||||
worlds.put(world, new ChunkUnloader(plugin, world));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
startTask();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startTask() {
|
|
||||||
if (task == null) {
|
|
||||||
task = new BukkitRunnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
worlds.values().forEach(ChunkUnloader::update);
|
|
||||||
}
|
|
||||||
}.runTaskTimerAsynchronously(plugin, 0L, 1L);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerMove(PlayerMoveEvent event) {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
Chunk previousChunk = event.getFrom().getChunk();
|
|
||||||
Chunk currentChunk = event.getTo().getChunk();
|
|
||||||
|
|
||||||
if (!previousChunk.equals(currentChunk)) {
|
|
||||||
playersInChunk.computeIfAbsent(previousChunk, k -> ConcurrentHashMap.newKeySet()).remove(player);
|
|
||||||
playersInChunk.computeIfAbsent(currentChunk, k -> ConcurrentHashMap.newKeySet()).add(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void exit() {
|
|
||||||
if (task != null) {
|
|
||||||
task.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onWorldLoad(WorldLoadEvent event) {
|
|
||||||
World world = event.getWorld();
|
|
||||||
if (IrisToolbelt.isIrisWorld(world)) {
|
|
||||||
worlds.put(world, new ChunkUnloader(plugin, world));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onWorldUnload(WorldUnloadEvent event) {
|
|
||||||
worlds.remove(event.getWorld());
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onChunkLoad(ChunkLoadEvent event) {
|
|
||||||
World world = event.getWorld();
|
|
||||||
if (worlds.containsKey(world)) {
|
|
||||||
worlds.get(world).onChunkLoad(event.getChunk());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onChunkUnload(ChunkUnloadEvent event) {
|
|
||||||
World world = event.getWorld();
|
|
||||||
if (worlds.containsKey(world)) {
|
|
||||||
worlds.get(world).onChunkUnload(event.getChunk());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ChunkUnloader {
|
|
||||||
private final JavaPlugin plugin;
|
|
||||||
private final World world;
|
|
||||||
private final Map<Chunk, Long> chunks = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
private ChunkUnloader(JavaPlugin plugin, World world) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.world = world;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onChunkLoad(Chunk chunk) {
|
|
||||||
// System.out.printf("%s > Loaded Chunk [x=%s, z=%s]%n", world.getName(), chunk.getX(), chunk.getZ());
|
|
||||||
chunks.put(chunk, System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onChunkUnload(Chunk chunk) {
|
|
||||||
chunks.remove(chunk);
|
|
||||||
playersInChunk.remove(chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update() {
|
|
||||||
try {
|
|
||||||
long currentTime = System.currentTimeMillis();
|
|
||||||
Set<Chunk> chunkSet = new HashSet<>(chunks.keySet());
|
|
||||||
for (Chunk chunk : chunkSet) {
|
|
||||||
if (!chunk.isLoaded()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isChunkNearby(chunk)) {
|
|
||||||
chunks.put(chunk, currentTime + TimeUnit.MINUTES.toMillis(3));
|
|
||||||
} else if (chunks.get(chunk) <= currentTime) {
|
|
||||||
unloadChunk(chunk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Log the error message
|
|
||||||
System.out.println("Error in update method: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private boolean isChunkNearby(Chunk chunk) {
|
|
||||||
Set<Player> players = playersInChunk.get(chunk);
|
|
||||||
if (players == null) {
|
|
||||||
players = ConcurrentHashMap.newKeySet();
|
|
||||||
playersInChunk.put(chunk, players);
|
|
||||||
}
|
|
||||||
return !players.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void unloadChunk(Chunk chunk) {
|
|
||||||
try {
|
|
||||||
// System.out.printf("%s > Unloading Chunk [x=%s, z=%s]%n", world.getName(), chunk.getX(), chunk.getZ());
|
|
||||||
Bukkit.getScheduler().runTask(plugin, () -> chunk.unload(true));
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.out.println("Error unloading chunk: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -44,7 +44,13 @@ public class IrisCeilingDecorator extends IrisEngineDecorator {
|
|||||||
if (decorator != null) {
|
if (decorator != null) {
|
||||||
if (!decorator.isStacking()) {
|
if (!decorator.isStacking()) {
|
||||||
if (height >= 0 || height < getEngine().getHeight()) {
|
if (height >= 0 || height < getEngine().getHeight()) {
|
||||||
data.set(x, height, z, fixFaces(decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()), realX, height, realZ));
|
if (null != decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData())) {
|
||||||
|
data.set(x, height, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));
|
||||||
|
height--;
|
||||||
|
data.set(x, height, z, decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData()));
|
||||||
|
} else {
|
||||||
|
data.set(x, height, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int stack = decorator.getHeight(getRng().nextParallelRNG(Cache.key(realX, realZ)), realX, realZ, getData());
|
int stack = decorator.getHeight(getRng().nextParallelRNG(Cache.key(realX, realZ)), realX, realZ, getData());
|
||||||
|
@ -40,7 +40,13 @@ public class IrisSeaFloorDecorator extends IrisEngineDecorator {
|
|||||||
if (decorator != null) {
|
if (decorator != null) {
|
||||||
if (!decorator.isStacking()) {
|
if (!decorator.isStacking()) {
|
||||||
if (height >= 0 || height < getEngine().getHeight()) {
|
if (height >= 0 || height < getEngine().getHeight()) {
|
||||||
data.set(x, height, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));
|
if (null != decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData())) {
|
||||||
|
data.set(x, height, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));
|
||||||
|
height++;
|
||||||
|
data.set(x, height, z, decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData()));
|
||||||
|
} else {
|
||||||
|
data.set(x, height, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int stack = decorator.getHeight(getRng().nextParallelRNG(Cache.key(realX, realZ)), realX, realZ, getData());
|
int stack = decorator.getHeight(getRng().nextParallelRNG(Cache.key(realX, realZ)), realX, realZ, getData());
|
||||||
|
@ -40,7 +40,13 @@ public class IrisSeaSurfaceDecorator extends IrisEngineDecorator {
|
|||||||
if (decorator != null) {
|
if (decorator != null) {
|
||||||
if (!decorator.isStacking()) {
|
if (!decorator.isStacking()) {
|
||||||
if (height >= 0 || height < getEngine().getHeight()) {
|
if (height >= 0 || height < getEngine().getHeight()) {
|
||||||
data.set(x, height + 1, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));
|
if (null != decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData())) {
|
||||||
|
data.set(x, height, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));
|
||||||
|
height++;
|
||||||
|
data.set(x, height, z, decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData()));
|
||||||
|
} else {
|
||||||
|
data.set(x, height, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int stack = decorator.getHeight(getRng().nextParallelRNG(Cache.key(realX, realZ)), realX, realZ, getData());
|
int stack = decorator.getHeight(getRng().nextParallelRNG(Cache.key(realX, realZ)), realX, realZ, getData());
|
||||||
|
@ -46,7 +46,13 @@ public class IrisShoreLineDecorator extends IrisEngineDecorator {
|
|||||||
|
|
||||||
if (decorator != null) {
|
if (decorator != null) {
|
||||||
if (!decorator.isStacking()) {
|
if (!decorator.isStacking()) {
|
||||||
data.set(x, height + 1, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));
|
if (null != decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData())) {
|
||||||
|
data.set(x, height, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));
|
||||||
|
height++;
|
||||||
|
data.set(x, height, z, decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData()));
|
||||||
|
} else {
|
||||||
|
data.set(x, height, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int stack = decorator.getHeight(getRng().nextParallelRNG(Cache.key(realX, realZ)), realX, realZ, getData());
|
int stack = decorator.getHeight(getRng().nextParallelRNG(Cache.key(realX, realZ)), realX, realZ, getData());
|
||||||
if (decorator.isScaleStack()) {
|
if (decorator.isScaleStack()) {
|
||||||
|
@ -60,7 +60,7 @@ public class HeightmapObjectPlacer implements IObjectPlacer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCarved(int x, int y, int z) {
|
public boolean isCarved(int x, int y, int z) {
|
||||||
return false;
|
return oplacer.isCarved(x,y,z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSolid(int param1Int1, int param1Int2, int param1Int3) {
|
public boolean isSolid(int param1Int1, int param1Int2, int param1Int3) {
|
||||||
|
@ -104,6 +104,8 @@ public class MantleJigsawComponent extends IrisMantleComponent {
|
|||||||
|
|
||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
public IrisJigsawStructure guess(int x, int z) {
|
public IrisJigsawStructure guess(int x, int z) {
|
||||||
|
// todo The guess doesnt bring into account that the placer may return -1
|
||||||
|
boolean t = false;
|
||||||
RNG rng = new RNG(cng.fit(-Integer.MAX_VALUE, Integer.MAX_VALUE, x, z));
|
RNG rng = new RNG(cng.fit(-Integer.MAX_VALUE, Integer.MAX_VALUE, x, z));
|
||||||
IrisBiome biome = getEngineMantle().getEngine().getSurfaceBiome((x << 4) + 8, (z << 4) + 8);
|
IrisBiome biome = getEngineMantle().getEngine().getSurfaceBiome((x << 4) + 8, (z << 4) + 8);
|
||||||
IrisRegion region = getEngineMantle().getEngine().getRegion((x << 4) + 8, (z << 4) + 8);
|
IrisRegion region = getEngineMantle().getEngine().getRegion((x << 4) + 8, (z << 4) + 8);
|
||||||
|
@ -123,6 +123,7 @@ public class MantleObjectComponent extends IrisMantleComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> guess(int x, int z) {
|
public Set<String> guess(int x, int z) {
|
||||||
|
// todo The guess doesnt bring into account that the placer may return -1
|
||||||
RNG rng = applyNoise(x, z, Cache.key(x, z) + seed());
|
RNG rng = applyNoise(x, z, Cache.key(x, z) + seed());
|
||||||
IrisBiome biome = getEngineMantle().getEngine().getSurfaceBiome((x << 4) + 8, (z << 4) + 8);
|
IrisBiome biome = getEngineMantle().getEngine().getSurfaceBiome((x << 4) + 8, (z << 4) + 8);
|
||||||
IrisRegion region = getEngineMantle().getEngine().getRegion((x << 4) + 8, (z << 4) + 8);
|
IrisRegion region = getEngineMantle().getEngine().getRegion((x << 4) + 8, (z << 4) + 8);
|
||||||
|
@ -234,7 +234,7 @@ public class IrisCompat {
|
|||||||
filters.add(new IrisCompatabilityBlockFilter("ACACIA_WALL_SIGN", "LEGACY_WALL_SIGN"));
|
filters.add(new IrisCompatabilityBlockFilter("ACACIA_WALL_SIGN", "LEGACY_WALL_SIGN"));
|
||||||
filters.add(new IrisCompatabilityBlockFilter("ACACIA_SIGN", "LEGACY_SIGN_POST"));
|
filters.add(new IrisCompatabilityBlockFilter("ACACIA_SIGN", "LEGACY_SIGN_POST"));
|
||||||
filters.add(new IrisCompatabilityBlockFilter("SCAFFOLDING", "BIRCH_FENCE"));
|
filters.add(new IrisCompatabilityBlockFilter("SCAFFOLDING", "BIRCH_FENCE"));
|
||||||
filters.add(new IrisCompatabilityBlockFilter("LOOM", "LOOM"));
|
//filters.add(new IrisCompatabilityBlockFilter("LOOM", "LOOM"));
|
||||||
filters.add(new IrisCompatabilityBlockFilter("LECTERN", "BOOKSHELF"));
|
filters.add(new IrisCompatabilityBlockFilter("LECTERN", "BOOKSHELF"));
|
||||||
filters.add(new IrisCompatabilityBlockFilter("LANTERN", "REDSTONE_LAMP"));
|
filters.add(new IrisCompatabilityBlockFilter("LANTERN", "REDSTONE_LAMP"));
|
||||||
filters.add(new IrisCompatabilityBlockFilter("JIGSAW", "AIR"));
|
filters.add(new IrisCompatabilityBlockFilter("JIGSAW", "AIR"));
|
||||||
@ -254,6 +254,7 @@ public class IrisCompat {
|
|||||||
filters.add(new IrisCompatabilityBlockFilter("BAMBOO", "BIRCH_FENCE"));
|
filters.add(new IrisCompatabilityBlockFilter("BAMBOO", "BIRCH_FENCE"));
|
||||||
filters.add(new IrisCompatabilityBlockFilter("BAMBOO_SAPLING", "BIRCH_SAPLING"));
|
filters.add(new IrisCompatabilityBlockFilter("BAMBOO_SAPLING", "BIRCH_SAPLING"));
|
||||||
filters.add(new IrisCompatabilityBlockFilter("POTTED_BAMBOO", "POTTED_BIRCH_SAPLING"));
|
filters.add(new IrisCompatabilityBlockFilter("POTTED_BAMBOO", "POTTED_BIRCH_SAPLING"));
|
||||||
|
filters.add(new IrisCompatabilityBlockFilter("GRASS", "SHORT_GRASS"));
|
||||||
|
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
@ -262,7 +263,7 @@ public class IrisCompat {
|
|||||||
String buf = n;
|
String buf = n;
|
||||||
int err = 16;
|
int err = 16;
|
||||||
|
|
||||||
BlockData tx = B.getOrNull(buf);
|
BlockData tx = B.getOrNull(buf, false);
|
||||||
|
|
||||||
if (tx != null) {
|
if (tx != null) {
|
||||||
return tx;
|
return tx;
|
||||||
@ -271,11 +272,19 @@ public class IrisCompat {
|
|||||||
searching:
|
searching:
|
||||||
while (true) {
|
while (true) {
|
||||||
if (err-- <= 0) {
|
if (err-- <= 0) {
|
||||||
return B.get("STONE");
|
Iris.error("Can't find block data for " + n);
|
||||||
|
return B.getNoCompat("STONE");
|
||||||
|
}
|
||||||
|
String m = buf;
|
||||||
|
if (m.contains("[")) {
|
||||||
|
m = m.split("\\Q[\\E")[0];
|
||||||
|
}
|
||||||
|
if (m.contains(":")) {
|
||||||
|
m = m.split("\\Q:\\E", 2)[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IrisCompatabilityBlockFilter i : blockFilters) {
|
for (IrisCompatabilityBlockFilter i : blockFilters) {
|
||||||
if (i.getWhen().equalsIgnoreCase(buf)) {
|
if (i.getWhen().equalsIgnoreCase(i.isExact() ? buf : m)) {
|
||||||
BlockData b = i.getReplace();
|
BlockData b = i.getReplace();
|
||||||
|
|
||||||
if (b != null) {
|
if (b != null) {
|
||||||
@ -287,7 +296,8 @@ public class IrisCompat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return B.get("STONE");
|
Iris.error("Can't find block data for " + n);
|
||||||
|
return B.getNoCompat("STONE");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,7 +340,7 @@ public class IrisCompat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buf = n;
|
buf = n;
|
||||||
BlockData tx = B.getOrNull(buf);
|
BlockData tx = B.getOrNull(buf, false);
|
||||||
|
|
||||||
if (tx != null) {
|
if (tx != null) {
|
||||||
return tx.getMaterial();
|
return tx.getMaterial();
|
||||||
|
@ -57,13 +57,13 @@ public class IrisCompatabilityBlockFilter {
|
|||||||
public BlockData getReplace() {
|
public BlockData getReplace() {
|
||||||
return replaceData.aquire(() ->
|
return replaceData.aquire(() ->
|
||||||
{
|
{
|
||||||
BlockData b = B.getOrNull(supplement);
|
BlockData b = B.getOrNull(supplement, false);
|
||||||
|
|
||||||
if (b == null) {
|
if (b == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Iris.warn("Compat: Using " + supplement + " in place of " + when + " since this server doesnt support '" + supplement + "'");
|
Iris.warn("Compat: Using '%s' in place of '%s' since this server doesnt support '%s'", supplement, when, when);
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
});
|
});
|
||||||
|
@ -505,6 +505,13 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (config.getCarvingSupport().supportsSurface()) {
|
||||||
|
// int y = placer.getHighest(x, z, rdata);
|
||||||
|
// if (placer.isCarved(x, y, z)) {
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
// Rotation calculation
|
// Rotation calculation
|
||||||
int slopeRotationY = 0;
|
int slopeRotationY = 0;
|
||||||
ProceduralStream<Double> heightStream = rdata.getEngine().getComplex().getHeightStream();
|
ProceduralStream<Double> heightStream = rdata.getEngine().getComplex().getHeightStream();
|
||||||
@ -699,7 +706,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
key = engine.getObjectPlacementKey(i, j, k);
|
key = engine.getObjectPlacementKey(i, j, k);
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
if (config.getForbiddenCollisions().contains(key) && !config.getAllowedCollisions().contains(key)) {
|
if (config.getForbiddenCollisions().contains(key) && !config.getAllowedCollisions().contains(key)) {
|
||||||
Iris.warn("%s collides with %s (%s / %s / %s)", getLoadKey(), key, i, j, k);
|
// Iris.debug("%s collides with %s (%s / %s / %s)", getLoadKey(), key, i, j, k);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.core.IrisSettings;
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.link.Identifier;
|
import com.volmit.iris.core.link.Identifier;
|
||||||
import com.volmit.iris.core.service.ExternalDataSVC;
|
import com.volmit.iris.core.service.ExternalDataSVC;
|
||||||
|
import com.volmit.iris.engine.object.IrisCompat;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||||
@ -144,6 +145,7 @@ public class B {
|
|||||||
Arrays.stream(new Material[]{
|
Arrays.stream(new Material[]{
|
||||||
GRASS,
|
GRASS,
|
||||||
TALL_GRASS,
|
TALL_GRASS,
|
||||||
|
TALL_SEAGRASS,
|
||||||
FERN,
|
FERN,
|
||||||
LARGE_FERN,
|
LARGE_FERN,
|
||||||
CORNFLOWER,
|
CORNFLOWER,
|
||||||
@ -406,7 +408,7 @@ public class B {
|
|||||||
return mat.getMaterial().isSolid();
|
return mat.getMaterial().isSolid();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockData getOrNull(String bdxf) {
|
public static BlockData getOrNull(String bdxf, boolean warn) {
|
||||||
try {
|
try {
|
||||||
String bd = bdxf.trim();
|
String bd = bdxf.trim();
|
||||||
|
|
||||||
@ -422,9 +424,9 @@ public class B {
|
|||||||
return DIRT_PATH.createBlockData();
|
return DIRT_PATH.createBlockData();
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockData bdx = parseBlockData(bd);
|
BlockData bdx = parseBlockData(bd, warn);
|
||||||
|
|
||||||
if (bdx == null) {
|
if (bdx == null && warn) {
|
||||||
if (clw.flip()) {
|
if (clw.flip()) {
|
||||||
Iris.warn("Unknown Block Data '" + bd + "'");
|
Iris.warn("Unknown Block Data '" + bd + "'");
|
||||||
}
|
}
|
||||||
@ -443,8 +445,8 @@ public class B {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockData get(String bdxf) {
|
public static BlockData getNoCompat(String bdxf) {
|
||||||
BlockData bd = getOrNull(bdxf);
|
BlockData bd = getOrNull(bdxf, true);
|
||||||
|
|
||||||
if (bd != null) {
|
if (bd != null) {
|
||||||
return bd;
|
return bd;
|
||||||
@ -453,20 +455,34 @@ public class B {
|
|||||||
return AIR;
|
return AIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static synchronized BlockData createBlockData(String s) {
|
public static BlockData get(String bdxf) {
|
||||||
|
if (bdxf.contains(":")) {
|
||||||
|
if (bdxf.startsWith("minecraft:")) {
|
||||||
|
return Iris.compat.getBlock(bdxf);
|
||||||
|
} else {
|
||||||
|
return getNoCompat(bdxf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Iris.compat.getBlock(bdxf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static synchronized BlockData createBlockData(String s, boolean warn) {
|
||||||
try {
|
try {
|
||||||
return Bukkit.createBlockData(s);
|
return Bukkit.createBlockData(s);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
if (s.contains("[")) {
|
if (s.contains("[")) {
|
||||||
return createBlockData(s.split("\\Q[\\E")[0]);
|
return createBlockData(s.split("\\Q[\\E")[0], warn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Iris.error("Can't find block data for " + s);
|
if (warn) {
|
||||||
|
Iris.error("Can't find block data for " + s);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BlockData parseBlockData(String ix) {
|
private static BlockData parseBlockData(String ix, boolean warn) {
|
||||||
try {
|
try {
|
||||||
BlockData bx = null;
|
BlockData bx = null;
|
||||||
|
|
||||||
@ -480,7 +496,7 @@ public class B {
|
|||||||
|
|
||||||
if (bx == null) {
|
if (bx == null) {
|
||||||
try {
|
try {
|
||||||
bx = createBlockData(ix.toLowerCase());
|
bx = createBlockData(ix.toLowerCase(), warn);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -488,7 +504,7 @@ public class B {
|
|||||||
|
|
||||||
if (bx == null) {
|
if (bx == null) {
|
||||||
try {
|
try {
|
||||||
bx = createBlockData("minecraft:" + ix.toLowerCase());
|
bx = createBlockData("minecraft:" + ix.toLowerCase(), warn);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -548,7 +564,7 @@ public class B {
|
|||||||
for (String key : stateMap.keySet()) { //Iterate through every state and check if its valid
|
for (String key : stateMap.keySet()) { //Iterate through every state and check if its valid
|
||||||
try {
|
try {
|
||||||
String newState = block + "[" + key + "=" + stateMap.get(key) + "]";
|
String newState = block + "[" + key + "=" + stateMap.get(key) + "]";
|
||||||
createBlockData(newState);
|
createBlockData(newState, warn);
|
||||||
newStates.put(key, stateMap.get(key));
|
newStates.put(key, stateMap.get(key));
|
||||||
|
|
||||||
} catch (IllegalArgumentException ignored) {
|
} catch (IllegalArgumentException ignored) {
|
||||||
@ -562,7 +578,7 @@ public class B {
|
|||||||
Iris.debug("Converting " + ix + " to " + newBlock);
|
Iris.debug("Converting " + ix + " to " + newBlock);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return createBlockData(newBlock);
|
return createBlockData(newBlock, warn);
|
||||||
} catch (Throwable e1) {
|
} catch (Throwable e1) {
|
||||||
Iris.reportError(e1);
|
Iris.reportError(e1);
|
||||||
}
|
}
|
||||||
|
@ -423,9 +423,9 @@ public class Mantle {
|
|||||||
ioTrim.set(true);
|
ioTrim.set(true);
|
||||||
unloadLock.lock();
|
unloadLock.lock();
|
||||||
try {
|
try {
|
||||||
Iris.debug("Trimming Tectonic Plates older than " + Form.duration(adjustedIdleDuration.get(), 0));
|
|
||||||
if (lastUse != null) {
|
if (lastUse != null) {
|
||||||
if (!lastUse.isEmpty()) {
|
if (!lastUse.isEmpty()) {
|
||||||
|
Iris.debug("Trimming Tectonic Plates older than " + Form.duration(adjustedIdleDuration.get(), 0));
|
||||||
for (Long i : new ArrayList<>(lastUse.keySet())) {
|
for (Long i : new ArrayList<>(lastUse.keySet())) {
|
||||||
double finalAdjustedIdleDuration = adjustedIdleDuration.get();
|
double finalAdjustedIdleDuration = adjustedIdleDuration.get();
|
||||||
hyperLock.withLong(i, () -> {
|
hyperLock.withLong(i, () -> {
|
||||||
|
@ -107,7 +107,7 @@ public class NBTWorld {
|
|||||||
p.deleteCharAt(p.length() - 1).append(']');
|
p.deleteCharAt(p.length() - 1).append(']');
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockData b = B.getOrNull(p.toString());
|
BlockData b = B.getOrNull(p.toString(), true);
|
||||||
|
|
||||||
if (b == null) {
|
if (b == null) {
|
||||||
return B.getAir();
|
return B.getAir();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user