Started implementing automated island ownership transfer

#167
This commit is contained in:
Florian CUNY 2019-01-02 23:02:52 +01:00
parent 4ae36ef8e0
commit 396425a52d
2 changed files with 107 additions and 21 deletions

View File

@ -149,6 +149,25 @@ public class Settings implements DataObject {
@ConfigEntry(path = "island.custom-ranks", experimental = true)
private Map<String, Integer> 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;
}
}

View File

@ -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));
// 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.");
// Automated island ownership transfer
if (plugin.getSettings().isEnableAutoOwnershipTransfer()) {
runAutomatedOwnershipTransfer(user);
}
island.setProtectionRange(range);
});
// Update the island range of the islands the player owns
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<UUID> 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());
}
}