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 <bonne@bonne.id.lv>

* Update IslandTeamKickCommand.java

* Change QuarantinedWorld to PendingKicks.

Increase PlayerChangedWorldEvent event priority.
This commit is contained in:
BONNe 2019-02-21 17:55:09 +02:00 committed by Florian CUNY
parent cdb83e576a
commit 54811c5dbd
3 changed files with 100 additions and 2 deletions

View File

@ -13,6 +13,7 @@ import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.Island;
public class IslandTeamKickCommand extends ConfirmableCommand { public class IslandTeamKickCommand extends ConfirmableCommand {
public IslandTeamKickCommand(CompositeCommand islandTeamCommand) { public IslandTeamKickCommand(CompositeCommand islandTeamCommand) {
@ -76,13 +77,20 @@ public class IslandTeamKickCommand extends ConfirmableCommand {
if (target.isOnline()) { if (target.isOnline()) {
target.getPlayer().getEnderChest().clear(); 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 (getIWM().isOnLeaveResetInventory(getWorld())) {
if (target.isOnline()) { if (target.isOnline()) {
target.getPlayer().getInventory().clear(); 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())) { if (getSettings().isUseEconomy() && getIWM().isOnLeaveResetMoney(getWorld())) {
getPlugin().getVault().ifPresent(vault -> vault.withdraw(target, vault.getBalance(target))); getPlugin().getVault().ifPresent(vault -> vault.withdraw(target, vault.getBalance(target)));

View File

@ -1,7 +1,9 @@
package world.bentobox.bentobox.database.objects; package world.bentobox.bentobox.database.objects;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -34,6 +36,14 @@ public class Players implements DataObject {
@Expose @Expose
private Map<String, Integer> deaths = new HashMap<>(); private Map<String, Integer> deaths = new HashMap<>();
/**
* This variable stores set of worlds where user inventory must be cleared.
* @since 1.3.0
*/
@Expose
private Set<String> pendingKicks = new HashSet<>();
/** /**
* This is required for database storage * This is required for database storage
*/ */
@ -271,4 +281,33 @@ public class Players implements DataObject {
this.deaths = deaths; this.deaths = deaths;
} }
/**
* This method returns the pendingKicks value.
* @return the value of pendingKicks.
*/
public Set<String> getPendingKicks()
{
return pendingKicks;
}
/**
* This method sets the pendingKicks value.
* @param pendingKicks the pendingKicks new value.
*/
public void setPendingKicks(Set<String> 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());
}
} }

View File

@ -6,9 +6,11 @@ import java.util.UUID;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.eclipse.jdt.annotation.NonNull; 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.localization.TextVariables;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.database.objects.Players;
import world.bentobox.bentobox.lists.Flags; import world.bentobox.bentobox.lists.Flags;
import world.bentobox.bentobox.managers.PlayersManager; import world.bentobox.bentobox.managers.PlayersManager;
import world.bentobox.bentobox.managers.RanksManager; 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())) { if (plugin.getIWM().inWorld(user.getLocation()) && Flags.REMOVE_MOBS.isSetForWorld(user.getWorld())) {
plugin.getIslands().clearArea(user.getLocation()); 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) { private void runAutomatedOwnershipTransfer(User user) {
plugin.getIWM().getOverWorlds().stream() plugin.getIWM().getOverWorlds().stream()
.filter(world -> plugin.getIslands().hasIsland(world, user) && !plugin.getIslands().isOwner(world, user.getUniqueId())) .filter(world -> plugin.getIslands().hasIsland(world, user) && !plugin.getIslands().isOwner(world, user.getUniqueId()))