9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2025-12-30 20:39:21 +00:00

Compare commits

..

34 Commits

Author SHA1 Message Date
Julian Krings
6d3edff459 make studio tools work on folia 2025-09-21 20:54:13 +02:00
Julian Krings
e06724fcf6 Merge branch 'refs/heads/dev' into feat/folia
# Conflicts:
#	core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java
#	core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java
#	core/src/main/java/com/volmit/iris/engine/framework/Engine.java
2025-09-21 20:41:11 +02:00
Julian Krings
b8219fac1b Merge branch 'dev' into feat/folia
# Conflicts:
#	core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java
#	core/src/main/java/com/volmit/iris/engine/framework/Engine.java
#	core/src/main/java/com/volmit/iris/engine/object/IrisEntity.java
2025-09-06 18:37:29 +02:00
Julian Krings
bddc061f46 make chunk retrieval to teleport async 2025-08-02 23:31:17 +02:00
Julian Krings
bf6af9a58d Merge branch 'dev' into feat/folia 2025-08-02 23:26:34 +02:00
Julian Krings
aaf2f2f8a6 fix teleport after world creation 2025-08-02 23:15:57 +02:00
Julian Krings
dc8cf0ad38 remove last usages of the bukkit scheduler 2025-08-02 23:15:21 +02:00
Julian Krings
bd07f5d325 add link for Worlds to bring back world creation on folia 2025-08-02 22:23:05 +02:00
Julian Krings
bd722fdacb Merge branch 'dev' into feat/folia
# Conflicts:
#	core/build.gradle.kts
#	core/src/main/java/com/volmit/iris/Iris.java
#	core/src/main/java/com/volmit/iris/core/commands/CommandIris.java
#	gradle/libs.versions.toml
2025-08-02 21:25:40 +02:00
Julian Krings
d5ec6a18a4 fix loot not being applied 2025-07-26 12:31:24 +02:00
Julian Krings
2f16c0cfb7 Merge branch 'dev' into feat/folia 2025-07-25 22:34:17 +02:00
Julian Krings
f7ac827692 don't relocate platform utils for now 2025-07-25 22:34:05 +02:00
Julian Krings
bddc62f385 fix object saving 2025-07-20 00:50:11 +02:00
Julian Krings
68a214edb5 move platform utils to the version catalog 2025-07-19 23:02:49 +02:00
Julian Krings
49d2392c80 use platform utils for regen 2025-07-19 22:55:25 +02:00
Julian Krings
fcbbd2135b apply folia modification to 1.21.7 nms 2025-07-19 22:53:06 +02:00
Julian Krings
c3442ab2ce Merge branch 'dev' into feat/folia
# Conflicts:
#	build.gradle.kts
#	core/build.gradle.kts
#	core/src/main/java/com/volmit/iris/Iris.java
#	core/src/main/java/com/volmit/iris/core/commands/CommandIris.java
#	core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java
#	core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java
#	core/src/main/resources/plugin.yml
#	nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java
#	nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java
#	nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java
#	nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java
#	nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java
#	nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java
#	nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java
#	settings.gradle.kts
2025-07-19 22:50:48 +02:00
Julian Krings
fd3971018b update platform utils 2025-06-23 16:16:25 +02:00
Julian Krings
b440d0257d fix iris what commands 2025-06-19 19:50:08 +02:00
Julian Krings
42a26a1de2 fix spawning empty particles and improve message for invalid tile states 2025-06-19 19:43:53 +02:00
Julian Krings
c8eab22427 fix a few sync teleports 2025-06-19 18:28:46 +02:00
Julian Krings
fa3e35f702 fix pregen save chunk failing 2025-06-19 18:28:22 +02:00
Julian Krings
cf0bc81778 replace scheduler and paperlib with platform utils 2025-06-19 17:46:08 +02:00
Julian Krings
bef99f18c3 fix effects 2025-06-18 12:00:55 +02:00
Julian Krings
96a384c09c fix modern tile states not applying 2025-06-18 11:51:09 +02:00
Julian Krings
d61b2205c0 handle failing restart command better 2025-06-18 11:25:41 +02:00
Julian Krings
ebdfb94392 Merge branch 'dev' into feat/folia 2025-06-17 21:28:29 +02:00
Julian Krings
1c5fe016cb handle failing world creation 2025-06-15 12:36:53 +02:00
Julian Krings
0957b9baf2 Merge branch 'dev' into feat/folia
# Conflicts:
#	core/src/main/java/com/volmit/iris/Iris.java
2025-06-15 12:24:18 +02:00
Julian Krings
7570064b1a fix locate command not teleporting 2025-06-14 19:36:32 +02:00
Julian Krings
e461c1e199 fix updater and mob spawning instantly failing 2025-06-14 19:35:28 +02:00
Julian Krings
35b879f0df get iris to load on folia, but it will not load worlds as this is currently not possible 2025-06-13 21:44:02 +02:00
Julian Krings
ba6fac5422 more helper methods 2025-06-13 21:05:11 +02:00
Julian Krings
2577344ac0 implement platform specific schedulers 2025-06-13 19:48:42 +02:00
84 changed files with 928 additions and 1127 deletions

View File

