From 1c3776b605ad17f8a3dd00b1a51bc050ddc48563 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Sun, 29 Oct 2023 10:55:31 +0100 Subject: [PATCH] Delay economy initialization to server load (#4216) --- .../bukkit/inject/BukkitModule.java | 74 +++++++++++++++---- .../bukkit/listener/ServerListener.java | 30 ++++++++ 2 files changed, 91 insertions(+), 13 deletions(-) diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java index 0b6810785..fba7790f0 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java @@ -23,13 +23,13 @@ import com.google.inject.Provides; import com.google.inject.Singleton; import com.google.inject.assistedinject.FactoryModuleBuilder; import com.plotsquared.bukkit.BukkitPlatform; +import com.plotsquared.bukkit.listener.ServerListener; import com.plotsquared.bukkit.listener.SingleWorldListener; import com.plotsquared.bukkit.player.BukkitPlayerManager; import com.plotsquared.bukkit.queue.BukkitChunkCoordinator; import com.plotsquared.bukkit.queue.BukkitQueueCoordinator; import com.plotsquared.bukkit.schematic.BukkitSchematicHandler; import com.plotsquared.bukkit.util.BukkitChunkManager; -import com.plotsquared.bukkit.util.BukkitEconHandler; import com.plotsquared.bukkit.util.BukkitInventoryUtil; import com.plotsquared.bukkit.util.BukkitRegionManager; import com.plotsquared.bukkit.util.BukkitSetupUtils; @@ -47,6 +47,9 @@ import com.plotsquared.core.inject.factory.ChunkCoordinatorBuilderFactory; import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory; import com.plotsquared.core.inject.factory.HybridPlotWorldFactory; import com.plotsquared.core.inject.factory.ProgressSubscriberFactory; +import com.plotsquared.core.player.OfflinePlotPlayer; +import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.world.DefaultPlotAreaManager; import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.SinglePlotAreaManager; @@ -72,6 +75,8 @@ import org.bukkit.command.ConsoleCommandSender; import org.bukkit.plugin.java.JavaPlugin; import org.checkerframework.checker.nullness.qual.NonNull; +import java.util.Objects; + public class BukkitModule extends AbstractModule { private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + BukkitModule.class.getSimpleName()); @@ -128,21 +133,64 @@ public class BukkitModule extends AbstractModule { @Provides @Singleton @NonNull EconHandler provideEconHandler() { - if (!Settings.Enabled_Components.ECONOMY) { + if (!Settings.Enabled_Components.ECONOMY || !Bukkit.getPluginManager().isPluginEnabled("Vault")) { return EconHandler.nullEconHandler(); } - if (Bukkit.getPluginManager().isPluginEnabled("Vault")) { - try { - BukkitEconHandler econHandler = new BukkitEconHandler(); - if (!econHandler.init()) { - LOGGER.warn("Economy is enabled but no plugin is providing an economy service. Falling back..."); - return EconHandler.nullEconHandler(); - } - return econHandler; - } catch (final Exception ignored) { - } + // Guice eagerly initializes singletons, so we need to bring the laziness ourselves + return new LazyEconHandler(); + } + + private static final class LazyEconHandler extends EconHandler implements ServerListener.MutableEconHandler { + private volatile EconHandler implementation; + + public void setImplementation(EconHandler econHandler) { + this.implementation = econHandler; } - return EconHandler.nullEconHandler(); + + @Override + public boolean init() { + return get().init(); + } + + @Override + public double getBalance(final PlotPlayer player) { + return get().getBalance(player); + } + + @Override + public void withdrawMoney(final PlotPlayer player, final double amount) { + get().withdrawMoney(player, amount); + } + + @Override + public void depositMoney(final PlotPlayer player, final double amount) { + get().depositMoney(player, amount); + } + + @Override + public void depositMoney(final OfflinePlotPlayer player, final double amount) { + get().depositMoney(player, amount); + } + + @Override + public boolean isEnabled(final PlotArea plotArea) { + return get().isEnabled(plotArea); + } + + @Override + public @NonNull String format(final double balance) { + return get().format(balance); + } + + @Override + public boolean isSupported() { + return get().isSupported(); + } + + private EconHandler get() { + return Objects.requireNonNull(this.implementation, "EconHandler not ready yet."); + } + } } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/ServerListener.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/ServerListener.java index 6e25ebe14..912f4066f 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/ServerListener.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/ServerListener.java @@ -21,9 +21,14 @@ package com.plotsquared.bukkit.listener; import com.google.inject.Inject; import com.plotsquared.bukkit.BukkitPlatform; import com.plotsquared.bukkit.placeholder.MVdWPlaceholders; +import com.plotsquared.bukkit.util.BukkitEconHandler; +import com.plotsquared.core.PlotSquared; import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.player.ConsolePlayer; +import com.plotsquared.core.util.EconHandler; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -32,6 +37,8 @@ import org.checkerframework.checker.nullness.qual.NonNull; public class ServerListener implements Listener { + private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + ServerListener.class.getSimpleName()); + private final BukkitPlatform plugin; @Inject @@ -45,6 +52,29 @@ public class ServerListener implements Listener { new MVdWPlaceholders(this.plugin, this.plugin.placeholderRegistry()); ConsolePlayer.getConsole().sendMessage(TranslatableCaption.of("placeholder.hooked")); } + if (Settings.Enabled_Components.ECONOMY && Bukkit.getPluginManager().isPluginEnabled("Vault")) { + EconHandler econHandler = new BukkitEconHandler(); + try { + if (!econHandler.init()) { + LOGGER.warn("Economy is enabled but no plugin is providing an economy service. Falling back..."); + econHandler = EconHandler.nullEconHandler(); + } + } catch (final Exception ignored) { + econHandler = EconHandler.nullEconHandler(); + } + if (PlotSquared.platform().econHandler() instanceof MutableEconHandler meh) { + meh.setImplementation(econHandler); + } + } + } + + /** + * Internal use only. Required to implement lazy econ loading using Guice. + * + * @since TODO + */ + public interface MutableEconHandler { + void setImplementation(EconHandler econHandler); } }