mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-05-19 16:10:42 +00:00
canvas checks
This commit is contained in:
+2
-1
@@ -54,7 +54,7 @@ registerCustomOutputTask("PixelFury", "C://Users/repix/workplace/Iris/1.21.3 - D
|
|||||||
registerCustomOutputTask("PixelFuryDev", "C://Users/repix/workplace/Iris/1.21 - Development-v3/plugins")
|
registerCustomOutputTask("PixelFuryDev", "C://Users/repix/workplace/Iris/1.21 - Development-v3/plugins")
|
||||||
// ========================== UNIX ==============================
|
// ========================== UNIX ==============================
|
||||||
registerCustomOutputTaskUnix("CyberpwnLT", "/Users/danielmills/development/server/plugins")
|
registerCustomOutputTaskUnix("CyberpwnLT", "/Users/danielmills/development/server/plugins")
|
||||||
registerCustomOutputTaskUnix("PsychoLT", "/Users/brianfopiano/Developer/RemoteGit/[Minecraft Server]/plugin-jars")
|
registerCustomOutputTaskUnix("PsychoLT", "/Users/brianfopiano/Developer/RemoteGit/[Minecraft Server]/consumers/plugin-consumers/dropins/plugins")
|
||||||
registerCustomOutputTaskUnix("PixelMac", "/Users/test/Desktop/mcserver/plugins")
|
registerCustomOutputTaskUnix("PixelMac", "/Users/test/Desktop/mcserver/plugins")
|
||||||
registerCustomOutputTaskUnix("CrazyDev22LT", "/home/julian/Desktop/server/plugins")
|
registerCustomOutputTaskUnix("CrazyDev22LT", "/home/julian/Desktop/server/plugins")
|
||||||
// ==============================================================
|
// ==============================================================
|
||||||
@@ -228,6 +228,7 @@ allprojects {
|
|||||||
compileJava {
|
compileJava {
|
||||||
options.compilerArgs.add("-parameters")
|
options.compilerArgs.add("-parameters")
|
||||||
options.encoding = "UTF-8"
|
options.encoding = "UTF-8"
|
||||||
|
options.debugOptions.debugLevel = "none"
|
||||||
}
|
}
|
||||||
|
|
||||||
javadoc {
|
javadoc {
|
||||||
|
|||||||
@@ -174,6 +174,7 @@ tasks {
|
|||||||
compileJava {
|
compileJava {
|
||||||
options.compilerArgs.add("-parameters")
|
options.compilerArgs.add("-parameters")
|
||||||
options.encoding = "UTF-8"
|
options.encoding = "UTF-8"
|
||||||
|
options.debugOptions.debugLevel = "none"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1004,7 +1004,6 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void splash() {
|
public void splash() {
|
||||||
Iris.info("Server type & version: " + Bukkit.getName() + " v" + Bukkit.getVersion());
|
|
||||||
Iris.info("Custom Biomes: " + INMS.get().countCustomBiomes());
|
Iris.info("Custom Biomes: " + INMS.get().countCustomBiomes());
|
||||||
printPacks();
|
printPacks();
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ package art.arcane.iris.core.commands;
|
|||||||
import art.arcane.iris.Iris;
|
import art.arcane.iris.Iris;
|
||||||
import art.arcane.iris.core.IrisSettings;
|
import art.arcane.iris.core.IrisSettings;
|
||||||
import art.arcane.iris.core.IrisWorlds;
|
import art.arcane.iris.core.IrisWorlds;
|
||||||
|
import art.arcane.iris.core.link.FoliaWorldsLink;
|
||||||
import art.arcane.iris.core.loader.IrisData;
|
import art.arcane.iris.core.loader.IrisData;
|
||||||
import art.arcane.iris.core.nms.INMS;
|
import art.arcane.iris.core.nms.INMS;
|
||||||
import art.arcane.iris.core.service.StudioSVC;
|
import art.arcane.iris.core.service.StudioSVC;
|
||||||
@@ -545,7 +546,7 @@ public class CommandIris implements DirectorExecutor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Bukkit.unloadWorld(world, false)) {
|
if (!FoliaWorldsLink.get().unloadWorld(world, false)) {
|
||||||
sender().sendMessage(C.RED + "Failed to unload world: " + world.getName());
|
sender().sendMessage(C.RED + "Failed to unload world: " + world.getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1998,8 +1999,12 @@ public class CommandIris implements DirectorExecutor {
|
|||||||
sender().sendMessage(C.GREEN + "Unloading world: " + world.getName());
|
sender().sendMessage(C.GREEN + "Unloading world: " + world.getName());
|
||||||
try {
|
try {
|
||||||
IrisToolbelt.evacuate(world);
|
IrisToolbelt.evacuate(world);
|
||||||
Bukkit.unloadWorld(world, false);
|
boolean unloaded = FoliaWorldsLink.get().unloadWorld(world, false);
|
||||||
|
if (unloaded) {
|
||||||
sender().sendMessage(C.GREEN + "World unloaded successfully.");
|
sender().sendMessage(C.GREEN + "World unloaded successfully.");
|
||||||
|
} else {
|
||||||
|
sender().sendMessage(C.RED + "Failed to unload the world.");
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
sender().sendMessage(C.RED + "Failed to unload the world: " + e.getMessage());
|
sender().sendMessage(C.RED + "Failed to unload the world: " + e.getMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import java.util.Locale;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class FoliaWorldsLink {
|
public class FoliaWorldsLink {
|
||||||
private static volatile FoliaWorldsLink instance;
|
private static volatile FoliaWorldsLink instance;
|
||||||
@@ -136,6 +137,11 @@ public class FoliaWorldsLink {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CompletableFuture<Boolean> asyncWorldUnload = unloadWorldViaAsyncApi(world, save);
|
||||||
|
if (asyncWorldUnload != null) {
|
||||||
|
return resolveAsyncUnload(asyncWorldUnload);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Bukkit.unloadWorld(world, save);
|
return Bukkit.unloadWorld(world, save);
|
||||||
} catch (UnsupportedOperationException unsupported) {
|
} catch (UnsupportedOperationException unsupported) {
|
||||||
@@ -158,6 +164,67 @@ public class FoliaWorldsLink {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean resolveAsyncUnload(CompletableFuture<Boolean> asyncWorldUnload) {
|
||||||
|
if (J.isPrimaryThread()) {
|
||||||
|
if (!asyncWorldUnload.isDone()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return Boolean.TRUE.equals(asyncWorldUnload.join());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new IllegalStateException("Failed to consume async world unload result.", unwrap(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return Boolean.TRUE.equals(asyncWorldUnload.get(120, TimeUnit.SECONDS));
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new IllegalStateException("Failed while waiting for async world unload result.", unwrap(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<Boolean> unloadWorldViaAsyncApi(World world, boolean save) {
|
||||||
|
Object bukkitServer = Bukkit.getServer();
|
||||||
|
if (bukkitServer == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Method unloadWorldAsyncMethod;
|
||||||
|
try {
|
||||||
|
unloadWorldAsyncMethod = bukkitServer.getClass().getMethod("unloadWorldAsync", World.class, boolean.class, Consumer.class);
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
CompletableFuture<Boolean> callbackFuture = new CompletableFuture<>();
|
||||||
|
Runnable invokeTask = () -> {
|
||||||
|
Consumer<Boolean> callback = result -> callbackFuture.complete(Boolean.TRUE.equals(result));
|
||||||
|
try {
|
||||||
|
unloadWorldAsyncMethod.invoke(bukkitServer, world, save, callback);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
callbackFuture.completeExceptionally(unwrap(e));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (J.isFolia() && !isGlobalTickThread()) {
|
||||||
|
CompletableFuture<Void> scheduled = J.sfut(invokeTask);
|
||||||
|
if (scheduled == null) {
|
||||||
|
callbackFuture.completeExceptionally(new IllegalStateException("Failed to schedule global world-unload task."));
|
||||||
|
return callbackFuture;
|
||||||
|
}
|
||||||
|
scheduled.whenComplete((unused, throwable) -> {
|
||||||
|
if (throwable != null) {
|
||||||
|
callbackFuture.completeExceptionally(unwrap(throwable));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
invokeTask.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
return callbackFuture;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isWorldsProviderActive() {
|
private boolean isWorldsProviderActive() {
|
||||||
return provider != null && levelStemClass != null && generatorTypeClass != null;
|
return provider != null && levelStemClass != null && generatorTypeClass != null;
|
||||||
}
|
}
|
||||||
@@ -457,17 +524,7 @@ public class FoliaWorldsLink {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Server server = Bukkit.getServer();
|
if (isGlobalTickThread()) {
|
||||||
boolean globalThread = false;
|
|
||||||
if (server != null) {
|
|
||||||
try {
|
|
||||||
Method isGlobalTickThreadMethod = server.getClass().getMethod("isGlobalTickThread");
|
|
||||||
globalThread = (boolean) isGlobalTickThreadMethod.invoke(server);
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (globalThread) {
|
|
||||||
detachTask.run();
|
detachTask.run();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -479,9 +536,29 @@ public class FoliaWorldsLink {
|
|||||||
detachFuture.get(15, TimeUnit.SECONDS);
|
detachFuture.get(15, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isGlobalTickThread() {
|
||||||
|
Server server = Bukkit.getServer();
|
||||||
|
if (server == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Method isGlobalTickThreadMethod = server.getClass().getMethod("isGlobalTickThread");
|
||||||
|
return Boolean.TRUE.equals(isGlobalTickThreadMethod.invoke(server));
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Throwable unwrap(Throwable throwable) {
|
private static Throwable unwrap(Throwable throwable) {
|
||||||
if (throwable instanceof InvocationTargetException invocationTargetException && invocationTargetException.getCause() != null) {
|
if (throwable instanceof InvocationTargetException invocationTargetException && invocationTargetException.getCause() != null) {
|
||||||
return invocationTargetException.getCause();
|
return unwrap(invocationTargetException.getCause());
|
||||||
|
}
|
||||||
|
if (throwable instanceof java.util.concurrent.CompletionException completionException && completionException.getCause() != null) {
|
||||||
|
return unwrap(completionException.getCause());
|
||||||
|
}
|
||||||
|
if (throwable instanceof java.util.concurrent.ExecutionException executionException && executionException.getCause() != null) {
|
||||||
|
return unwrap(executionException.getCause());
|
||||||
}
|
}
|
||||||
return throwable;
|
return throwable;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ import java.io.IOException;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@SuppressWarnings("ALL")
|
@SuppressWarnings("ALL")
|
||||||
@@ -291,11 +292,45 @@ public class IrisProject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
J.attemptAsync(() -> IO.delete(folder));
|
J.attemptAsync(() -> deleteStudioFolderWithRetry(folder, worldName));
|
||||||
Iris.debug("Closed Active Provider " + worldName);
|
Iris.debug("Closed Active Provider " + worldName);
|
||||||
activeProvider = null;
|
activeProvider = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void deleteStudioFolderWithRetry(File folder, String worldName) {
|
||||||
|
if (folder == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
long unloadWaitDeadlineMs = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(20);
|
||||||
|
while (Bukkit.getWorld(worldName) != null && System.currentTimeMillis() < unloadWaitDeadlineMs) {
|
||||||
|
J.sleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
int attempts = 0;
|
||||||
|
while (folder.exists() && attempts < 40) {
|
||||||
|
IO.delete(folder);
|
||||||
|
if (!folder.exists()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
attempts++;
|
||||||
|
J.sleep(250);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!folder.exists()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Iris.queueWorldDeletionOnStartup(java.util.Collections.singleton(worldName));
|
||||||
|
Iris.warn("Queued deferred deletion for studio world folder \"" + worldName + "\".");
|
||||||
|
} catch (IOException e) {
|
||||||
|
Iris.warn("Failed to queue deferred deletion for studio world folder \"" + worldName + "\".");
|
||||||
|
Iris.reportError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public File getCodeWorkspaceFile() {
|
public File getCodeWorkspaceFile() {
|
||||||
return new File(path, getName() + ".code-workspace");
|
return new File(path, getName() + ".code-workspace");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package art.arcane.iris.core.tools;
|
|||||||
|
|
||||||
|
|
||||||
import art.arcane.iris.Iris;
|
import art.arcane.iris.Iris;
|
||||||
|
import art.arcane.iris.core.link.FoliaWorldsLink;
|
||||||
import art.arcane.iris.core.pregenerator.PregenTask;
|
import art.arcane.iris.core.pregenerator.PregenTask;
|
||||||
import art.arcane.iris.engine.framework.Engine;
|
import art.arcane.iris.engine.framework.Engine;
|
||||||
import art.arcane.iris.engine.object.IrisDimension;
|
import art.arcane.iris.engine.object.IrisDimension;
|
||||||
@@ -102,7 +103,7 @@ public class IrisPackBenchmarking {
|
|||||||
var world = Bukkit.getWorld("benchmark");
|
var world = Bukkit.getWorld("benchmark");
|
||||||
if (world == null) return;
|
if (world == null) return;
|
||||||
IrisToolbelt.evacuate(world);
|
IrisToolbelt.evacuate(world);
|
||||||
Bukkit.unloadWorld(world, true);
|
FoliaWorldsLink.get().unloadWorld(world, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
stopwatch.end();
|
stopwatch.end();
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import art.arcane.iris.Iris
|
|||||||
import art.arcane.iris.core.IrisSettings
|
import art.arcane.iris.core.IrisSettings
|
||||||
import art.arcane.iris.util.format.C
|
import art.arcane.iris.util.format.C
|
||||||
import art.arcane.volmlib.util.format.Form
|
import art.arcane.volmlib.util.format.Form
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
enum class Mode(private val color: C) {
|
enum class Mode(private val color: C) {
|
||||||
STABLE(C.IRIS),
|
STABLE(C.IRIS),
|
||||||
@@ -34,6 +37,11 @@ enum class Mode(private val color: C) {
|
|||||||
fun splash() {
|
fun splash() {
|
||||||
val padd = Form.repeat(" ", 8)
|
val padd = Form.repeat(" ", 8)
|
||||||
val padd2 = Form.repeat(" ", 4)
|
val padd2 = Form.repeat(" ", 4)
|
||||||
|
val version = Iris.instance.description.version
|
||||||
|
val releaseTrain = getReleaseTrain(version)
|
||||||
|
val serverVersion = getServerVersion()
|
||||||
|
val startupDate = getStartupDate()
|
||||||
|
val javaVersion = getJavaVersion()
|
||||||
|
|
||||||
val splash = arrayOf(
|
val splash = arrayOf(
|
||||||
padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@",
|
padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@",
|
||||||
@@ -51,14 +59,16 @@ enum class Mode(private val color: C) {
|
|||||||
|
|
||||||
val info = arrayOf(
|
val info = arrayOf(
|
||||||
"",
|
"",
|
||||||
|
padd2 + color + " Iris, " + C.AQUA + "Iris, Dimension Engine " + C.RED + "[" + releaseTrain + " RELEASE]",
|
||||||
|
padd2 + C.GRAY + " Version: " + color + version,
|
||||||
|
padd2 + C.GRAY + " By: " + color + "Arcane Arts (Volmit Software)",
|
||||||
|
padd2 + C.GRAY + " Server: " + color + serverVersion,
|
||||||
|
padd2 + C.GRAY + " Java: " + color + javaVersion + C.GRAY + " | Date: " + color + startupDate,
|
||||||
|
padd2 + C.GRAY + " Commit: " + color + BuildConstants.COMMIT + C.GRAY + "/" + color + BuildConstants.ENVIRONMENT,
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
padd2 + color + " Iris",
|
|
||||||
padd2 + C.GRAY + " by " + color + "Volmit Software",
|
|
||||||
padd2 + C.GRAY + " v" + color + Iris.instance.description.version,
|
|
||||||
padd2 + C.GRAY + " c" + color + BuildConstants.COMMIT + C.GRAY + "/" + color + BuildConstants.ENVIRONMENT,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -73,4 +83,43 @@ enum class Mode(private val color: C) {
|
|||||||
|
|
||||||
Iris.info(builder.toString())
|
Iris.info(builder.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getServerVersion(): String {
|
||||||
|
var version = Bukkit.getVersion()
|
||||||
|
val mcMarkerIndex = version.indexOf(" (MC:")
|
||||||
|
if (mcMarkerIndex != -1) {
|
||||||
|
version = version.substring(0, mcMarkerIndex)
|
||||||
|
}
|
||||||
|
return version
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getJavaVersion(): Int {
|
||||||
|
var version = System.getProperty("java.version")
|
||||||
|
if (version.startsWith("1.")) {
|
||||||
|
version = version.substring(2, 3)
|
||||||
|
} else {
|
||||||
|
val dot = version.indexOf(".")
|
||||||
|
if (dot != -1) {
|
||||||
|
version = version.substring(0, dot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return version.toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getStartupDate(): String {
|
||||||
|
return LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getReleaseTrain(version: String): String {
|
||||||
|
var value = version
|
||||||
|
val suffixIndex = value.indexOf("-")
|
||||||
|
if (suffixIndex >= 0) {
|
||||||
|
value = value.substring(0, suffixIndex)
|
||||||
|
}
|
||||||
|
val split = value.split('.')
|
||||||
|
if (split.size >= 2) {
|
||||||
|
return split[0] + "." + split[1]
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -56,6 +56,7 @@ private val incompatibilities by task {
|
|||||||
|
|
||||||
private val software by task {
|
private val software by task {
|
||||||
val supported = setOf(
|
val supported = setOf(
|
||||||
|
"canvas",
|
||||||
"folia",
|
"folia",
|
||||||
"purpur",
|
"purpur",
|
||||||
"pufferfish",
|
"pufferfish",
|
||||||
@@ -64,10 +65,10 @@ private val software by task {
|
|||||||
"bukkit"
|
"bukkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
if (supported.any { server.name.contains(it, true) }) STABLE.withDiagnostics()
|
if (isCanvasServer() || supported.any { server.name.contains(it, true) }) STABLE.withDiagnostics()
|
||||||
else WARNING.withDiagnostics(
|
else WARNING.withDiagnostics(
|
||||||
WARN.create("Unsupported Server Software"),
|
WARN.create("Unsupported Server Software"),
|
||||||
WARN.create("- Please consider using Folia, Paper, or Purpur instead.")
|
WARN.create("- Please consider using Canvas, Folia, Paper, or Purpur instead.")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +89,7 @@ private val injection by task {
|
|||||||
WARNING.withDiagnostics(
|
WARNING.withDiagnostics(
|
||||||
WARN.create("Java Agent"),
|
WARN.create("Java Agent"),
|
||||||
WARN.create("- Skipping dynamic Java agent attach on Spigot/Bukkit to avoid runtime agent warnings."),
|
WARN.create("- Skipping dynamic Java agent attach on Spigot/Bukkit to avoid runtime agent warnings."),
|
||||||
WARN.create("- For full runtime injection support, run with -javaagent:" + Agent.AGENT_JAR.path + " or use Paper/Purpur.")
|
WARN.create("- For full runtime injection support, run with -javaagent:" + Agent.AGENT_JAR.path + " or use Canvas/Folia/Paper/Purpur.")
|
||||||
)
|
)
|
||||||
} else if (!Agent.install()) UNSTABLE.withDiagnostics(
|
} else if (!Agent.install()) UNSTABLE.withDiagnostics(
|
||||||
ERROR.create("Java Agent"),
|
ERROR.create("Java Agent"),
|
||||||
@@ -154,7 +155,20 @@ val tasks = listOf(
|
|||||||
private val server get() = Bukkit.getServer()
|
private val server get() = Bukkit.getServer()
|
||||||
private fun isPaperPreferredServer(): Boolean {
|
private fun isPaperPreferredServer(): Boolean {
|
||||||
val name = server.name.lowercase(Locale.ROOT)
|
val name = server.name.lowercase(Locale.ROOT)
|
||||||
return name.contains("folia") || name.contains("paper") || name.contains("purpur") || name.contains("pufferfish")
|
return isCanvasServer()
|
||||||
|
|| name.contains("folia")
|
||||||
|
|| name.contains("paper")
|
||||||
|
|| name.contains("purpur")
|
||||||
|
|| name.contains("pufferfish")
|
||||||
|
}
|
||||||
|
private fun isCanvasServer(): Boolean {
|
||||||
|
val loader: ClassLoader? = server.javaClass.classLoader
|
||||||
|
return try {
|
||||||
|
Class.forName("io.canvasmc.canvas.region.WorldRegionizer", false, loader)
|
||||||
|
true
|
||||||
|
} catch (_: Throwable) {
|
||||||
|
server.name.contains("canvas", true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private fun <T> MutableList<T>.addAll(vararg values: T) = values.forEach(this::add)
|
private fun <T> MutableList<T>.addAll(vararg values: T) = values.forEach(this::add)
|
||||||
fun task(action: () -> ValueWithDiagnostics<Mode>) = PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, Task>> { _, _ ->
|
fun task(action: () -> ValueWithDiagnostics<Mode>) = PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, Task>> { _, _ ->
|
||||||
|
|||||||
Reference in New Issue
Block a user