mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-01-06 15:51:30 +00:00
restructure safeguard
This commit is contained in:
@@ -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<String, Int>()
|
||||
nmsBindings.forEach { key, value ->
|
||||
nmsBindings.forEach { (key, value) ->
|
||||
project(":nms:$key") {
|
||||
apply<JavaPlugin>()
|
||||
apply<NMSToolsPlugin>()
|
||||
@@ -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) })
|
||||
|
||||
@@ -184,10 +184,10 @@ val generateTemplates = tasks.register<Copy>("generateTemplates") {
|
||||
"commit" to provider {
|
||||
val res = runCatching { project.extensions.getByType<Grgit>().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"
|
||||
}()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ import com.volmit.iris.core.link.IrisPapiExpansion;
|
||||
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.KList;
|
||||
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.M;
|
||||
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.function.Predicate;
|
||||
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<Runnable> syncJobs = new ShurikenQueue<>();
|
||||
@@ -306,9 +300,6 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
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 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
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 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
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 class Iris extends VolmitPlugin implements Listener {
|
||||
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 class Iris extends VolmitPlugin implements Listener {
|
||||
|
||||
@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 class Iris extends VolmitPlugin implements Listener {
|
||||
}
|
||||
|
||||
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 " + "<rainbow>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() {
|
||||
|
||||
@@ -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<String, Object> asContext() {
|
||||
KMap<String, Object> 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<String> incompatiblePlugins = new KList<>();
|
||||
ServerBootSFG.incompatibilities.forEach((plugin, present) -> {
|
||||
if (present) incompatiblePlugins.add(plugin);
|
||||
});
|
||||
m.put("plugins", incompatiblePlugins);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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("");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.volmit.iris.core.safeguard;
|
||||
|
||||
public class PerformanceSFG {
|
||||
public static void calculatePerformance() {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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<String, Boolean> 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<String, Boolean> 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<String> getDimensionTypes() {
|
||||
return IrisWorlds.get()
|
||||
.getDimensions()
|
||||
.map(IrisDimension::getDimensionTypeKey)
|
||||
.collect(Collectors.toCollection(KSet::new));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ package com.volmit.iris.util.format;
|
||||
|
||||
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 enum C {
|
||||
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
|
||||
*
|
||||
|
||||
@@ -56,7 +56,7 @@ public class Bindings {
|
||||
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 class Bindings {
|
||||
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());
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.volmit.iris.util.sentry;
|
||||
|
||||
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 @@ import java.util.concurrent.Callable;
|
||||
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);
|
||||
|
||||
@@ -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<Task, ValueWithDiagnostics<Mode>> = emptyMap()
|
||||
private var context: Map<String, String> = emptyMap()
|
||||
private var attachment: Map<String, List<String>> = emptyMap()
|
||||
private var mode = Mode.STABLE
|
||||
private var count = 0
|
||||
|
||||
@JvmStatic
|
||||
fun execute() {
|
||||
val results = LinkedHashMap<Task, ValueWithDiagnostics<Mode>>(tasks.size)
|
||||
val context = LinkedHashMap<String, String>(tasks.size)
|
||||
val attachment = LinkedHashMap<String, List<String>>(tasks.size)
|
||||
var mode = Mode.STABLE
|
||||
var count = 0
|
||||
for (task in tasks) {
|
||||
var result: ValueWithDiagnostics<Mode>
|
||||
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("")
|
||||
}
|
||||
}
|
||||
76
core/src/main/kotlin/com/volmit/iris/core/safeguard/Mode.kt
Normal file
76
core/src/main/kotlin/com/volmit/iris/core/safeguard/Mode.kt
Normal file
@@ -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())
|
||||
}
|
||||
}
|
||||
@@ -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<Mode>
|
||||
|
||||
companion object {
|
||||
fun of(id: String, name: String = id, action: () -> ValueWithDiagnostics<Mode>) = object : Task(id, name) {
|
||||
override fun run() = action()
|
||||
}
|
||||
|
||||
fun of(id: String, action: () -> ValueWithDiagnostics<Mode>) = object : Task(id) {
|
||||
override fun run() = action()
|
||||
}
|
||||
|
||||
fun task(action: () -> ValueWithDiagnostics<Mode>) = PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, Task>> { _, _ ->
|
||||
ReadOnlyProperty { _, property -> of(property.name, action) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Diagnostic>()
|
||||
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 <T> MutableList<T>.addAll(vararg values: T) = values.forEach(this::add)
|
||||
fun task(action: () -> ValueWithDiagnostics<Mode>) = PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, Task>> { _, _ ->
|
||||
ReadOnlyProperty { _, property -> of(property.name, action) }
|
||||
}
|
||||
@@ -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<out T>(
|
||||
val value: T,
|
||||
val diagnostics: List<Diagnostic>
|
||||
) {
|
||||
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> T.withDiagnostics(vararg diagnostics: Diagnostic) = ValueWithDiagnostics(this, diagnostics.toList())
|
||||
fun <T> T.withDiagnostics(diagnostics: List<Diagnostic>) = ValueWithDiagnostics(this, diagnostics)
|
||||
Reference in New Issue
Block a user