diff --git a/build.gradle.kts b/build.gradle.kts index 682335c2a..595224eaa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -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 /* @@ -94,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 + } } } @@ -111,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("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 { @@ -195,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 { diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 8e4894bd4..12c1ee35f 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -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") diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index 14607fdba..045c58c10 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -62,6 +62,8 @@ 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.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 static void safeguard(String format, Object... args) { @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 Iris() { private void enable() { services = new KMap<>(); + platform = PlatformUtils.createPlatform(this); setupAudience(); Bindings.setupSentry(); initialize("com.volmit.iris.core.service").forEach((i) -> services.put((Class) i.getClass(), (IrisService) i)); @@ -456,7 +460,7 @@ private void enable() { 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 void checkForBukkitWorlds(Predicate filter) { 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 @@ private void autoStartStudio() { 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 void onEnable() { public void onDisable() { services.values().forEach(IrisService::onDisable); - Bukkit.getScheduler().cancelTasks(this); HandlerList.unregisterAll((Plugin) this); postShutdown.forEach(Runnable::run); super.onDisable(); diff --git a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java index b4bd3e083..206d69efd 100644 --- a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java +++ b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java @@ -179,11 +179,14 @@ public static void restart() { 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"); }); } diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index 75448c8dc..d8ef40989 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -42,7 +42,6 @@ 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 void teleport( 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") diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandObject.java b/core/src/main/java/com/volmit/iris/core/commands/CommandObject.java index fd057b300..080e9908b 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandObject.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandObject.java @@ -128,7 +128,7 @@ public void setTile(int xx, int yy, int zz, TileData tile) { public Engine getEngine() { return null; } - }; + }.sync(world); } @Decree(description = "Check the composition of an object") diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java index 555ce4f48..c203aaffd 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java @@ -47,20 +47,16 @@ 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.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 void regen( 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 void loot( return; } + Player player = player(); + var scheduler = Iris.platform.getEntityScheduler(player); + scheduler.run(() -> { + sender().sendMessage(C.GREEN + "Opening inventory now!"); + player.openInventory(inv); - O ta = new O<>(); - ta.set(-1); - - 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(); - } + scheduler.runAtFixedRate(refresh -> { + if (!player.getOpenInventory().getType().equals(InventoryType.CHEST)) { + refresh.cancel(); + return; + } - 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)); + if (!add) { + inv.clear(); + } - 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 void regions(@Param(description = "The radius in chunks", defaultValue = 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 void regions(@Param(description = "The radius in chunks", defaultValue = })).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 void distances(@Param(description = "The radius in chunks") int radius) { 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 void distances(@Param(description = "The radius in chunks") int radius) { 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 void tpstudio() { } 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 void update( } } - @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 void objects() { sender().sendMessage("You must be in an iris world."); return; } - KList chunks = new KList<>(); - int bx = player().getLocation().getChunk().getX(); - int bz = player().getLocation().getChunk().getZ(); + KMap> 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(); - - 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(); + 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.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 void objects() { 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 void objects() { Iris.reportError(e); } - KList biomes = new KList<>(); - KList caveBiomes = new KList<>(); - KMap>> objects = new KMap<>(); - - for (Chunk i : chunks) { - for (int j = 0; j < 16; j += 3) { - - 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); + KSet biomes = new KSet<>(); + KSet caveBiomes = new KSet<>(); + KMap>> objects = new KMap<>(); + + var engine = engine(); + assert engine != null; + + KList> 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 void objects() { 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 void objects() { } } - private void exportObjects(IrisBiome bb, PrintWriter pw, Engine g, KMap>> objects) { - String n1 = bb.getName() + " [" + Form.capitalize(bb.getInferredType().name().toLowerCase()) + "] " + " (" + bb.getLoadFile().getName() + ")"; + private void exportObjects(IrisBiome bb, PrintWriter pw, Engine g, KMap>> objects) { + String n1 = bb.getName() + " [" + Form.capitalize(String.valueOf(bb.getInferredType()).toLowerCase()) + "] " + " (" + bb.getLoadFile().getName() + ")"; int m = 0; KSet stop = new KSet<>(); for (IrisObjectPlacement f : bb.getObjects()) { @@ -876,7 +891,7 @@ private void exportObjects(IrisBiome bb, PrintWriter pw, Engine g, KMap new KMap<>()) - .computeIfAbsent(n2, (k) -> new KList<>()).addIfMissing(n3); + .computeIfAbsent(n2, (k) -> new KSet<>()).add(n3); } } } diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandWhat.java b/core/src/main/java/com/volmit/iris/core/commands/CommandWhat.java index 48d8c726e..c26376085 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandWhat.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandWhat.java @@ -74,22 +74,22 @@ public void biome() { } 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 void region() { } } - @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 { diff --git a/core/src/main/java/com/volmit/iris/core/edit/BlockSignal.java b/core/src/main/java/com/volmit/iris/core/edit/BlockSignal.java index 65526cd87..05315838b 100644 --- a/core/src/main/java/com/volmit/iris/core/edit/BlockSignal.java +++ b/core/src/main/java/com/volmit/iris/core/edit/BlockSignal.java @@ -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 static Runnable forever(Block block) { 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 void run() { 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(); } }; diff --git a/core/src/main/java/com/volmit/iris/core/edit/JigsawEditor.java b/core/src/main/java/com/volmit/iris/core/edit/JigsawEditor.java index 2b20693be..0fce7e919 100644 --- a/core/src/main/java/com/volmit/iris/core/edit/JigsawEditor.java +++ b/core/src/main/java/com/volmit/iris/core/edit/JigsawEditor.java @@ -30,6 +30,7 @@ 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 falling = new KMap<>(); private final ChronoLatch cl = new ChronoLatch(100); private Location target; @@ -106,21 +107,26 @@ public void on(PlayerMoveEvent e) { } 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 void close() { } public void exit() { - J.car(ticker); + if (ticker != null) ticker.cancel(); Iris.instance.unregisterListener(this); try { J.sfut(() -> { diff --git a/core/src/main/java/com/volmit/iris/core/gui/VisionGUI.java b/core/src/main/java/com/volmit/iris/core/gui/VisionGUI.java index 32bc1f79d..fa2332ff7 100644 --- a/core/src/main/java/com/volmit/iris/core/gui/VisionGUI.java +++ b/core/src/main/java/com/volmit/iris/core/gui/VisionGUI.java @@ -763,7 +763,7 @@ private void teleport() { 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."); diff --git a/core/src/main/java/com/volmit/iris/core/link/FoliaWorldsLink.java b/core/src/main/java/com/volmit/iris/core/link/FoliaWorldsLink.java new file mode 100644 index 000000000..f21ac8a78 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/link/FoliaWorldsLink.java @@ -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 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(); + } +} diff --git a/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java index dc8e23e22..37e85b08e 100644 --- a/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java +++ b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java @@ -20,6 +20,7 @@ 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.inventory.ItemStack; import java.awt.Color; +import java.util.concurrent.CompletableFuture; import java.util.List; public interface INMSBinding { @@ -101,6 +103,15 @@ && missingDimensionTypes(gen.getTarget().getDimension().getDimensionTypeKey())) return c.createWorld(); } + default CompletableFuture 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); diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java index bce79233c..d86bebcd5 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java @@ -14,7 +14,6 @@ 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 @@ private boolean loadChunksIfGenerated(int x, int z) { 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 @@ private boolean loadChunksIfGenerated(int x, int z) { 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 @@ private boolean loadChunksIfGenerated(int x, int z) { 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))); diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/DeepSearchPregenerator.java b/core/src/main/java/com/volmit/iris/core/pregenerator/DeepSearchPregenerator.java index e9d2b8f74..685898c65 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/DeepSearchPregenerator.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/DeepSearchPregenerator.java @@ -22,7 +22,6 @@ 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 void shutdownInstance(World world) throws IOException { } 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(); diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/LazyPregenerator.java b/core/src/main/java/com/volmit/iris/core/pregenerator/LazyPregenerator.java index dc58f2ed5..db4180c2d 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/LazyPregenerator.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/LazyPregenerator.java @@ -11,7 +11,6 @@ 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.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 @@ private long computeETA() { 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 void shutdownInstance(World world) throws IOException { } 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(); diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/TurboPregenerator.java b/core/src/main/java/com/volmit/iris/core/pregenerator/TurboPregenerator.java index 4588597c3..46f72108e 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/TurboPregenerator.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/TurboPregenerator.java @@ -17,7 +17,6 @@ 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.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 @@ private long computeETA() { 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 void shutdownInstance(World world) throws IOException { } 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(); diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncOrMedievalPregenMethod.java b/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncOrMedievalPregenMethod.java deleted file mode 100644 index f33fe2cdc..000000000 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncOrMedievalPregenMethod.java +++ /dev/null @@ -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 . - */ - -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(); - } -} diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java b/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java index 7e92807bf..a32d7a523 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java @@ -23,17 +23,17 @@ 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 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 AsyncPregenMethod(World world, int unusedThreads) { 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> 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 @@ private class ServiceExecutor implements Executor { 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 void shutdown() { 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(); diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java b/core/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java deleted file mode 100644 index 8ae773641..000000000 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java +++ /dev/null @@ -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 . - */ - -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(); - } -} diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java b/core/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java deleted file mode 100644 index 2ebfb64b2..000000000 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java +++ /dev/null @@ -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 . - */ - -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> futures; - private final Map 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; - } -} diff --git a/core/src/main/java/com/volmit/iris/core/service/EditSVC.java b/core/src/main/java/com/volmit/iris/core/service/EditSVC.java index dc944f1f2..95c1d0ce9 100644 --- a/core/src/main/java/com/volmit/iris/core/service/EditSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/EditSVC.java @@ -24,7 +24,6 @@ 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 diff --git a/core/src/main/java/com/volmit/iris/core/service/ObjectSVC.java b/core/src/main/java/com/volmit/iris/core/service/ObjectSVC.java index 5fadf8b4a..07a76268a 100644 --- a/core/src/main/java/com/volmit/iris/core/service/ObjectSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/ObjectSVC.java @@ -22,7 +22,6 @@ 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 @@ private void loopChange(int amount) { */ private void revert(Map blocks) { Iterator> it = blocks.entrySet().iterator(); - Bukkit.getScheduler().runTask(Iris.instance, () -> { - int amount = 0; - while (it.hasNext()) { - Map.Entry entry = it.next(); - BlockData data = entry.getValue(); - entry.getKey().setBlockData(data, false); - - it.remove(); - - amount++; + var scheduler = Iris.platform.getRegionScheduler(); + for (int i = 0; i < 200 && it.hasNext(); i++) { + Map.Entry entry = it.next(); + Block block = entry.getKey(); + BlockData data = entry.getValue(); + it.remove(); + + scheduler.run(block.getLocation(), () -> block.setBlockData(data, false)); + } - if (amount > 200) { - J.s(() -> revert(blocks), 1); - } - } - }); + if (it.hasNext()) { + J.s(() -> revert(blocks), 1); + } } } \ No newline at end of file diff --git a/core/src/main/java/com/volmit/iris/core/service/TreeSVC.java b/core/src/main/java/com/volmit/iris/core/service/TreeSVC.java index 58be7738c..69a937367 100644 --- a/core/src/main/java/com/volmit/iris/core/service/TreeSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/TreeSVC.java @@ -142,9 +142,10 @@ public int getHighest(int x, int z, IrisData data, boolean ignoreFluid) { 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 Engine getEngine() { 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); diff --git a/core/src/main/java/com/volmit/iris/core/service/WandSVC.java b/core/src/main/java/com/volmit/iris/core/service/WandSVC.java index 8d984ba91..ffe84e900 100644 --- a/core/src/main/java/com/volmit/iris/core/service/WandSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/WandSVC.java @@ -35,6 +35,7 @@ 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 static IrisObject createSchematic(Player p, boolean legacy) { 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) { diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java b/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java index f58cc5c69..38e44f38a 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java @@ -11,6 +11,7 @@ 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 static void convertSchematics(VolmitSender sender) { 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 static void convertSchematics(VolmitSender sender) { 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 static void convertSchematics(VolmitSender sender) { } } } - if (i != -1) J.car(i); + if (i != null) i.cancel(); try { object.shrinkwrap(); object.write(new File(folder, schem.getName().replace(".schem", ".iob"))); diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java index b112ed779..46bb66b8b 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java @@ -32,7 +32,6 @@ 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 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 World create() throws IrisException { } AtomicDouble pp = new AtomicDouble(0); - O done = new O<>(); - done.set(false); WorldCreator wc = new IrisWorldCreator() .dimension(dimension) .name(name) @@ -143,6 +142,7 @@ public World create() throws IrisException { 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 World create() throws IrisException { }); - 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 World create() throws IrisException { 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) { diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java b/core/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java index 06651213c..314deb1ba 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java @@ -24,8 +24,8 @@ 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 static PregeneratorJob pregenerate(PregenTask task, PregeneratorMethod me * @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 static PregeneratorJob pregenerate(PregenTask task, World world) { 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 static boolean evacuate(World world) { 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 static boolean evacuate(World world, String m) { 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; } diff --git a/core/src/main/java/com/volmit/iris/engine/IrisEngine.java b/core/src/main/java/com/volmit/iris/engine/IrisEngine.java index 3586965e7..7b5d51efd 100644 --- a/core/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/core/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -51,6 +51,7 @@ 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 engineData = new AtomicCache<>(); private final AtomicBoolean cleaning; private final ChronoLatch cleanLatch; @@ -427,7 +428,7 @@ public void printMetrics(CommandSender sender) { public void close() { PregeneratorJob.shutdownInstance(); closed = true; - J.car(art); + art.cancel(); getWorldManager().close(); getTarget().close(); saveEngineData(); diff --git a/core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java b/core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java index 1edfee1f1..db1ae2405 100644 --- a/core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java +++ b/core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java @@ -43,7 +43,6 @@ 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.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 @@ private void discoverChunks() { 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 @@ private void updateChunks() { } } } - } + 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 void teleportAsync(PlayerTeleportEvent e) { 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 @@ private void warmupAreaAsync(Player player, Location to, Runnable r) { } 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 Map> getSpawnersFromMarkers(Chunk c) { IrisPosition pos = new IrisPosition((c.getX() << 4) + x, y, (c.getZ() << 4) + z); if (mark.isEmptyAbove()) { - AtomicBoolean remove = new AtomicBoolean(false); - - 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()) { + 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(); + + if (remove == Boolean.TRUE) { b.add(pos); return; } diff --git a/core/src/main/java/com/volmit/iris/engine/framework/Engine.java b/core/src/main/java/com/volmit/iris/engine/framework/Engine.java index 9d5cfad00..df9fd129e 100644 --- a/core/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/core/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -64,7 +64,6 @@ 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; @@ -302,12 +301,12 @@ default void updateChunk(Chunk c) { 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,7 +351,7 @@ default void updateChunk(Chunk c) { }); chunk.deleteSlices(MatterUpdate.class); getMetrics().getUpdates().put(p.getMilliseconds()); - }, RNG.r.i(1, 20))); //Why is there a random delay here? + }, c, RNG.r.i(2, 20))); //Why is there a random delay here? }); try { @@ -363,12 +362,12 @@ default void updateChunk(Chunk c) { } } - private static Runnable run(Semaphore semaphore, Runnable runnable, int delay) { + private static Runnable run(Semaphore semaphore, Runnable runnable, Chunk chunk, int delay) { return () -> { if (!semaphore.tryAcquire()) return; - J.s(() -> { + Iris.platform.getRegionScheduler().runDelayed(chunk.getWorld(), chunk.getX(), chunk.getZ(), () -> { try { runnable.run(); } finally { @@ -527,8 +526,9 @@ default void addItems(boolean debug, Inventory inv, RNG rng, KList> 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); @@ -537,10 +537,10 @@ default void addItems(boolean debug, Inventory inv, RNG rng, KList player.teleport(ll)); + Iris.platform.teleportAsync(player, ll); } return; diff --git a/core/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java b/core/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java index e53b35e5c..d016927c9 100644 --- a/core/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java +++ b/core/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java @@ -20,39 +20,34 @@ 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 void on(ChunkLoadEvent e) { public void close() { super.close(); Iris.instance.unregisterListener(this); - Bukkit.getScheduler().cancelTask(taskId); + if (task != null) task.cancel(); } } diff --git a/core/src/main/java/com/volmit/iris/engine/framework/Locator.java b/core/src/main/java/com/volmit/iris/engine/framework/Locator.java index 0c05c068b..794b3838e 100644 --- a/core/src/main/java/com/volmit/iris/engine/framework/Locator.java +++ b/core/src/main/java/com/volmit/iris/engine/framework/Locator.java @@ -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.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 @@ static Locator caveOrMantleBiome(String loadKey) { 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()); } diff --git a/core/src/main/java/com/volmit/iris/engine/framework/placer/SafeObjectPlacer.java b/core/src/main/java/com/volmit/iris/engine/framework/placer/SafeObjectPlacer.java new file mode 100644 index 000000000..f7fd61109 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/engine/framework/placer/SafeObjectPlacer.java @@ -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(); + } +} diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index c045cf922..72662fcac 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -160,8 +160,9 @@ public boolean place(PlannedPiece i, int startHeight, IrisObjectPlacement o, IOb }, null, getData().getEngine() != null ? getData() : eng.getData()) != -1; } + //TODO properly fix for folia public void place(WorldObjectPlacer placer, Consumer 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() { diff --git a/core/src/main/java/com/volmit/iris/engine/object/IObjectPlacer.java b/core/src/main/java/com/volmit/iris/engine/object/IObjectPlacer.java index 3a7a89a38..46c955cec 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IObjectPlacer.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IObjectPlacer.java @@ -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; + } } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisCommand.java b/core/src/main/java/com/volmit/iris/engine/object/IrisCommand.java index 0555bb6bb..e7dc2750e 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisCommand.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisCommand.java @@ -67,6 +67,7 @@ public void run(Location at) { 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 void run(Location at) { .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)); } } } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisEffect.java b/core/src/main/java/com/volmit/iris/engine/object/IrisEffect.java index d2c6eca6b..ddec5d9a5 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisEffect.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisEffect.java @@ -24,7 +24,6 @@ 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 void apply(Player p, Engine g) { 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 void apply(Player p, Engine g) { 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 void apply(Player p, Engine g) { 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 void apply(Player p, Engine g) { 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 void apply(Entity p) { 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 void apply(Entity p) { 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 void apply(Entity p) { 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 void apply(Entity p) { } } } + + private void schedule(Entity entity, Runnable task) { + Iris.platform.getEntityScheduler(entity).run(task, null); + } } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisEntity.java b/core/src/main/java/com/volmit/iris/engine/object/IrisEntity.java index a1f51863f..1ed253a9f 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisEntity.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisEntity.java @@ -33,8 +33,6 @@ 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.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; @@ -183,38 +179,34 @@ public Entity spawn(Engine gen, Location at) { 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 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 Entity spawn(Engine gen, Location at, RNG rng) { 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 (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 populateLoot(Random random, LootContext context) { - KList items = new KList<>(); + 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()); + } - 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())); - } + @Override + public Collection populateLoot(Random random, LootContext context) { + KList 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, at.getWorld(), at.getBlockX(), at.getBlockY(), at.getBlockZ())); } - @Override - public void fillInventory(Inventory inventory, Random random, LootContext context) { - for (ItemStack i : populateLoot(random, context)) { - inventory.addItem(i); - } + return items; + } - gen.scramble(inventory, rng); + @Override + public void fillInventory(Inventory inventory, Random random, LootContext context) { + for (ItemStack i : populateLoot(random, context)) { + inventory.addItem(i); } - }); - } + + 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 void fillInventory(Inventory inventory, Random random, LootContext contex rawCommands.forEach(r -> r.run(fat)); } - Location finalAt1 = at; - - 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; - } + 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; + } - 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); + 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); } - }, 0)); - } - }); + } else { + task.cancel(); + living.setNoDamageTicks(0); + living.setCollidable(true); + living.setAI(true); + e.setInvulnerable(false); + } + }, 1, 1); + } return e; @@ -429,29 +400,6 @@ private Entity doSpawn(Location at) { 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 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)); } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawn.java b/core/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawn.java index a0eb9500d..acbee7305 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawn.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawn.java @@ -36,8 +36,14 @@ 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 @@ private Entity spawn100(Engine g, Location at, boolean ignoreSurfaces) { 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 @@ private boolean isAreaClearForSpawn(Location center, Vector3d boundingBox) { 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(); } } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisSurface.java b/core/src/main/java/com/volmit/iris/engine/object/IrisSurface.java index e8a2e2e3c..885ba95f5 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisSurface.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisSurface.java @@ -20,7 +20,7 @@ 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 diff --git a/core/src/main/java/com/volmit/iris/engine/object/LegacyTileData.java b/core/src/main/java/com/volmit/iris/engine/object/LegacyTileData.java index 7cbcc094c..b4a7e2b7c 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/LegacyTileData.java +++ b/core/src/main/java/com/volmit/iris/engine/object/LegacyTileData.java @@ -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 boolean isApplicable(BlockData data) { @Override public void toBukkit(Block block) { - J.s(() -> handler.toBukkit(block)); + Iris.platform.getRegionScheduler().run(block.getLocation(), () -> handler.toBukkit(block)); } @Override diff --git a/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java b/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java index c16bebc3a..a68dd5481 100644 --- a/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java +++ b/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java @@ -38,10 +38,11 @@ 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 @@ private boolean initialize(World world) { @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 EngineTarget getTarget() { } @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 void injectChunkReplacement(World world, int x, int z, Executor syncExecu KList> 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 void injectChunkReplacement(World world, int x, int z, Executor syncExecu } } } - }, 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 void injectChunkReplacement(World world, int x, int z, Executor syncExecu 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()); - } - } } } diff --git a/core/src/main/java/com/volmit/iris/engine/platform/PlatformChunkGenerator.java b/core/src/main/java/com/volmit/iris/engine/platform/PlatformChunkGenerator.java index 93066fb62..5a6427d8e 100644 --- a/core/src/main/java/com/volmit/iris/engine/platform/PlatformChunkGenerator.java +++ b/core/src/main/java/com/volmit/iris/engine/platform/PlatformChunkGenerator.java @@ -23,12 +23,12 @@ 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 @@ default IrisData getData() { @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(); diff --git a/core/src/main/java/com/volmit/iris/util/board/BoardManager.java b/core/src/main/java/com/volmit/iris/util/board/BoardManager.java index fe61666de..e0d01514a 100644 --- a/core/src/main/java/com/volmit/iris/util/board/BoardManager.java +++ b/core/src/main/java/com/volmit/iris/util/board/BoardManager.java @@ -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 scoreboards; - private final BukkitTask updateTask; + private final Task updateTask; private BoardSettings boardSettings; @@ -42,7 +43,7 @@ public BoardManager(JavaPlugin plugin, BoardSettings boardSettings) { 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); } diff --git a/core/src/main/java/com/volmit/iris/util/board/BoardUpdateTask.java b/core/src/main/java/com/volmit/iris/util/board/BoardUpdateTask.java index 1a54bf498..7436f4d02 100644 --- a/core/src/main/java/com/volmit/iris/util/board/BoardUpdateTask.java +++ b/core/src/main/java/com/volmit/iris/util/board/BoardUpdateTask.java @@ -20,7 +20,6 @@ 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 @@ * @since 5/31/2018 */ @RequiredArgsConstructor -public class BoardUpdateTask extends BukkitRunnable { +public class BoardUpdateTask implements Runnable { private static final Predicate PLAYER_IS_ONLINE = uuid -> Bukkit.getPlayer(uuid) != null; diff --git a/core/src/main/java/com/volmit/iris/util/data/Cuboid.java b/core/src/main/java/com/volmit/iris/util/data/Cuboid.java index ccd837eb2..2411bb621 100644 --- a/core/src/main/java/com/volmit/iris/util/data/Cuboid.java +++ b/core/src/main/java/com/volmit/iris/util/data/Cuboid.java @@ -316,17 +316,17 @@ public int getUpperZ() { * * @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 List getChunks() { * @see java.lang.Iterable#iterator() */ @Override + @Deprecated(forRemoval = true) public Iterator iterator() { return new CuboidIterator(getWorld(), x1, y1, z1, x2, y2, z2); } - public Iterator chunkedIterator() { + public Iterator chunkedIterator() { return new ChunkedCuboidIterator(getWorld(), x1, y1, z1, x2, y2, z2); } @@ -751,7 +752,7 @@ public void remove() { } } - public static class ChunkedCuboidIterator implements Iterator { + public static class ChunkedCuboidIterator implements Iterator { 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 boolean hasNextChunk() { } @Override - public Block next() { + public Location next() { if (chunk == null) { chunk = new Position2(cX, cZ); if (++cX > maxCX) { @@ -809,7 +810,7 @@ public Block next() { 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) { diff --git a/core/src/main/java/com/volmit/iris/util/decree/virtual/VirtualDecreeCommand.java b/core/src/main/java/com/volmit/iris/util/decree/virtual/VirtualDecreeCommand.java index 4bd5e9168..c370d8f9b 100644 --- a/core/src/main/java/com/volmit/iris/util/decree/virtual/VirtualDecreeCommand.java +++ b/core/src/main/java/com/volmit/iris/util/decree/virtual/VirtualDecreeCommand.java @@ -31,8 +31,8 @@ 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 @@ private boolean invokeNode(VolmitSender sender, KMap map) { }; 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(); } diff --git a/core/src/main/java/com/volmit/iris/util/math/BlockPosition.java b/core/src/main/java/com/volmit/iris/util/math/BlockPosition.java index 9ca1363f8..ec564fca2 100644 --- a/core/src/main/java/com/volmit/iris/util/math/BlockPosition.java +++ b/core/src/main/java/com/volmit/iris/util/math/BlockPosition.java @@ -89,6 +89,7 @@ public long asLong() { return toLong(getX(), getY(), getZ()); } + @Deprecated(forRemoval = true) public Block toBlock(World world) { return world.getBlockAt(x, y, z); } diff --git a/core/src/main/java/com/volmit/iris/util/parallel/SyncExecutor.java b/core/src/main/java/com/volmit/iris/util/parallel/SyncExecutor.java deleted file mode 100644 index 00966b226..000000000 --- a/core/src/main/java/com/volmit/iris/util/parallel/SyncExecutor.java +++ /dev/null @@ -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 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(); - } -} diff --git a/core/src/main/java/com/volmit/iris/util/plugin/VirtualCommand.java b/core/src/main/java/com/volmit/iris/util/plugin/VirtualCommand.java index 789c88661..bfd021efa 100644 --- a/core/src/main/java/com/volmit/iris/util/plugin/VirtualCommand.java +++ b/core/src/main/java/com/volmit/iris/util/plugin/VirtualCommand.java @@ -24,6 +24,7 @@ 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 @@ private boolean checkPermissions(CommandSender sender, ICommand command2) { 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)); } } diff --git a/core/src/main/java/com/volmit/iris/util/plugin/VolmitPlugin.java b/core/src/main/java/com/volmit/iris/util/plugin/VolmitPlugin.java index 130f8b686..0174b06fb 100644 --- a/core/src/main/java/com/volmit/iris/util/plugin/VolmitPlugin.java +++ b/core/src/main/java/com/volmit/iris/util/plugin/VolmitPlugin.java @@ -245,7 +245,6 @@ private void registerPermission(MortarPermission pc) { @Override public void onDisable() { stop(); - Bukkit.getScheduler().cancelTasks(this); unregisterListener(this); unregisterAll(); } diff --git a/core/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java b/core/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java index dccb95ce7..4825a4df6 100644 --- a/core/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java +++ b/core/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java @@ -48,8 +48,8 @@ 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 @@ private Component createComponentRaw(String message) { } public void showWaiting(String passive, CompletableFuture f) { - AtomicInteger v = new AtomicInteger(); AtomicReference 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()); diff --git a/core/src/main/java/com/volmit/iris/util/profile/MsptTimings.java b/core/src/main/java/com/volmit/iris/util/profile/MsptTimings.java index 2d098e1e7..75fb5eddc 100644 --- a/core/src/main/java/com/volmit/iris/util/profile/MsptTimings.java +++ b/core/src/main/java/com/volmit/iris/util/profile/MsptTimings.java @@ -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 final int getMspt() { 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 { diff --git a/core/src/main/java/com/volmit/iris/util/scheduling/AR.java b/core/src/main/java/com/volmit/iris/util/scheduling/AR.java index b5fda2c52..e7fb25eb0 100644 --- a/core/src/main/java/com/volmit/iris/util/scheduling/AR.java +++ b/core/src/main/java/com/volmit/iris/util/scheduling/AR.java @@ -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(); } } diff --git a/core/src/main/java/com/volmit/iris/util/scheduling/J.java b/core/src/main/java/com/volmit/iris/util/scheduling/J.java index 550b94092..3200737c9 100644 --- a/core/src/main/java/com/volmit/iris/util/scheduling/J.java +++ b/core/src/main/java/com/volmit/iris/util/scheduling/J.java @@ -26,11 +26,13 @@ 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 static void aBukkit(Runnable a) { if (!Bukkit.getPluginManager().isPluginEnabled(Iris.instance)) { return; } - Bukkit.getScheduler().scheduleAsyncDelayedTask(Iris.instance, a); + Iris.platform.getAsyncScheduler().run(a); } public static Future a(Callable a) { @@ -224,48 +226,36 @@ public static void s(Runnable r) { 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 CompletableFuture sfut(Supplier r) { - CompletableFuture 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 static void s(Runnable r, int delay) { 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 static void csr(int id) { * @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 void run() { * @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 static void car(int id) { * @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); } /** diff --git a/core/src/main/java/com/volmit/iris/util/scheduling/SR.java b/core/src/main/java/com/volmit/iris/util/scheduling/SR.java index bbb41cd85..a53c877a3 100644 --- a/core/src/main/java/com/volmit/iris/util/scheduling/SR.java +++ b/core/src/main/java/com/volmit/iris/util/scheduling/SR.java @@ -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(); + } } } diff --git a/core/src/main/java/com/volmit/iris/util/scheduling/jobs/Job.java b/core/src/main/java/com/volmit/iris/util/scheduling/jobs/Job.java index a378770b5..1b2408bba 100644 --- a/core/src/main/java/com/volmit/iris/util/scheduling/jobs/Job.java +++ b/core/src/main/java/com/volmit/iris/util/scheduling/jobs/Job.java @@ -63,7 +63,7 @@ default void execute(VolmitSender sender, Runnable whenComplete) { 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 @@ default void execute(VolmitSender sender, boolean silentMsg, Runnable whenComple } }, 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)); } diff --git a/core/src/main/java/com/volmit/iris/util/scheduling/jobs/ScanJob.java b/core/src/main/java/com/volmit/iris/util/scheduling/jobs/ScanJob.java new file mode 100644 index 000000000..42036fe7a --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/scheduling/jobs/ScanJob.java @@ -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 action; + private final int msPerTick, total; + private volatile Chunk chunk; + + public ScanJob(String name, + Cuboid cuboid, + int msPerTick, + BiConsumer 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(); + } +} diff --git a/core/src/main/resources/plugin.yml b/core/src/main/resources/plugin.yml index 99fa326be..5506ae2f1 100644 --- a/core/src/main/resources/plugin.yml +++ b/core/src/main/resources/plugin.yml @@ -8,4 +8,6 @@ description: More than a Dimension! commands: iris: aliases: [ ir, irs ] -api-version: '${apiVersion}' \ No newline at end of file +api-version: '${apiVersion}' +hotload-dependencies: false +folia-supported: true \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6f2bb9e04..309eca7ee 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -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" } diff --git a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java index 4b3d04f22..0963f9b64 100644 --- a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java +++ b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java @@ -24,7 +24,6 @@ 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 void deserializeTile(KMap map, Location pos) { 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) { diff --git a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java index d1db20679..872f9929e 100644 --- a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java +++ b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java @@ -232,7 +232,7 @@ public void deserializeTile(KMap map, Location pos) { 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) { diff --git a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java index 97f6adb54..2fa74ee99 100644 --- a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java +++ b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java @@ -232,7 +232,7 @@ public void deserializeTile(KMap map, Location pos) { 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) { diff --git a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java index fb6939c8d..149929802 100644 --- a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java +++ b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java @@ -37,7 +37,6 @@ 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 void deserializeTile(KMap map, Location pos) { 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) { diff --git a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java index 0738a5eea..a644c01c6 100644 --- a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java +++ b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java @@ -238,7 +238,7 @@ public void deserializeTile(KMap map, Location pos) { 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) { diff --git a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java index 1f14b42a2..1248635eb 100644 --- a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java +++ b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java @@ -232,7 +232,7 @@ public void deserializeTile(KMap map, Location pos) { 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) { diff --git a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java index 061a8effa..377859162 100644 --- a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java +++ b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java @@ -27,7 +27,6 @@ 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 void deserializeTile(KMap map, Location pos) { 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) { diff --git a/nms/v1_21_R4/src/main/java/com/volmit/iris/core/nms/v1_21_R4/NMSBinding.java b/nms/v1_21_R4/src/main/java/com/volmit/iris/core/nms/v1_21_R4/NMSBinding.java index 04d1acae2..7ed97c3f1 100644 --- a/nms/v1_21_R4/src/main/java/com/volmit/iris/core/nms/v1_21_R4/NMSBinding.java +++ b/nms/v1_21_R4/src/main/java/com/volmit/iris/core/nms/v1_21_R4/NMSBinding.java @@ -25,7 +25,6 @@ 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 void deserializeTile(KMap map, Location pos) { 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) { diff --git a/nms/v1_21_R5/src/main/java/com/volmit/iris/core/nms/v1_21_R5/NMSBinding.java b/nms/v1_21_R5/src/main/java/com/volmit/iris/core/nms/v1_21_R5/NMSBinding.java index e4e0f6808..de7639c72 100644 --- a/nms/v1_21_R5/src/main/java/com/volmit/iris/core/nms/v1_21_R5/NMSBinding.java +++ b/nms/v1_21_R5/src/main/java/com/volmit/iris/core/nms/v1_21_R5/NMSBinding.java @@ -220,7 +220,7 @@ public void deserializeTile(KMap map, Location pos) { 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) { diff --git a/settings.gradle.kts b/settings.gradle.kts index 18cbee3fe..16dbd2591 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -16,7 +16,7 @@ * along with this program. If not, see . */ 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"