From 396425a52d706a7a92f75e9f9420ad33f35c3a03 Mon Sep 17 00:00:00 2001 From: Florian CUNY Date: Wed, 2 Jan 2019 23:02:52 +0100 Subject: [PATCH] Started implementing automated island ownership transfer #167 --- .../world/bentobox/bentobox/Settings.java | 46 ++++++++++- .../bentobox/listeners/JoinLeaveListener.java | 82 +++++++++++++++---- 2 files changed, 107 insertions(+), 21 deletions(-) diff --git a/src/main/java/world/bentobox/bentobox/Settings.java b/src/main/java/world/bentobox/bentobox/Settings.java index 01eaaa209..8db1ee76a 100644 --- a/src/main/java/world/bentobox/bentobox/Settings.java +++ b/src/main/java/world/bentobox/bentobox/Settings.java @@ -149,6 +149,25 @@ public class Settings implements DataObject { @ConfigEntry(path = "island.custom-ranks", experimental = true) private Map customRanks = new HashMap<>(); + // Automated ownership transfer + @ConfigComment("Toggles the automated ownership transfer.") + @ConfigComment("It automatically transfers the ownership of an island to one of its members in case the current owner is inactive.") + @ConfigComment("More precisely, it transfers the ownership of the island to the player who's active, whose rank is the highest") + @ConfigComment("and who's been part of the island the longest time.") + @ConfigComment("Setting this to 'false' will disable the feature.") + @ConfigEntry(path = "island.automated-ownership-transfer.enable") + private boolean enableAutoOwnershipTransfer = true; + + @ConfigComment("Time in days since the island owner's last disconnection before they are considered inactive.") + @ConfigEntry(path = "island.automated-ownership-transfer.inactivity-threshold") + private int autoOwnershipTransferInactivityThreshold = 30; + + @ConfigComment("Ranks are being considered when transferring the island ownership to one of its member.") + @ConfigComment("Ignoring ranks will result in the island ownership being transferred to the player who's active and") + @ConfigComment("who's been member of the island the longest time.") + @ConfigEntry(path = "island.automated-ownership-transfer.ignore-ranks") + private boolean autoOwnershipTransferIgnoreRanks = false; + //---------------------------------------------------------------------------------------/ @ConfigComment("These settings should not be edited") private String uniqueId = "config"; @@ -386,6 +405,30 @@ public class Settings implements DataObject { this.customRanks = customRanks; } + public boolean isEnableAutoOwnershipTransfer() { + return enableAutoOwnershipTransfer; + } + + public void setEnableAutoOwnershipTransfer(boolean enableAutoOwnershipTransfer) { + this.enableAutoOwnershipTransfer = enableAutoOwnershipTransfer; + } + + public int getAutoOwnershipTransferInactivityThreshold() { + return autoOwnershipTransferInactivityThreshold; + } + + public void setAutoOwnershipTransferInactivityThreshold(int autoOwnershipTransferInactivityThreshold) { + this.autoOwnershipTransferInactivityThreshold = autoOwnershipTransferInactivityThreshold; + } + + public boolean isAutoOwnershipTransferIgnoreRanks() { + return autoOwnershipTransferIgnoreRanks; + } + + public void setAutoOwnershipTransferIgnoreRanks(boolean autoOwnershipTransferIgnoreRanks) { + this.autoOwnershipTransferIgnoreRanks = autoOwnershipTransferIgnoreRanks; + } + /** * @return the uniqueId */ @@ -401,7 +444,4 @@ public class Settings implements DataObject { public void setUniqueId(String uniqueId) { this.uniqueId = uniqueId; } - - - } \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java b/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java index d558c5a76..75a2a8b2d 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java @@ -1,7 +1,12 @@ package world.bentobox.bentobox.listeners; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.UUID; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -48,24 +53,13 @@ public class JoinLeaveListener implements Listener { .filter(w -> event.getPlayer().getLastPlayed() < plugin.getIWM().getResetEpoch(w)) .forEach(w -> players.setResets(w, playerUUID, 0)); + // Automated island ownership transfer + if (plugin.getSettings().isEnableAutoOwnershipTransfer()) { + runAutomatedOwnershipTransfer(user); + } + // Update the island range of the islands the player owns - plugin.getIWM().getOverWorlds().stream() - .filter(world -> plugin.getIslands().isOwner(world, user.getUniqueId())) - .forEach(world -> { - Island island = plugin.getIslands().getIsland(world, user); - - // Check if new owner has a different range permission than the island size - int range = user.getPermissionValue(plugin.getIWM().getAddon(island.getWorld()).get().getPermissionPrefix() + "island.range", plugin.getIWM().getIslandProtectionRange(Util.getWorld(island.getWorld()))); - - // Range can go up or down - if (range != island.getProtectionRange()) { - user.sendMessage("commands.admin.setrange.range-updated", TextVariables.NUMBER, String.valueOf(range)); - plugin.log("Setowner: Island protection range changed from " + island.getProtectionRange() + " to " - + range + " for " + user.getName() + " due to permission."); - } - - island.setProtectionRange(range); - }); + updateIslandRange(user); // Set the player's name (it may have changed), but only if it isn't empty if (!user.getName().isEmpty()) { @@ -82,6 +76,59 @@ public class JoinLeaveListener implements Listener { } } + private void runAutomatedOwnershipTransfer(User user) { + plugin.getIWM().getOverWorlds().stream() + .filter(world -> plugin.getIslands().hasIsland(world, user) && !plugin.getIslands().isOwner(world, user.getUniqueId())) + .forEach(world -> { + Island island = plugin.getIslands().getIsland(world, user); + + OfflinePlayer owner = Bukkit.getOfflinePlayer(island.getOwner()); + + // Converting the setting (in days) to milliseconds. + long inactivityThreshold = plugin.getSettings().getAutoOwnershipTransferInactivityThreshold() * 24 * 60 * 60 * 1000; + long timestamp = System.currentTimeMillis() - inactivityThreshold; + + // We make sure the current owner is inactive. + if (owner.getLastPlayed() != 0 && owner.getLastPlayed() < timestamp) { + // The current owner is inactive + // Now, let's run through all of the island members (except the player who's just joined) and see who's active. + // Sadly, this will make us calculate the owner inactivity again... :( + List candidates = Arrays.asList((UUID[]) island.getMemberSet().stream() + .filter(uuid -> !user.getUniqueId().equals(uuid)) + .filter(uuid -> Bukkit.getOfflinePlayer(uuid).getLastPlayed() != 0 + && Bukkit.getOfflinePlayer(uuid).getLastPlayed() < timestamp) + .toArray()); + + if (!candidates.isEmpty()) { + if (!plugin.getSettings().isAutoOwnershipTransferIgnoreRanks()) { + // Ranks are not ignored, our candidates can only have the highest rank + + } + } + } + }); + } + + private void updateIslandRange(User user) { + plugin.getIWM().getOverWorlds().stream() + .filter(world -> plugin.getIslands().isOwner(world, user.getUniqueId())) + .forEach(world -> { + Island island = plugin.getIslands().getIsland(world, user); + + // Check if new owner has a different range permission than the island size + int range = user.getPermissionValue(plugin.getIWM().getAddon(island.getWorld()).get().getPermissionPrefix() + "island.range", plugin.getIWM().getIslandProtectionRange(Util.getWorld(island.getWorld()))); + + // Range can go up or down + if (range != island.getProtectionRange()) { + user.sendMessage("commands.admin.setrange.range-updated", TextVariables.NUMBER, String.valueOf(range)); + plugin.log("Island protection range changed from " + island.getProtectionRange() + " to " + + range + " for " + user.getName() + " due to permission."); + } + + island.setProtectionRange(range); + }); + } + @EventHandler(priority = EventPriority.NORMAL) public void onPlayerQuit(final PlayerQuitEvent event) { // Remove any coops if all the island players have left @@ -105,6 +152,5 @@ public class JoinLeaveListener implements Listener { plugin.getIslands().clearRank(RanksManager.COOP_RANK, event.getPlayer().getUniqueId()); players.save(event.getPlayer().getUniqueId()); User.removePlayer(event.getPlayer()); - } }