diff --git a/src/main/java/ch/njol/skript/Skript.java b/src/main/java/ch/njol/skript/Skript.java index c51112be9ac..bf20c42abd0 100644 --- a/src/main/java/ch/njol/skript/Skript.java +++ b/src/main/java/ch/njol/skript/Skript.java @@ -131,6 +131,8 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.logging.Filter; @@ -249,17 +251,6 @@ public static ServerPlatform getServerPlatform() { } } - /** - * Returns true if the underlying installed Java/JVM is 32-bit, false otherwise. - * Note that this depends on a internal system property and these can always be overridden by user using -D JVM options, - * more specifically, this method will return false on non OracleJDK/OpenJDK based JVMs, that don't include bit information in java.vm.name system property. - * @return Whether the installed Java/JVM is 32-bit or not. - */ - private static boolean using32BitJava() { - // Property returned should either be "Java HotSpot(TM) 32-Bit Server VM" or "OpenJDK 32-Bit Server VM" if 32-bit and using OracleJDK/OpenJDK - return System.getProperty("java.vm.name").contains("32"); - } - /** * Checks if server software and Minecraft version are supported. * Prints errors or warnings to console if something is wrong. @@ -490,6 +481,8 @@ public void onEnable() { // ... but also before platform check, because there is a config option to ignore some errors SkriptConfig.load(); + CompletableFuture aliases = Aliases.loadAsync(); + // Now override the verbosity if test mode is enabled if (TestMode.VERBOSITY != null) SkriptLogger.setVerbosity(Verbosity.valueOf(TestMode.VERBOSITY)); @@ -502,20 +495,6 @@ public void onEnable() { updater.updateCheck(console); } - try { - Aliases.load(); // Loaded before anything that might use them - } catch (StackOverflowError e) { - if (using32BitJava()) { - Skript.error(""); - Skript.error("There was a StackOverflowError that occured while loading aliases."); - Skript.error("As you are currently using 32-bit Java, please update to 64-bit Java to resolve the error."); - Skript.error("Please report this issue to our GitHub only if updating to 64-bit Java does not fix the issue."); - Skript.error(""); - } else { - throw e; // Uh oh, this shouldn't happen. Re-throw the error. - } - } - // If loading can continue (platform ok), check for potentially thrown error if (classLoadError != null) { exception(classLoadError); @@ -587,6 +566,12 @@ public void run() { } finishedLoadingHooks = true; + try { + aliases.get(); // await alias load + } catch (InterruptedException | ExecutionException e) { + exception(e, "Could not load aliases concurrently"); + } + if (TestMode.ENABLED) { info("Preparing Skript for testing..."); tainted = true; diff --git a/src/main/java/ch/njol/skript/SkriptCommand.java b/src/main/java/ch/njol/skript/SkriptCommand.java index c735541cae3..dd287fa5db2 100644 --- a/src/main/java/ch/njol/skript/SkriptCommand.java +++ b/src/main/java/ch/njol/skript/SkriptCommand.java @@ -156,15 +156,15 @@ public boolean onCommand(CommandSender sender, Command command, String label, St reloading(sender, "config, aliases and scripts", logHandler); SkriptConfig.load(); Aliases.clear(); - Aliases.load(); - - ScriptLoader.unloadScripts(ScriptLoader.getLoadedScripts()); - ScriptLoader.loadScripts(Skript.getInstance().getScriptsFolder(), OpenCloseable.combine(logHandler, timingLogHandler)) - .thenAccept(info -> { - if (info.files == 0) - Skript.warning(Skript.m_no_scripts.toString()); - reloaded(sender, logHandler, timingLogHandler, "config, aliases and scripts"); - }); + Aliases.loadAsync().thenRun(() -> { + ScriptLoader.unloadScripts(ScriptLoader.getLoadedScripts()); + ScriptLoader.loadScripts(Skript.getInstance().getScriptsFolder(), OpenCloseable.combine(logHandler, timingLogHandler)) + .thenAccept(info -> { + if (info.files == 0) + Skript.warning(Skript.m_no_scripts.toString()); + reloaded(sender, logHandler, timingLogHandler, "config, aliases and scripts"); + }); + }); } else if (args[1].equalsIgnoreCase("scripts")) { reloading(sender, "scripts", logHandler); @@ -182,8 +182,7 @@ public boolean onCommand(CommandSender sender, Command command, String label, St } else if (args[1].equalsIgnoreCase("aliases")) { reloading(sender, "aliases", logHandler); Aliases.clear(); - Aliases.load(); - reloaded(sender, logHandler, timingLogHandler, "aliases"); + Aliases.loadAsync().thenRun(() -> reloaded(sender, logHandler, timingLogHandler, "aliases")); } else { // Reloading an individual Script or folder File scriptFile = getScriptFromArgs(sender, args); if (scriptFile == null) diff --git a/src/main/java/ch/njol/skript/aliases/Aliases.java b/src/main/java/ch/njol/skript/aliases/Aliases.java index 19daed69359..bb24c305756 100644 --- a/src/main/java/ch/njol/skript/aliases/Aliases.java +++ b/src/main/java/ch/njol/skript/aliases/Aliases.java @@ -1,21 +1,3 @@ -/** - * This file is part of Skript. - * - * Skript is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Skript is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Skript. If not, see . - * - * Copyright Peter Güttinger, SkriptLang team and contributors - */ package ch.njol.skript.aliases; import ch.njol.skript.Skript; @@ -25,35 +7,28 @@ import ch.njol.skript.config.Node; import ch.njol.skript.config.SectionNode; import ch.njol.skript.entity.EntityData; -import org.bukkit.entity.EntityType; -import org.skriptlang.skript.lang.script.Script; import ch.njol.skript.lang.parser.ParserInstance; -import ch.njol.skript.localization.ArgsMessage; -import ch.njol.skript.localization.Language; -import ch.njol.skript.localization.Message; -import ch.njol.skript.localization.Noun; -import ch.njol.skript.localization.RegexMessage; +import ch.njol.skript.localization.*; import ch.njol.skript.log.BlockingLogHandler; import ch.njol.skript.util.EnchantmentType; import ch.njol.skript.util.Utils; import ch.njol.skript.util.Version; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.lang.script.Script; import java.io.IOException; import java.io.UncheckedIOException; import java.net.URI; import java.net.URISyntaxException; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; +import java.nio.file.*; import java.util.HashMap; import java.util.Locale; import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -379,11 +354,14 @@ private static ItemType getAlias(final String s) { public static void clear() { provider.clearAliases(); } - + /** * Loads aliases from Skript's standard locations. * Exceptions will be logged, but not thrown. + * + * @deprecated Freezes server on call. Use {@link #loadAsync()} instead. */ + @Deprecated public static void load() { try { long start = System.currentTimeMillis(); @@ -394,6 +372,44 @@ public static void load() { } } + /** + * Loads aliases from Skript's standard locations asynchronously. + * Exceptions will be logged, but not thrown. + * + * @return A future that completes when the aliases are loaded. + * The returned value is true if the loading was successful, false otherwise. + */ + public static CompletableFuture loadAsync() { + return CompletableFuture.supplyAsync(() -> { + try { + long start = System.currentTimeMillis(); + loadInternal(); + Skript.info("Loaded " + provider.getAliasCount() + " aliases in " + (System.currentTimeMillis() - start) + "ms"); + return true; + } catch (StackOverflowError e) { + /* + * Returns true if the underlying installed Java/JVM is 32-bit, false otherwise. + * Note that this depends on a internal system property and these can always be overridden by user using -D JVM options, + * more specifically, this method will return false on non OracleJDK/OpenJDK based JVMs, that don't include bit information in java.vm.name system property + */ + if (System.getProperty("java.vm.name").contains("32")) { + Skript.error(""); + Skript.error("There was a StackOverflowError that occurred while loading aliases."); + Skript.error("As you are currently using 32-bit Java, please update to 64-bit Java to resolve the error."); + Skript.error("Please report this issue to our GitHub only if updating to 64-bit Java does not fix the issue."); + Skript.error(""); + } else { + Skript.exception(e); + Bukkit.getPluginManager().disablePlugin(Skript.getInstance()); + } + return false; + } catch (IOException e) { + Skript.exception(e); + return false; + } + }); + } + /** * Temporarily create an alias for a material which may not have an alias yet. */