diff --git a/build.gradle.kts b/build.gradle.kts index 417008f79..4c8e42a3f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -62,7 +62,7 @@ val serverMinHeap = "2G" val serverMaxHeap = "8G" //Valid values are: none, truecolor, indexed256, indexed16, indexed8 val color = "truecolor" -val errorReporting = findProperty("errorReporting") as Boolean? ?: false +val errorReporting = "true" == findProperty("errorReporting") val nmsBindings = mapOf( "v1_21_R5" to "1.21.8-R0.1-SNAPSHOT", @@ -76,7 +76,7 @@ val nmsBindings = mapOf( "v1_20_R1" to "1.20.1-R0.1-SNAPSHOT", ) val jvmVersion = mapOf() -nmsBindings.forEach { key, value -> +nmsBindings.forEach { (key, value) -> project(":nms:$key") { apply() apply() @@ -112,7 +112,7 @@ nmsBindings.forEach { key, value -> tasks { jar { duplicatesStrategy = DuplicatesStrategy.EXCLUDE - nmsBindings.forEach { key, _ -> + nmsBindings.forEach { (key, _) -> from(project(":nms:$key").tasks.named("remap").map { zipTree(it.outputs.files.singleFile) }) } from(project(":core").tasks.shadowJar.flatMap { it.archiveFile }.map { zipTree(it) }) diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 8e4894bd4..e5faab614 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -184,10 +184,10 @@ val generateTemplates = tasks.register("generateTemplates") { "commit" to provider { val res = runCatching { project.extensions.getByType().head().id } res.getOrDefault("") - .takeIf { it.length == 40 } ?: { - logger.error("Git commit hash not found", res.exceptionOrNull()) + .takeIf { it.length == 40 } ?: run { + this.logger.error("Git commit hash not found", res.exceptionOrNull()) "unknown" - }() + } }, ) diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index 14607fdba..463a85ff3 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -28,7 +28,6 @@ import com.volmit.iris.core.link.MultiverseCoreLink; import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.nms.INMS; -import com.volmit.iris.core.nms.v1X.NMSBinding1X; import com.volmit.iris.core.pregenerator.LazyPregenerator; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.core.tools.IrisToolbelt; @@ -43,7 +42,6 @@ import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.exceptions.IrisException; import com.volmit.iris.util.format.C; -import com.volmit.iris.util.format.Form; import com.volmit.iris.util.function.NastyRunnable; import com.volmit.iris.util.io.FileWatcher; import com.volmit.iris.util.io.IO; @@ -53,7 +51,6 @@ import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.misc.Bindings; import com.volmit.iris.util.misc.SlimJar; -import com.volmit.iris.util.misc.getHardware; import com.volmit.iris.util.parallel.MultiBurst; import com.volmit.iris.util.plugin.IrisService; import com.volmit.iris.util.plugin.VolmitPlugin; @@ -83,9 +80,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import static com.volmit.iris.core.safeguard.IrisSafeguard.*; -import static com.volmit.iris.core.safeguard.ServerBootSFG.passedserversoftware; - @SuppressWarnings("CanBeFinal") public class Iris extends VolmitPlugin implements Listener { private static final Queue syncJobs = new ShurikenQueue<>(); @@ -306,9 +300,6 @@ public static void success(String string) { public static void info(String format, Object... args) { msg(C.WHITE + String.format(format, args)); } - public static void safeguard(String format, Object... args) { - msg(C.RESET + String.format(format, args)); - } @SuppressWarnings("deprecation") public static void later(NastyRunnable object) { @@ -447,16 +438,15 @@ private void enable() { IO.delete(new File("iris")); compat = IrisCompat.configured(getDataFile("compat.json")); ServerConfigurator.configure(); - IrisSafeguard.IrisSafeguardSystem(); + IrisSafeguard.execute(); getSender().setTag(getTag()); - IrisSafeguard.splash(true); + IrisSafeguard.splash(); linkMultiverseCore = new MultiverseCoreLink(); configWatcher = new FileWatcher(getDataFile("settings.json")); services.values().forEach(IrisService::onEnable); services.values().forEach(this::registerListener); addShutdownHook(); J.s(() -> { - J.a(IrisSafeguard::suggestPaper); J.a(() -> IO.delete(getTemp())); J.a(LazyPregenerator::loadLazyGenerators, 100); J.a(this::bstats); @@ -464,7 +454,6 @@ private void enable() { J.sr(this::tickQueue, 0); J.s(this::setupPapi); J.a(ServerConfigurator::configure, 20); - IrisSafeguard.splash(false); autoStartStudio(); checkForBukkitWorlds(s -> true); @@ -557,10 +546,10 @@ public void onEnable() { enable(); super.onEnable(); Bukkit.getPluginManager().registerEvents(this, this); - setupChecks(); } public void onDisable() { + if (IrisSafeguard.isForceShutdown()) return; services.values().forEach(IrisService::onDisable); Bukkit.getScheduler().cancelTasks(this); HandlerList.unregisterAll((Plugin) this); @@ -588,49 +577,7 @@ public void stop() { @Override public String getTag(String subTag) { - if (unstablemode) { - return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.RED + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": "; - } - if (warningmode) { - return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.GOLD + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": "; - } - return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.IRIS + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": "; - - } - - private boolean setupChecks() { - boolean passed = true; - Iris.info("Version Information: " + instance.getServer().getVersion() + " | " + instance.getServer().getBukkitVersion()); - if (INMS.get() instanceof NMSBinding1X) { - passed = false; - Iris.warn("============================================"); - Iris.warn("="); - Iris.warn("="); - Iris.warn("="); - Iris.warn("Iris is not compatible with this version of Minecraft."); - Iris.warn("="); - Iris.warn("="); - Iris.warn("="); - Iris.warn("============================================"); - } - - try { - Class.forName("io.papermc.paper.configuration.PaperConfigurations"); - } catch (ClassNotFoundException e) { - Iris.info(C.RED + "Iris requires paper or above to function properly.."); - return false; - } - - try { - Class.forName("org.purpurmc.purpur.PurpurConfig"); - } catch (ClassNotFoundException e) { - Iris.info("We recommend using Purpur for the best experience with Iris."); - Iris.info("Purpur is a fork of Paper that is optimized for performance and stability."); - Iris.info("Plugins that work on Spigot / Paper work on Purpur."); - Iris.info("You can download it here: https://purpurmc.org"); - return false; - } - return passed; + return IrisSafeguard.mode().tag(subTag); } private void checkConfigHotload() { @@ -738,88 +685,11 @@ public static IrisDimension loadDimension(@NonNull String worldName, @NonNull St } public void splash() { - if (!IrisSettings.get().getGeneral().isSplashLogoStartup()) { - return; - } - - String padd = Form.repeat(" ", 8); - String padd2 = Form.repeat(" ", 4); - String[] info = {"", "", "", "", "", padd2 + C.IRIS + " Iris", padd2 + C.GRAY + " by " + "Volmit Software", padd2 + C.GRAY + " v" + C.IRIS + getDescription().getVersion()}; - if (unstablemode) { - info = new String[]{"", "", "", "", "", padd2 + C.RED + " Iris", padd2 + C.GRAY + " by " + C.DARK_RED + "Volmit Software", padd2 + C.GRAY + " v" + C.RED + getDescription().getVersion()}; - } - if (warningmode) { - info = new String[]{"", "", "", "", "", padd2 + C.GOLD + " Iris", padd2 + C.GRAY + " by " + C.GOLD + "Volmit Software", padd2 + C.GRAY + " v" + C.GOLD + getDescription().getVersion()}; - } - - String[] splashstable = { - padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@", - padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + C.IRIS + " .(((()))). ", - padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + C.IRIS + " .((((((())))))). ", - padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + C.IRIS + " ((((((((())))))))) " + C.GRAY + " @", - padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + C.IRIS + " ((((((((-))))))))) " + C.GRAY + " @@", - padd + C.GRAY + "@@@&&" + C.IRIS + " ((((((({ })))))))) " + C.GRAY + " &&@@@", - padd + C.GRAY + "@@" + C.IRIS + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@", - padd + C.GRAY + "@" + C.IRIS + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@", - padd + C.GRAY + "" + C.IRIS + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@", - padd + C.GRAY + "" + C.IRIS + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@", - padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@" - }; - - String[] splashunstable = { - padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@", - padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + C.RED + " .(((()))). ", - padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + C.RED + " .((((((())))))). ", - padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + C.RED + " ((((((((())))))))) " + C.GRAY + " @", - padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + C.RED + " ((((((((-))))))))) " + C.GRAY + " @@", - padd + C.GRAY + "@@@&&" + C.RED + " ((((((({ })))))))) " + C.GRAY + " &&@@@", - padd + C.GRAY + "@@" + C.RED + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@", - padd + C.GRAY + "@" + C.RED + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@", - padd + C.GRAY + "" + C.RED + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@", - padd + C.GRAY + "" + C.RED + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@", - padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@" - }; - String[] splashwarning = { - padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@", - padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + C.GOLD + " .(((()))). ", - padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + C.GOLD + " .((((((())))))). ", - padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + C.GOLD + " ((((((((())))))))) " + C.GRAY + " @", - padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + C.GOLD + " ((((((((-))))))))) " + C.GRAY + " @@", - padd + C.GRAY + "@@@&&" + C.GOLD + " ((((((({ })))))))) " + C.GRAY + " &&@@@", - padd + C.GRAY + "@@" + C.GOLD + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@", - padd + C.GRAY + "@" + C.GOLD + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@", - padd + C.GRAY + "" + C.GOLD + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@", - padd + C.GRAY + "" + C.GOLD + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@", - padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@" - }; - String[] splash; - File freeSpace = new File(Bukkit.getWorldContainer() + "."); - if (unstablemode) { - splash = splashunstable; - } else if (warningmode) { - splash = splashwarning; - } else { - splash = splashstable; - } - - if (!passedserversoftware) { - Iris.info("Server type & version: " + C.RED + Bukkit.getVersion()); - } else { Iris.info("Server type & version: " + Bukkit.getVersion()); } - Iris.info("Java: " + getJava()); - if (getHardware.getProcessMemory() < 5999) { - Iris.warn("6GB+ Ram is recommended"); - Iris.warn("Process Memory: " + getHardware.getProcessMemory() + " MB"); - } - Iris.info("Bukkit distro: " + Bukkit.getName()); + Iris.info("Server type & version: " + Bukkit.getName() + " v" + Bukkit.getVersion()); Iris.info("Custom Biomes: " + INMS.get().countCustomBiomes()); - setupChecks(); printPacks(); - for (int i = 0; i < info.length; i++) { - splash[i] += info[i]; - } - - Iris.info("\n\n " + new KList<>(splash).toString("\n") + "\n"); + IrisSafeguard.mode().trySplash(); } private void printPacks() { diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/IrisSafeguard.java b/core/src/main/java/com/volmit/iris/core/safeguard/IrisSafeguard.java deleted file mode 100644 index bef5f165a..000000000 --- a/core/src/main/java/com/volmit/iris/core/safeguard/IrisSafeguard.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.volmit.iris.core.safeguard; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; -import io.papermc.lib.PaperLib; - -import java.util.concurrent.atomic.AtomicBoolean; - -public class IrisSafeguard { - private static final AtomicBoolean sfg = new AtomicBoolean(false); - public static boolean unstablemode = false; - public static boolean warningmode = false; - public static boolean stablemode = false; - - public static void IrisSafeguardSystem() { - Iris.info("Enabled Iris SafeGuard"); - ServerBootSFG.BootCheck(); - } - - public static void splash(boolean early) { - if (early && (ServerBootSFG.safeguardPassed || IrisSettings.get().getGeneral().DoomsdayAnnihilationSelfDestructMode)) - return; - - if (!sfg.getAndSet(true)) { - Iris.instance.splash(); - UtilsSFG.splash(); - } - } - - public static String mode() { - if (unstablemode) { - return "unstable"; - } else if (warningmode) { - return "warning"; - } else { - return "stable"; - } - } - - public static void suggestPaper() { - PaperLib.suggestPaper(Iris.instance); - } - - public static KMap asContext() { - KMap m = new KMap<>(); - m.put("diskSpace", !ServerBootSFG.hasEnoughDiskSpace); - m.put("javaVersion", !ServerBootSFG.isCorrectJDK); - m.put("jre", ServerBootSFG.isJRE); - m.put("missingAgent", ServerBootSFG.missingAgent); - m.put("missingDimensionTypes", ServerBootSFG.missingDimensionTypes); - m.put("failedInjection", ServerBootSFG.failedInjection); - m.put("unsupportedVersion", ServerBootSFG.unsuportedversion); - m.put("serverSoftware", !ServerBootSFG.passedserversoftware); - KList incompatiblePlugins = new KList<>(); - ServerBootSFG.incompatibilities.forEach((plugin, present) -> { - if (present) incompatiblePlugins.add(plugin); - }); - m.put("plugins", incompatiblePlugins); - return m; - } -} - diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/ModesSFG.java b/core/src/main/java/com/volmit/iris/core/safeguard/ModesSFG.java deleted file mode 100644 index 17c55e13d..000000000 --- a/core/src/main/java/com/volmit/iris/core/safeguard/ModesSFG.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.volmit.iris.core.safeguard; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.util.format.C; - -public class ModesSFG { - public static void selectMode() { - if (IrisSafeguard.unstablemode) { - Iris.safeguard(C.DARK_RED + "Iris is running in Unstable Mode"); - unstable(); - } - if (IrisSafeguard.warningmode) { - Iris.safeguard(C.GOLD + "Iris is running in Warning Mode"); - warning(); - } - if (IrisSafeguard.stablemode) { - stable(); - } - } - - public static void stable() { - Iris.safeguard(C.BLUE + "Iris is running Stable"); - } - - public static void unstable() { - - UtilsSFG.printIncompatibleWarnings(); - - if (IrisSafeguard.unstablemode) { - Iris.info(""); - Iris.info(C.DARK_GRAY + "--==<" + C.RED + " IMPORTANT " + C.DARK_GRAY + ">==--"); - Iris.info(C.RED + "Iris is running in unstable mode which may cause the following issues:"); - Iris.info(C.DARK_RED + "Server Issues"); - Iris.info(C.RED + "- Server won't boot"); - Iris.info(C.RED + "- Data Loss"); - Iris.info(C.RED + "- Unexpected behavior."); - Iris.info(C.RED + "- And More..."); - Iris.info(C.DARK_RED + "World Issues"); - Iris.info(C.RED + "- Worlds can't load due to corruption."); - Iris.info(C.RED + "- Worlds may slowly corrupt until they can't load."); - Iris.info(C.RED + "- World data loss."); - Iris.info(C.RED + "- And More..."); - Iris.info(C.DARK_RED + "ATTENTION: " + C.RED + "While running Iris in unstable mode, you won't be eligible for support."); - Iris.info(C.DARK_RED + "CAUSE: " + C.RED + UtilsSFG.MSGIncompatibleWarnings()); - - if (IrisSettings.get().getGeneral().DoomsdayAnnihilationSelfDestructMode) { - Iris.info(C.DARK_RED + "Boot Unstable is set to true, continuing with the startup process."); - } else { - Iris.info(C.DARK_RED + "Go to plugins/iris/settings.json and set DoomsdayAnnihilationSelfDestructMode to true if you wish to proceed."); - while (true) { - try { - Thread.sleep(Long.MAX_VALUE); - } catch (InterruptedException e) { - // no - } - } - } - Iris.info(""); - } - } - - public static void warning() { - - UtilsSFG.printIncompatibleWarnings(); - - if (IrisSafeguard.warningmode) { - Iris.info(""); - Iris.info(C.DARK_GRAY + "--==<" + C.GOLD + " IMPORTANT " + C.DARK_GRAY + ">==--"); - Iris.info(C.GOLD + "Iris is running in warning mode which may cause the following issues:"); - Iris.info(C.YELLOW + "- Data Loss"); - Iris.info(C.YELLOW + "- Errors"); - Iris.info(C.YELLOW + "- Broken worlds"); - Iris.info(C.YELLOW + "- Unexpected behavior."); - Iris.info(C.YELLOW + "- And perhaps further complications."); - Iris.info(C.GOLD + "CAUSE: " + C.YELLOW + UtilsSFG.MSGIncompatibleWarnings()); - Iris.info(""); - } - } -} diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/PerformanceSFG.java b/core/src/main/java/com/volmit/iris/core/safeguard/PerformanceSFG.java deleted file mode 100644 index 90aab8cf5..000000000 --- a/core/src/main/java/com/volmit/iris/core/safeguard/PerformanceSFG.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.volmit.iris.core.safeguard; - -public class PerformanceSFG { - public static void calculatePerformance() { - - - } -} diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java b/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java deleted file mode 100644 index 50de28b29..000000000 --- a/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java +++ /dev/null @@ -1,194 +0,0 @@ -package com.volmit.iris.core.safeguard; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisWorlds; -import com.volmit.iris.core.nms.INMS; -import com.volmit.iris.core.nms.v1X.NMSBinding1X; -import com.volmit.iris.engine.object.IrisDimension; -import com.volmit.iris.util.agent.Agent; -import com.volmit.iris.util.collection.KSet; -import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.PluginManager; -import javax.tools.JavaCompiler; -import javax.tools.ToolProvider; -import java.io.File; -import java.nio.channels.FileChannel; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.*; -import java.util.stream.Collectors; - -import static com.volmit.iris.Iris.getJavaVersion; -import static com.volmit.iris.core.safeguard.IrisSafeguard.*; - -public class ServerBootSFG { - public static final Map incompatibilities = new HashMap<>(); - public static boolean isCorrectJDK = true; - public static boolean hasEnoughDiskSpace = true; - public static boolean isJRE = false; - public static boolean hasPrivileges = true; - public static boolean unsuportedversion = false; - public static boolean missingDimensionTypes = false; - public static boolean missingAgent = false; - public static boolean failedInjection = false; - protected static boolean safeguardPassed; - public static boolean passedserversoftware = true; - protected static int count; - protected static byte severityLow; - protected static byte severityMedium; - protected static byte severityHigh; - public static String allIncompatibilities; - - public static void BootCheck() { - Iris.info("Checking for possible conflicts.."); - PluginManager pluginManager = Bukkit.getPluginManager(); - Plugin[] plugins = pluginManager.getPlugins(); - - incompatibilities.clear(); - incompatibilities.put("dynmap", false); - incompatibilities.put("Stratos", false); - - String pluginName; - for (Plugin plugin : plugins) { - pluginName = plugin.getName(); - Boolean flag = incompatibilities.get(pluginName); - if (flag != null && !flag) { - severityHigh++; - incompatibilities.put(pluginName, true); - } - } - - StringJoiner joiner = new StringJoiner(", "); - for (Map.Entry entry : incompatibilities.entrySet()) { - if (entry.getValue()) { - joiner.add(entry.getKey()); - } - } - // Legacy ServerInfo - String distro = Bukkit.getName().toLowerCase(); - if ( - !distro.contains("purpur") && - !distro.contains("paper") && - !distro.contains("spigot") && - !distro.contains("pufferfish") && - !distro.contains("bukkit")) { - - - passedserversoftware = false; - joiner.add("Server Software"); - severityMedium++; - } - - - if (INMS.get() instanceof NMSBinding1X) { - unsuportedversion = true; - joiner.add("Unsupported Minecraft Version"); - severityHigh++; - } - - if (!List.of(21).contains(getJavaVersion())) { - isCorrectJDK = false; - joiner.add("Unsupported Java version"); - severityMedium++; - } - - if (!isJDK()) { - isJRE = true; - joiner.add("Unsupported JDK"); - severityMedium++; - } - -// if (!hasPrivileges()){ -// hasPrivileges = false; -// joiner.add("Insufficient Privileges"); -// severityMedium++; -// } Some servers dont like this - - if (!enoughDiskSpace()){ - hasEnoughDiskSpace = false; - joiner.add("Insufficient Disk Space"); - severityMedium++; - } - - if (!Agent.install()) { - missingAgent = true; - joiner.add("Missing Java Agent"); - severityHigh++; - } else { - if (missingDimensionTypes()) { - missingDimensionTypes = true; - joiner.add("Missing Dimension Types"); - severityHigh++; - } - if (!INMS.get().injectBukkit()) { - failedInjection = true; - joiner.add("Failed Bukkit Injection"); - severityHigh++; - } - } - - allIncompatibilities = joiner.toString(); - - safeguardPassed = (severityHigh == 0 && severityMedium == 0 && severityLow == 0); - count = severityHigh + severityMedium + severityLow; - if (safeguardPassed) { - stablemode = true; - Iris.safeguard("Stable mode has been activated."); - } - if (!safeguardPassed) { - if (severityMedium >= 1 && severityHigh == 0) { - warningmode = true; - Iris.safeguard("Warning mode has been activated."); - } - if (severityHigh >= 1) { - unstablemode = true; - Iris.safeguard("Unstable mode has been activated."); - } - } - } - - - public static boolean isJDK() { - try { - JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - // If the compiler is null, it means this is a JRE environment, not a JDK. - return compiler != null; - } catch (Exception ignored) {} - return false; - } - public static boolean hasPrivileges() { - Path pv = Paths.get(Bukkit.getWorldContainer() + "iristest.json"); - try (FileChannel fc = FileChannel.open(pv, StandardOpenOption.CREATE, StandardOpenOption.DELETE_ON_CLOSE, StandardOpenOption.READ, StandardOpenOption.WRITE)) { - if (Files.isReadable(pv) && Files.isWritable(pv)) { - return true; - } - } catch (Exception e) { - return false; - } - return false; - } - - public static boolean enoughDiskSpace() { - File freeSpace = Bukkit.getWorldContainer(); - double gigabytes = freeSpace.getFreeSpace() / (1024.0 * 1024.0 * 1024.0); - return gigabytes > 3; - } - - private static boolean checkJavac(String path) { - return !path.isEmpty() && (new File(path, "javac").exists() || new File(path, "javac.exe").exists()); - } - - private static boolean missingDimensionTypes() { - return INMS.get().missingDimensionTypes(getDimensionTypes().toArray(String[]::new)); - } - - private static KSet getDimensionTypes() { - return IrisWorlds.get() - .getDimensions() - .map(IrisDimension::getDimensionTypeKey) - .collect(Collectors.toCollection(KSet::new)); - } -} diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java b/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java deleted file mode 100644 index 064f48db0..000000000 --- a/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.volmit.iris.core.safeguard; - -import com.volmit.iris.Iris; -import com.volmit.iris.util.agent.Agent; -import com.volmit.iris.util.format.C; - -public class UtilsSFG { - public static void splash() { - ModesSFG.selectMode(); - } - - public static void printIncompatibleWarnings() { - String[] parts = Iris.instance.getDescription().getVersion().split("-"); - String minVersion = parts[1]; - String maxVersion = parts[2]; - - if (ServerBootSFG.safeguardPassed) { - Iris.safeguard(C.BLUE + "0 Conflicts found"); - } else { - if (IrisSafeguard.unstablemode) { - Iris.safeguard(C.DARK_RED + "" + ServerBootSFG.count + " Conflicts found"); - } - if (IrisSafeguard.warningmode) { - Iris.safeguard(C.YELLOW + "" + ServerBootSFG.count + " Conflicts found"); - } - - if (ServerBootSFG.incompatibilities.get("dynmap")) { - Iris.safeguard(C.RED + "Dynmap"); - Iris.safeguard(C.RED + "- The plugin Dynmap is not compatible with the server."); - Iris.safeguard(C.RED + "- If you want to have a map plugin like Dynmap, consider Bluemap."); - } - if (ServerBootSFG.incompatibilities.get("Stratos")) { - Iris.safeguard(C.YELLOW + "Stratos"); - Iris.safeguard(C.YELLOW + "- Iris is not compatible with other worldgen plugins."); - } - if (ServerBootSFG.unsuportedversion) { - Iris.safeguard(C.RED + "Server Version"); - Iris.safeguard(C.RED + "- Iris only supports " + minVersion + " > " + maxVersion); - } - if (ServerBootSFG.missingDimensionTypes) { - Iris.safeguard(C.RED + "Dimension Types"); - Iris.safeguard(C.RED + "- Required Iris dimension types were not loaded."); - Iris.safeguard(C.RED + "- If this still happens after a restart please contact support."); - } - if (ServerBootSFG.missingAgent) { - Iris.safeguard(C.RED + "Java Agent"); - Iris.safeguard(C.RED + "- Please enable dynamic agent loading by adding -XX:+EnableDynamicAgentLoading to your jvm arguments."); - Iris.safeguard(C.RED + "- or add the jvm argument -javaagent:" + Agent.AGENT_JAR.getPath()); - } - if (!ServerBootSFG.passedserversoftware) { - Iris.safeguard(C.YELLOW + "Unsupported Server Software"); - Iris.safeguard(C.YELLOW + "- Please consider using Paper or Purpur instead."); - } - if (!ServerBootSFG.hasPrivileges) { - Iris.safeguard(C.YELLOW + "Insufficient Privileges"); - Iris.safeguard(C.YELLOW + "- The server has insufficient Privileges to run iris. Please contact support."); - } - if (!ServerBootSFG.hasEnoughDiskSpace) { - Iris.safeguard(C.YELLOW + "Insufficient Disk Space"); - Iris.safeguard(C.YELLOW + "- The server has insufficient Free DiskSpace to run iris required 3GB+."); - } - if (!ServerBootSFG.isCorrectJDK) { - Iris.safeguard(C.YELLOW + "Unsupported java version"); - Iris.safeguard(C.YELLOW + "- Please consider using JDK 21 Instead of JDK " + Iris.getJavaVersion()); - } - if (ServerBootSFG.isJRE) { - Iris.safeguard(C.YELLOW + "Unsupported Server JDK"); - Iris.safeguard(C.YELLOW + "- Please consider using JDK 21 Instead of JRE " + Iris.getJavaVersion()); - } - } - } - - public static String MSGIncompatibleWarnings() { - return ServerBootSFG.allIncompatibilities; - } -} diff --git a/core/src/main/java/com/volmit/iris/util/format/C.java b/core/src/main/java/com/volmit/iris/util/format/C.java index 85deb3cac..c33d52032 100644 --- a/core/src/main/java/com/volmit/iris/util/format/C.java +++ b/core/src/main/java/com/volmit/iris/util/format/C.java @@ -20,6 +20,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.util.plugin.VolmitSender; +import net.kyori.adventure.text.minimessage.MiniMessage; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.TextComponent; import org.apache.commons.lang.Validate; @@ -495,6 +496,14 @@ public static String stripColor(final String input) { return STRIP_COLOR_PATTERN.matcher(input).replaceAll(""); } + public static String strip(final String input) { + if (input == null) { + return null; + } + + return MiniMessage.miniMessage().stripTags(stripColor(input)); + } + /** * DyeColor to ChatColor * diff --git a/core/src/main/java/com/volmit/iris/util/misc/Bindings.java b/core/src/main/java/com/volmit/iris/util/misc/Bindings.java index d48879151..d26e924dc 100644 --- a/core/src/main/java/com/volmit/iris/util/misc/Bindings.java +++ b/core/src/main/java/com/volmit/iris/util/misc/Bindings.java @@ -56,7 +56,7 @@ public static void setupSentry() { options.setEnvironment(BuildConstants.ENVIRONMENT); options.setBeforeSend((event, hint) -> { if (suppress(event.getThrowable())) return null; - event.setTag("iris.safeguard", IrisSafeguard.mode()); + event.setTag("iris.safeguard", IrisSafeguard.mode().getId()); event.setTag("iris.nms", INMS.get().getClass().getCanonicalName()); var context = IrisContext.get(); if (context != null) event.getContexts().set("engine", context.asContext()); @@ -67,6 +67,7 @@ public static void setupSentry() { Sentry.configureScope(scope -> { if (settings.includeServerId) scope.setUser(ServerID.asUser()); scope.addAttachment(Attachments.PLUGINS); + scope.addAttachment(Attachments.SAFEGUARD); scope.setTag("server", Bukkit.getVersion()); scope.setTag("server.type", Bukkit.getName()); scope.setTag("server.api", Bukkit.getBukkitVersion()); diff --git a/core/src/main/java/com/volmit/iris/util/sentry/Attachments.java b/core/src/main/java/com/volmit/iris/util/sentry/Attachments.java index a338ea6ce..d6dbcccfa 100644 --- a/core/src/main/java/com/volmit/iris/util/sentry/Attachments.java +++ b/core/src/main/java/com/volmit/iris/util/sentry/Attachments.java @@ -2,6 +2,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.volmit.iris.core.safeguard.IrisSafeguard; import com.volmit.iris.util.collection.KMap; import io.sentry.Attachment; import org.bukkit.Bukkit; @@ -12,6 +13,7 @@ public class Attachments { private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create(); public static final Attachment PLUGINS = jsonProvider(Attachments::plugins, "plugins.json"); + public static final Attachment SAFEGUARD = jsonProvider(IrisSafeguard::asAttachment, "safeguard.json"); public static Attachment json(Object object, String name) { return new Attachment(GSON.toJson(object).getBytes(StandardCharsets.UTF_8), name, "application/json", "event.attachment", true); diff --git a/core/src/main/kotlin/com/volmit/iris/core/safeguard/IrisSafeguard.kt b/core/src/main/kotlin/com/volmit/iris/core/safeguard/IrisSafeguard.kt new file mode 100644 index 000000000..0c9d66c4e --- /dev/null +++ b/core/src/main/kotlin/com/volmit/iris/core/safeguard/IrisSafeguard.kt @@ -0,0 +1,143 @@ +package com.volmit.iris.core.safeguard + +import com.volmit.iris.Iris +import com.volmit.iris.core.IrisSettings +import com.volmit.iris.core.safeguard.task.Diagnostic +import com.volmit.iris.core.safeguard.task.Task +import com.volmit.iris.core.safeguard.task.ValueWithDiagnostics +import com.volmit.iris.core.safeguard.task.tasks +import com.volmit.iris.util.format.C +import com.volmit.iris.util.scheduling.J +import org.bukkit.Bukkit +import java.util.* + +object IrisSafeguard { + @Volatile + private var forceShutdown = false + private var results: Map> = emptyMap() + private var context: Map = emptyMap() + private var attachment: Map> = emptyMap() + private var mode = Mode.STABLE + private var count = 0 + + @JvmStatic + fun execute() { + val results = LinkedHashMap>(tasks.size) + val context = LinkedHashMap(tasks.size) + val attachment = LinkedHashMap>(tasks.size) + var mode = Mode.STABLE + var count = 0 + for (task in tasks) { + var result: ValueWithDiagnostics + try { + result = task.run() + } catch (e: Throwable) { + Iris.reportError(e) + result = ValueWithDiagnostics( + Mode.WARNING, + Diagnostic(Diagnostic.Logger.ERROR, "Error while running task ${task.id}", e) + ) + } + mode = mode.highest(result.value) + results[task] = result + context[task.id] = result.value.id + attachment[task.id] = result.diagnostics.flatMap { it.toString().split('\n') } + if (result.value != Mode.STABLE) count++ + } + + this.results = Collections.unmodifiableMap(results) + this.context = Collections.unmodifiableMap(context) + this.attachment = Collections.unmodifiableMap(attachment) + this.mode = mode + this.count = count + } + + @JvmStatic + fun mode() = mode + + @JvmStatic + fun asContext() = context + + @JvmStatic + fun asAttachment() = attachment + + @JvmStatic + fun splash() { + Iris.instance.splash() + printReports() + printFooter() + } + + @JvmStatic + fun printReports() { + when (mode) { + Mode.STABLE -> Iris.info(C.BLUE.toString() + "0 Conflicts found") + Mode.WARNING -> Iris.warn(C.GOLD.toString() + "%s Issues found", count) + Mode.UNSTABLE -> Iris.error(C.DARK_RED.toString() + "%s Issues found", count) + } + + results.values.forEach { it.log(withStackTrace = true) } + } + + @JvmStatic + fun printFooter() { + when (mode) { + Mode.STABLE -> Iris.info(C.BLUE.toString() + "Iris is running Stable") + Mode.WARNING -> warning() + Mode.UNSTABLE -> unstable() + } + } + + @JvmStatic + fun isForceShutdown() = forceShutdown + + private fun warning() { + Iris.warn(C.GOLD.toString() + "Iris is running in Warning Mode") + + Iris.warn("") + Iris.warn(C.DARK_GRAY.toString() + "--==<" + C.GOLD + " IMPORTANT " + C.DARK_GRAY + ">==--") + Iris.warn(C.GOLD.toString() + "Iris is running in warning mode which may cause the following issues:") + Iris.warn("- Data Loss") + Iris.warn("- Errors") + Iris.warn("- Broken worlds") + Iris.warn("- Unexpected behavior.") + Iris.warn("- And perhaps further complications.") + Iris.warn("") + } + + private fun unstable() { + Iris.error(C.DARK_RED.toString() + "Iris is running in Unstable Mode") + + Iris.error("") + Iris.error(C.DARK_GRAY.toString() + "--==<" + C.RED + " IMPORTANT " + C.DARK_GRAY + ">==--") + Iris.error("Iris is running in unstable mode which may cause the following issues:") + Iris.error(C.DARK_RED.toString() + "Server Issues") + Iris.error("- Server won't boot") + Iris.error("- Data Loss") + Iris.error("- Unexpected behavior.") + Iris.error("- And More...") + Iris.error(C.DARK_RED.toString() + "World Issues") + Iris.error("- Worlds can't load due to corruption.") + Iris.error("- Worlds may slowly corrupt until they can't load.") + Iris.error("- World data loss.") + Iris.error("- And More...") + Iris.error(C.DARK_RED.toString() + "ATTENTION: " + C.RED + "While running Iris in unstable mode, you won't be eligible for support.") + + if (IrisSettings.get().general.isDoomsdayAnnihilationSelfDestructMode) { + Iris.error(C.DARK_RED.toString() + "Boot Unstable is set to true, continuing with the startup process in 10 seconds.") + J.sleep(10000L) + } else { + Iris.error(C.DARK_RED.toString() + "Go to plugins/iris/settings.json and set DoomsdayAnnihilationSelfDestructMode to true if you wish to proceed.") + Iris.error(C.DARK_RED.toString() + "The server will shutdown in 10 seconds.") + J.sleep(10000L) + Iris.error(C.DARK_RED.toString() + "Shutting down server.") + forceShutdown = true + try { + Bukkit.getPluginManager().disablePlugins() + } finally { + Runtime.getRuntime().halt(42) + } + } + Iris.info("") + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/volmit/iris/core/safeguard/Mode.kt b/core/src/main/kotlin/com/volmit/iris/core/safeguard/Mode.kt new file mode 100644 index 000000000..6a5b282b2 --- /dev/null +++ b/core/src/main/kotlin/com/volmit/iris/core/safeguard/Mode.kt @@ -0,0 +1,76 @@ +package com.volmit.iris.core.safeguard + +import com.volmit.iris.BuildConstants +import com.volmit.iris.Iris +import com.volmit.iris.core.IrisSettings +import com.volmit.iris.util.format.C +import com.volmit.iris.util.format.Form + +enum class Mode(private val color: C) { + STABLE(C.IRIS), + WARNING(C.GOLD), + UNSTABLE(C.RED); + + val id = name.lowercase() + + fun highest(m: Mode): Mode { + return if (m.ordinal > ordinal) m else this + } + + fun tag(subTag: String?): String { + if (subTag == null || subTag.isBlank()) return wrap("Iris") + C.GRAY + ": " + return wrap("Iris") + " " + wrap(subTag) + C.GRAY + ": " + } + + private fun wrap(tag: String?): String { + return C.BOLD.toString() + "" + C.DARK_GRAY + "[" + C.BOLD + color + tag + C.BOLD + C.DARK_GRAY + "]" + C.RESET + } + + fun trySplash() { + if (!IrisSettings.get().general.isSplashLogoStartup) return + splash() + } + + fun splash() { + val padd = Form.repeat(" ", 8) + val padd2 = Form.repeat(" ", 4) + + val splash = arrayOf( + padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@", + padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + color + " .(((()))). ", + padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + color + " .((((((())))))). ", + padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + color + " ((((((((())))))))) " + C.GRAY + " @", + padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + color + " ((((((((-))))))))) " + C.GRAY + " @@", + padd + C.GRAY + "@@@&&" + color + " ((((((({ })))))))) " + C.GRAY + " &&@@@", + padd + C.GRAY + "@@" + color + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@", + padd + C.GRAY + "@" + color + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@", + padd + C.GRAY + "" + color + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@", + padd + C.GRAY + "" + color + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@", + padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@", + ) + + val info = arrayOf( + "", + "", + "", + "", + "", + 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, + ) + + + val builder = StringBuilder("\n\n") + for (i in splash.indices) { + builder.append(splash[i]) + if (i < info.size) { + builder.append(info[i]) + } + builder.append("\n") + } + + Iris.info(builder.toString()) + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/volmit/iris/core/safeguard/task/Task.kt b/core/src/main/kotlin/com/volmit/iris/core/safeguard/task/Task.kt new file mode 100644 index 000000000..aa0dd9202 --- /dev/null +++ b/core/src/main/kotlin/com/volmit/iris/core/safeguard/task/Task.kt @@ -0,0 +1,28 @@ +package com.volmit.iris.core.safeguard.task + +import com.volmit.iris.core.safeguard.Mode +import com.volmit.iris.util.format.Form +import kotlin.properties.PropertyDelegateProvider +import kotlin.properties.ReadOnlyProperty + +abstract class Task( + val id: String, + val name: String = Form.capitalizeWords(id.replace(" ", "_").lowercase()), +) { + + abstract fun run(): ValueWithDiagnostics + + companion object { + fun of(id: String, name: String = id, action: () -> ValueWithDiagnostics) = object : Task(id, name) { + override fun run() = action() + } + + fun of(id: String, action: () -> ValueWithDiagnostics) = object : Task(id) { + override fun run() = action() + } + + fun task(action: () -> ValueWithDiagnostics) = PropertyDelegateProvider> { _, _ -> + ReadOnlyProperty { _, property -> of(property.name, action) } + } + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/volmit/iris/core/safeguard/task/Tasks.kt b/core/src/main/kotlin/com/volmit/iris/core/safeguard/task/Tasks.kt new file mode 100644 index 000000000..54961fc0f --- /dev/null +++ b/core/src/main/kotlin/com/volmit/iris/core/safeguard/task/Tasks.kt @@ -0,0 +1,138 @@ +package com.volmit.iris.core.safeguard.task + +import com.volmit.iris.Iris +import com.volmit.iris.core.IrisWorlds +import com.volmit.iris.core.nms.INMS +import com.volmit.iris.core.nms.v1X.NMSBinding1X +import com.volmit.iris.core.safeguard.Mode +import com.volmit.iris.core.safeguard.Mode.* +import com.volmit.iris.core.safeguard.task.Diagnostic.Logger.* +import com.volmit.iris.core.safeguard.task.Task.Companion.of +import com.volmit.iris.util.agent.Agent +import com.volmit.iris.util.misc.getHardware +import org.bukkit.Bukkit +import java.util.stream.Collectors +import javax.tools.ToolProvider +import kotlin.properties.PropertyDelegateProvider +import kotlin.properties.ReadOnlyProperty + +private val memory by task { + val mem = getHardware.getProcessMemory() + if (mem >= 5999) STABLE.withDiagnostics() + else STABLE.withDiagnostics( + WARN.create("Low Memory"), + WARN.create("- 6GB+ Ram is recommended"), + WARN.create("- Process Memory: $mem MB") + ) +} + +private val incompatibilities by task { + val plugins = mutableSetOf("dynmap", "Stratos") + plugins.removeIf { server.pluginManager.getPlugin(it) == null } + + if (plugins.isEmpty()) STABLE.withDiagnostics() + else { + val diagnostics = mutableListOf() + if ("dynmap" in plugins) diagnostics.addAll( + ERROR.create("Dynmap"), + ERROR.create("- The plugin Dynmap is not compatible with the server."), + ERROR.create("- If you want to have a map plugin like Dynmap, consider Bluemap.") + ) + if ("Stratos" in plugins) diagnostics.addAll( + ERROR.create("Stratos"), + ERROR.create("- Iris is not compatible with other worldgen plugins.") + ) + WARNING.withDiagnostics(diagnostics) + } +} + +private val software by task { + val supported = setOf( + "purpur", + "pufferfish", + "paper", + "spigot", + "bukkit" + ) + + if (supported.any { server.name.contains(it, true) }) STABLE.withDiagnostics() + else WARNING.withDiagnostics( + WARN.create("Unsupported Server Software"), + WARN.create("- Please consider using Paper or Purpur instead.") + ) +} + +private val version by task { + val parts = Iris.instance.description.version.split('-') + val minVersion = parts[1] + val maxVersion = parts[2] + + if (INMS.get() !is NMSBinding1X) STABLE.withDiagnostics() + else UNSTABLE.withDiagnostics( + ERROR.create("Server Version"), + ERROR.create("- Iris only supports $minVersion > $maxVersion") + ) +} + +private val injection by task { + if (!Agent.install()) UNSTABLE.withDiagnostics( + ERROR.create("Java Agent"), + ERROR.create("- Please enable dynamic agent loading by adding -XX:+EnableDynamicAgentLoading to your jvm arguments."), + ERROR.create("- or add the jvm argument -javaagent:" + Agent.AGENT_JAR.path) + ) + else if (!INMS.get().injectBukkit()) UNSTABLE.withDiagnostics( + ERROR.create("Code Injection"), + ERROR.create("- Failed to inject code. Please contact support") + ) + else STABLE.withDiagnostics() +} + +private val dimensionTypes by task { + val keys = IrisWorlds.get() + .dimensions + .map { it.dimensionTypeKey } + .collect(Collectors.toSet()) + + if (!INMS.get().missingDimensionTypes(*keys.toTypedArray())) STABLE.withDiagnostics() + else UNSTABLE.withDiagnostics( + ERROR.create("Dimension Types"), + ERROR.create("- Required Iris dimension types were not loaded."), + ERROR.create("- If this still happens after a restart please contact support.") + ) +} + +private val diskSpace by task { + if (server.worldContainer.freeSpace.toDouble().div(0x4000_0000) > 3) STABLE.withDiagnostics() + else WARNING.withDiagnostics( + WARN.create("Insufficient Disk Space"), + WARN.create("- 3GB of free space is required for Iris to function.") + ) +} + +private val java by task { + val version = Iris.getJavaVersion() + val jdk = runCatching { ToolProvider.getSystemJavaCompiler() }.getOrNull() != null + if (version in setOf(21) && jdk) STABLE.withDiagnostics() + else WARNING.withDiagnostics( + WARN.create("Unsupported Java version"), + WARN.create("- Please consider using JDK 21 Instead of ${if(jdk) "JDK" else "JRE"} $version") + ) +} + + +val tasks = listOf( + memory, + incompatibilities, + software, + version, + injection, + dimensionTypes, + diskSpace, + java, +) + +private val server get() = Bukkit.getServer() +private fun MutableList.addAll(vararg values: T) = values.forEach(this::add) +fun task(action: () -> ValueWithDiagnostics) = PropertyDelegateProvider> { _, _ -> + ReadOnlyProperty { _, property -> of(property.name, action) } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/volmit/iris/core/safeguard/task/ValueWithDiagnostics.kt b/core/src/main/kotlin/com/volmit/iris/core/safeguard/task/ValueWithDiagnostics.kt new file mode 100644 index 000000000..d388f3d26 --- /dev/null +++ b/core/src/main/kotlin/com/volmit/iris/core/safeguard/task/ValueWithDiagnostics.kt @@ -0,0 +1,74 @@ +package com.volmit.iris.core.safeguard.task + +import com.volmit.iris.Iris +import com.volmit.iris.util.format.C +import java.io.ByteArrayOutputStream +import java.io.PrintStream + +data class ValueWithDiagnostics( + val value: T, + val diagnostics: List +) { + constructor(value: T, vararg diagnostics: Diagnostic) : this(value, diagnostics.toList()) + + @JvmOverloads + fun log( + withException: Boolean = true, + withStackTrace: Boolean = false + ) { + diagnostics.forEach { it.log(withException, withStackTrace) } + } +} + +data class Diagnostic @JvmOverloads constructor( + val logger: Logger = Logger.ERROR, + val message: String, + val exception: Throwable? = null +) { + + enum class Logger( + private val logger: (String) -> Unit + ) { + DEBUG(Iris::debug), + RAW(Iris::msg), + INFO(Iris::info), + WARN(Iris::warn), + ERROR(Iris::error); + + fun print(message: String) = message.split('\n').forEach(logger) + fun create(message: String, exception: Throwable? = null) = Diagnostic(this, message, exception) + } + + @JvmOverloads + fun log( + withException: Boolean = true, + withStackTrace: Boolean = false + ) { + logger.print(render(withException, withStackTrace)) + } + + fun render( + withException: Boolean = true, + withStackTrace: Boolean = false + ): String = buildString { + append(message) + if (withException && exception != null) { + append(": ") + append(exception) + if (withStackTrace) { + ByteArrayOutputStream().use { os -> + val ps = PrintStream(os) + exception.printStackTrace(ps) + ps.flush() + append("\n") + append(os.toString()) + } + } + } + } + + override fun toString(): String = C.strip(render()) +} + +fun T.withDiagnostics(vararg diagnostics: Diagnostic) = ValueWithDiagnostics(this, diagnostics.toList()) +fun T.withDiagnostics(diagnostics: List) = ValueWithDiagnostics(this, diagnostics) \ No newline at end of file