@@ -2,6 +2,7 @@ import com.volmit.nmstools.NMSToolsExtension
import com.volmit.nmstools.NMSToolsPlugin
import de.undercouch.gradle.tasks.download.Download
import xyz.jpenilla.runpaper.task.RunServer
import xyz.jpenilla.runtask.service.DownloadsAPIService
import kotlin.system.exitProcess
/*
@@ -24,7 +25,7 @@ import kotlin.system.exitProcess
buildscript {
repositories.maven("https://jitpack.io")
dependencies.classpath("com.github.VolmitSoftware:NMSTools:c88961416f")
dependencies.classpath("com.github.VolmitSoftware:NMSTools:c5cbc46ce6")
}
plugins {
@@ -36,7 +37,7 @@ plugins {
}
group = "com.volmit"
version = "3.7.10-1.20.1-1.21.8"
version = "3.7.2-1.20.1-1.21.8"
apply<ApiGenerator>()
@@ -65,7 +66,7 @@ val color = "truecolor"
val errorReporting = findProperty("errorReporting") as Boolean? ?: false
val nmsBindings = mapOf(
"v1_21_R5" to "1.21.8-R0.1-SNAPSHOT",
"v1_21_R5" to "1.21.7-R0.1-SNAPSHOT",
"v1_21_R4" to "1.21.5-R0.1-SNAPSHOT",
"v1_21_R3" to "1.21.4-R0.1-SNAPSHOT",
"v1_21_R2" to "1.21.3-R0.1-SNAPSHOT",
@@ -81,6 +82,10 @@ nmsBindings.forEach { key, value ->
apply<JavaPlugin>()
apply<NMSToolsPlugin>()
repositories {
maven("https://libraries.minecraft.net")
}
extensions.configure(NMSToolsExtension::class) {
jvm = jvmVersion.getOrDefault(key, 21)
version = value
@@ -90,6 +95,9 @@ nmsBindings.forEach { key, value ->
compileOnly(project(":core"))
compileOnly(rootProject.libs.annotations)
compileOnly(rootProject.libs.byteBuddy.core)
compileOnly(rootProject.libs.platformUtils) {
isTransitive = false
}
}
}
@@ -107,6 +115,22 @@ nmsBindings.forEach { key, value ->
systemProperty("iris.suppressReporting", !errorReporting)
jvmArgs("-javaagent:${project(":core:agent").tasks.jar.flatMap { it.archiveFile }.get().asFile.absolutePath}")
}
tasks.register<RunServer>("runFolia-$key") {
group = "servers"
downloadsApiService = DownloadsAPIService.folia(project)
minecraftVersion(value.split("-")[0])
minHeapSize = serverMinHeap
maxHeapSize = serverMaxHeap
pluginJars(tasks.jar.flatMap { it.archiveFile })
javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(jvmVersion.getOrDefault(key, 21))}
runDirectory.convention(layout.buildDirectory.dir("run/$key"))
systemProperty("disable.watchdog", "")
systemProperty("net.kyori.ansi.colorLevel", color)
systemProperty("com.mojang.eula.agree", true)
systemProperty("iris.suppressReporting", !errorReporting)
jvmArgs("-javaagent:${project(":core:agent").tasks.jar.flatMap { it.archiveFile }.get().asFile.absolutePath}")
}
}
tasks {
@@ -191,6 +215,7 @@ allprojects {
maven("https://mvn.lumine.io/repository/maven-public/") // mythic
maven("https://nexus.phoenixdevt.fr/repository/maven-public/") //MMOItems
maven("https://repo.onarandombox.com/content/groups/public/") //Multiverse Core
maven("https://repo.thenextlvl.net/releases") //Worlds
}
dependencies {

View File

@@ -67,16 +67,21 @@ dependencies {
isTransitive = false
}
compileOnly(libs.multiverseCore)
compileOnly(libs.worlds)
// Shaded
implementation(slimjarHelper("spigot"))
implementation(rootProject.libs.platformUtils) {
isTransitive = false
}
// Dynamically Loaded
slim(libs.paralithic)
slim(libs.paperlib)
slim(libs.adventure.api)
slim(libs.adventure.minimessage)
slim(libs.adventure.platform)
slim(libs.adventure.gson)
slim(libs.adventure.legacy)
slim(libs.bstats)
slim(libs.sentry)
@@ -108,6 +113,11 @@ dependencies {
slim(libs.mavenCore)
}
}
constraints {
slim(libs.gson)
compileOnly(libs.gson)
}
}
java {
@@ -131,8 +141,7 @@ slimJar {
))
relocate("com.dfsek.paralithic", "$lib.paralithic")
relocate("io.papermc.lib", "$lib.paper")
relocate("net.kyori", "$lib.kyori")
relocate("net.kyori.audience", "$lib.audience")
relocate("org.bstats", "$lib.metrics")
relocate("io.sentry", "$lib.sentry")
relocate("org.apache.maven", "$lib.maven")

View File

@@ -62,6 +62,8 @@ import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.Queue;
import com.volmit.iris.util.scheduling.ShurikenQueue;
import lombok.NonNull;
import de.crazydev22.platformutils.Platform;
import de.crazydev22.platformutils.PlatformUtils;
import org.bukkit.*;
import org.bukkit.block.data.BlockData;
import org.bukkit.command.Command;
@@ -79,6 +81,7 @@ import java.io.*;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -95,6 +98,7 @@ public class Iris extends VolmitPlugin implements Listener {
public static MultiverseCoreLink linkMultiverseCore;
public static IrisCompat compat;
public static FileWatcher configWatcher;
public static Platform platform;
private static VolmitSender sender;
private static Thread shutdownHook;
@@ -313,15 +317,14 @@ public class Iris extends VolmitPlugin implements Listener {
@SuppressWarnings("deprecation")
public static void later(NastyRunnable object) {
try {
Bukkit.getScheduler().scheduleAsyncDelayedTask(instance, () ->
{
platform.getAsyncScheduler().runDelayed(task -> {
try {
object.run();
} catch (Throwable e) {
e.printStackTrace();
Iris.reportError(e);
}
}, RNG.r.i(100, 1200));
}, RNG.r.i(5, 60), TimeUnit.SECONDS);
} catch (IllegalPluginAccessException ignored) {
}
@@ -441,6 +444,7 @@ public class Iris extends VolmitPlugin implements Listener {
private void enable() {
services = new KMap<>();
platform = PlatformUtils.createPlatform(this);
setupAudience();
Bindings.setupSentry();
initialize("com.volmit.iris.core.service").forEach((i) -> services.put((Class<? extends IrisService>) i.getClass(), (IrisService) i));
@@ -456,7 +460,7 @@ public class Iris extends VolmitPlugin implements Listener {
services.values().forEach(this::registerListener);
addShutdownHook();
J.s(() -> {
J.a(IrisSafeguard::suggestPaper);
//J.a(IrisSafeguard::suggestPaper); //TODO reimplement this
J.a(() -> IO.delete(getTemp()));
J.a(LazyPregenerator::loadLazyGenerators, 100);
J.a(this::bstats);
@@ -506,8 +510,13 @@ public class Iris extends VolmitPlugin implements Listener {
WorldCreator c = new WorldCreator(s)
.generator(gen)
.environment(dim.getEnvironment());
INMS.get().createWorld(c);
Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!");
INMS.get().createWorldAsync(c)
.thenAccept(w -> Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!"))
.exceptionally(e -> {
Iris.error("Failed to load world " + s + "!");
e.printStackTrace();
return null;
});
} catch (Throwable e) {
Iris.error("Failed to load world " + s + "!");
e.printStackTrace();
@@ -528,7 +537,7 @@ public class Iris extends VolmitPlugin implements Listener {
J.s(() -> {
for (Player i : getServer().getOnlinePlayers()) {
i.setGameMode(GameMode.SPECTATOR);
i.teleport(new Location(w, 0, 200, 0));
platform.teleportAsync(i, new Location(w, 0, 200, 0));
}
});
});
@@ -562,7 +571,6 @@ public class Iris extends VolmitPlugin implements Listener {
public void onDisable() {
services.values().forEach(IrisService::onDisable);
Bukkit.getScheduler().cancelTasks(this);
HandlerList.unregisterAll((Plugin) this);
postShutdown.forEach(Runnable::run);
super.onDisable();

View File

@@ -179,11 +179,14 @@ public class ServerConfigurator {
Iris.warn("New data pack entries have been installed in Iris! Restarting server!");
Iris.warn("This will only happen when your pack changes (updates/first time setup)");
Iris.warn("(You can disable this auto restart in iris settings)");
if (!Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "restart")) {
Iris.warn("Looks like the restart command didn't work. Stopping the server instead!");
Bukkit.shutdown();
}
J.s(() -> {
Iris.warn("Looks like the restart command didn't work. Stopping the server instead!");
Bukkit.shutdown();
}, 100);
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "restart");
});
}

View File

@@ -42,7 +42,6 @@ import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.io.*;
import java.util.List;
@@ -158,13 +157,8 @@ public class CommandIris implements DecreeExecutor {
return;
}
new BukkitRunnable() {
@Override
public void run() {
target.teleport(world.getSpawnLocation());
new VolmitSender(target).sendMessage(C.GREEN + "You have been teleported to " + world.getName() + ".");
}
}.runTask(Iris.instance);
Iris.platform.teleportAsync(target, world.getSpawnLocation()).thenRun(() ->
new VolmitSender(target).sendMessage(C.GREEN + "You have been teleported to " + world.getName() + "."));
}
@Decree(description = "Print version information")

View File

@@ -128,7 +128,7 @@ public class CommandObject implements DecreeExecutor {
public Engine getEngine() {
return null;
}
};
}.sync(world);
}
@Decree(description = "Check the composition of an object")

View File

@@ -47,20 +47,16 @@ import com.volmit.iris.util.io.IO;
import com.volmit.iris.util.json.JSONArray;
import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.mantle.MantleChunk;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.math.Spiraler;
import com.volmit.iris.util.math.*;
import com.volmit.iris.util.noise.CNG;
import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.parallel.SyncExecutor;
import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.O;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import com.volmit.iris.util.scheduling.jobs.ParallelQueueJob;
import io.papermc.lib.PaperLib;
import de.crazydev22.platformutils.scheduler.task.Task;
import org.bukkit.*;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.util.BlockVector;
@@ -77,6 +73,7 @@ import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
@@ -174,7 +171,7 @@ public class CommandStudio implements DecreeExecutor {
PlatformChunkGenerator plat = IrisToolbelt.access(world);
Engine engine = plat.getEngine();
DecreeContext.touch(sender);
try (SyncExecutor executor = new SyncExecutor(20)) {
try (var executor = Iris.platform.createRegionExecutor(20)) {
int x = loc.getBlockX() >> 4;
int z = loc.getBlockZ() >> 4;
@@ -335,27 +332,25 @@ public class CommandStudio implements DecreeExecutor {
return;
}
Player player = player();
var scheduler = Iris.platform.getEntityScheduler(player);
scheduler.run(() -> {
sender().sendMessage(C.GREEN + "Opening inventory now!");
player.openInventory(inv);
O<Integer> ta = new O<>();
ta.set(-1);
scheduler.runAtFixedRate(refresh -> {
if (!player.getOpenInventory().getType().equals(InventoryType.CHEST)) {
refresh.cancel();
return;
}
ta.set(Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, () ->
{
if (!player().getOpenInventory().getType().equals(InventoryType.CHEST)) {
Bukkit.getScheduler().cancelTask(ta.get());
sender().sendMessage(C.GREEN + "Opened inventory!");
return;
}
if (!add) {
inv.clear();
}
if (!add) {
inv.clear();
}
engine().addItems(true, inv, new RNG(RNG.r.imax()), tables, InventorySlotType.STORAGE, player().getWorld(), player().getLocation().getBlockX(), player().getLocation().getBlockY(), player().getLocation().getBlockZ(), 1);
}, 0, fast ? 5 : 35));
sender().sendMessage(C.GREEN + "Opening inventory now!");
player().openInventory(inv);
engine().addItems(true, inv, new RNG(RNG.r.imax()), tables, InventorySlotType.STORAGE, player.getWorld(), player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ(), 1);
}, null, 1, fast ? 5 : 35);
}, null);
}
@Decree(description = "Calculate the chance for each region to generate", origin = DecreeOrigin.PLAYER)
@@ -378,7 +373,7 @@ public class CommandStudio implements DecreeExecutor {
var loc = player.getLocation();
int totalTasks = d * d;
AtomicInteger completedTasks = new AtomicInteger(0);
int c = J.ar(() -> sender.sendProgress((double) completedTasks.get() / totalTasks, "Finding regions"), 0);
Task c = J.ar(() -> sender.sendProgress((double) completedTasks.get() / totalTasks, "Finding regions"), 0);
new Spiraler(d, d, (x, z) -> executor.queue(() -> {
var region = engine.getRegion((x << 4) + 8, (z << 4) + 8);
data.computeIfAbsent(region.getLoadKey(), (k) -> new AtomicInteger(0))
@@ -387,7 +382,7 @@ public class CommandStudio implements DecreeExecutor {
})).setOffset(loc.getBlockX(), loc.getBlockZ()).drain();
executor.complete();
multiBurst.close();
J.car(c);
c.cancel();
sender.sendMessage(C.GREEN + "Done!");
var loader = engine.getData().getRegionLoader();
@@ -412,9 +407,7 @@ public class CommandStudio implements DecreeExecutor {
var loc = player().getLocation();
int totalTasks = d * d;
AtomicInteger completedTasks = new AtomicInteger(0);
int c = J.ar(() -> {
sender.sendProgress((double) completedTasks.get() / totalTasks, "Finding structures");
}, 0);
var c = J.ar(() -> sender.sendProgress((double) completedTasks.get() / totalTasks, "Finding structures"), 0);
new Spiraler(d, d, (x, z) -> executor.queue(() -> {
var struct = engine.getStructureAt(x, z);
@@ -426,7 +419,7 @@ public class CommandStudio implements DecreeExecutor {
executor.complete();
multiBurst.close();
J.car(c);
if (c != null) c.cancel();
for (var key : data.keySet()) {
var list = data.get(key);
@@ -704,8 +697,9 @@ public class CommandStudio implements DecreeExecutor {
}
sender().sendMessage(C.GREEN + "Sending you to the studio world!");
player().teleport(Iris.service(StudioSVC.class).getActiveProject().getActiveProvider().getTarget().getWorld().spawnLocation());
player().setGameMode(GameMode.SPECTATOR);
Player player = player();
Iris.platform.teleportAsync(player, Iris.service(StudioSVC.class).getActiveProject().getActiveProvider().getTarget().getWorld().spawnLocation());
Iris.platform.getEntityScheduler(player).run(() -> player.setGameMode(GameMode.SPECTATOR), null);
}
@Decree(description = "Update your dimension projects VSCode workspace")
@@ -721,7 +715,7 @@ public class CommandStudio implements DecreeExecutor {
}
}
@Decree(aliases = "find-objects", description = "Get information about nearby structures")
@Decree(aliases = "find-objects", description = "Get information about nearby structures", origin = DecreeOrigin.PLAYER)
public void objects() {
if (!IrisToolbelt.isIrisWorld(player().getWorld())) {
sender().sendMessage(C.RED + "You must be in an Iris world");
@@ -734,21 +728,29 @@ public class CommandStudio implements DecreeExecutor {
sender().sendMessage("You must be in an iris world.");
return;
}
KList<Chunk> chunks = new KList<>();
int bx = player().getLocation().getChunk().getX();
int bz = player().getLocation().getChunk().getZ();
KMap<Position2, CompletableFuture<Chunk>> chunks = new KMap<>();
var location = player().getLocation();
int bx = location.getBlockX() >> 4;
int bz = location.getBlockZ() >> 4;
Spiraled spiraled = (x, z) -> chunks.putIfAbsent(new Position2(x, z), Iris.platform.getChunkAtAsync(world, x, z));
try {
Location l = player().getTargetBlockExact(48, FluidCollisionMode.NEVER).getLocation();
var player = player();
var task = Iris.platform.getEntityScheduler(player).run(() -> {
var target = player.getTargetBlockExact(48, FluidCollisionMode.NEVER);
if (target == null) return;
Location l = target.getLocation();
int cx = l.getChunk().getX();
int cz = l.getChunk().getZ();
new Spiraler(3, 3, (x, z) -> chunks.addIfMissing(world.getChunkAt(x + cx, z + cz))).drain();
int cx = l.getBlockX() >> 4;
int cz = l.getBlockZ() >> 4;
new Spiraler(3, 3, (x, z) -> spiraled.on(x + cx, z + cz)).drain();
}, null);
if (task != null) task.getResult().join();
} catch (Throwable e) {
Iris.reportError(e);
}
new Spiraler(3, 3, (x, z) -> chunks.addIfMissing(world.getChunkAt(x + bx, z + bz))).drain();
new Spiraler(3, 3, (x, z) -> spiraled.on(x + bx, z + bz)).drain();
sender().sendMessage("Capturing IGenData from " + chunks.size() + " nearby chunks.");
try {
File ff = Iris.instance.getDataFile("reports/" + M.ms() + ".txt");
@@ -758,11 +760,11 @@ public class CommandStudio implements DecreeExecutor {
pw.println("Iris Version: " + Iris.instance.getDescription().getVersion());
pw.println("Bukkit Version: " + Bukkit.getBukkitVersion());
pw.println("MC Version: " + Bukkit.getVersion());
pw.println("PaperSpigot: " + (PaperLib.isPaper() ? "Yup!" : "Nope!"));
//pw.println("PaperSpigot: " + (PaperLib.isPaper() ? "Yup!" : "Nope!")); //TODO update this
pw.println("Report Captured At: " + new Date());
pw.println("Chunks: (" + chunks.size() + "): ");
for (Chunk i : chunks) {
for (Position2 i : chunks.keySet()) {
pw.println("- [" + i.getX() + ", " + i.getZ() + "]");
}
@@ -787,25 +789,31 @@ public class CommandStudio implements DecreeExecutor {
Iris.reportError(e);
}
KList<String> biomes = new KList<>();
KList<String> caveBiomes = new KList<>();
KMap<String, KMap<String, KList<String>>> objects = new KMap<>();
KSet<String> biomes = new KSet<>();
KSet<String> caveBiomes = new KSet<>();
KMap<String, KMap<String, KSet<String>>> objects = new KMap<>();
for (Chunk i : chunks) {
for (int j = 0; j < 16; j += 3) {
var engine = engine();
assert engine != null;
for (int k = 0; k < 16; k += 3) {
assert engine() != null;
IrisBiome bb = engine().getSurfaceBiome((i.getX() * 16) + j, (i.getZ() * 16) + k);
IrisBiome bxf = engine().getCaveBiome((i.getX() * 16) + j, (i.getZ() * 16) + k);
biomes.addIfMissing(bb.getName() + " [" + Form.capitalize(bb.getInferredType().name().toLowerCase()) + "] " + " (" + bb.getLoadFile().getName() + ")");
caveBiomes.addIfMissing(bxf.getName() + " (" + bxf.getLoadFile().getName() + ")");
exportObjects(bb, pw, engine(), objects);
exportObjects(bxf, pw, engine(), objects);
KList<CompletableFuture<?>> futures = new KList<>(chunks.size());
for (var future : chunks.values()) {
futures.add(future.thenAccept(i -> {
int bX = i.getX() << 4;
int bZ = i.getZ() << 4;
for (int j = 0; j < 16; j += 3) {
for (int k = 0; k < 16; k += 3) {
IrisBiome bb = engine.getSurfaceBiome(bX + j, bZ + k);
IrisBiome bxf = engine.getCaveBiome(bX + j, bZ + k);
biomes.add(bb.getName() + " [" + Form.capitalize(String.valueOf(bb.getInferredType()).toLowerCase()) + "] " + " (" + bb.getLoadFile().getName() + ")");
caveBiomes.add(bxf.getName() + " (" + bxf.getLoadFile().getName() + ")");
exportObjects(bb, pw, engine, objects);
exportObjects(bxf, pw, engine, objects);
}
}
}
}));
}
CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new)).join();
regions = Objects.requireNonNull(new File(world.getWorldFolder().getPath() + "/region").list()).length;
@@ -825,6 +833,13 @@ public class CommandStudio implements DecreeExecutor {
pw.println("- " + i);
}
pw.println();
pw.println("== Cave Biome Info ==");
pw.println("Found " + caveBiomes.size() + " Cave Biome(s): ");
for (String i : caveBiomes) {
pw.println("- " + i);
}
pw.println();
pw.println("== Object Info ==");
@@ -850,8 +865,8 @@ public class CommandStudio implements DecreeExecutor {
}
}
private void exportObjects(IrisBiome bb, PrintWriter pw, Engine g, KMap<String, KMap<String, KList<String>>> objects) {
String n1 = bb.getName() + " [" + Form.capitalize(bb.getInferredType().name().toLowerCase()) + "] " + " (" + bb.getLoadFile().getName() + ")";
private void exportObjects(IrisBiome bb, PrintWriter pw, Engine g, KMap<String, KMap<String, KSet<String>>> objects) {
String n1 = bb.getName() + " [" + Form.capitalize(String.valueOf(bb.getInferredType()).toLowerCase()) + "] " + " (" + bb.getLoadFile().getName() + ")";
int m = 0;
KSet<String> stop = new KSet<>();
for (IrisObjectPlacement f : bb.getObjects()) {
@@ -876,7 +891,7 @@ public class CommandStudio implements DecreeExecutor {
String n3 = nn3;
objects.computeIfAbsent(n1, (k1) -> new KMap<>())
.computeIfAbsent(n2, (k) -> new KList<>()).addIfMissing(n3);
.computeIfAbsent(n2, (k) -> new KSet<>()).add(n3);
}
}
}

View File

@@ -74,22 +74,22 @@ public class CommandWhat implements DecreeExecutor {
} catch (Throwable e) {
Iris.reportError(e);
sender().sendMessage("Non-Iris Biome: " + player().getLocation().getBlock().getBiome().name());
if (player().getLocation().getBlock().getBiome().equals(Biome.CUSTOM)) {
try {
sender().sendMessage("Data Pack Biome: " + INMS.get().getTrueBiomeBaseKey(player().getLocation()) + " (ID: " + INMS.get().getTrueBiomeBaseId(INMS.get().getTrueBiomeBase(player().getLocation())) + ")");
} catch (Throwable ee) {
Iris.reportError(ee);
}
}
var loc = player().getLocation();
var sender = sender();
Iris.platform.getRegionScheduler().run(loc, () -> {
var biome = loc.getBlock().getBiome();
if (biome != Biome.CUSTOM && biome.getKey().getNamespace().equals("minecraft"))
return;
sender.sendMessage("Data Pack Biome: " + INMS.get().getTrueBiomeBaseKey(loc) + " (ID: " + INMS.get().getTrueBiomeBaseId(INMS.get().getTrueBiomeBase(loc)) + ")");
});
}
}
@Decree(description = "What region am i in?", origin = DecreeOrigin.PLAYER)
public void region() {
try {
Chunk chunk = world().getChunkAt(player().getLocation().getBlockZ() / 16, player().getLocation().getBlockZ() / 16);
IrisRegion r = engine().getRegion(chunk);
var loc = player().getLocation();
IrisRegion r = engine().getRegion(loc);
sender().sendMessage("IRegion: " + r.getLoadKey() + " (" + r.getName() + ")");
} catch (Throwable e) {
@@ -98,7 +98,7 @@ public class CommandWhat implements DecreeExecutor {
}
}
@Decree(description = "What block am i looking at?", origin = DecreeOrigin.PLAYER)
@Decree(description = "What block am i looking at?", origin = DecreeOrigin.PLAYER, sync = true)
public void block() {
BlockData bd;
try {

View File

@@ -18,9 +18,10 @@
package com.volmit.iris.core.edit;
import com.volmit.iris.Iris;
import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.scheduling.AR;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.SR;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
@@ -79,7 +80,7 @@ public class BlockSignal {
e.setTicksLived(1);
e.setVelocity(new Vector(0, 0, 0));
new SR(20) {
new AR(20) {
@Override
public void run() {
if (e.isDead()) {
@@ -87,9 +88,10 @@ public class BlockSignal {
return;
}
e.setTicksLived(1);
e.teleport(tg.clone());
e.setVelocity(new Vector(0, 0, 0));
Iris.platform.teleportAsync(e, tg.clone()).thenAccept(b -> {
e.setTicksLived(1);
e.setVelocity(new Vector(0, 0, 0));
}).join();
}
};

View File

@@ -30,6 +30,7 @@ import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
import de.crazydev22.platformutils.scheduler.task.Task;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
@@ -55,7 +56,7 @@ public class JigsawEditor implements Listener {
private final IrisJigsawPiece piece;
private final Location origin;
private final Cuboid cuboid;
private final int ticker;
private final Task ticker;
private final KMap<IrisPosition, Runnable> falling = new KMap<>();
private final ChronoLatch cl = new ChronoLatch(100);
private Location target;
@@ -106,21 +107,26 @@ public class JigsawEditor implements Listener {
}
public Location toLocation(IrisPosition i) {
return origin.clone()
return toBlock(origin.clone()
.add(new Vector(i.getX(), i.getY(), i.getZ()))
.add(object.getCenter())
.getBlock()
.getLocation();
.add(object.getCenter()));
}
public IrisPosition toPosition(Location l) {
return new IrisPosition(l.clone().getBlock().getLocation()
return new IrisPosition(l.clone()
.subtract(origin.clone())
.subtract(object.getCenter())
.add(1, 1, 1)
.toVector());
}
private Location toBlock(Location location) {
location.setX(Math.floor(location.getX()));
location.setY(Math.floor(location.getY()));
location.setZ(Math.floor(location.getZ()));
return location;
}
@EventHandler
public void on(PlayerInteractEvent e) {
if (e.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
@@ -197,7 +203,7 @@ public class JigsawEditor implements Listener {
}
public void exit() {
J.car(ticker);
if (ticker != null) ticker.cancel();
Iris.instance.unregisterListener(this);
try {
J.sfut(() -> {

View File

@@ -763,7 +763,7 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener
int xx = (int) getWorldX(hx);
int zz = (int) getWorldZ(hz);
int h = engine.getComplex().getRoundedHeighteightStream().get(xx, zz);
player.teleport(new Location(player.getWorld(), xx, h, zz));
Iris.platform.teleportAsync(player, new Location(player.getWorld(), xx, h, zz));
notify("Teleporting to " + xx + ", " + h + ", " + zz);
} else {
notify("No player in world, can't teleport.");

View File

@@ -0,0 +1,68 @@
package com.volmit.iris.core.link;
import lombok.NonNull;
import net.thenextlvl.worlds.api.WorldsProvider;
import net.thenextlvl.worlds.api.generator.GeneratorType;
import net.thenextlvl.worlds.api.generator.LevelStem;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.concurrent.CompletableFuture;
public class FoliaWorldsLink {
private static FoliaWorldsLink instance;
private final Object provider;
private FoliaWorldsLink(Object provider) {
this.provider = provider;
}
public static FoliaWorldsLink get() {
if(instance == null) {
synchronized (FoliaWorldsLink.class) {
try {
Server.class.getDeclaredMethod("isGlobalTickThread");
instance = new FoliaWorldsLink(Bukkit.getServicesManager().load(WorldsProvider.class));
} catch (Throwable e) {
instance = new FoliaWorldsLink(null);
}
}
}
return instance;
}
public boolean isActive() {
return provider != null;
}
@Nullable
public CompletableFuture<World> createWorld(@NonNull WorldCreator creator) {
if (provider == null) return null;
return ((WorldsProvider) provider)
.levelBuilder(new File(Bukkit.getWorldContainer(), creator.name()).toPath())
.name(creator.name())
.seed(creator.seed())
.levelStem(switch (creator.environment()) {
case CUSTOM, NORMAL -> LevelStem.OVERWORLD;
case NETHER -> LevelStem.NETHER;
case THE_END -> LevelStem.END;
})
.chunkGenerator(creator.generator())
.biomeProvider(creator.biomeProvider())
.generatorType(switch (creator.type()) {
case NORMAL -> GeneratorType.NORMAL;
case FLAT -> GeneratorType.FLAT;
case LARGE_BIOMES -> GeneratorType.LARGE_BIOMES;
case AMPLIFIED -> GeneratorType.AMPLIFIED;
})
.structures(creator.generateStructures())
.hardcore(creator.hardcore())
.build()
.createAsync();
}
}

View File

@@ -35,7 +35,7 @@ import java.io.File;
@Data
public abstract class IrisRegistrant {
@Desc("Preprocess this object in-memory when it's loaded, run scripts using the variable 'object' and modify properties about this object before it's used.\nFile extension: .prox.kts")
@Desc("Preprocess this object in-memory when it's loaded, run scripts using the variable 'Iris.getPreprocessorObject()' and modify properties about this object before it's used.")
@RegistryListResource(IrisScript.class)
@ArrayType(min = 1, type = String.class)
private KList<String> preprocessors = new KList<>();

View File

@@ -20,6 +20,7 @@ package com.volmit.iris.core.nms;
import com.volmit.iris.core.link.Identifier;
import com.volmit.iris.core.nms.container.AutoClosing;
import com.volmit.iris.core.link.FoliaWorldsLink;
import com.volmit.iris.core.nms.container.BiomeColor;
import com.volmit.iris.core.nms.container.BlockProperty;
import com.volmit.iris.core.nms.container.Pair;
@@ -43,6 +44,7 @@ import org.bukkit.generator.ChunkGenerator;
import org.bukkit.inventory.ItemStack;
import java.awt.Color;
import java.util.concurrent.CompletableFuture;
import java.util.List;
public interface INMSBinding {
@@ -101,6 +103,15 @@ public interface INMSBinding {
return c.createWorld();
}
default CompletableFuture<World> createWorldAsync(WorldCreator c) {
try {
var link = FoliaWorldsLink.get();
return link.isActive() ? link.createWorld(c) : CompletableFuture.completedFuture(createWorld(c));
} catch (Throwable e) {
return CompletableFuture.failedFuture(e);
}
}
int countCustomBiomes();
void forceBiomeInto(int x, int y, int z, Object somethingVeryDirty, ChunkGenerator.BiomeGrid chunk);

View File

@@ -14,7 +14,6 @@ import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.RollingSequence;
import com.volmit.iris.util.profile.LoadBalancer;
import com.volmit.iris.util.scheduling.J;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
@@ -223,7 +222,7 @@ public class ChunkUpdater {
for (int dx = -1; dx <= 1; dx++) {
for (int dz = -1; dz <= 1; dz++) {
if (!PaperLib.isChunkGenerated(world, x + dx, z + dz)) {
if (!Iris.platform.isChunkGenerated(world, x + dx, z + dz)) {
return false;
}
}
@@ -239,7 +238,7 @@ public class ChunkUpdater {
try {
Chunk c;
try {
c = PaperLib.getChunkAtAsync(world, xx, zz, false, true)
c = Iris.platform.getChunkAtAsync(world, xx, zz, false, true)
.thenApply(chunk -> {
if (chunk != null)
chunk.addPluginChunkTicket(Iris.instance);
@@ -260,7 +259,7 @@ public class ChunkUpdater {
if (future != null) future.join();
}
if (!PaperLib.isChunkGenerated(c.getWorld(), xx, zz))
if (!Iris.platform.isChunkGenerated(c.getWorld(), xx, zz))
generated.set(false);
var pair = lastUse.computeIfAbsent(Cache.key(c), k -> new Pair<>(0L, new AtomicInteger(-1)));

View File

@@ -22,7 +22,6 @@ import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldUnloadEvent;
import org.bukkit.scheduler.BukkitRunnable;
import java.io.File;
import java.io.FileWriter;
@@ -235,16 +234,13 @@ public class DeepSearchPregenerator extends Thread implements Listener {
}
save();
jobs.remove(world.getName());
new BukkitRunnable() {
@Override
public void run() {
while (deepFile.exists()){
deepFile.delete();
J.sleep(1000);
}
Iris.info("DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " File deleted and instance closed.");
J.a(() -> {
while (deepFile.exists()) {
deepFile.delete();
J.sleep(1000);
}
}.runTaskLater(Iris.instance, 20L);
Iris.info("DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " File deleted and instance closed.");
}, 10);
} catch (Exception e) {
Iris.error("Failed to shutdown DeepSearch for " + world.getName());
e.printStackTrace();

View File

@@ -11,7 +11,6 @@ import com.volmit.iris.util.math.RollingSequence;
import com.volmit.iris.util.math.Spiraler;
import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
import io.papermc.lib.PaperLib;
import lombok.Data;
import lombok.Getter;
import org.bukkit.Bukkit;
@@ -19,7 +18,6 @@ import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldUnloadEvent;
import org.bukkit.scheduler.BukkitRunnable;
import java.io.File;
import java.io.IOException;
@@ -149,23 +147,9 @@ public class LazyPregenerator extends Thread implements Listener {
private void tickGenerate(Position2 chunk) {
executorService.submit(() -> {
CountDownLatch latch = new CountDownLatch(1);
if (PaperLib.isPaper()) {
PaperLib.getChunkAtAsync(world, chunk.getX(), chunk.getZ(), true)
.thenAccept((i) -> {
Iris.verbose("Generated Async " + chunk);
latch.countDown();
});
} else {
J.s(() -> {
world.getChunkAt(chunk.getX(), chunk.getZ());
Iris.verbose("Generated " + chunk);
latch.countDown();
});
}
try {
latch.await();
} catch (InterruptedException ignored) {}
Iris.platform.getChunkAtAsync(world, chunk.getX(), chunk.getZ(), true).thenAccept((i) -> {
Iris.verbose("Generated Async " + chunk);
}).join();
lazyGeneratedChunks.addAndGet(1);
});
}
@@ -238,16 +222,13 @@ public class LazyPregenerator extends Thread implements Listener {
}
save();
jobs.remove(world.getName());
new BukkitRunnable() {
@Override
public void run() {
while (lazyFile.exists()){
lazyFile.delete();
J.sleep(1000);
}
Iris.info("LazyGen: " + C.IRIS + world.getName() + C.BLUE + " File deleted and instance closed.");
J.a(() -> {
while (lazyFile.exists()){
lazyFile.delete();
J.sleep(1000);
}
}.runTaskLater(Iris.instance, 20L);
Iris.info("LazyGen: " + C.IRIS + world.getName() + C.BLUE + " File deleted and instance closed.");
}, 20);
} catch (Exception e) {
Iris.error("Failed to shutdown Lazygen for " + world.getName());
e.printStackTrace();

View File

@@ -17,7 +17,6 @@ import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import io.papermc.lib.PaperLib;
import lombok.Data;
import lombok.Getter;
import org.apache.logging.log4j.core.util.ExecutorServices;
@@ -26,7 +25,6 @@ import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldUnloadEvent;
import org.bukkit.scheduler.BukkitRunnable;
import org.checkerframework.checker.units.qual.N;
import java.io.File;
@@ -227,7 +225,7 @@ public class TurboPregenerator extends Thread implements Listener {
private void tickGenerate(Position2 chunk) {
executorService.submit(() -> {
CountDownLatch latch = new CountDownLatch(1);
PaperLib.getChunkAtAsync(world, chunk.getX(), chunk.getZ(), true)
Iris.platform.getChunkAtAsync(world, chunk.getX(), chunk.getZ(), true)
.thenAccept((i) -> {
latch.countDown();
});
@@ -302,16 +300,13 @@ public class TurboPregenerator extends Thread implements Listener {
}
save();
jobs.remove(world.getName());
new BukkitRunnable() {
@Override
public void run() {
while (turboFile.exists()) {
turboFile.delete();
J.sleep(1000);
}
Iris.info("turboGen: " + C.IRIS + world.getName() + C.BLUE + " File deleted and instance closed.");
J.a(() -> {
while (turboFile.exists()) {
turboFile.delete();
J.sleep(1000);
}
}.runTaskLater(Iris.instance, 20L);
Iris.info("turboGen: " + C.IRIS + world.getName() + C.BLUE + " File deleted and instance closed.");
}, 20);
} catch (Exception e) {
Iris.error("Failed to shutdown turbogen for " + world.getName());
e.printStackTrace();

View File

@@ -1,73 +0,0 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2022 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.core.pregenerator.methods;
import com.volmit.iris.core.pregenerator.PregenListener;
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
import com.volmit.iris.util.mantle.Mantle;
import io.papermc.lib.PaperLib;
import org.bukkit.World;
public class AsyncOrMedievalPregenMethod implements PregeneratorMethod {
private final PregeneratorMethod method;
public AsyncOrMedievalPregenMethod(World world, int threads) {
method = PaperLib.isPaper() ? new AsyncPregenMethod(world, threads) : new MedievalPregenMethod(world);
}
@Override
public void init() {
method.init();
}
@Override
public void close() {
method.close();
}
@Override
public void save() {
method.save();
}
@Override
public String getMethod(int x, int z) {
return method.getMethod(x, z);
}
@Override
public boolean supportsRegions(int x, int z, PregenListener listener) {
return false;
}
@Override
public void generateRegion(int x, int z, PregenListener listener) {
throw new UnsupportedOperationException();
}
@Override
public void generateChunk(int x, int z, PregenListener listener) {
method.generateChunk(x, z, listener);
}
@Override
public Mantle getMantle() {
return method.getMantle();
}
}

View File

@@ -23,17 +23,17 @@ import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.pregenerator.PregenListener;
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
import com.volmit.iris.core.tools.IrisToolbelt;
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.math.M;
import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.scheduling.J;
import io.papermc.lib.PaperLib;
import org.bukkit.Chunk;
import org.bukkit.World;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
@@ -48,11 +48,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
private final boolean urgent;
private final Map<Chunk, Long> lastUse;
public AsyncPregenMethod(World world, int unusedThreads) {
if (!PaperLib.isPaper()) {
throw new UnsupportedOperationException("Cannot use PaperAsync on non paper!");
}
public AsyncPregenMethod(World world) {
this.world = world;
this.executor = IrisSettings.get().getPregen().isUseTicketQueue() ? new TicketExecutor() : new ServiceExecutor();
this.threads = IrisSettings.get().getPregen().getMaxConcurrency();
@@ -63,26 +59,28 @@ public class AsyncPregenMethod implements PregeneratorMethod {
private void unloadAndSaveAllChunks() {
try {
J.sfut(() -> {
if (world == null) {
Iris.warn("World was null somehow...");
return;
}
if (world == null) {
Iris.warn("World was null somehow...");
return;
}
long minTime = M.ms() - 10_000;
lastUse.entrySet().removeIf(i -> {
final Chunk chunk = i.getKey();
final Long lastUseTime = i.getValue();
if (!chunk.isLoaded() || lastUseTime == null)
return true;
if (lastUseTime < minTime) {
chunk.unload();
return true;
}
return false;
});
world.save();
}).get();
long minTime = M.ms() - 10_000;
KList<CompletableFuture<?>> futures = new KList<>();
lastUse.entrySet().removeIf(i -> {
final Chunk chunk = i.getKey();
final Long lastUseTime = i.getValue();
if (!chunk.isLoaded() || lastUseTime == null)
return true;
if (lastUseTime < minTime) {
futures.add(Iris.platform.getRegionScheduler()
.run(chunk.getWorld(), chunk.getX(), chunk.getZ(), () -> chunk.unload())
.getResult());
return true;
}
return false;
});
futures.add(Iris.platform.getRegionScheduler().run(world, 0, 0, world::save).getResult());
CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new)).join();
} catch (Throwable e) {
e.printStackTrace();
}
@@ -197,7 +195,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
public void generate(int x, int z, PregenListener listener) {
service.submit(() -> {
try {
PaperLib.getChunkAtAsync(world, x, z, true, urgent).thenAccept((i) -> {
Iris.platform.getChunkAtAsync(world, x, z, true, urgent).thenAccept((i) -> {
listener.onChunkGenerated(x, z);
listener.onChunkCleaned(x, z);
if (i == null) return;
@@ -222,7 +220,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
private class TicketExecutor implements Executor {
@Override
public void generate(int x, int z, PregenListener listener) {
PaperLib.getChunkAtAsync(world, x, z, true, urgent)
Iris.platform.getChunkAtAsync(world, x, z, true, urgent)
.exceptionally(e -> {
Iris.reportError(e);
e.printStackTrace();

View File

@@ -1,74 +0,0 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2022 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.core.pregenerator.methods;
import com.volmit.iris.core.pregenerator.PregenListener;
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
import com.volmit.iris.util.mantle.Mantle;
import org.bukkit.World;
public class HybridPregenMethod implements PregeneratorMethod {
private final PregeneratorMethod inWorld;
private final World world;
public HybridPregenMethod(World world, int threads) {
this.world = world;
inWorld = new AsyncOrMedievalPregenMethod(world, threads);
}
@Override
public String getMethod(int x, int z) {
return "Hybrid<" + inWorld.getMethod(x, z) + ">";
}
@Override
public void init() {
inWorld.init();
}
@Override
public void close() {
inWorld.close();
}
@Override
public void save() {
inWorld.save();
}
@Override
public boolean supportsRegions(int x, int z, PregenListener listener) {
return inWorld.supportsRegions(x, z, listener);
}
@Override
public void generateRegion(int x, int z, PregenListener listener) {
inWorld.generateRegion(x, z, listener);
}
@Override
public void generateChunk(int x, int z, PregenListener listener) {
inWorld.generateChunk(x, z, listener);
}
@Override
public Mantle getMantle() {
return inWorld.getMantle();
}
}

View File

@@ -1,138 +0,0 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2022 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.core.pregenerator.methods;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.pregenerator.PregenListener;
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
import com.volmit.iris.core.tools.IrisToolbelt;
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.math.M;
import com.volmit.iris.util.scheduling.J;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
public class MedievalPregenMethod implements PregeneratorMethod {
private final World world;
private final KList<CompletableFuture<?>> futures;
private final Map<Chunk, Long> lastUse;
public MedievalPregenMethod(World world) {
this.world = world;
futures = new KList<>();
this.lastUse = new KMap<>();
}
private void waitForChunks() {
for (CompletableFuture<?> i : futures) {
try {
i.get();
} catch (Throwable e) {
e.printStackTrace();
}
}
futures.clear();
}
private void unloadAndSaveAllChunks() {
try {
J.sfut(() -> {
if (world == null) {
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();
}).get();
} catch (Throwable e) {
e.printStackTrace();
}
}
@Override
public void init() {
unloadAndSaveAllChunks();
}
@Override
public void close() {
unloadAndSaveAllChunks();
}
@Override
public void save() {
unloadAndSaveAllChunks();
}
@Override
public boolean supportsRegions(int x, int z, PregenListener listener) {
return false;
}
@Override
public void generateRegion(int x, int z, PregenListener listener) {
throw new UnsupportedOperationException();
}
@Override
public String getMethod(int x, int z) {
return "Medieval";
}
@Override
public void generateChunk(int x, int z, PregenListener listener) {
if (futures.size() > IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getParallelism())) {
waitForChunks();
}
listener.onChunkGenerating(x, z);
futures.add(J.sfut(() -> {
world.getChunkAt(x, z);
Chunk c = Bukkit.getWorld(world.getUID()).getChunkAt(x, z);
lastUse.put(c, M.ms());
listener.onChunkGenerated(x, z);
listener.onChunkCleaned(x, z);
}));
}
@Override
public Mantle getMantle() {
if (IrisToolbelt.isIrisWorld(world)) {
return IrisToolbelt.access(world).getEngine().getMantle().getMantle();
}
return null;
}
}

View File

@@ -1,12 +1,9 @@
package com.volmit.iris.core.scripting.environment;
import com.volmit.iris.core.loader.IrisRegistrant;
import com.volmit.iris.core.scripting.func.UpdateExecutor;
import com.volmit.iris.core.scripting.kotlin.environment.IrisExecutionEnvironment;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.mantle.MantleChunk;
import lombok.NonNull;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.jetbrains.annotations.Nullable;
@@ -25,6 +22,4 @@ public interface EngineEnvironment extends PackEnvironment {
void postSpawnMob(@NonNull String script, @NonNull Location location, @NonNull Entity mob);
void preprocessObject(@NonNull String script, @NonNull IrisRegistrant object);
void updateChunk(@NonNull String script, @NonNull MantleChunk mantleChunk, @NonNull Chunk chunk, @NonNull UpdateExecutor executor);
}

View File

@@ -1,22 +0,0 @@
package com.volmit.iris.core.scripting.func;
import org.jetbrains.annotations.NotNull;
@FunctionalInterface
public interface UpdateExecutor {
@NotNull Runnable wrap(int delay, @NotNull Runnable runnable);
@NotNull
default Runnable wrap(@NotNull Runnable runnable) {
return wrap(1, runnable);
}
default void execute(@NotNull Runnable runnable) {
execute(1, runnable);
}
default void execute(int delay, @NotNull Runnable runnable) {
wrap(delay, runnable).run();
}
}

View File

@@ -24,7 +24,6 @@ import com.volmit.iris.core.edit.BukkitBlockEditor;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.plugin.IrisService;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
@@ -38,7 +37,7 @@ public class EditSVC implements IrisService {
@Override
public void onEnable() {
this.editors = new KMap<>();
Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::update, 1000, 1000);
Iris.platform.getGlobalScheduler().runAtFixedRate(this::update, 1000, 1000);
}
@Override

View File

@@ -22,7 +22,6 @@ import com.volmit.iris.Iris;
import com.volmit.iris.util.plugin.IrisService;
import com.volmit.iris.util.scheduling.J;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
@@ -71,21 +70,18 @@ public class ObjectSVC implements IrisService {
*/
private void revert(Map<Block, BlockData> blocks) {
Iterator<Map.Entry<Block, BlockData>> it = blocks.entrySet().iterator();
Bukkit.getScheduler().runTask(Iris.instance, () -> {
int amount = 0;
while (it.hasNext()) {
Map.Entry<Block, BlockData> entry = it.next();
BlockData data = entry.getValue();
entry.getKey().setBlockData(data, false);
var scheduler = Iris.platform.getRegionScheduler();
for (int i = 0; i < 200 && it.hasNext(); i++) {
Map.Entry<Block, BlockData> entry = it.next();
Block block = entry.getKey();
BlockData data = entry.getValue();
it.remove();
it.remove();
scheduler.run(block.getLocation(), () -> block.setBlockData(data, false));
}
amount++;
if (amount > 200) {
J.s(() -> revert(blocks), 1);
}
}
});
if (it.hasNext()) {
J.s(() -> revert(blocks), 1);
}
}
}

