From 54811c5dbda42da310d0644480640b0b2e641c7d Mon Sep 17 00:00:00 2001 From: BONNe Date: Thu, 21 Feb 2019 17:55:09 +0200 Subject: [PATCH] Fix issue with offline players that kept inventory (#564) Fixes #521 * Fix issue with offline players that kept inventory, after being kicked out of team. (#521) * Update src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java Co-Authored-By: BONNe * Update IslandTeamKickCommand.java * Change QuarantinedWorld to PendingKicks. Increase PlayerChangedWorldEvent event priority. --- .../island/team/IslandTeamKickCommand.java | 12 ++++- .../bentobox/database/objects/Players.java | 39 ++++++++++++++ .../bentobox/listeners/JoinLeaveListener.java | 51 +++++++++++++++++++ 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java index b76362b68..4ab66b329 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java @@ -13,6 +13,7 @@ import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; + public class IslandTeamKickCommand extends ConfirmableCommand { public IslandTeamKickCommand(CompositeCommand islandTeamCommand) { @@ -76,13 +77,20 @@ public class IslandTeamKickCommand extends ConfirmableCommand { if (target.isOnline()) { target.getPlayer().getEnderChest().clear(); } - // FIXME need some special handling here if the target's offline. + else { + getPlayers().getPlayer(targetUUID).addToPendingKick(getWorld()); + getPlayers().save(targetUUID); + } } if (getIWM().isOnLeaveResetInventory(getWorld())) { if (target.isOnline()) { target.getPlayer().getInventory().clear(); } - // FIXME need some special handling here if the target's offline. + else { + getPlayers().getPlayer(targetUUID).addToPendingKick(getWorld()); + getPlayers().save(targetUUID); + + } } if (getSettings().isUseEconomy() && getIWM().isOnLeaveResetMoney(getWorld())) { getPlugin().getVault().ifPresent(vault -> vault.withdraw(target, vault.getBalance(target))); diff --git a/src/main/java/world/bentobox/bentobox/database/objects/Players.java b/src/main/java/world/bentobox/bentobox/database/objects/Players.java index 7dbdbc34f..a6d41bcae 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/Players.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/Players.java @@ -1,7 +1,9 @@ package world.bentobox.bentobox.database.objects; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; @@ -34,6 +36,14 @@ public class Players implements DataObject { @Expose private Map deaths = new HashMap<>(); + /** + * This variable stores set of worlds where user inventory must be cleared. + * @since 1.3.0 + */ + @Expose + private Set pendingKicks = new HashSet<>(); + + /** * This is required for database storage */ @@ -271,4 +281,33 @@ public class Players implements DataObject { this.deaths = deaths; } + + /** + * This method returns the pendingKicks value. + * @return the value of pendingKicks. + */ + public Set getPendingKicks() + { + return pendingKicks; + } + + + /** + * This method sets the pendingKicks value. + * @param pendingKicks the pendingKicks new value. + */ + public void setPendingKicks(Set pendingKicks) + { + this.pendingKicks = pendingKicks; + } + + + /** + * This method adds given world in pendingKicks world set. + * @param world World that must be added to pendingKicks set. + */ + public void addToPendingKick(World world) + { + this.pendingKicks.add(Util.getWorld(world).getName()); + } } diff --git a/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java b/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java index 0cbce88bd..b6405d7e1 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java @@ -6,9 +6,11 @@ import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; +import org.bukkit.World; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.eclipse.jdt.annotation.NonNull; @@ -17,6 +19,7 @@ import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.database.objects.Players; import world.bentobox.bentobox.lists.Flags; import world.bentobox.bentobox.managers.PlayersManager; import world.bentobox.bentobox.managers.RanksManager; @@ -73,9 +76,57 @@ public class JoinLeaveListener implements Listener { if (plugin.getIWM().inWorld(user.getLocation()) && Flags.REMOVE_MOBS.isSetForWorld(user.getWorld())) { plugin.getIslands().clearArea(user.getLocation()); } + + // Clear inventory if required + this.clearPlayersInventory(Util.getWorld(event.getPlayer().getWorld()), + User.getInstance(event.getPlayer())); } } + + /** + * This event will clean players inventor + * @param event SwitchWorld event. + */ + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPlayerSwitchWorld(final PlayerChangedWorldEvent event) + { + // Clear inventory if required + this.clearPlayersInventory(Util.getWorld(event.getPlayer().getWorld()), + User.getInstance(event.getPlayer())); + } + + + /** + * This method clears player inventory and ender chest if given world is quarantined + * in user data file and it is required by plugin settings. + * @param world World where cleaning must occur. + * @param user Targeted user. + */ + private void clearPlayersInventory(World world, User user) + { + // Clear inventory if required + Players players = this.players.getPlayer(user.getUniqueId()); + + if (!players.getPendingKicks().isEmpty() && + players.getPendingKicks().contains(world.getName())) + { + if (plugin.getIWM().isOnLeaveResetEnderChest(world)) + { + user.getPlayer().getEnderChest().clear(); + } + + if (plugin.getIWM().isOnLeaveResetInventory(world)) + { + user.getPlayer().getInventory().clear(); + } + + players.getPendingKicks().remove(world.getName()); + this.players.save(user.getUniqueId()); + } + } + + private void runAutomatedOwnershipTransfer(User user) { plugin.getIWM().getOverWorlds().stream() .filter(world -> plugin.getIslands().hasIsland(world, user) && !plugin.getIslands().isOwner(world, user.getUniqueId()))