diff --git a/src/main/java/world/bentobox/bentobox/BentoBox.java b/src/main/java/world/bentobox/bentobox/BentoBox.java index 003000ddd..1a1dcf81d 100644 --- a/src/main/java/world/bentobox/bentobox/BentoBox.java +++ b/src/main/java/world/bentobox/bentobox/BentoBox.java @@ -9,6 +9,7 @@ import org.bukkit.Bukkit; import org.bukkit.generator.ChunkGenerator; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitTask; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; @@ -89,6 +90,8 @@ public class BentoBox extends JavaPlugin { private Config configObject; + private BukkitTask blueprintLoadingTask; + @Override public void onEnable(){ if (!ServerCompatibility.getInstance().checkCompatibility().isCanLaunch()) { @@ -163,7 +166,7 @@ public class BentoBox extends JavaPlugin { final long loadTime = System.currentTimeMillis() - loadStart; - getServer().getScheduler().runTask(instance, () -> { + Bukkit.getScheduler().runTask(instance, () -> { final long enableStart = System.currentTimeMillis(); hooksManager.registerHook(new PlaceholderAPIHook()); hooksManager.registerHook(new MVdWPlaceholderAPIHook()); @@ -183,7 +186,7 @@ public class BentoBox extends JavaPlugin { islandsManager.load(); // Save islands & players data every X minutes - instance.getServer().getScheduler().runTaskTimer(instance, () -> { + Bukkit.getScheduler().runTaskTimer(instance, () -> { playersManager.asyncSaveAll(); islandsManager.asyncSaveAll(); }, getSettings().getDatabaseBackupPeriod() * 20 * 60L, getSettings().getDatabaseBackupPeriod() * 20 * 60L); @@ -215,11 +218,18 @@ public class BentoBox extends JavaPlugin { TextVariables.VERSION, instance.getDescription().getVersion(), "[time]", String.valueOf(loadTime + enableTime)); - // Tell all addons that everything is loaded - isLoaded = true; - this.addonsManager.allLoaded(); - // Fire plugin ready event - this should go last after everything else - Bukkit.getServer().getPluginManager().callEvent(new BentoBoxReadyEvent()); + // Poll for blueprints loading to be finished - async so could be a completely variable time + blueprintLoadingTask = Bukkit.getScheduler().runTaskTimer(instance, () -> { + if (getBlueprintsManager().isBlueprintsLoaded()) { + blueprintLoadingTask.cancel(); + // Tell all addons that everything is loaded + isLoaded = true; + this.addonsManager.allLoaded(); + // Fire plugin ready event - this should go last after everything else + Bukkit.getServer().getPluginManager().callEvent(new BentoBoxReadyEvent()); + instance.log("All blueprints loaded."); + } + }, 0L, 1L); if (getSettings().getDatabaseType().equals(DatabaseSetup.DatabaseType.YAML)) { logWarning("*** You're still using YAML database ! ***"); diff --git a/src/main/java/world/bentobox/bentobox/managers/BlueprintsManager.java b/src/main/java/world/bentobox/bentobox/managers/BlueprintsManager.java index fcd45f35a..e8a8bda4b 100644 --- a/src/main/java/world/bentobox/bentobox/managers/BlueprintsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/BlueprintsManager.java @@ -11,9 +11,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.EnumMap; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.jar.JarFile; import java.util.stream.Collectors; @@ -79,6 +81,8 @@ public class BlueprintsManager { private @NonNull BentoBox plugin; + private @NonNull Set blueprintsLoaded; + public BlueprintsManager(@NonNull BentoBox plugin) { this.plugin = plugin; @@ -100,6 +104,8 @@ public class BlueprintsManager { // Register adapter factory builder.registerTypeAdapterFactory(new BentoboxTypeAdapterFactory(plugin)); gson = builder.create(); + // Loaded tracker + blueprintsLoaded = new HashSet<>(); } /** @@ -172,10 +178,13 @@ public class BlueprintsManager { * @param addon the {@link GameModeAddon} to load the blueprints of. */ public void loadBlueprintBundles(@NonNull GameModeAddon addon) { + // Set loading flag + blueprintsLoaded.add(addon); Bukkit .getScheduler() .runTaskAsynchronously( plugin, () -> { + // Load bundles blueprintBundles.put(addon, new ArrayList<>()); // See if there are any schems that need converting new SchemToBlueprint(plugin).convertSchems(addon); @@ -185,9 +194,20 @@ public class BlueprintsManager { } // Load blueprints loadBlueprints(addon); + + // Clear loading flag + blueprintsLoaded.remove(addon); }); } + /** + * Check if all blueprints are loaded. Only query after all GameModes have been loaded. + * @return true if all blueprints are loaded + */ + public boolean isBlueprintsLoaded() { + return blueprintsLoaded.isEmpty(); + } + private boolean loadBundles(@NonNull GameModeAddon addon) { File bpf = getBlueprintsFolder(addon); if (!bpf.exists()) {