Handle island deletion better

This commit is contained in:
tastybento 2024-04-10 23:00:20 -07:00
parent 12b08aacc6
commit 8b15888968
4 changed files with 136 additions and 58 deletions

View File

@ -119,14 +119,6 @@ public class IslandsManager {
islandCache.addIsland(island);
}
});
// Remove islands
MultiLib.onString(plugin, "bentobox-deleteIsland", id -> {
BentoBox.getInstance().logDebug("Delete island " + id);
Island island = handler.loadObject(id);
if (island != null) {
islandCache.removeIsland(island);
}
});
// Set or clear spawn
MultiLib.onString(plugin, "bentobox-setspawn", sp -> {
String[] split = sp.split(",");
@ -275,6 +267,7 @@ public class IslandsManager {
* @param involvedPlayer - player related to the island deletion, if any
*/
public void deleteIsland(@NonNull Island island, boolean removeBlocks, @Nullable UUID involvedPlayer) {
BentoBox.getInstance().logDebug("Deleting island " + island.getUniqueId() + " remove blocks = " + removeBlocks);
// Fire event
IslandBaseEvent event = IslandEvent.builder().island(island).involvedPlayer(involvedPlayer)
.reason(Reason.DELETE).build();
@ -284,19 +277,18 @@ public class IslandsManager {
// Set the owner of the island to no one.
island.setOwner(null);
island.setFlag(Flags.LOCK, RanksManager.VISITOR_RANK);
island.setDeleted(true);
if (removeBlocks) {
// Remove island from the cache
islandCache.deleteIslandFromCache(island);
// Delete the island
handler.deleteObject(island);
// Inform other servers
MultiLib.notify("bentobox-deletedIsland", island.getUniqueId());
// Remove players from island
removePlayersFromIsland(island);
if (!plugin.getSettings().isKeepPreviousIslandOnReset()) {
// Remove blocks from world
plugin.getIslandDeletionManager().getIslandChunkDeletionManager().add(new IslandDeletion(island));
}
// Delete the island from the database
handler.deleteObject(island);
}
}

View File

@ -9,6 +9,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
@ -59,8 +60,13 @@ public class IslandCache {
* @param newIsland island
*/
public void updateIsland(@NonNull Island newIsland) {
if (newIsland.isDeleted()) {
this.deleteIslandFromCache(newIsland);
return;
}
// Get the old island
Island oldIsland = islandsById.get(newIsland.getUniqueId());
compareIslands(oldIsland, newIsland);
Set<UUID> newMembers = newIsland.getMembers().keySet();
if (oldIsland != null) {
Set<UUID> oldMembers = oldIsland.getMembers().keySet();
@ -90,6 +96,113 @@ public class IslandCache {
}
public void compareIslands(Island island1, Island island2) {
if (island1 == null || island2 == null) {
BentoBox.getInstance().logDebug("One or both islands are null. Cannot compare.");
return;
}
if (!island1.getUniqueId().equals(island2.getUniqueId())) {
BentoBox.getInstance().logDebug("Island unique IDs are different.");
}
if (island1.isDeleted() != island2.isDeleted()) {
BentoBox.getInstance().logDebug("Island deleted states are different.");
}
if (!Objects.equals(island1.getCenter(), island2.getCenter())) {
BentoBox.getInstance().logDebug("Island centers are different.");
}
if (island1.getRange() != island2.getRange()) {
BentoBox.getInstance().logDebug("Island ranges are different.");
}
if (island1.getProtectionRange() != island2.getProtectionRange()) {
BentoBox.getInstance().logDebug("Island protection ranges are different.");
}
if (!island1.getBonusRanges().equals(island2.getBonusRanges())) {
BentoBox.getInstance().logDebug("Island bonus ranges are different.");
}
if (island1.getMaxEverProtectionRange() != island2.getMaxEverProtectionRange()) {
BentoBox.getInstance().logDebug("Island max ever protection ranges are different.");
}
if (!island1.getWorld().equals(island2.getWorld())) {
BentoBox.getInstance().logDebug("Island worlds are different.");
}
if (!Objects.equals(island1.getGameMode(), island2.getGameMode())) {
BentoBox.getInstance().logDebug("Island game modes are different.");
}
if (!Objects.equals(island1.getName(), island2.getName())) {
BentoBox.getInstance().logDebug("Island names are different.");
}
if (island1.getCreatedDate() != island2.getCreatedDate()) {
BentoBox.getInstance().logDebug("Island created dates are different.");
}
if (island1.getUpdatedDate() != island2.getUpdatedDate()) {
BentoBox.getInstance().logDebug("Island updated dates are different.");
}
if (!Objects.equals(island1.getOwner(), island2.getOwner())) {
BentoBox.getInstance().logDebug("Island owners are different.");
}
if (!island1.getMembers().equals(island2.getMembers())) {
BentoBox.getInstance().logDebug("Island members are different.");
}
if (!Objects.equals(island1.getMaxMembers(), island2.getMaxMembers())) {
BentoBox.getInstance().logDebug("Island max members are different.");
}
if (island1.isSpawn() != island2.isSpawn()) {
BentoBox.getInstance().logDebug("Island spawn states are different.");
}
if (!island1.getFlags().equals(island2.getFlags())) {
BentoBox.getInstance().logDebug("Island flags are different.");
}
if (!island1.getHistory().equals(island2.getHistory())) {
BentoBox.getInstance().logDebug("Island histories are different.");
}
if (!island1.getSpawnPoint().equals(island2.getSpawnPoint())) {
BentoBox.getInstance().logDebug("Island spawn points are different.");
}
if (island1.isDoNotLoad() != island2.isDoNotLoad()) {
BentoBox.getInstance().logDebug("Island do not load states are different.");
}
if (!island1.getCooldowns().equals(island2.getCooldowns())) {
BentoBox.getInstance().logDebug("Island cooldowns are different.");
}
if (!Objects.equals(island1.getCommandRanks(), island2.getCommandRanks())) {
BentoBox.getInstance().logDebug("Island command ranks are different.");
}
if (!Objects.equals(island1.getMetaData(), island2.getMetaData())) {
BentoBox.getInstance().logDebug("Island metadata are different.");
}
if (!Objects.equals(island1.getHomes(), island2.getHomes())) {
BentoBox.getInstance().logDebug("Island homes are different.");
}
if (!Objects.equals(island1.getMaxHomes(), island2.getMaxHomes())) {
BentoBox.getInstance().logDebug("Island max homes are different.");
}
}
/**
* Adds an island to the grid
*
@ -148,6 +261,7 @@ public class IslandCache {
*/
public boolean deleteIslandFromCache(@NonNull Island island) {
if (!islandsByLocation.remove(island.getCenter(), island)) {
// Already deleted
return false;
}
islandsById.remove(island.getUniqueId());
@ -416,27 +530,6 @@ public class IslandCache {
return islandsById.get(uniqueId);
}
/**
* Removes an island from the cache completely without altering the island
* object
*
* @param island - island to remove
* @since 1.3.0
*/
public void removeIsland(@NonNull Island island) {
islandsByLocation.values().removeIf(island::equals);
islandsById.values().removeIf(island::equals);
islandsByUUID.values().forEach(s -> s.removeIf(island::equals));
World w = Util.getWorld(island.getWorld());
if (w == null) {
return;
}
if (grids.containsKey(w)) {
grids.get(w).removeFromGrid(island);
}
}
/**
* Resets all islands in this game mode to default flag settings
*

View File

@ -3,7 +3,6 @@ package world.bentobox.bentobox.managers.island;
import java.util.Map.Entry;
import java.util.TreeMap;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.database.objects.Island;
/**
@ -57,31 +56,23 @@ class IslandGrid {
* @return true if island existed and was deleted, false if there was nothing to delete
*/
public boolean removeFromGrid(Island island) {
// Remove from grid
if (island != null) {
int x = island.getMinX();
int z = island.getMinZ();
if (grid.containsKey(x)) {
TreeMap<Integer, String> zEntry = grid.get(x);
if (zEntry.containsKey(z)) {
// Island exists - delete it
zEntry.remove(z);
grid.put(x, zEntry);
return true;
}
}
}
return false;
}
String id = island.getUniqueId();
boolean removed = grid.values().stream()
.anyMatch(innerMap -> innerMap.values().removeIf(innerValue -> innerValue.equals(id)));
grid.values().removeIf(TreeMap::isEmpty);
return removed;
}
/**
* Retrieves the island located at the specified x and z coordinates, covering both the protected area
* and the full island space. Returns null if no island exists at the given location.
*
* @param x the x coordinate of the location
* @param z the z coordinate of the location
* @return the Island at the specified location, or null if no island is found
*/
* Retrieves the island located at the specified x and z coordinates, covering both the protected area
* and the full island space. Returns null if no island exists at the given location.
*
* @param x the x coordinate of the location
* @param z the z coordinate of the location
* @return the Island at the specified location, or null if no island is found
*/
public Island getIslandAt(int x, int z) {
// Attempt to find the closest x-coordinate entry that does not exceed 'x'
Entry<Integer, TreeMap<Integer, String>> xEntry = grid.floorEntry(x);

View File

@ -19,6 +19,7 @@ import world.bentobox.bentobox.api.events.island.IslandResetEvent;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.managers.BlueprintsManager;
import world.bentobox.bentobox.managers.IslandsManager;
/**
* Create and paste a new island
@ -216,8 +217,9 @@ public class NewIsland {
island.setFlagsDefaults();
// Register metrics
plugin.getMetrics().ifPresent(BStats::increaseIslandsCreatedCount);
plugin.getIslands();
// Save island
plugin.getIslands().updateIsland(island);
IslandsManager.updateIsland(island);
}
/**