diff --git a/src/main/java/org/mvplugins/multiverse/inventories/MultiverseInventories.java b/src/main/java/org/mvplugins/multiverse/inventories/MultiverseInventories.java index c1e1bf88..48fbb644 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/MultiverseInventories.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/MultiverseInventories.java @@ -16,9 +16,8 @@ import org.mvplugins.multiverse.inventories.dataimport.DataImportManager; import org.mvplugins.multiverse.inventories.dataimport.DataImporter; import org.mvplugins.multiverse.inventories.destination.LastLocationDestination; -import org.mvplugins.multiverse.inventories.handleshare.ShareHandleListener; import org.mvplugins.multiverse.inventories.handleshare.SingleShareWriter; -import org.mvplugins.multiverse.inventories.handleshare.SpawnChangeListener; +import org.mvplugins.multiverse.inventories.listeners.MVInvListener; import org.mvplugins.multiverse.inventories.handleshare.WriteOnlyShareHandler; import org.mvplugins.multiverse.inventories.profile.PlayerNamesMapper; import org.mvplugins.multiverse.inventories.profile.ProfileCacheManager; @@ -55,12 +54,6 @@ public class MultiverseInventories extends MultiverseModule { @Inject private Provider inventoriesConfig; @Inject - private Provider shareHandleListener; - @Inject - private Provider respawnListener; - @Inject - private Provider mvEventsListener; - @Inject private Provider worldGroupManager; @Inject private Provider playerNamesMapperProvider; @@ -82,7 +75,6 @@ public class MultiverseInventories extends MultiverseModule { private Provider mvInvCommandPermissions; private InventoriesDupingPatch dupingPatch; - private boolean usingSpawnChangeEvent = false; public MultiverseInventories() { super(); @@ -114,7 +106,7 @@ public final void onEnable() { inventoriesConfig.get().save().onFailure(e -> Logging.severe("Failed to save config file!")); // Register Stuff - this.registerEvents(); + this.registerDynamicListeners(MVInvListener.class); this.setUpLocales(); this.registerCommands(); this.registerDestinations(); @@ -160,23 +152,6 @@ public void onDisable() { Logging.shutdown(); } - private void registerEvents() { - PluginManager pluginManager = this.getServer().getPluginManager(); - pluginManager.registerEvents(shareHandleListener.get(), this); - pluginManager.registerEvents(respawnListener.get(), this); - pluginManager.registerEvents(mvEventsListener.get(), this); - if (inventoriesConfig.get().getUseImprovedRespawnLocationDetection()) { - try { - Class.forName("org.bukkit.event.player.PlayerSpawnChangeEvent"); - pluginManager.registerEvents(new SpawnChangeListener(this), this); - usingSpawnChangeEvent = true; - Logging.fine("Yayy PlayerSpawnChangeEvent will be used!"); - } catch (ClassNotFoundException e) { - Logging.fine("PlayerSpawnChangeEvent will not be used!"); - } - } - } - private void registerCommands() { Try.run(() -> { mvInvCommandCompletion.get(); @@ -259,8 +234,4 @@ public void reloadConfig() { worldGroupManager.get().checkForConflicts(null); }, 1L); } - - public boolean isUsingSpawnChangeEvent() { - return usingSpawnChangeEvent; - } } diff --git a/src/main/java/org/mvplugins/multiverse/inventories/handleshare/GameModeShareHandler.java b/src/main/java/org/mvplugins/multiverse/inventories/handleshare/GameModeShareHandler.java index fc0b1ae2..22cb973b 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/handleshare/GameModeShareHandler.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/handleshare/GameModeShareHandler.java @@ -19,7 +19,7 @@ /** * GameMode change implementation of ShareHandler. */ -final class GameModeShareHandler extends ShareHandler { +public final class GameModeShareHandler extends ShareHandler { private final GameMode fromGameMode; private final GameMode toGameMode; @@ -28,7 +28,7 @@ final class GameModeShareHandler extends ShareHandler { private final String world; private final List worldGroups; - GameModeShareHandler(MultiverseInventories inventories, Player player, + public GameModeShareHandler(MultiverseInventories inventories, Player player, GameMode fromGameMode, GameMode toGameMode) { super(inventories, player); this.fromGameMode = fromGameMode; diff --git a/src/main/java/org/mvplugins/multiverse/inventories/handleshare/SpawnChangeListener.java b/src/main/java/org/mvplugins/multiverse/inventories/handleshare/SpawnChangeListener.java deleted file mode 100644 index fcad9fae..00000000 --- a/src/main/java/org/mvplugins/multiverse/inventories/handleshare/SpawnChangeListener.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.mvplugins.multiverse.inventories.handleshare; - -import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerSpawnChangeEvent; -import org.bukkit.event.player.PlayerSpawnChangeEvent.Cause; -import org.mvplugins.multiverse.inventories.MultiverseInventories; -import org.mvplugins.multiverse.inventories.share.Sharables; - -import static org.mvplugins.multiverse.inventories.util.MinecraftTools.findAnchorFromRespawnLocation; -import static org.mvplugins.multiverse.inventories.util.MinecraftTools.findBedFromRespawnLocation; - -/** - * Handles player spawn location changes for BED_SPAWN sharable. - */ -public final class SpawnChangeListener implements Listener { - - private final MultiverseInventories inventories; - - public SpawnChangeListener(MultiverseInventories inventories) { - this.inventories = inventories; - } - - @EventHandler(priority = EventPriority.MONITOR) - void onSpawnChange(PlayerSpawnChangeEvent event) { - if (Sharables.isIgnoringSpawnListener(event.getPlayer())) { - return; - } - Player player = event.getPlayer(); - if (event.getCause() == Cause.BED) { - updatePlayerSpawn(player, findBedFromRespawnLocation(event.getNewSpawn())); - return; - } - if (event.getCause() == Cause.RESPAWN_ANCHOR) { - updatePlayerSpawn(player, findAnchorFromRespawnLocation(event.getNewSpawn())); - return; - } - updatePlayerSpawn(player, event.getNewSpawn()); - } - - private void updatePlayerSpawn(Player player, Location location) { - SingleShareWriter.of(this.inventories, player, Sharables.BED_SPAWN) - .write(location == null ? null : location.clone(), true); - } -} diff --git a/src/main/java/org/mvplugins/multiverse/inventories/handleshare/WorldChangeShareHandler.java b/src/main/java/org/mvplugins/multiverse/inventories/handleshare/WorldChangeShareHandler.java index c6bdd788..24ff5a97 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/handleshare/WorldChangeShareHandler.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/handleshare/WorldChangeShareHandler.java @@ -16,14 +16,14 @@ /** * WorldChange implementation of ShareHandler. */ -final class WorldChangeShareHandler extends ShareHandler { +public final class WorldChangeShareHandler extends ShareHandler { private final String fromWorld; private final String toWorld; private final List fromWorldGroups; private final List toWorldGroups; - WorldChangeShareHandler(MultiverseInventories inventories, Player player, String fromWorld, String toWorld) { + public WorldChangeShareHandler(MultiverseInventories inventories, Player player, String fromWorld, String toWorld) { super(inventories, player); this.fromWorld = fromWorld; this.toWorld = toWorld; diff --git a/src/main/java/org/mvplugins/multiverse/inventories/MVEventsListener.java b/src/main/java/org/mvplugins/multiverse/inventories/listeners/MVEventsListener.java similarity index 94% rename from src/main/java/org/mvplugins/multiverse/inventories/MVEventsListener.java rename to src/main/java/org/mvplugins/multiverse/inventories/listeners/MVEventsListener.java index 0f0d136d..fd4d65a9 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/MVEventsListener.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/listeners/MVEventsListener.java @@ -1,24 +1,23 @@ -package org.mvplugins.multiverse.inventories; +package org.mvplugins.multiverse.inventories.listeners; import com.dumptruckman.minecraft.util.Logging; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; import org.jetbrains.annotations.NotNull; import org.jvnet.hk2.annotations.Service; +import org.mvplugins.multiverse.core.dynamiclistener.annotations.EventMethod; import org.mvplugins.multiverse.core.event.MVConfigReloadEvent; import org.mvplugins.multiverse.core.event.MVDebugModeEvent; import org.mvplugins.multiverse.core.event.MVDumpsDebugInfoEvent; import org.mvplugins.multiverse.external.jakarta.inject.Inject; +import org.mvplugins.multiverse.inventories.MultiverseInventories; import org.mvplugins.multiverse.inventories.config.InventoriesConfig; import org.mvplugins.multiverse.inventories.profile.ProfileCacheManager; -import org.mvplugins.multiverse.inventories.profile.ProfileDataSource; import org.mvplugins.multiverse.inventories.profile.group.WorldGroup; import org.mvplugins.multiverse.inventories.profile.group.WorldGroupManager; import java.io.File; @Service -final class MVEventsListener implements Listener { +final class MVEventsListener implements MVInvListener { private final MultiverseInventories inventories; private final InventoriesConfig config; @@ -42,7 +41,7 @@ final class MVEventsListener implements Listener { * * @param event The MVVersionEvent that this plugin will listen for. */ - @EventHandler + @EventMethod void dumpsDebugInfoRequest(MVDumpsDebugInfoEvent event) { event.appendDebugInfo(getDebugInfo()); File configFile = new File(this.inventories.getDataFolder(), "config.yml"); @@ -94,7 +93,7 @@ private String getDebugInfo() { return versionInfo.toString(); } - @EventHandler + @EventMethod void onDebugModeChange(MVDebugModeEvent event) { Logging.setDebugLevel(event.getLevel()); } @@ -104,7 +103,7 @@ void onDebugModeChange(MVDebugModeEvent event) { * * @param event The MVConfigReloadEvent that this plugin will listen for. */ - @EventHandler + @EventMethod void configReload(MVConfigReloadEvent event) { this.inventories.reloadConfig(); event.addConfig("Multiverse-Inventories - config.yml"); diff --git a/src/main/java/org/mvplugins/multiverse/inventories/listeners/MVInvListener.java b/src/main/java/org/mvplugins/multiverse/inventories/listeners/MVInvListener.java new file mode 100644 index 00000000..6e760c37 --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/inventories/listeners/MVInvListener.java @@ -0,0 +1,8 @@ +package org.mvplugins.multiverse.inventories.listeners; + +import org.jvnet.hk2.annotations.Contract; +import org.mvplugins.multiverse.core.dynamiclistener.DynamicListener; + +@Contract +public sealed interface MVInvListener extends DynamicListener permits MVEventsListener, RespawnListener, ShareHandleListener, SpawnChangeListener { +} diff --git a/src/main/java/org/mvplugins/multiverse/inventories/RespawnListener.java b/src/main/java/org/mvplugins/multiverse/inventories/listeners/RespawnListener.java similarity index 85% rename from src/main/java/org/mvplugins/multiverse/inventories/RespawnListener.java rename to src/main/java/org/mvplugins/multiverse/inventories/listeners/RespawnListener.java index 176b6917..ea81a4cb 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/RespawnListener.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/listeners/RespawnListener.java @@ -1,12 +1,12 @@ -package org.mvplugins.multiverse.inventories; +package org.mvplugins.multiverse.inventories.listeners; import org.bukkit.Location; import org.bukkit.World; -import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerRespawnEvent; import org.jvnet.hk2.annotations.Service; +import org.mvplugins.multiverse.core.dynamiclistener.annotations.DefaultEventPriority; +import org.mvplugins.multiverse.core.dynamiclistener.annotations.EventMethod; import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld; import org.mvplugins.multiverse.core.world.WorldManager; import org.mvplugins.multiverse.external.jakarta.inject.Inject; @@ -19,7 +19,7 @@ * Specific events for handling player respawns location */ @Service -final class RespawnListener implements Listener { +final class RespawnListener implements MVInvListener { private final WorldGroupManager worldGroupManager; private final WorldManager worldManager; @@ -38,7 +38,8 @@ final class RespawnListener implements Listener { * * @param event The player respawn event. */ - @EventHandler(priority = EventPriority.LOWEST) + @EventMethod + @DefaultEventPriority(EventPriority.LOWEST) void lowestPriorityRespawn(PlayerRespawnEvent event) { if (!event.isBedSpawn()) { World world = event.getPlayer().getWorld(); @@ -52,7 +53,8 @@ void lowestPriorityRespawn(PlayerRespawnEvent event) { * * @param event The player respawn event. */ - @EventHandler(priority = EventPriority.LOW) + @EventMethod + @DefaultEventPriority(EventPriority.LOW) void lowPriorityRespawn(PlayerRespawnEvent event) { if (!event.isBedSpawn()) { this.handleRespawn(event, EventPriority.LOW); @@ -64,7 +66,8 @@ void lowPriorityRespawn(PlayerRespawnEvent event) { * * @param event The player respawn event. */ - @EventHandler(priority = EventPriority.NORMAL) + @EventMethod + @DefaultEventPriority(EventPriority.NORMAL) void normalPriorityRespawn(PlayerRespawnEvent event) { if (!event.isBedSpawn()) { this.handleRespawn(event, EventPriority.NORMAL); @@ -76,7 +79,8 @@ void normalPriorityRespawn(PlayerRespawnEvent event) { * * @param event The player respawn event. */ - @EventHandler(priority = EventPriority.HIGH) + @EventMethod + @DefaultEventPriority(EventPriority.HIGH) void highPriorityRespawn(PlayerRespawnEvent event) { if (!event.isBedSpawn()) { this.handleRespawn(event, EventPriority.HIGH); @@ -88,7 +92,8 @@ void highPriorityRespawn(PlayerRespawnEvent event) { * * @param event The player respawn event. */ - @EventHandler(priority = EventPriority.HIGHEST) + @EventMethod + @DefaultEventPriority(EventPriority.HIGHEST) void highestPriorityRespawn(PlayerRespawnEvent event) { if (!event.isBedSpawn()) { this.handleRespawn(event, EventPriority.HIGHEST); @@ -100,7 +105,8 @@ void highestPriorityRespawn(PlayerRespawnEvent event) { * * @param event The player respawn event. */ - @EventHandler(priority = EventPriority.MONITOR) + @EventMethod + @DefaultEventPriority(EventPriority.MONITOR) void monitorPriorityRespawn(PlayerRespawnEvent event) { if (!event.isBedSpawn()) { this.handleRespawn(event, EventPriority.MONITOR); diff --git a/src/main/java/org/mvplugins/multiverse/inventories/handleshare/ShareHandleListener.java b/src/main/java/org/mvplugins/multiverse/inventories/listeners/ShareHandleListener.java similarity index 92% rename from src/main/java/org/mvplugins/multiverse/inventories/handleshare/ShareHandleListener.java rename to src/main/java/org/mvplugins/multiverse/inventories/listeners/ShareHandleListener.java index 0a2f2f41..af2751eb 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/handleshare/ShareHandleListener.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/listeners/ShareHandleListener.java @@ -1,12 +1,20 @@ -package org.mvplugins.multiverse.inventories.handleshare; +package org.mvplugins.multiverse.inventories.listeners; import com.dumptruckman.minecraft.util.Logging; import com.google.common.base.Strings; import org.jvnet.hk2.annotations.Service; +import org.mvplugins.multiverse.core.dynamiclistener.annotations.DefaultEventPriority; +import org.mvplugins.multiverse.core.dynamiclistener.annotations.EventMethod; +import org.mvplugins.multiverse.core.dynamiclistener.annotations.IgnoreIfCancelled; import org.mvplugins.multiverse.core.world.WorldManager; import org.mvplugins.multiverse.external.vavr.control.Try; import org.mvplugins.multiverse.inventories.MultiverseInventories; import org.mvplugins.multiverse.inventories.config.InventoriesConfig; +import org.mvplugins.multiverse.inventories.handleshare.GameModeShareHandler; +import org.mvplugins.multiverse.inventories.handleshare.ReadOnlyShareHandler; +import org.mvplugins.multiverse.inventories.handleshare.SingleShareWriter; +import org.mvplugins.multiverse.inventories.handleshare.WorldChangeShareHandler; +import org.mvplugins.multiverse.inventories.handleshare.WriteOnlyShareHandler; import org.mvplugins.multiverse.inventories.profile.ProfileDataSource; import org.mvplugins.multiverse.inventories.profile.key.GlobalProfileKey; import org.mvplugins.multiverse.inventories.profile.key.ProfileKey; @@ -25,9 +33,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Item; import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityPortalEvent; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.AsyncPlayerPreLoginEvent; @@ -55,7 +61,7 @@ * Events related to handling of player profile changes. */ @Service -public final class ShareHandleListener implements Listener { +final class ShareHandleListener implements MVInvListener { private final MultiverseInventories inventories; private final InventoriesConfig config; @@ -79,7 +85,8 @@ public final class ShareHandleListener implements Listener { this.profileContainerStoreProvider = profileContainerStoreProvider; } - @EventHandler(priority = EventPriority.MONITOR) + @EventMethod + @DefaultEventPriority(EventPriority.MONITOR) void playerPreLogin(AsyncPlayerPreLoginEvent event) { if (event.getLoginResult() != Result.ALLOWED) { return; @@ -105,7 +112,7 @@ void playerPreLogin(AsyncPlayerPreLoginEvent event) { * * @param event The player join event. */ - @EventHandler + @EventMethod void playerJoin(final PlayerJoinEvent event) { final Player player = event.getPlayer(); // Just in case AsyncPlayerPreLoginEvent was still the old name @@ -146,7 +153,7 @@ private void verifyCorrectPlayerName(UUID uuid, String name) { * * @param event The player quit event. */ - @EventHandler + @EventMethod void playerQuit(final PlayerQuitEvent event) { final Player player = event.getPlayer(); final String world = event.getPlayer().getWorld().getName(); @@ -181,7 +188,8 @@ private void verifyCorrectWorld(Player player, String world, GlobalProfile globa * * @param event The game mode change event. */ - @EventHandler(priority = EventPriority.MONITOR) + @EventMethod + @DefaultEventPriority(EventPriority.MONITOR) void playerGameModeChange(PlayerGameModeChangeEvent event) { if (event.isCancelled() || !config.getEnableGamemodeShareHandling()) { return; @@ -197,7 +205,8 @@ void playerGameModeChange(PlayerGameModeChangeEvent event) { * * @param event The world change event. */ - @EventHandler(priority = EventPriority.LOW) + @EventMethod + @DefaultEventPriority(EventPriority.LOW) void playerChangedWorld(PlayerChangedWorldEvent event) { Player player = event.getPlayer(); World fromWorld = event.getFrom(); @@ -223,7 +232,8 @@ void playerChangedWorld(PlayerChangedWorldEvent event) { * * @param event The player teleport event. */ - @EventHandler(priority = EventPriority.MONITOR) + @EventMethod + @DefaultEventPriority(EventPriority.MONITOR) void playerTeleport(PlayerTeleportEvent event) { if (event.isCancelled() || event.getFrom().getWorld().equals(event.getTo().getWorld()) @@ -243,7 +253,8 @@ void playerTeleport(PlayerTeleportEvent event) { * * @param event The player death event. */ - @EventHandler(priority = EventPriority.MONITOR) + @EventMethod + @DefaultEventPriority(EventPriority.MONITOR) void playerDeath(PlayerDeathEvent event) { Logging.finer("=== Handling PlayerDeathEvent for: " + event.getEntity().getName() + " ==="); String deathWorld = event.getEntity().getWorld().getName(); @@ -267,7 +278,8 @@ private void resetStatsOnDeath(PlayerDeathEvent event, PlayerProfile profile) { profileDataSource.updatePlayerProfile(profile); } - @EventHandler(priority = EventPriority.MONITOR) + @EventMethod + @DefaultEventPriority(EventPriority.MONITOR) void playerRespawn(PlayerRespawnEvent event) { Location respawnLoc = event.getRespawnLocation(); if (respawnLoc == null) { @@ -284,7 +296,9 @@ void playerRespawn(PlayerRespawnEvent event) { 2L); } - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + @EventMethod + @IgnoreIfCancelled + @DefaultEventPriority(EventPriority.HIGH) void entityPortal(EntityPortalEvent event) { Entity entity = event.getEntity(); if (!(entity instanceof Item) && !(entity instanceof InventoryHolder)) { @@ -334,7 +348,7 @@ void entityPortal(EntityPortalEvent event) { event.setCancelled(true); } - @EventHandler + @EventMethod void worldUnload(WorldUnloadEvent event) { String unloadWorldName = event.getWorld().getName(); diff --git a/src/main/java/org/mvplugins/multiverse/inventories/listeners/SpawnChangeListener.java b/src/main/java/org/mvplugins/multiverse/inventories/listeners/SpawnChangeListener.java new file mode 100644 index 00000000..27f4c7d9 --- /dev/null +++ b/src/main/java/org/mvplugins/multiverse/inventories/listeners/SpawnChangeListener.java @@ -0,0 +1,85 @@ +package org.mvplugins.multiverse.inventories.listeners; + +import com.destroystokyo.paper.event.player.PlayerSetSpawnEvent; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerSpawnChangeEvent; +import org.jvnet.hk2.annotations.Service; +import org.mvplugins.multiverse.core.dynamiclistener.EventRunnable; +import org.mvplugins.multiverse.core.dynamiclistener.annotations.DefaultEventPriority; +import org.mvplugins.multiverse.core.dynamiclistener.annotations.EventClass; +import org.mvplugins.multiverse.core.dynamiclistener.annotations.SkipIfEventExist; +import org.mvplugins.multiverse.external.jakarta.inject.Inject; +import org.mvplugins.multiverse.inventories.MultiverseInventories; +import org.mvplugins.multiverse.inventories.handleshare.SingleShareWriter; +import org.mvplugins.multiverse.inventories.share.Sharables; + +import static org.mvplugins.multiverse.inventories.util.MinecraftTools.findAnchorFromRespawnLocation; +import static org.mvplugins.multiverse.inventories.util.MinecraftTools.findBedFromRespawnLocation; + +/** + * Handles player spawn location changes for BED_SPAWN sharable. + */ +@Service +final class SpawnChangeListener implements MVInvListener { + + private final MultiverseInventories inventories; + + @Inject + public SpawnChangeListener(MultiverseInventories inventories) { + this.inventories = inventories; + } + + @EventClass("com.destroystokyo.paper.event.player.PlayerSetSpawnEvent") + @DefaultEventPriority(EventPriority.MONITOR) + EventRunnable onPlayerSetSpawn() { + return new EventRunnable() { + @Override + public void onEvent(PlayerSetSpawnEvent event) { + if (Sharables.isIgnoringSpawnListener(event.getPlayer())) { + return; + } + Player player = event.getPlayer(); + if (event.getCause() == PlayerSetSpawnEvent.Cause.BED) { + updatePlayerSpawn(player, findBedFromRespawnLocation(event.getLocation())); + return; + } + if (event.getCause() == PlayerSetSpawnEvent.Cause.RESPAWN_ANCHOR) { + updatePlayerSpawn(player, findAnchorFromRespawnLocation(event.getLocation())); + return; + } + updatePlayerSpawn(player, event.getLocation()); + } + }; + } + + @EventClass("org.bukkit.event.player.PlayerSpawnChangeEvent") + @SkipIfEventExist("com.destroystokyo.paper.event.player.PlayerSetSpawnEvent") + @DefaultEventPriority(EventPriority.MONITOR) + EventRunnable onPlayerSpawnChange() { + return new EventRunnable() { + @Override + public void onEvent(PlayerSpawnChangeEvent event) { + if (Sharables.isIgnoringSpawnListener(event.getPlayer())) { + return; + } + Player player = event.getPlayer(); + if (event.getCause() == PlayerSpawnChangeEvent.Cause.BED) { + updatePlayerSpawn(player, findBedFromRespawnLocation(event.getNewSpawn())); + return; + } + if (event.getCause() == PlayerSpawnChangeEvent.Cause.RESPAWN_ANCHOR) { + updatePlayerSpawn(player, findAnchorFromRespawnLocation(event.getNewSpawn())); + return; + } + updatePlayerSpawn(player, event.getNewSpawn()); + } + }; + } + + private void updatePlayerSpawn(Player player, Location location) { + SingleShareWriter.of(this.inventories, player, Sharables.BED_SPAWN) + .write(location == null ? null : location.clone(), true); + } +} diff --git a/src/main/java/org/mvplugins/multiverse/inventories/share/Sharables.java b/src/main/java/org/mvplugins/multiverse/inventories/share/Sharables.java index dc94c24a..ff1a25a9 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/share/Sharables.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/share/Sharables.java @@ -3,8 +3,10 @@ import com.dumptruckman.minecraft.util.Logging; import com.google.common.collect.Sets; import org.bukkit.advancement.AdvancementProgress; +import org.jetbrains.annotations.ApiStatus; import org.mvplugins.multiverse.core.economy.MVEconomist; import org.mvplugins.multiverse.core.teleportation.AsyncSafetyTeleporter; +import org.mvplugins.multiverse.core.utils.ReflectHelper; import org.mvplugins.multiverse.external.vavr.control.Option; import org.mvplugins.multiverse.inventories.MultiverseInventories; import org.mvplugins.multiverse.inventories.config.InventoriesConfig; @@ -554,7 +556,7 @@ public boolean updatePlayer(Player player, ProfileData profile) { new SharableHandler() { @Override public void updateProfile(ProfileData profile, Player player) { - if (inventories.isUsingSpawnChangeEvent()) { + if (hasSetSpawnEvent) { // Bed spawn location already updated during PlayerSpawnChangeEvent return; } @@ -597,7 +599,10 @@ public boolean updatePlayer(Player player, ProfileData profile) { // todo: handle this somewhere better private static List ignoreSpawnListener = new ArrayList<>(); + private static boolean hasSetSpawnEvent = ReflectHelper.hasClass("org.bukkit.event.player.PlayerSpawnChangeEvent") + || ReflectHelper.hasClass("com.destroystokyo.paper.event.player.PlayerSetSpawnEvent"); + @ApiStatus.Internal public static boolean isIgnoringSpawnListener(Player player) { return ignoreSpawnListener.contains(player.getUniqueId()); } diff --git a/src/main/java/org/mvplugins/multiverse/inventories/util/MinecraftTools.java b/src/main/java/org/mvplugins/multiverse/inventories/util/MinecraftTools.java index 0fa4771d..2375955e 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/util/MinecraftTools.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/util/MinecraftTools.java @@ -56,7 +56,7 @@ public static ItemStack[] fillWithAir(ItemStack[] items) { } } } - Logging.warning("Unable to anchor, respawn may not work as expected!"); + Logging.warning("Unable to find bed, respawn may not work as expected!"); return respawnLocation; } @@ -77,7 +77,7 @@ public static ItemStack[] fillWithAir(ItemStack[] items) { } } } - Logging.warning("Unable to anchor, respawn may not work as expected!"); + Logging.warning("Unable to find anchor, respawn may not work as expected!"); return respawnLocation; } diff --git a/src/test/java/org/mvplugins/multiverse/inventories/InjectionTest.kt b/src/test/java/org/mvplugins/multiverse/inventories/InjectionTest.kt index 36d7c644..53dad107 100644 --- a/src/test/java/org/mvplugins/multiverse/inventories/InjectionTest.kt +++ b/src/test/java/org/mvplugins/multiverse/inventories/InjectionTest.kt @@ -4,7 +4,7 @@ import org.junit.jupiter.api.Test import org.mvplugins.multiverse.inventories.commands.InventoriesCommand import org.mvplugins.multiverse.inventories.config.InventoriesConfig import org.mvplugins.multiverse.inventories.dataimport.DataImportManager -import org.mvplugins.multiverse.inventories.handleshare.ShareHandleListener +import org.mvplugins.multiverse.inventories.listeners.MVInvListener import org.mvplugins.multiverse.inventories.profile.ProfileDataSource import org.mvplugins.multiverse.inventories.profile.container.ProfileContainerStoreProvider import org.mvplugins.multiverse.inventories.profile.group.WorldGroupManager @@ -25,7 +25,7 @@ class InjectionTest : TestWithMockBukkit() { @Test fun `InventoriesListener is available as a service`() { - assertNotNull(serviceLocator.getActiveService(ShareHandleListener::class.java)) + assertEquals(4, serviceLocator.getAllActiveServices(MVInvListener::class.java).size) } @Test