View File

@@ -142,9 +142,10 @@ public class TreeSVC implements IrisService {
public void set(int x, int y, int z, BlockData d) {
Block b = event.getWorld().getBlockAt(x, y, z);
BlockState state = b.getState();
if (d instanceof IrisCustomData data)
if (d instanceof IrisCustomData data) {
state.setBlockData(data.getBase());
else state.setBlockData(d);
Iris.service(ExternalDataSVC.class).processUpdate(engine, b, data.getCustom());
} else state.setBlockData(d);
blockStateList.add(b.getState());
dataCache.put(new Location(event.getWorld(), x, y, z), d);
}
@@ -207,8 +208,7 @@ public class TreeSVC implements IrisService {
event.setCancelled(true);
J.s(() -> {
Iris.platform.getRegionScheduler().run(event.getLocation(), () -> {
StructureGrowEvent iGrow = new StructureGrowEvent(event.getLocation(), event.getSpecies(), event.isFromBonemeal(), event.getPlayer(), blockStateList);
block = true;
Bukkit.getServer().getPluginManager().callEvent(iGrow);

View File

@@ -35,6 +35,7 @@ import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.SR;
import com.volmit.iris.util.scheduling.jobs.Job;
import com.volmit.iris.util.scheduling.jobs.ScanJob;
import org.bukkit.*;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
@@ -86,80 +87,10 @@ public class WandSVC implements IrisService {
Cuboid c = new Cuboid(f[0], f[1]);
IrisObject s = new IrisObject(c.getSizeX(), c.getSizeY(), c.getSizeZ());
var it = c.chunkedIterator();
int total = c.getSizeX() * c.getSizeY() * c.getSizeZ();
var latch = new CountDownLatch(1);
new Job() {
private int i;
private Chunk chunk;
@Override
public String getName() {
return "Scanning Selection";
}
@Override
public void execute() {
new SR() {
@Override
public void run() {
var time = M.ms() + MS_PER_TICK;
while (time > M.ms()) {
if (!it.hasNext()) {
if (chunk != null) {
chunk.removePluginChunkTicket(Iris.instance);
chunk = null;
}
cancel();
latch.countDown();
return;
}
try {
var b = it.next();
var bChunk = b.getChunk();
if (chunk == null) {
chunk = bChunk;
chunk.addPluginChunkTicket(Iris.instance);
} else if (chunk != bChunk) {
chunk.removePluginChunkTicket(Iris.instance);
chunk = bChunk;
}
if (b.getType().equals(Material.AIR))
continue;
BlockVector bv = b.getLocation().subtract(c.getLowerNE().toVector()).toVector().toBlockVector();
s.setUnsigned(bv.getBlockX(), bv.getBlockY(), bv.getBlockZ(), b, legacy);
} finally {
i++;
}
}
}
};
try {
latch.await();
} catch (InterruptedException ignored) {}
}
@Override
public void completeWork() {}
@Override
public int getTotalWork() {
return total;
}
@Override
public int getWorkCompleted() {
return i;
}
}.execute(new VolmitSender(p), true, () -> {});
try {
latch.await();
} catch (InterruptedException ignored) {}
new ScanJob("Scanning Selection", c, MS_PER_TICK, (bv, b) -> {
if (b.getType().equals(Material.AIR)) return;
s.setUnsigned(bv.getBlockX(), bv.getBlockY(), bv.getBlockZ(), b, legacy);
}).execute(new VolmitSender(p), true, () -> {});
return s;
} catch (Throwable e) {

View File

@@ -11,6 +11,7 @@ import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.reflect.V;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import de.crazydev22.platformutils.scheduler.task.Task;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import org.apache.commons.io.FileUtils;
import org.bukkit.Bukkit;
@@ -58,7 +59,7 @@ public class IrisConverter {
int objW = ((ShortTag) compound.get("Width")).getValue();
int objH = ((ShortTag) compound.get("Height")).getValue();
int objD = ((ShortTag) compound.get("Length")).getValue();
int i = -1;
Task i = null;
int mv = objW * objH * objD;
AtomicInteger v = new AtomicInteger(0);
if (mv > 500_000) {
@@ -66,9 +67,7 @@ public class IrisConverter {
Iris.info(C.GRAY + "Converting.. "+ schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
Iris.info(C.GRAY + "- It may take a while");
if (sender.isPlayer()) {
i = J.ar(() -> {
sender.sendProgress((double) v.get() / mv, "Converting");
}, 0);
i = J.ar(() -> sender.sendProgress((double) v.get() / mv, "Converting"), 0);
}
}
@@ -97,7 +96,7 @@ public class IrisConverter {
}
}
}
if (i != -1) J.car(i);
if (i != null) i.cancel();
try {
object.shrinkwrap();
object.write(new File(folder, schem.getName().replace(".schem", ".iob")));

View File

@@ -32,7 +32,6 @@ import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.O;
import lombok.Data;
import lombok.experimental.Accessors;
import org.bukkit.*;
@@ -41,8 +40,10 @@ import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.function.IntSupplier;
import static com.volmit.iris.util.misc.ServerProperties.BUKKIT_YML;
@@ -128,8 +129,6 @@ public class IrisCreator {
}
AtomicDouble pp = new AtomicDouble(0);
O<Boolean> done = new O<>();
done.set(false);
WorldCreator wc = new IrisWorldCreator()
.dimension(dimension)
.name(name)
@@ -143,6 +142,7 @@ public class IrisCreator {
PlatformChunkGenerator access = (PlatformChunkGenerator) wc.generator();
if (access == null) throw new IrisException("Access is null. Something bad happened.");
AtomicBoolean done = new AtomicBoolean(false);
J.a(() -> {
IntSupplier g = () -> {
if (access.getEngine() == null) {
@@ -166,9 +166,11 @@ public class IrisCreator {
});
World world;
final World world;
try {
world = J.sfut(() -> INMS.get().createWorld(wc)).get();
world = J.sfut(() -> INMS.get().createWorldAsync(wc))
.thenCompose(Function.identity())
.get();
} catch (Throwable e) {
done.set(true);
throw new IrisException("Failed to create world!", e);
@@ -177,7 +179,15 @@ public class IrisCreator {
done.set(true);
if (sender.isPlayer() && !benchmark) {
J.s(() -> sender.player().teleport(new Location(world, 0, world.getHighestBlockYAt(0, 0) + 1, 0)));
Iris.platform.getChunkAtAsync(world, 0, 0, true, true)
.thenApply(Objects::requireNonNull)
.thenApply(c -> c.getChunkSnapshot(true, false, false).getHighestBlockYAt(0, 0) + 1)
.thenAccept(y -> Iris.platform.teleportAsync(sender.player(), new Location(world, 0, y, 0)))
.exceptionally(err -> {
sender.sendMessage(C.RED + "Failed to teleport you to the world!");
err.printStackTrace();
return null;
});
}
if (studio || benchmark) {

View File

@@ -24,8 +24,8 @@ import com.volmit.iris.core.gui.PregeneratorJob;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.core.pregenerator.PregenTask;
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
import com.volmit.iris.core.pregenerator.methods.AsyncPregenMethod;
import com.volmit.iris.core.pregenerator.methods.CachedPregenMethod;
import com.volmit.iris.core.pregenerator.methods.HybridPregenMethod;
import com.volmit.iris.core.service.StudioSVC;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.IrisDimension;
@@ -165,8 +165,7 @@ public class IrisToolbelt {
* @return the pregenerator job (already started)
*/
public static PregeneratorJob pregenerate(PregenTask task, PlatformChunkGenerator gen) {
return pregenerate(task, new HybridPregenMethod(gen.getEngine().getWorld().realWorld(),
IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getParallelism())), gen.getEngine());
return pregenerate(task, new AsyncPregenMethod(gen.getEngine().getWorld().realWorld()), gen.getEngine());
}
/**
@@ -182,7 +181,7 @@ public class IrisToolbelt {
return pregenerate(task, access(world));
}
return pregenerate(task, new HybridPregenMethod(world, IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getParallelism())), null);
return pregenerate(task, new AsyncPregenMethod(world), null);
}
/**
@@ -196,7 +195,7 @@ public class IrisToolbelt {
if (!i.getName().equals(world.getName())) {
for (Player j : world.getPlayers()) {
new VolmitSender(j, Iris.instance.getTag()).sendMessage("You have been evacuated from this world.");
j.teleport(i.getSpawnLocation());
Iris.platform.teleportAsync(j, i.getSpawnLocation());
}
return true;
@@ -218,7 +217,7 @@ public class IrisToolbelt {
if (!i.getName().equals(world.getName())) {
for (Player j : world.getPlayers()) {
new VolmitSender(j, Iris.instance.getTag()).sendMessage("You have been evacuated from this world. " + m);
j.teleport(i.getSpawnLocation());
Iris.platform.teleportAsync(j, i.getSpawnLocation());
}
return true;
}

View File

@@ -51,6 +51,7 @@ import com.volmit.iris.util.matter.slices.container.JigsawStructureContainer;
import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import de.crazydev22.platformutils.scheduler.task.Task;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@@ -86,7 +87,7 @@ public class IrisEngine implements Engine {
private final EngineMetrics metrics;
private final boolean studio;
private final AtomicRollingSequence wallClock;
private final int art;
private final Task art;
private final AtomicCache<IrisEngineData> engineData = new AtomicCache<>();
private final AtomicBoolean cleaning;
private final ChronoLatch cleanLatch;
@@ -427,7 +428,7 @@ public class IrisEngine implements Engine {
public void close() {
PregeneratorJob.shutdownInstance();
closed = true;
J.car(art);
art.cancel();
getWorldManager().close();
getTarget().close();
saveEngineData();

View File

@@ -43,7 +43,6 @@ import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.Looper;
import com.volmit.iris.util.scheduling.jobs.QueueJob;
import io.papermc.lib.PaperLib;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.bukkit.Chunk;
@@ -61,10 +60,7 @@ import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -190,32 +186,54 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
for (Player i : getEngine().getWorld().realWorld().getPlayers()) {
int r = 1;
int cX = i.getLocation().getBlockX() >> 4;
int cZ = i.getLocation().getBlockZ() >> 4;
for (int x = -r; x <= r; x++) {
for (int z = -r; z <= r; z++) {
mantle.getChunk(i.getLocation().getChunk()).flag(MantleFlag.DISCOVERED, true);
mantle.getChunk(cX + x, cZ + z).flag(MantleFlag.DISCOVERED, true);
}
}
}
}
private void updateChunks() {
for (Player i : getEngine().getWorld().realWorld().getPlayers()) {
int r = 1;
int radius = 1;
int diameter = radius * 2 + 1;
int count = (diameter * diameter) + 1;
Chunk c = i.getLocation().getChunk();
for (int x = -r; x <= r; x++) {
for (int z = -r; z <= r; z++) {
if (c.getWorld().isChunkLoaded(c.getX() + x, c.getZ() + z) && Chunks.isSafe(getEngine().getWorld().realWorld(), c.getX() + x, c.getZ() + z)) {
var players = new KList<>(getEngine().getWorld().realWorld().getPlayers());
var latch = new CountDownLatch(count * players.size());
if (IrisSettings.get().getWorld().isPostLoadBlockUpdates()) {
getEngine().updateChunk(c.getWorld().getChunkAt(c.getX() + x, c.getZ() + z));
for (Player i : players) {
if (!i.isOnline() || !i.isValid() || i.isDead()) {
for (int j = 0; j < count; j++) {
latch.countDown();
}
continue;
}
Iris.platform.getEntityScheduler(i).run(() -> {
Chunk c = i.getLocation().getChunk();
for (int x = -radius; x <= radius; x++) {
for (int z = -radius; z <= radius; z++) {
int cX = c.getX() + x;
int cZ = c.getZ() + z;
if (!c.getWorld().isChunkLoaded(cX, cZ) || !Chunks.isSafe(getEngine().getWorld().realWorld(), cX, cZ)) {
latch.countDown();
continue;
}
if (IrisSettings.get().getWorld().isPostLoadBlockUpdates()) {
Chunk cx = c.getWorld().getChunkAt(cX, cZ);
J.a(() -> {
getEngine().updateChunk(cx);
latch.countDown();
});
} else latch.countDown();
if (IrisSettings.get().getWorld().isMarkerEntitySpawningSystem()) {
Chunk cx = getEngine().getWorld().realWorld().getChunkAt(c.getX() + x, c.getZ() + z);
int finalX = c.getX() + x;
int finalZ = c.getZ() + z;
J.a(() -> getMantle().raiseFlag(finalX, finalZ, MantleFlag.INITIAL_SPAWNED_MARKER,
Chunk cx = getEngine().getWorld().realWorld().getChunkAt(cX, cZ);
J.a(() -> getMantle().raiseFlag(cX, cZ, MantleFlag.INITIAL_SPAWNED_MARKER,
() -> {
J.a(() -> spawnIn(cx, true), RNG.r.i(5, 200));
getSpawnersFromMarkers(cx).forEach((blockf, spawners) -> {
@@ -231,8 +249,17 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
}
}
}
}
latch.countDown();
}, () -> {
for (int j = 0; j < count; j++) {
latch.countDown();
}
});
}
try {
latch.await();
} catch (InterruptedException ignored) {}
}
private boolean onAsyncTick() {
@@ -493,8 +520,8 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
e.setCancelled(true);
warmupAreaAsync(e.getPlayer(), e.getTo(), () -> J.s(() -> {
ignoreTP.set(true);
e.getPlayer().teleport(e.getTo(), e.getCause());
ignoreTP.set(false);
Iris.platform.teleportAsync(e.getPlayer(), e.getTo(), e.getCause())
.thenRun(() -> ignoreTP.set(false));
}));
}
}
@@ -514,7 +541,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
}
futures.add(MultiBurst.burst.completeValue(()
-> PaperLib.getChunkAtAsync(to.getWorld(),
-> Iris.platform.getChunkAtAsync(to.getWorld(),
(to.getBlockX() >> 4) + finalI,
(to.getBlockZ() >> 4) + finalJ,
true, IrisSettings.get().getWorld().getAsyncTeleport().isUrgent()).get()));
@@ -551,19 +578,17 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
IrisPosition pos = new IrisPosition((c.getX() << 4) + x, y, (c.getZ() << 4) + z);
if (mark.isEmptyAbove()) {
AtomicBoolean remove = new AtomicBoolean(false);
Boolean remove = Iris.platform.getRegionScheduler()
.run(c.getWorld(), c.getX(), c.getZ(), () -> c.getBlock(x, y + 1, z).getType().isSolid() || c.getBlock(x, y + 2, z).getType().isSolid())
.getResult()
.exceptionally(e -> {
Iris.reportError(e);
e.printStackTrace();
return false;
})
.join();
try {
J.sfut(() -> {
if (c.getBlock(x, y + 1, z).getBlockData().getMaterial().isSolid() || c.getBlock(x, y + 2, z).getBlockData().getMaterial().isSolid()) {
remove.set(true);
}
}).get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
if (remove.get()) {
if (remove == Boolean.TRUE) {
b.add(pos);
return;
}

View File

@@ -64,7 +64,6 @@ import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import com.volmit.iris.util.stream.ProceduralStream;
import io.papermc.lib.PaperLib;
import org.bukkit.*;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
@@ -294,7 +293,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
var chunk = mantle.getChunk(c).use();
try {
Semaphore semaphore = new Semaphore(1024);
Semaphore semaphore = new Semaphore(3);
chunk.raiseFlag(MantleFlag.ETCHED, () -> {
chunk.raiseFlagUnchecked(MantleFlag.TILE, run(semaphore, () -> {
chunk.iterate(TileWrapper.class, (x, y, z, v) -> {
@@ -302,12 +301,12 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
if (!TileData.setTileState(block, v.getData()))
Iris.warn("Failed to set tile entity data at [%d %d %d | %s] for tile %s!", block.getX(), block.getY(), block.getZ(), block.getType().getKey(), v.getData().getMaterial().getKey());
});
}, 0));
}, c, 1));
chunk.raiseFlagUnchecked(MantleFlag.CUSTOM, run(semaphore, () -> {
chunk.iterate(Identifier.class, (x, y, z, v) -> {
Iris.service(ExternalDataSVC.class).processUpdate(this, c.getBlock(x & 15, y + getWorld().minHeight(), z & 15), v);
});
}, 0));
}, c, 1));
chunk.raiseFlagUnchecked(MantleFlag.UPDATE, run(semaphore, () -> {
PrecisionStopwatch p = PrecisionStopwatch.start();
@@ -352,36 +351,23 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
});
chunk.deleteSlices(MatterUpdate.class);
getMetrics().getUpdates().put(p.getMilliseconds());
}, RNG.r.i(1, 20))); //Why is there a random delay here?
});
chunk.raiseFlagUnchecked(MantleFlag.SCRIPT, () -> {
var scripts = getDimension().getChunkUpdateScripts();
if (scripts == null || scripts.isEmpty())
return;
for (var script : scripts) {
getExecution().updateChunk(script, chunk, c, (delay, task) -> run(semaphore, task, delay));
}
}, c, RNG.r.i(2, 20))); //Why is there a random delay here?
});
try {
semaphore.acquire(1024);
semaphore.acquire(3);
} catch (InterruptedException ignored) {}
} finally {
chunk.release();
}
}
private static Runnable run(Semaphore semaphore, Runnable runnable, int delay) {
private static Runnable run(Semaphore semaphore, Runnable runnable, Chunk chunk, int delay) {
return () -> {
try {
semaphore.acquire();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (!semaphore.tryAcquire())
return;
J.s(() -> {
Iris.platform.getRegionScheduler().runDelayed(chunk.getWorld(), chunk.getX(), chunk.getZ(), () -> {
try {
runnable.run();
} finally {
@@ -540,8 +526,9 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
if (IrisLootEvent.callLootEvent(items, inv, world, x, y, z))
return;
if (PaperLib.isPaper() && getWorld().hasRealWorld()) {
PaperLib.getChunkAtAsync(getWorld().realWorld(), x >> 4, z >> 4).thenAccept((c) -> {
if (world != null) {
final int cX = x >> 4, cZ = z >> 4;
Iris.platform.getChunkAtAsync(world, cX, cZ, true, false).thenAccept((c) -> {
Runnable r = () -> {
for (ItemStack i : items) {
inv.addItem(i);
@@ -550,10 +537,10 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
scramble(inv, rng);
};
if (Bukkit.isPrimaryThread()) {
if (Iris.platform.isOwnedByCurrentRegion(world, cX, cZ)) {
r.run();
} else {
J.s(r);
Iris.platform.getRegionScheduler().run(world, cX, cZ, r);
}
});
} else {
@@ -898,7 +885,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
player.sendMessage(C.GOLD + "No strongholds in world.");
} else {
Location ll = new Location(player.getWorld(), pr.getX(), 40, pr.getZ());
J.s(() -> player.teleport(ll));
Iris.platform.teleportAsync(player, ll);
}
return;

View File

@@ -20,39 +20,34 @@ package com.volmit.iris.engine.framework;
import com.volmit.iris.Iris;
import com.volmit.iris.core.events.IrisEngineHotloadEvent;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.plugin.VolmitSender;
import de.crazydev22.platformutils.scheduler.task.Task;
import org.bukkit.*;
import org.bukkit.entity.EnderSignal;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.WorldSaveEvent;
import org.bukkit.event.world.WorldUnloadEvent;
import org.bukkit.inventory.EquipmentSlot;
import java.util.concurrent.atomic.AtomicBoolean;
public abstract class EngineAssignedWorldManager extends EngineAssignedComponent implements EngineWorldManager, Listener {
private final int taskId;
private final Task task;
protected AtomicBoolean ignoreTP = new AtomicBoolean(false);
public EngineAssignedWorldManager() {
super(null, null);
taskId = -1;
task = null;
}
public EngineAssignedWorldManager(Engine engine) {
super(engine, "World");
Iris.instance.registerListener(this);
taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::onTick, 0, 0);
task = Iris.platform.getGlobalScheduler().runAtFixedRate(this::onTick, 1, 1);
}
@EventHandler
@@ -129,6 +124,6 @@ public abstract class EngineAssignedWorldManager extends EngineAssignedComponent
public void close() {
super.close();
Iris.instance.unregisterListener(this);
Bukkit.getScheduler().cancelTask(taskId);
if (task != null) task.cancel();
}
}

View File

@@ -18,6 +18,7 @@
package com.volmit.iris.engine.framework;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.nms.container.BlockPos;
import com.volmit.iris.core.nms.container.Pair;
@@ -36,7 +37,6 @@ import com.volmit.iris.util.matter.MatterCavern;
import com.volmit.iris.util.parallel.BurstExecutor;
import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import com.volmit.iris.util.scheduling.jobs.SingleJob;
import org.bukkit.Location;
@@ -114,7 +114,7 @@ public interface Locator<T> {
default void find(Player player, boolean teleport, String message) {
find(player, location -> {
if (teleport) {
J.s(() -> player.teleport(location));
Iris.platform.teleportAsync(player, location);
} else {
player.sendMessage(C.GREEN + message + " at: " + location.getBlockX() + " " + location.getBlockY() + " " + location.getBlockZ());
}

View File

@@ -0,0 +1,111 @@
package com.volmit.iris.engine.framework.placer;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.IObjectPlacer;
import com.volmit.iris.engine.object.TileData;
import lombok.EqualsAndHashCode;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
import static com.volmit.iris.Iris.platform;
@EqualsAndHashCode
public class SafeObjectPlacer implements IObjectPlacer {
private final World world;
private final IObjectPlacer placer;
public SafeObjectPlacer(World world, IObjectPlacer placer) {
this.world = world;
this.placer = placer;
}
@Override
public int getHighest(int x, int z, IrisData data) {
if (!platform.isOwnedByCurrentRegion(world, x >> 4, z >> 4)) {
return platform.getRegionScheduler().run(world, x >> 4, z >> 4, () -> getHighest(x, z, data))
.getResult()
.join();
}
return placer.getHighest(x, z, data);
}
@Override
public int getHighest(int x, int z, IrisData data, boolean ignoreFluid) {
if (!platform.isOwnedByCurrentRegion(world, x >> 4, z >> 4)) {
if (platform.isTickThread()) throw new IllegalStateException("Cannot run async on primary thread!");
return platform.getRegionScheduler().run(world, x >> 4, z >> 4, () -> getHighest(x, z, data, ignoreFluid))
.getResult()
.join();
}
return placer.getHighest(x, z, data);
}
@Override
public void set(int x, int y, int z, BlockData d) {
if (!platform.isOwnedByCurrentRegion(world, x >> 4, z >> 4)) {
if (platform.isTickThread()) throw new IllegalStateException("Cannot run async on primary thread!");
platform.getRegionScheduler().run(world, x >> 4, z >> 4, () -> set(x, y, z, d)).getResult().join();
} else placer.set(x, y, z, d);
}
@Override
public BlockData get(int x, int y, int z) {
if (!platform.isOwnedByCurrentRegion(world, x >> 4, z >> 4)) {
if (platform.isTickThread()) throw new IllegalStateException("Cannot run async on primary thread!");
return platform.getRegionScheduler().run(world, x >> 4, z >> 4, () -> get(x, y, z)).getResult().join();
}
return placer.get(x, y, z);
}
@Override
public boolean isPreventingDecay() {
return placer.isPreventingDecay();
}
@Override
public boolean isCarved(int x, int y, int z) {
return placer.isCarved(x, y, z);
}
@Override
public boolean isSolid(int x, int y, int z) {
if (!platform.isOwnedByCurrentRegion(world, x >> 4, z >> 4)) {
if (platform.isTickThread()) throw new IllegalStateException("Cannot run async on primary thread!");
return platform.getRegionScheduler().run(world, x >> 4, z >> 4, () -> isSolid(x, y, z)).getResult().join();
}
return placer.isSolid(x, y, z);
}
@Override
public boolean isUnderwater(int x, int z) {
if (!platform.isOwnedByCurrentRegion(world, x >> 4, z >> 4)) {
if (platform.isTickThread()) throw new IllegalStateException("Cannot run async on primary thread!");
return platform.getRegionScheduler().run(world, x >> 4, z >> 4, () -> isUnderwater(x, z)).getResult().join();
}
return placer.isUnderwater(x, z);
}
@Override
public int getFluidHeight() {
return placer.getFluidHeight();
}
@Override
public boolean isDebugSmartBore() {
return placer.isDebugSmartBore();
}
@Override
public void setTile(int xx, int yy, int zz, TileData tile) {
if (!platform.isOwnedByCurrentRegion(world, xx >> 4, zz >> 4)) {
if (platform.isTickThread()) throw new IllegalStateException("Cannot run async on primary thread!");
platform.getRegionScheduler().run(world, xx >> 4, zz >> 4, () -> setTile(xx, yy, zz, tile)).getResult().join();
} else placer.setTile(xx, yy, zz, tile);
}
@Override
public Engine getEngine() {
return placer.getEngine();
}
}

View File

@@ -160,8 +160,9 @@ public class PlannedStructure {
}, null, getData().getEngine() != null ? getData() : eng.getData()) != -1;
}
//TODO properly fix for folia
public void place(WorldObjectPlacer placer, Consumer<Boolean> consumer) {
J.s(() -> consumer.accept(place(placer, placer.getMantle().getMantle(), placer.getEngine())));
Iris.platform.getRegionScheduler().run(placer.getWorld(), position.getX() >> 4, position.getZ() >> 4, () -> consumer.accept(place(placer, placer.getMantle().getMantle(), placer.getEngine())));
}
private void generateOutwards() {

View File

@@ -18,9 +18,12 @@
package com.volmit.iris.engine.object;
import com.volmit.iris.Iris;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.engine.framework.Engine;
import org.bukkit.block.TileState;
import com.volmit.iris.engine.framework.placer.SafeObjectPlacer;
import de.crazydev22.platformutils.Type;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
public interface IObjectPlacer {
@@ -47,4 +50,10 @@ public interface IObjectPlacer {
void setTile(int xx, int yy, int zz, TileData tile);
Engine getEngine();
default IObjectPlacer sync(World world) {
if (Iris.platform.getType() == Type.FOLIA)
return new SafeObjectPlacer(world, this);
return this;
}
}

View File

@@ -67,6 +67,7 @@ public class IrisCommand {
return;
}
var scheduler = Iris.platform.getGlobalScheduler();
for (String command : commands) {
command = (command.startsWith("/") ? command.replaceFirst("/", "") : command)
.replaceAll("\\Q{x}\\E", String.valueOf(at.getBlockX()))
@@ -74,9 +75,9 @@ public class IrisCommand {
.replaceAll("\\Q{z}\\E", String.valueOf(at.getBlockZ()));
final String finalCommand = command;
if (repeat) {
Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, () -> Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), finalCommand), delay, repeatDelay);
scheduler.runAtFixedRate(() -> Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), finalCommand), Math.max(delay, 1), Math.max(repeatDelay, 1));
} else {
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), finalCommand), delay);
scheduler.runDelayed(() -> Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), finalCommand), Math.max(delay, 1));
}
}
}

View File

@@ -249,18 +249,14 @@ public class IrisDimension extends IrisRegistrant {
@Desc("A list of globally applied pre-processors")
@ArrayType(type = IrisPreProcessors.class)
private KList<IrisPreProcessors> globalPreProcessors = new KList<>();
@Desc("A list of scripts executed on engine setup\nFile extension: .engine.kts")
@Desc("A list of scripts executed on engine setup")
@RegistryListResource(IrisScript.class)
@ArrayType(type = String.class, min = 1)
private KList<String> engineScripts = new KList<>();
@Desc("A list of scripts executed on data setup\nFile extension: .data.kts")
@Desc("A list of scripts executed on data setup")
@RegistryListResource(IrisScript.class)
@ArrayType(type = String.class, min = 1)
private KList<String> dataScripts = new KList<>();
@Desc("A list of scripts executed on chunk update\nFile extension: .update.kts")
@RegistryListResource(IrisScript.class)
@ArrayType(type = String.class, min = 1)
private KList<String> chunkUpdateScripts = new KList<>();
@Desc("Use legacy rarity instead of modern one\nWARNING: Changing this may break expressions and image maps")
private boolean legacyRarity = true;

View File

@@ -39,7 +39,7 @@ public class IrisDimensionMode {
private IrisDimensionModeType type = IrisDimensionModeType.OVERWORLD;
@RegistryListResource(IrisScript.class)
@Desc("The script to create the dimension mode instead of using provided types\nFile extension: .engine.kts")
@Desc("The script to create the dimension mode instead of using provided types")
private String script;
public EngineMode create(Engine engine) {

View File

@@ -24,7 +24,6 @@ import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -194,7 +193,7 @@ public class IrisEffect {
if (sound != null) {
Location part = p.getLocation().clone().add(RNG.r.i(-soundDistance, soundDistance), RNG.r.i(-soundDistance, soundDistance), RNG.r.i(-soundDistance, soundDistance));
J.s(() -> p.playSound(part, getSound(), (float) volume, (float) RNG.r.d(minPitch, maxPitch)));
schedule(p, () -> p.playSound(part, getSound(), (float) volume, (float) RNG.r.d(minPitch, maxPitch)));
}
if (particleEffect != null) {
@@ -204,7 +203,7 @@ public class IrisEffect {
part.add(RNG.r.d(), 0, RNG.r.d());
int offset = p.getWorld().getMinHeight();
if (extra != 0) {
J.s(() -> p.spawnParticle(particleEffect, part.getX(), part.getY() + offset + RNG.r.i(particleOffset),
schedule(p, () -> p.spawnParticle(particleEffect, part.getX(), part.getY() + offset + RNG.r.i(particleOffset),
part.getZ(),
particleCount,
randomAltX ? RNG.r.d(-particleAltX, particleAltX) : particleAltX,
@@ -212,7 +211,7 @@ public class IrisEffect {
randomAltZ ? RNG.r.d(-particleAltZ, particleAltZ) : particleAltZ,
extra));
} else {
J.s(() -> p.spawnParticle(particleEffect, part.getX(), part.getY() + offset + RNG.r.i(particleOffset), part.getZ(),
schedule(p, () -> p.spawnParticle(particleEffect, part.getX(), part.getY() + offset + RNG.r.i(particleOffset), part.getZ(),
particleCount,
randomAltX ? RNG.r.d(-particleAltX, particleAltX) : particleAltX,
randomAltY ? RNG.r.d(-particleAltY, particleAltY) : particleAltY,
@@ -231,10 +230,10 @@ public class IrisEffect {
return;
}
J.s(() -> p.removePotionEffect(getRealType()));
schedule(p, () -> p.removePotionEffect(getRealType()));
}
J.s(() -> p.addPotionEffect(new PotionEffect(getRealType(),
schedule(p, () -> p.addPotionEffect(new PotionEffect(getRealType(),
RNG.r.i(Math.min(potionTicksMax, potionTicksMin),
Math.max(potionTicksMax, potionTicksMin)),
getPotionStrength(),
@@ -254,7 +253,7 @@ public class IrisEffect {
if (sound != null) {
Location part = p.getLocation().clone().add(RNG.r.i(-soundDistance, soundDistance), RNG.r.i(-soundDistance, soundDistance), RNG.r.i(-soundDistance, soundDistance));
J.s(() -> p.getWorld().playSound(part, getSound(), (float) volume, (float) RNG.r.d(minPitch, maxPitch)));
schedule(p, () -> p.getWorld().playSound(part, getSound(), (float) volume, (float) RNG.r.d(minPitch, maxPitch)));
}
if (particleEffect != null) {
@@ -262,7 +261,7 @@ public class IrisEffect {
part.add(RNG.r.d(), 0, RNG.r.d());
int offset = p.getWorld().getMinHeight();
if (extra != 0) {
J.s(() -> p.getWorld().spawnParticle(particleEffect, part.getX(), part.getY() + offset + RNG.r.i(particleOffset),
schedule(p, () -> p.getWorld().spawnParticle(particleEffect, part.getX(), part.getY() + offset + RNG.r.i(particleOffset),
part.getZ(),
particleCount,
randomAltX ? RNG.r.d(-particleAltX, particleAltX) : particleAltX,
@@ -270,7 +269,7 @@ public class IrisEffect {
randomAltZ ? RNG.r.d(-particleAltZ, particleAltZ) : particleAltZ,
extra));
} else {
J.s(() -> p.getWorld().spawnParticle(particleEffect, part.getX(), part.getY() + offset + RNG.r.i(particleOffset), part.getZ(),
schedule(p, () -> p.getWorld().spawnParticle(particleEffect, part.getX(), part.getY() + offset + RNG.r.i(particleOffset), part.getZ(),
particleCount,
randomAltX ? RNG.r.d(-particleAltX, particleAltX) : particleAltX,
randomAltY ? RNG.r.d(-particleAltY, particleAltY) : particleAltY,
@@ -278,4 +277,8 @@ public class IrisEffect {
}
}
}
private void schedule(Entity entity, Runnable task) {
Iris.platform.getEntityScheduler(entity).run(task, null);
}
}

View File

@@ -33,8 +33,6 @@ import com.volmit.iris.util.math.M;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.plugin.Chunks;
import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -50,13 +48,11 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.loot.LootContext;
import org.bukkit.loot.LootTable;
import org.bukkit.loot.Lootable;
import org.bukkit.util.Vector;
import java.util.Collection;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import static com.volmit.iris.util.data.registry.Particles.ITEM;
@@ -166,12 +162,12 @@ public class IrisEntity extends IrisRegistrant {
@Desc("Set to true if you want to apply all of the settings here to the mob, even though an external plugin has already done so. Scripts are always applied.")
private boolean applySettingsToCustomMobAnyways = false;
@Desc("Set the entity type to UNKNOWN, then define a script here which ends with the entity variable (the result). You can use location to find the target location. You can spawn any entity this way.\nFile extension: .spawn.kts")
@Desc("Set the entity type to UNKNOWN, then define a script here which ends with the entity variable (the result). You can use Iris.getLocation() to find the target location. You can spawn any entity this way.")
@RegistryListResource(IrisScript.class)
private String spawnerScript = "";
@ArrayType(min = 1, type = String.class)
@Desc("Executed post spawn you can modify the entity however you want with it\nFile extension: .postspawn.kts")
@Desc("Set the entity type to UNKNOWN, then define a script here. You can use Iris.getLocation() to find the target location. You can spawn any entity this way.")
@RegistryListResource(IrisScript.class)
private KList<String> postSpawnScripts = new KList<>();
@@ -183,38 +179,34 @@ public class IrisEntity extends IrisRegistrant {
return spawn(gen, at, new RNG(at.hashCode()));
}
public Entity spawn(Engine gen, Location at, RNG rng) {
public Entity spawn(Engine gen, final Location at, RNG rng) {
if (!Iris.platform.isOwnedByCurrentRegion(at)) {
try {
final Location finalAt = at;
return Iris.platform.getRegionScheduler().run(at, () -> spawn(gen, finalAt, rng))
.getResult()
.get(500, TimeUnit.MILLISECONDS);
} catch (Throwable e) {
return null;
}
}
if (!Chunks.isSafe(at)) {
return null;
}
if (isSpawnEffectRiseOutOfGround()) {
AtomicReference<Location> f = new AtomicReference<>(at);
try {
J.sfut(() -> {
if (Chunks.hasPlayersNearby(f.get())) {
Location b = f.get().clone();
Location start = new Location(b.getWorld(), b.getX(), b.getY() - 5, b.getZ());
f.set(start);
}
}).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
at = f.get();
if (isSpawnEffectRiseOutOfGround() && Chunks.hasPlayersNearby(at)) {
at.add(0, -5, 0);
}
Entity ee = doSpawn(at);
if (ee == null && !Chunks.isSafe(at)) {
if (ee == null) {
return null;
}
if (!spawnerScript.isEmpty() && ee == null) {
synchronized (this) {
try {
ee = (Entity) gen.getExecution().spawnMob(spawnerScript, at);
ee = (Entity) gen.getExecution().spawnMob(spawnerScript, at.clone());
} catch (Throwable ex) {
Iris.error("You must return an Entity in your scripts to use entity scripts!");
ex.printStackTrace();
@@ -241,111 +233,96 @@ public class IrisEntity extends IrisRegistrant {
int gg = 0;
for (IrisEntity i : passengers) {
Entity passenger = i.spawn(gen, at, rng.nextParallelRNG(234858 + gg++));
if (!Bukkit.isPrimaryThread()) {
J.s(() -> e.addPassenger(passenger));
}
e.addPassenger(i.spawn(gen, at, rng.nextParallelRNG(234858 + gg++)));
}
if (e instanceof Attributable) {
Attributable a = (Attributable) e;
if (e instanceof Attributable attributable) {
for (IrisAttributeModifier i : getAttributes()) {
i.apply(rng, a);
i.apply(rng, attributable);
}
}
if (e instanceof Lootable) {
Lootable l = (Lootable) e;
if (e instanceof Lootable lootable && getLoot().getTables().isNotEmpty()) {
lootable.setLootTable(new LootTable() {
@Override
public NamespacedKey getKey() {
return new NamespacedKey(Iris.instance, "loot-" + IrisEntity.this.hashCode());
}
if (getLoot().getTables().isNotEmpty()) {
Location finalAt = at;
l.setLootTable(new LootTable() {
@Override
public NamespacedKey getKey() {
return new NamespacedKey(Iris.instance, "loot-" + IrisEntity.this.hashCode());
@Override
public Collection<ItemStack> populateLoot(Random random, LootContext context) {
KList<ItemStack> items = new KList<>();
for (String fi : getLoot().getTables()) {
IrisLootTable i = gen.getData().getLootLoader().load(fi);
items.addAll(i.getLoot(gen.isStudio(), rng.nextParallelRNG(345911), InventorySlotType.STORAGE, at.getWorld(), at.getBlockX(), at.getBlockY(), at.getBlockZ()));
}
@Override
public Collection<ItemStack> populateLoot(Random random, LootContext context) {
KList<ItemStack> items = new KList<>();
return items;
}
for (String fi : getLoot().getTables()) {
IrisLootTable i = gen.getData().getLootLoader().load(fi);
items.addAll(i.getLoot(gen.isStudio(), rng.nextParallelRNG(345911), InventorySlotType.STORAGE, finalAt.getWorld(), finalAt.getBlockX(), finalAt.getBlockY(), finalAt.getBlockZ()));
}
return items;
@Override
public void fillInventory(Inventory inventory, Random random, LootContext context) {
for (ItemStack i : populateLoot(random, context)) {
inventory.addItem(i);
}
@Override
public void fillInventory(Inventory inventory, Random random, LootContext context) {
for (ItemStack i : populateLoot(random, context)) {
inventory.addItem(i);
}
gen.scramble(inventory, rng);
}
});
}
gen.scramble(inventory, rng);
}
});
}
if (e instanceof LivingEntity) {
LivingEntity l = (LivingEntity) e;
l.setAI(isAi());
l.setCanPickupItems(isPickupItems());
if (e instanceof LivingEntity living) {
living.setAI(isAi());
living.setCanPickupItems(isPickupItems());
if (getLeashHolder() != null) {
l.setLeashHolder(getLeashHolder().spawn(gen, at, rng.nextParallelRNG(234548)));
living.setLeashHolder(getLeashHolder().spawn(gen, at, rng.nextParallelRNG(234548)));
}
l.setRemoveWhenFarAway(isRemovable());
living.setRemoveWhenFarAway(isRemovable());
if (getHelmet() != null && rng.i(1, getHelmet().getRarity()) == 1) {
l.getEquipment().setHelmet(getHelmet().get(gen.isStudio(), rng));
living.getEquipment().setHelmet(getHelmet().get(gen.isStudio(), rng));
}
if (getChestplate() != null && rng.i(1, getChestplate().getRarity()) == 1) {
l.getEquipment().setChestplate(getChestplate().get(gen.isStudio(), rng));
living.getEquipment().setChestplate(getChestplate().get(gen.isStudio(), rng));
}
if (getLeggings() != null && rng.i(1, getLeggings().getRarity()) == 1) {
l.getEquipment().setLeggings(getLeggings().get(gen.isStudio(), rng));
living.getEquipment().setLeggings(getLeggings().get(gen.isStudio(), rng));
}
if (getBoots() != null && rng.i(1, getBoots().getRarity()) == 1) {
l.getEquipment().setBoots(getBoots().get(gen.isStudio(), rng));
living.getEquipment().setBoots(getBoots().get(gen.isStudio(), rng));
}
if (getMainHand() != null && rng.i(1, getMainHand().getRarity()) == 1) {
l.getEquipment().setItemInMainHand(getMainHand().get(gen.isStudio(), rng));
living.getEquipment().setItemInMainHand(getMainHand().get(gen.isStudio(), rng));
}
if (getOffHand() != null && rng.i(1, getOffHand().getRarity()) == 1) {
l.getEquipment().setItemInOffHand(getOffHand().get(gen.isStudio(), rng));
living.getEquipment().setItemInOffHand(getOffHand().get(gen.isStudio(), rng));
}
}
if (e instanceof Ageable && isBaby()) {
((Ageable) e).setBaby();
if (e instanceof Ageable ageable && isBaby()) {
ageable.setBaby();
}
if (e instanceof Panda) {
((Panda) e).setMainGene(getPandaMainGene());
((Panda) e).setMainGene(getPandaHiddenGene());
if (e instanceof Panda panda) {
panda.setMainGene(getPandaMainGene());
panda.setMainGene(getPandaHiddenGene());
}
if (e instanceof Villager) {
Villager villager = (Villager) e;
if (e instanceof Villager villager) {
villager.setRemoveWhenFarAway(false);
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> {
villager.setPersistent(true);
}, 1);
villager.setPersistent(true);
}
if (e instanceof Mob) {
Mob m = (Mob) e;
m.setAware(isAware());
if (e instanceof Mob mob) {
mob.setAware(isAware());
}
if (spawnEffect != null) {
@@ -365,41 +342,35 @@ public class IrisEntity extends IrisRegistrant {
rawCommands.forEach(r -> r.run(fat));
}
Location finalAt1 = at;
if (isSpawnEffectRiseOutOfGround() && e instanceof LivingEntity living && Chunks.hasPlayersNearby(at)) {
e.setInvulnerable(true);
living.setAI(false);
living.setCollidable(false);
living.setNoDamageTicks(100000);
AtomicInteger t = new AtomicInteger(0);
Iris.platform.getRegionScheduler().runAtFixedRate(at, task -> {
if (t.get() > 100) {
task.cancel();
return;
}
J.s(() -> {
if (isSpawnEffectRiseOutOfGround() && e instanceof LivingEntity && Chunks.hasPlayersNearby(finalAt1)) {
Location start = finalAt1.clone();
e.setInvulnerable(true);
((LivingEntity) e).setAI(false);
((LivingEntity) e).setCollidable(false);
((LivingEntity) e).setNoDamageTicks(100000);
AtomicInteger t = new AtomicInteger(0);
AtomicInteger v = new AtomicInteger(0);
v.set(J.sr(() -> {
if (t.get() > 100) {
J.csr(v.get());
return;
t.incrementAndGet();
if (e.getLocation().getBlock().getType().isSolid() || living.getEyeLocation().getBlock().getType().isSolid()) {
Iris.platform.teleportAsync(e, at.add(0, 0.1, 0));
Material material = living.getEyeLocation().subtract(0, 2, 0).getBlock().getType();
if (!material.isAir()) e.getWorld().spawnParticle(ITEM, living.getEyeLocation(), 6, 0.2, 0.4, 0.2, 0.06f, new ItemStack(material));
if (M.r(0.2)) {
e.getWorld().playSound(e.getLocation(), Sound.BLOCK_CHORUS_FLOWER_GROW, 0.8f, 0.1f);
}
t.incrementAndGet();
if (e.getLocation().getBlock().getType().isSolid() || ((LivingEntity) e).getEyeLocation().getBlock().getType().isSolid()) {
e.teleport(start.add(new Vector(0, 0.1, 0)));
ItemStack itemCrackData = new ItemStack(((LivingEntity) e).getEyeLocation().clone().subtract(0, 2, 0).getBlock().getBlockData().getMaterial());
e.getWorld().spawnParticle(ITEM, ((LivingEntity) e).getEyeLocation(), 6, 0.2, 0.4, 0.2, 0.06f, itemCrackData);
if (M.r(0.2)) {
e.getWorld().playSound(e.getLocation(), Sound.BLOCK_CHORUS_FLOWER_GROW, 0.8f, 0.1f);
}
} else {
J.csr(v.get());
((LivingEntity) e).setNoDamageTicks(0);
((LivingEntity) e).setCollidable(true);
((LivingEntity) e).setAI(true);
e.setInvulnerable(false);
}
}, 0));
}
});
} else {
task.cancel();
living.setNoDamageTicks(0);
living.setCollidable(true);
living.setAI(true);
e.setInvulnerable(false);
}
}, 1, 1);
}
return e;
@@ -429,29 +400,6 @@ public class IrisEntity extends IrisRegistrant {
return null;
}
if (!Bukkit.isPrimaryThread()) {
// Someone called spawn (worldedit maybe?) on a non server thread
// Due to the structure of iris, we will call it sync and busy wait until it's done.
AtomicReference<Entity> ae = new AtomicReference<>();
try {
J.s(() -> ae.set(doSpawn(at)));
} catch (Throwable e) {
return null;
}
PrecisionStopwatch p = PrecisionStopwatch.start();
while (ae.get() == null) {
J.sleep(25);
if (p.getMilliseconds() > 500) {
return null;
}
}
return ae.get();
}
if (isSpecialType()) {
return Iris.service(ExternalDataSVC.class).spawnMob(at, Identifier.fromString(specialType));
}

View File

@@ -36,8 +36,14 @@ import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Entity;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicBoolean;
import static com.volmit.iris.Iris.platform;
@Snippet("entity-spawn")
@Accessors(chain = true)
@NoArgsConstructor
@@ -164,8 +170,15 @@ public class IrisEntitySpawn implements IRare {
return null;
}
if (!ignoreSurfaces && !irisEntity.getSurface().matches(at.clone().subtract(0, 1, 0).getBlock())) {
return null;
if (!ignoreSurfaces) {
Location block = at.clone().subtract(0, 1, 0);
BlockData data = platform.getRegionScheduler()
.run(block, () -> block.getBlock().getBlockData())
.getResult()
.join();
if (!irisEntity.getSurface().matches(data)) {
return null;
}
}
Vector3d boundingBox = INMS.get().getBoundingbox(irisEntity.getType());
@@ -199,15 +212,22 @@ public class IrisEntitySpawn implements IRare {
int startZ = center.getBlockZ() - (int) (boundingBox.z / 2);
int endZ = center.getBlockZ() + (int) (boundingBox.z / 2);
var region = platform.getRegionScheduler();
var lock = new Semaphore(Integer.MAX_VALUE, true);
var bool = new AtomicBoolean(true);
for (int x = startX; x <= endX; x++) {
for (int y = startY; y <= endY; y++) {
for (int z = startZ; z <= endZ; z++) {
if (world.getBlockAt(x, y, z).getType() != Material.AIR) {
return false;
}
Location l = new Location(world, x, y, z);
lock.acquireUninterruptibly();
region.run(l, () -> {
if (!bool.get()) return false;
return bool.compareAndSet(true, l.getBlock().getType() == Material.AIR);
}).getResult().exceptionally(f -> false).thenRun(lock::release);
}
}
}
return true;
lock.acquireUninterruptibly(Integer.MAX_VALUE);
return bool.get();
}
}

View File

@@ -58,7 +58,7 @@ public class IrisGeneratorStyle {
private String expression = null;
@Desc("Use an Image map instead of a generated value")
private IrisImageMap imageMap = null;
@Desc("Instead of using the style property, use a custom noise generator to represent this style.\nFile extension: .noise.kts")
@Desc("Instead of using the style property, use a custom noise generator to represent this style.")
@RegistryListResource(IrisScript.class)
private String script = null;
@MinNumber(0.00001)

View File

@@ -18,7 +18,7 @@ public class IrisPreProcessors {
private String type = "dimension";
@Required
@Desc("The preprocessor scripts\nFile extension: .proc.kts")
@Desc("The preprocessor scripts")
@RegistryListResource(IrisScript.class)
@ArrayType(type = String.class, min = 1)
private KList<String> scripts = new KList<>();

View File

@@ -20,7 +20,7 @@ package com.volmit.iris.engine.object;
import com.volmit.iris.engine.object.annotations.Desc;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Waterlogged;
@Desc("The type of surface entities should spawn on")
@@ -47,8 +47,8 @@ public enum IrisSurface {
* @param state The blockstate
* @return True if it matches
*/
public boolean matches(Block state) {
Material type = state.getType();
public boolean matches(BlockData state) {
Material type = state.getMaterial();
if (type.isSolid()) {
return this == LAND || this == OVERWORLD || (this == ANIMAL
&& (type == Material.GRASS_BLOCK || type == Material.DIRT

View File

@@ -1,10 +1,10 @@
package com.volmit.iris.engine.object;
import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.container.Pair;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.scheduling.J;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
@@ -80,7 +80,7 @@ public class LegacyTileData extends TileData {
@Override
public void toBukkit(Block block) {
J.s(() -> handler.toBukkit(block));
Iris.platform.getRegionScheduler().run(block.getLocation(), () -> handler.toBukkit(block));
}
@Override

View File

@@ -38,10 +38,11 @@ import com.volmit.iris.util.data.IrisBiomeStorage;
import com.volmit.iris.util.hunk.view.BiomeGridHunkHolder;
import com.volmit.iris.util.hunk.view.ChunkDataHunkHolder;
import com.volmit.iris.util.io.ReactiveFolder;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.Looper;
import io.papermc.lib.PaperLib;
import de.crazydev22.platformutils.scheduler.IRegionExecutor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Setter;
@@ -142,7 +143,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
@Override
public Location getFixedSpawnLocation(@NotNull World world, @NotNull Random random) {
Location location = new Location(world, 0, 64, 0);
PaperLib.getChunkAtAsync(location)
Iris.platform.getChunkAtAsync(location)
.thenAccept(c -> {
World w = c.getWorld();
if (!w.getSpawnLocation().equals(location))
@@ -195,16 +196,16 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
}
@Override
public void injectChunkReplacement(World world, int x, int z, Executor syncExecutor) {
public void injectChunkReplacement(World world, int x, int z, IRegionExecutor executor) {
try {
loadLock.acquire();
IrisBiomeStorage st = new IrisBiomeStorage();
TerrainChunk tc = TerrainChunk.createUnsafe(world, st);
this.world.bind(world);
getEngine().generate(x << 4, z << 4, tc, IrisSettings.get().getGenerator().useMulticore);
generateNoise(world, RNG.r, x, z, tc);
Chunk c = PaperLib.getChunkAtAsync(world, x, z)
Chunk c = Iris.platform.getChunkAtAsync(world, x, z)
.thenApply(d -> {
if (d == null) throw new IllegalStateException("Chunk is null!");
d.addPluginChunkTicket(Iris.instance);
for (Entity ee : d.getEntities()) {
@@ -223,7 +224,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
KList<CompletableFuture<?>> futures = new KList<>(1 + getEngine().getHeight() >> 4);
for (int i = getEngine().getHeight() >> 4; i >= 0; i--) {
int finalI = i << 4;
futures.add(CompletableFuture.runAsync(() -> {
futures.add(executor.queue(world, x, z, () -> {
for (int xx = 0; xx < 16; xx++) {
for (int yy = 0; yy < 16; yy++) {
for (int zz = 0; zz < 16; zz++) {
@@ -235,15 +236,15 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
}
}
}
}, syncExecutor));
}));
}
futures.add(CompletableFuture.runAsync(() -> INMS.get().placeStructures(c), syncExecutor));
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenRunAsync(() -> {
CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new))
.thenCompose($ -> executor.queue(world, x, z, () -> INMS.get().placeStructures(c)))
.thenCompose($ -> executor.queue(world, x, z, () -> {
c.removePluginChunkTicket(Iris.instance);
engine.getWorldManager().onChunkLoad(c, true);
}, syncExecutor)
}))
.get();
Iris.debug("Regenerated " + x + " " + z);
@@ -254,14 +255,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
e.printStackTrace();
Iris.reportErrorChunk(x, z, e, "CHUNK");
Iris.error("======================================");
ChunkData d = Bukkit.createChunkData(world);
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
d.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA.createBlockData());
}
}
}
}

View File

@@ -23,12 +23,12 @@ import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineTarget;
import com.volmit.iris.engine.framework.Hotloadable;
import com.volmit.iris.util.data.DataProvider;
import de.crazydev22.platformutils.scheduler.IRegionExecutor;
import org.bukkit.World;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
public interface PlatformChunkGenerator extends Hotloadable, DataProvider {
@Nullable
@@ -42,7 +42,7 @@ public interface PlatformChunkGenerator extends Hotloadable, DataProvider {
@NotNull
EngineTarget getTarget();
void injectChunkReplacement(World world, int x, int z, Executor syncExecutor);
void injectChunkReplacement(World world, int x, int z, IRegionExecutor executor);
void close();

View File

@@ -18,10 +18,11 @@
package com.volmit.iris.util.board;
import com.volmit.iris.Iris;
import de.crazydev22.platformutils.scheduler.task.Task;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;
import java.util.Collections;
import java.util.Map;
@@ -34,7 +35,7 @@ public class BoardManager {
private final JavaPlugin plugin;
private final Map<UUID, Board> scoreboards;
private final BukkitTask updateTask;
private final Task updateTask;
private BoardSettings boardSettings;
@@ -42,7 +43,7 @@ public class BoardManager {
this.plugin = plugin;
this.boardSettings = boardSettings;
this.scoreboards = new ConcurrentHashMap<>();
this.updateTask = new BoardUpdateTask(this).runTaskTimer(plugin, 2L, 20L);
this.updateTask = Iris.platform.getGlobalScheduler().runAtFixedRate(new BoardUpdateTask(this), 2L, 20L);
plugin.getServer().getOnlinePlayers().forEach(this::setup);
}

View File

@@ -20,7 +20,6 @@ package com.volmit.iris.util.board;
import lombok.RequiredArgsConstructor;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.UUID;
import java.util.function.Predicate;
@@ -30,7 +29,7 @@ import java.util.function.Predicate;
* @since 5/31/2018
*/
@RequiredArgsConstructor
public class BoardUpdateTask extends BukkitRunnable {
public class BoardUpdateTask implements Runnable {
private static final Predicate<UUID> PLAYER_IS_ONLINE = uuid -> Bukkit.getPlayer(uuid) != null;

View File

@@ -316,17 +316,17 @@ public class Cuboid implements Iterable<Block>, Cloneable, ConfigurationSerializ
*
* @return array of Block objects representing the Cuboid corners
*/
public Block[] corners() {
Block[] res = new Block[8];
public Location[] corners() {
Location[] res = new Location[8];
World w = getWorld();
res[0] = w.getBlockAt(x1, y1, z1);
res[1] = w.getBlockAt(x1, y1, z2);
res[2] = w.getBlockAt(x1, y2, z1);
res[3] = w.getBlockAt(x1, y2, z2);
res[4] = w.getBlockAt(x2, y1, z1);
res[5] = w.getBlockAt(x2, y1, z2);
res[6] = w.getBlockAt(x2, y2, z1);
res[7] = w.getBlockAt(x2, y2, z2);
res[0] = new Location(w, x1, y1, z1);
res[1] = new Location(w, x1, y1, z2);
res[2] = new Location(w, x1, y2, z1);
res[3] = new Location(w, x1, y2, z2);
res[4] = new Location(w, x2, y1, z1);
res[5] = new Location(w, x2, y1, z2);
res[6] = new Location(w, x2, y2, z1);
res[7] = new Location(w, x2, y2, z2);
return res;
}
@@ -648,11 +648,12 @@ public class Cuboid implements Iterable<Block>, Cloneable, ConfigurationSerializ
* @see java.lang.Iterable#iterator()
*/
@Override
@Deprecated(forRemoval = true)
public Iterator<Block> iterator() {
return new CuboidIterator(getWorld(), x1, y1, z1, x2, y2, z2);
}
public Iterator<Block> chunkedIterator() {
public Iterator<Location> chunkedIterator() {
return new ChunkedCuboidIterator(getWorld(), x1, y1, z1, x2, y2, z2);
}
@@ -751,7 +752,7 @@ public class Cuboid implements Iterable<Block>, Cloneable, ConfigurationSerializ
}
}
public static class ChunkedCuboidIterator implements Iterator<Block> {
public static class ChunkedCuboidIterator implements Iterator<Location> {
private final World w;
private final int minRX, minY, minRZ, maxRX, maxY, maxRZ;
private final int minCX, minCZ, maxCX, maxCZ;
@@ -795,7 +796,7 @@ public class Cuboid implements Iterable<Block>, Cloneable, ConfigurationSerializ
}
@Override
public Block next() {
public Location next() {
if (chunk == null) {
chunk = new Position2(cX, cZ);
if (++cX > maxCX) {
@@ -809,7 +810,7 @@ public class Cuboid implements Iterable<Block>, Cloneable, ConfigurationSerializ
rZ = chunk.getZ() == minCZ ? minRZ : 0;
}
var b = w.getBlockAt((chunk.getX() << 4) + rX, y, (chunk.getZ() << 4) + rZ);
var b = new Location(w, (chunk.getX() << 4) + rX, y, (chunk.getZ() << 4) + rZ);
if (++y > maxY) {
y = minY;
if (++rX > mX) {

View File

@@ -31,8 +31,8 @@ import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.plugin.CommandDummy;
import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
import lombok.Data;
import org.bukkit.entity.Entity;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -493,7 +493,10 @@ public class VirtualDecreeCommand {
};
if (getNode().isSync()) {
J.s(rx);
switch (sender.getS()) {
case Entity entity -> Iris.platform.getEntityScheduler(entity).run(rx, null);
case null, default -> Iris.platform.getGlobalScheduler().run(rx);
}
} else {
rx.run();
}

View File

@@ -176,26 +176,14 @@ public class MantleChunk {
if (guard != null && isFlagged(guard)) return;
synchronized (flagLocks[flag.ordinal()]) {
if (flags.compareAndSet(flag.ordinal(), false, true)) {
try {
r.run();
} catch (RuntimeException | Error e) {
flags.set(flag.ordinal(), false);
throw e;
}
r.run();
}
}
}
public void raiseFlagUnchecked(MantleFlag flag, Runnable r) {
if (closed.get()) throw new IllegalStateException("Chunk is closed!");
if (flags.compareAndSet(flag.ordinal(), false, true)) {
try {
r.run();
} catch (RuntimeException | Error e) {
flags.set(flag.ordinal(), false);
throw e;
}
}
if (flags.compareAndSet(flag.ordinal(), false, true)) r.run();
}
public boolean isFlagged(MantleFlag flag) {

View File

@@ -40,7 +40,6 @@ public sealed interface MantleFlag permits CustomFlag, ReservedFlag {
MantleFlag CUSTOM = ReservedFlag.CUSTOM;
MantleFlag DISCOVERED = ReservedFlag.DISCOVERED;
MantleFlag CUSTOM_ACTIVE = ReservedFlag.CUSTOM_ACTIVE;
MantleFlag SCRIPT = ReservedFlag.SCRIPT;
int RESERVED_FLAGS = ReservedFlag.values().length;

View File

@@ -16,8 +16,7 @@ public enum ReservedFlag implements MantleFlag {
TILE,
CUSTOM,
DISCOVERED,
CUSTOM_ACTIVE,
SCRIPT;
CUSTOM_ACTIVE;
@Override
public boolean isCustom() {

View File

@@ -89,6 +89,7 @@ public class BlockPosition {
return toLong(getX(), getY(), getZ());
}
@Deprecated(forRemoval = true)
public Block toBlock(World world) {
return world.getBlockAt(x, y, z);
}

View File

@@ -1,46 +0,0 @@
package com.volmit.iris.util.parallel;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.scheduling.SR;
import org.jetbrains.annotations.NotNull;
import java.util.Queue;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
public class SyncExecutor implements Executor, AutoCloseable {
private final CountDownLatch latch = new CountDownLatch(1);
private final Queue<Runnable> queue = new ConcurrentLinkedQueue<>();
private final AtomicBoolean closed = new AtomicBoolean(false);
public SyncExecutor(int msPerTick) {
new SR() {
@Override
public void run() {
var time = M.ms() + msPerTick;
while (time > M.ms()) {
Runnable r = queue.poll();
if (r == null) break;
r.run();
}
if (closed.get() && queue.isEmpty()) {
cancel();
latch.countDown();
}
}
};
}
@Override
public void execute(@NotNull Runnable command) {
if (closed.get()) throw new IllegalStateException("Executor is closed!");
queue.add(command);
}
@Override
public void close() throws Exception {
closed.set(true);
latch.await();
}
}

View File

@@ -24,6 +24,7 @@ import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.reflect.V;
import com.volmit.iris.util.scheduling.J;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.command.CommandSender;
@@ -171,7 +172,7 @@ public class VirtualCommand {
for (String i : command.getRequiredPermissions()) {
if (!sender.hasPermission(i)) {
failed = true;
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> sender.sendMessage("- " + C.WHITE + i), 0);
J.s(() -> sender.sendMessage("- " + C.WHITE + i));
}
}

View File

@@ -245,7 +245,6 @@ public abstract class VolmitPlugin extends JavaPlugin implements Listener {
@Override
public void onDisable() {
stop();
Bukkit.getScheduler().cancelTasks(this);
unregisterListener(this);
unregisterAll();
}

View File

@@ -48,8 +48,8 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
/**
@@ -298,17 +298,16 @@ public class VolmitSender implements CommandSender {
}
public <T> void showWaiting(String passive, CompletableFuture<T> f) {
AtomicInteger v = new AtomicInteger();
AtomicReference<T> g = new AtomicReference<>();
v.set(J.ar(() -> {
Iris.platform.getAsyncScheduler().runAtFixedRate(task -> {
if (f.isDone() && g.get() != null) {
J.car(v.get());
task.cancel();
sendAction(" ");
return;
}
sendProgress(-1, passive);
}, 0));
}, 0, 50, TimeUnit.MILLISECONDS);
J.a(() -> {
try {
g.set(f.get());

View File

@@ -1,9 +1,9 @@
package com.volmit.iris.util.profile;
import com.volmit.iris.Iris;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.Looper;
import org.bukkit.Bukkit;
import de.crazydev22.platformutils.scheduler.task.Task;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
@@ -12,7 +12,7 @@ public abstract class MsptTimings extends Looper {
private final AtomicInteger currentTick = new AtomicInteger(0);
private int lastTick, lastMspt;
private long lastTime;
private int taskId = -1;
private Task task = null;
public MsptTimings() {
setName("MsptTimings");
@@ -52,18 +52,18 @@ public abstract class MsptTimings extends Looper {
protected abstract void update(int mspt);
private boolean startTickTask() {
if (taskId != -1 && (Bukkit.getScheduler().isQueued(taskId) || Bukkit.getScheduler().isCurrentlyRunning(taskId)))
if (task != null && !task.isCancelled())
return false;
taskId = J.sr(() -> {
task = Iris.platform.getGlobalScheduler().runAtFixedRate(t -> {
if (isInterrupted()) {
J.csr(taskId);
t.cancel();
return;
}
currentTick.incrementAndGet();
}, 1);
return taskId != -1;
}, 1, 1);
return true;
}
private static class Simple extends MsptTimings {

View File

@@ -19,24 +19,21 @@
package com.volmit.iris.util.scheduling;
import com.volmit.iris.util.plugin.CancellableTask;
import de.crazydev22.platformutils.scheduler.task.Task;
public abstract class AR implements Runnable, CancellableTask {
private int id = 0;
private final Task task;
public AR() {
this(0);
this(1);
}
public AR(int interval) {
id = J.ar(this, interval);
task = J.ar(this, interval);
}
@Override
public void cancel() {
J.car(id);
}
public int getId() {
return id;
task.cancel();
}
}

View File

@@ -26,11 +26,13 @@ import com.volmit.iris.util.function.NastyRunnable;
import com.volmit.iris.util.function.NastySupplier;
import com.volmit.iris.util.math.FinalInteger;
import com.volmit.iris.util.parallel.MultiBurst;
import de.crazydev22.platformutils.scheduler.task.Task;
import org.bukkit.Bukkit;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -91,7 +93,7 @@ public class J {
if (!Bukkit.getPluginManager().isPluginEnabled(Iris.instance)) {
return;
}
Bukkit.getScheduler().scheduleAsyncDelayedTask(Iris.instance, a);
Iris.platform.getAsyncScheduler().run(a);
}
public static <T> Future<T> a(Callable<T> a) {
@@ -224,48 +226,36 @@ public class J {
if (!Bukkit.getPluginManager().isPluginEnabled(Iris.instance)) {
return;
}
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, r);
Iris.platform.getGlobalScheduler().run(r);
}
public static CompletableFuture sfut(Runnable r) {
CompletableFuture f = new CompletableFuture();
if (!Bukkit.getPluginManager().isPluginEnabled(Iris.instance)) {
return null;
}
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> {
return Iris.platform.getGlobalScheduler().run(() -> {
r.run();
f.complete(null);
});
return f;
return null;
}).getResult();
}
public static <T> CompletableFuture<T> sfut(Supplier<T> r) {
CompletableFuture<T> f = new CompletableFuture<>();
if (!Bukkit.getPluginManager().isPluginEnabled(Iris.instance)) {
return null;
}
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> {
try {
f.complete(r.get());
} catch (Throwable e) {
f.completeExceptionally(e);
}
});
return f;
return Iris.platform.getGlobalScheduler().run(r).getResult();
}
public static CompletableFuture sfut(Runnable r, int delay) {
CompletableFuture f = new CompletableFuture();
if (!Bukkit.getPluginManager().isPluginEnabled(Iris.instance)) {
return null;
}
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> {
return Iris.platform.getGlobalScheduler().runDelayed(() -> {
r.run();
f.complete(null);
}, delay);
return f;
return null;
}, delay).getResult();
}
public static CompletableFuture afut(Runnable r) {
@@ -288,21 +278,12 @@ public class J {
if (!Bukkit.getPluginManager().isPluginEnabled(Iris.instance)) {
return;
}
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, r, delay);
Iris.platform.getGlobalScheduler().runDelayed(r, delay);
} catch (Throwable e) {
Iris.reportError(e);
}
}
/**
* Cancel a sync repeating task
*
* @param id the task id
*/
public static void csr(int id) {
Bukkit.getScheduler().cancelTask(id);
}
/**
* Start a sync repeating task
*
@@ -310,34 +291,11 @@ public class J {
* @param interval the interval
* @return the task id
*/
public static int sr(Runnable r, int interval) {
public static Task sr(Runnable r, int interval) {
if (!Bukkit.getPluginManager().isPluginEnabled(Iris.instance)) {
return -1;
return null;
}
return Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, r, 0, interval);
}
/**
* Start a sync repeating task for a limited amount of ticks
*
* @param r the runnable
* @param interval the interval in ticks
* @param intervals the maximum amount of intervals to run
*/
public static void sr(Runnable r, int interval, int intervals) {
FinalInteger fi = new FinalInteger(0);
new SR() {
@Override
public void run() {
fi.add(1);
r.run();
if (fi.get() >= intervals) {
cancel();
}
}
};
return Iris.platform.getGlobalScheduler().runAtFixedRate(r, 1, Math.max(interval, 1));
}
/**
@@ -346,22 +304,12 @@ public class J {
* @param r the runnable
* @param delay the delay to wait before running
*/
@SuppressWarnings("deprecation")
public static void a(Runnable r, int delay) {
if (Bukkit.getPluginManager().isPluginEnabled(Iris.instance)) {
Bukkit.getScheduler().scheduleAsyncDelayedTask(Iris.instance, r, delay);
Iris.platform.getAsyncScheduler().runDelayed(r, Math.max(delay * 50, 0), TimeUnit.MILLISECONDS);
}
}
/**
* Cancel an async repeat task
*
* @param id the id
*/
public static void car(int id) {
Bukkit.getScheduler().cancelTask(id);
}
/**
* Start an async repeat task
*
@@ -369,12 +317,11 @@ public class J {
* @param interval the interval in ticks
* @return the task id
*/
@SuppressWarnings("deprecation")
public static int ar(Runnable r, int interval) {
public static Task ar(Runnable r, int interval) {
if (!Bukkit.getPluginManager().isPluginEnabled(Iris.instance)) {
return -1;
return null;
}
return Bukkit.getScheduler().scheduleAsyncRepeatingTask(Iris.instance, r, 0, interval);
return Iris.platform.getAsyncScheduler().runAtFixedRate(r, 0, Math.max(interval, 1) * 50, TimeUnit.MILLISECONDS);
}
/**

View File

@@ -19,24 +19,23 @@
package com.volmit.iris.util.scheduling;
import com.volmit.iris.util.plugin.CancellableTask;
import de.crazydev22.platformutils.scheduler.task.Task;
public abstract class SR implements Runnable, CancellableTask {
private int id = 0;
private final Task id;
public SR() {
this(0);
}
public SR(int interval) {
id = J.sr(this, interval);
this.id = J.sr(this, interval);
}
@Override
public void cancel() {
J.csr(id);
}
public int getId() {
return id;
if (id != null) {
id.cancel();
}
}
}

View File

@@ -63,7 +63,7 @@ public interface Job {
default void execute(VolmitSender sender, boolean silentMsg, Runnable whenComplete) {
PrecisionStopwatch p = PrecisionStopwatch.start();
CompletableFuture<?> f = J.afut(this::execute);
int c = J.ar(() -> {
var c = J.ar(() -> {
if (sender.isPlayer()) {
sender.sendProgress(getProgress(), getName());
} else {
@@ -71,7 +71,7 @@ public interface Job {
}
}, sender.isPlayer() ? 0 : 20);
f.whenComplete((fs, ff) -> {
J.car(c);
if (c != null) c.cancel();
if (!silentMsg) {
sender.sendMessage(C.AQUA + "Completed " + getName() + " in " + Form.duration(p.getMilliseconds(), 1));
}

View File

@@ -0,0 +1,118 @@
package com.volmit.iris.util.scheduling.jobs;
import com.volmit.iris.Iris;
import com.volmit.iris.util.data.Cuboid;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.plugin.VolmitSender;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.util.BlockVector;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
public class ScanJob implements Job {
private final CountDownLatch latch = new CountDownLatch(1);
private final AtomicInteger completed = new AtomicInteger();
private final String name;
private final Cuboid cuboid;
private final BiConsumer<BlockVector, Block> action;
private final int msPerTick, total;
private volatile Chunk chunk;
public ScanJob(String name,
Cuboid cuboid,
int msPerTick,
BiConsumer<BlockVector, Block> action
) {
this.name = name;
this.cuboid = cuboid;
this.action = action;
this.msPerTick = msPerTick;
total = cuboid.volume();
}
@Override
public String getName() {
return name;
}
@Override
public void execute() {
Thread.ofVirtual()
.name("Iris Job - " + name)
.start(this::executeTask);
await();
}
public void await() {
try {
latch.await();
} catch (InterruptedException ignored) {}
}
private void executeTask() {
var it = cuboid.chunkedIterator();
var region = Iris.platform.getRegionScheduler();
var tmp = it.next();
while (tmp != null) {
Location finalTmp = tmp;
tmp = region.run(tmp, () -> {
var time = M.ms() + msPerTick;
var next = finalTmp;
while (time > M.ms()) {
if (!consume(next)) break;
completed.incrementAndGet();
next = it.hasNext() ? it.next() : null;
}
return next;
}).getResult().join();
}
latch.countDown();
}
private boolean consume(Location next) {
if (!Iris.platform.isOwnedByCurrentRegion(next))
return true;
final Chunk nextChunk = next.getChunk();
if (chunk == null) {
chunk.removePluginChunkTicket(Iris.instance);
chunk = next.getChunk();
} else if (chunk != nextChunk) {
chunk.removePluginChunkTicket(Iris.instance);
chunk = nextChunk;
chunk.addPluginChunkTicket(Iris.instance);
}
final Block block = next.getBlock();
action.accept(next.subtract(cuboid.getLowerNE().toVector()).toVector().toBlockVector(), block);
return false;
}
@Override
public void completeWork() {
}
@Override
public int getTotalWork() {
return total;
}
@Override
public int getWorkCompleted() {
return completed.get();
}
@Override
public void execute(VolmitSender sender, boolean silentMsg, Runnable whenComplete) {
Job.super.execute(sender, silentMsg, whenComplete);
await();
}
}

View File

@@ -1,21 +0,0 @@
package com.volmit.iris.core.scripting.kotlin.base
import com.volmit.iris.core.scripting.func.UpdateExecutor
import com.volmit.iris.util.mantle.MantleChunk
import org.bukkit.Chunk
import kotlin.script.experimental.annotations.KotlinScript
import kotlin.script.experimental.api.ScriptCompilationConfiguration
import kotlin.script.experimental.api.providedProperties
@KotlinScript(fileExtension = "update.kts", compilationConfiguration = ChunkUpdateScriptDefinition::class)
abstract class ChunkUpdateScript
object ChunkUpdateScriptDefinition : ScriptCompilationConfiguration(listOf(EngineScriptDefinition), {
providedProperties(
"mantleChunk" to MantleChunk::class,
"chunk" to Chunk::class,
"executor" to UpdateExecutor::class
)
}) {
private fun readResolve(): Any = MobSpawningScriptDefinition
}

View File

@@ -3,15 +3,11 @@ package com.volmit.iris.core.scripting.kotlin.environment
import com.volmit.iris.core.loader.IrisRegistrant
import com.volmit.iris.core.scripting.environment.EngineEnvironment
import com.volmit.iris.core.scripting.func.BiomeLookup
import com.volmit.iris.core.scripting.func.UpdateExecutor
import com.volmit.iris.core.scripting.kotlin.base.ChunkUpdateScript
import com.volmit.iris.core.scripting.kotlin.base.EngineScript
import com.volmit.iris.core.scripting.kotlin.base.MobSpawningScript
import com.volmit.iris.core.scripting.kotlin.base.PostMobSpawningScript
import com.volmit.iris.core.scripting.kotlin.base.PreprocessorScript
import com.volmit.iris.engine.framework.Engine
import com.volmit.iris.util.mantle.MantleChunk
import org.bukkit.Chunk
import org.bukkit.Location
import org.bukkit.entity.Entity
@@ -35,9 +31,6 @@ data class IrisExecutionEnvironment(
override fun preprocessObject(script: String, `object`: IrisRegistrant) =
execute(script, PreprocessorScript::class.java, engine.parameters("object" to `object`))
override fun updateChunk(script: String, mantleChunk: MantleChunk, chunk: Chunk, executor: UpdateExecutor) =
execute(script, ChunkUpdateScript::class.java, engine.parameters("mantleChunk" to mantleChunk, "chunk" to chunk, "executor" to executor))
private fun Engine.parameters(vararg values: Pair<String, Any?>): Map<String, Any?> {
return mapOf(
"data" to data,

View File

@@ -8,4 +8,6 @@ description: More than a Dimension!
commands:
iris:
aliases: [ ir, irs ]
api-version: '${apiVersion}'
api-version: '${apiVersion}'
hotload-dependencies: false
folia-supported: true

View File

@@ -17,6 +17,7 @@ spigot = "1.20.1-R0.1-SNAPSHOT" # https://hub.spigotmc.org/nexus/repository/snap
log4j = "2.19.0" # https://central.sonatype.com/artifact/org.apache.logging.log4j/log4j-api
adventure-api = "4.24.0" # https://github.com/KyoriPowered/adventure
adventure-platform = "4.4.1" # https://github.com/KyoriPowered/adventure-platform
platform-utils = "27453094ed" # https://github.com/CrazyDev05/PlatformUtils
annotations = "26.0.2" # https://central.sonatype.com/artifact/org.jetbrains/annotations
paralithic = "0.8.1" # https://github.com/PolyhedralDev/Paralithic/
@@ -55,6 +56,7 @@ mythic = "5.9.5"
mythic-chrucible = "2.1.0"
kgenerators = "7.3" # https://repo.codemc.io/repository/maven-public/me/kryniowesegryderiusz/kgenerators-core/maven-metadata.xml
multiverseCore = "5.1.0"
worlds = "3.2.5" # https://modrinth.com/plugin/worlds-1
[libraries]
# Core Libraries
@@ -63,10 +65,12 @@ spigot = { module = "org.spigotmc:spigot-api", version.ref = "spigot" }
log4j-api = { module = "org.apache.logging.log4j:log4j-api", version.ref = "log4j" }
log4j-core = { module = "org.apache.logging.log4j:log4j-core", version.ref = "log4j" }
annotations = { module = "org.jetbrains:annotations", version.ref = "annotations" }
platformUtils = { module = "com.github.CrazyDev05:PlatformUtils", version.ref = "platform-utils" }
# Dynamically Loaded
adventure-api = { module = "net.kyori:adventure-api", version.ref = "adventure-api" }
adventure-minimessage = { module = "net.kyori:adventure-text-minimessage", version.ref = "adventure-api" }
adventure-gson = { module = "net.kyori:adventure-text-serializer-gson", version.ref = "adventure-api" }
adventure-legacy = { module = "net.kyori:adventure-text-serializer-legacy", version.ref = "adventure-api" }
adventure-platform = { module = "net.kyori:adventure-platform-bukkit", version.ref = "adventure-platform" }
paralithic = { module = "com.dfsek:paralithic", version.ref = "paralithic" }
@@ -110,6 +114,7 @@ mythic = { module = "io.lumine:Mythic-Dist", version.ref = "mythic" }
mythicChrucible = { module = "io.lumine:MythicCrucible-Dist", version.ref = "mythic-chrucible" }
kgenerators = { module = "me.kryniowesegryderiusz:kgenerators-core", version.ref = "kgenerators" }
multiverseCore = { module = "org.mvplugins.multiverse.core:multiverse-core", version.ref = "multiverseCore" }
worlds = { module = "net.thenextlvl:worlds", version.ref = "worlds" }
[plugins]
shadow = { id = "com.gradleup.shadow", version.ref = "shadow" }

View File

@@ -24,7 +24,6 @@ import com.volmit.iris.util.matter.MatterBiomeInject;
import com.volmit.iris.util.nbt.mca.NBTWorld;
import com.volmit.iris.util.nbt.mca.palette.*;
import com.volmit.iris.util.nbt.tag.CompoundTag;
import com.volmit.iris.util.scheduling.J;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.asm.Advice;
@@ -217,7 +216,7 @@ public class NMSBinding implements INMSBinding {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
Iris.platform.getRegionScheduler().run(pos, () -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {

View File

@@ -232,7 +232,7 @@ public class NMSBinding implements INMSBinding {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
Iris.platform.getRegionScheduler().run(pos, () -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {

View File

@@ -232,7 +232,7 @@ public class NMSBinding implements INMSBinding {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
Iris.platform.getRegionScheduler().run(pos, () -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {

View File

@@ -37,7 +37,6 @@ import com.volmit.iris.util.nbt.mca.NBTWorld;
import com.volmit.iris.util.nbt.mca.palette.*;
import com.volmit.iris.engine.object.IrisJigsawStructurePlacement;
import com.volmit.iris.util.nbt.tag.CompoundTag;
import com.volmit.iris.util.scheduling.J;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.asm.Advice;
@@ -230,7 +229,7 @@ public class NMSBinding implements INMSBinding {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
Iris.platform.getRegionScheduler().run(pos, () -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {

View File

@@ -238,7 +238,7 @@ public class NMSBinding implements INMSBinding {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
Iris.platform.getRegionScheduler().run(pos, () -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {

View File

@@ -232,7 +232,7 @@ public class NMSBinding implements INMSBinding {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
Iris.platform.getRegionScheduler().run(pos, () -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {

View File

@@ -27,7 +27,6 @@ import com.volmit.iris.util.matter.MatterBiomeInject;
import com.volmit.iris.util.nbt.mca.NBTWorld;
import com.volmit.iris.util.nbt.mca.palette.*;
import com.volmit.iris.util.nbt.tag.CompoundTag;
import com.volmit.iris.util.scheduling.J;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.shorts.ShortList;
import net.bytebuddy.ByteBuddy;
@@ -228,7 +227,7 @@ public class NMSBinding implements INMSBinding {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
Iris.platform.getRegionScheduler().run(pos, () -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {

View File

@@ -25,7 +25,6 @@ import com.volmit.iris.util.matter.MatterBiomeInject;
import com.volmit.iris.util.nbt.mca.NBTWorld;
import com.volmit.iris.util.nbt.mca.palette.*;
import com.volmit.iris.util.nbt.tag.CompoundTag;
import com.volmit.iris.util.scheduling.J;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.shorts.ShortList;
import net.bytebuddy.ByteBuddy;
@@ -221,7 +220,7 @@ public class NMSBinding implements INMSBinding {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
Iris.platform.getRegionScheduler().run(pos, () -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {

View File

@@ -220,7 +220,7 @@ public class NMSBinding implements INMSBinding {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64);
var level = ((CraftWorld) pos.getWorld()).getHandle();
var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
J.s(() -> merge(level, blockPos, tag));
Iris.platform.getRegionScheduler().run(pos, () -> merge(level, blockPos, tag));
}
private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) {

View File

@@ -16,14 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
plugins {
id ("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}
rootProject.name = "Iris"
include(":core", ":core:agent")
include(
":nms:v1_21_R6",
":nms:v1_21_R5",
":nms:v1_21_R4",
":nms:v1_21_R3",