Abstract out getting and setting islands by ID

This is preparation for potentially making the cache smaller and pulling
from the database instead when required. However, there are issues with
this because some calls can result in loading the whole database anyway.
This commit is contained in:
tastybento 2024-05-18 22:49:20 -07:00
parent d701b7e43c
commit 50276cb8e5
2 changed files with 11 additions and 109 deletions

View File

@ -1692,107 +1692,6 @@ public class IslandsManager {
.anyMatch(n -> ChatColor.stripColor(n).equals(ChatColor.stripColor(name))); .anyMatch(n -> ChatColor.stripColor(n).equals(ChatColor.stripColor(name)));
} }
/**
* Called by the admin team fix command. Attempts to fix the database for teams.
* It will identify and correct situations where a player is listed in multiple
* teams, or is the owner of multiple teams. It will also try to fix the current
* cache. It is recommended to restart the server after this command is run.
*
* @param user - admin calling
* @param world - game world to check
* @return CompletableFuture boolean - true when done
* @deprecated Not compatible with multi-islands. Will be removed.
*/
@Deprecated
public CompletableFuture<Boolean> checkTeams(User user, World world) {
CompletableFuture<Boolean> r = new CompletableFuture<>();
user.sendMessage("commands.admin.team.fix.scanning");
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
Map<UUID, Island> owners = new HashMap<>();
Map<UUID, Integer> freq = new HashMap<>();
Map<UUID, List<Island>> memberships = new HashMap<>();
handler.loadObjects().stream().filter(i -> i.getOwner() != null).filter(i -> i.getWorld() != null)
.filter(i -> i.getWorld().equals(world)).filter(i -> !i.isDoNotLoad()).forEach(i -> {
int count = freq.getOrDefault(i.getOwner(), 0);
freq.put(i.getOwner(), count + 1);
if (owners.containsKey(i.getOwner())) {
// Player already has an island in the database
user.sendMessage("commands.admin.team.fix.duplicate-owner", TextVariables.NAME,
plugin.getPlayers().getName(i.getOwner()));
Island prev = owners.get(i.getOwner());
// Find out if this island is in the cache
Island cachedIsland = this.getIsland(i.getWorld(), i.getOwner());
if (cachedIsland != null && !cachedIsland.getUniqueId().equals(i.getUniqueId())) {
islandCache.deleteIslandFromCache(i.getUniqueId());
handler.deleteID(i.getUniqueId());
}
if (cachedIsland != null && !cachedIsland.getUniqueId().equals(prev.getUniqueId())) {
islandCache.deleteIslandFromCache(prev.getUniqueId());
handler.deleteID(prev.getUniqueId());
}
} else {
owners.put(i.getOwner(), i);
i.getMemberSet().forEach(u ->
// Place into membership
memberships.computeIfAbsent(u, k -> new ArrayList<>()).add(i));
}
});
freq.entrySet().stream().filter(en -> en.getValue() > 1)
.forEach(en -> user.sendMessage("commands.admin.team.fix.player-has", TextVariables.NAME,
plugin.getPlayers().getName(en.getKey()), TextVariables.NUMBER,
String.valueOf(en.getValue())));
// Check for players in multiple teams
memberships.entrySet().stream().filter(en -> en.getValue().size() > 1).forEach(en -> {
// Get the islands
String ownerName = plugin.getPlayers().getName(en.getKey());
user.sendMessage("commands.admin.team.fix.duplicate-member", TextVariables.NAME, ownerName);
int highestRank = 0;
Island highestIsland = null;
for (Island i : en.getValue()) {
int rankValue = i.getRank(en.getKey());
String rank = RanksManager.getInstance().getRank(rankValue);
if (rankValue > highestRank || highestIsland == null) {
highestRank = rankValue;
highestIsland = i;
}
String xyz = Util.xyz(i.getCenter().toVector());
user.sendMessage("commands.admin.team.fix.rank-on-island", TextVariables.RANK,
user.getTranslation(rank), TextVariables.XYZ, xyz);
user.sendRawMessage(i.getUniqueId());
}
// Fix island ownership in cache
// Correct island cache
if (highestRank == RanksManager.OWNER_RANK && highestIsland != null
&& islandCache.getIslandById(highestIsland.getUniqueId()) != null) {
islandCache.setOwner(islandCache.getIslandById(highestIsland.getUniqueId()), en.getKey());
}
// Fix all the entries that are not the highest
for (Island island : en.getValue()) {
if (!island.equals(highestIsland)) {
// Get the actual island being used in the cache
Island i = islandCache.getIslandById(island.getUniqueId());
if (i != null) {
// Remove membership of this island
i.removeMember(en.getKey());
}
// Remove from database island
island.removeMember(en.getKey());
// Save to database
handler.saveObjectAsync(island)
.thenRun(() -> user.sendMessage("commands.admin.team.fix.fixed"));
} else {
// Special check for when a player is an owner and member
}
}
});
user.sendMessage("commands.admin.team.fix.done");
r.complete(true);
});
return r;
}
/** /**
* Is user mid home teleport? * Is user mid home teleport?
* *

View File

@ -62,7 +62,7 @@ public class IslandCache {
return; return;
} }
// Get the old island // Get the old island
Island oldIsland = islandsById.get(newIsland.getUniqueId()); Island oldIsland = getIslandById(newIsland.getUniqueId());
Set<UUID> newMembers = newIsland.getMembers().keySet(); Set<UUID> newMembers = newIsland.getMembers().keySet();
if (oldIsland != null) { if (oldIsland != null) {
Set<UUID> oldMembers = oldIsland.getMembers().keySet(); Set<UUID> oldMembers = oldIsland.getMembers().keySet();
@ -84,7 +84,7 @@ public class IslandCache {
islandsByUUID.put(newMember, set); islandsByUUID.put(newMember, set);
} }
if (islandsById.put(newIsland.getUniqueId(), newIsland) == null) { if (setIslandById(newIsland) == null) {
BentoBox.getInstance().logError("islandsById failed to update"); BentoBox.getInstance().logError("islandsById failed to update");
} }
@ -101,7 +101,7 @@ public class IslandCache {
return false; return false;
} }
if (addToGrid(island)) { if (addToGrid(island)) {
islandsById.put(island.getUniqueId(), island); setIslandById(island);
// Only add islands to this map if they are owned // Only add islands to this map if they are owned
if (island.isOwned()) { if (island.isOwned()) {
islandsByUUID.computeIfAbsent(island.getOwner(), k -> new HashSet<>()).add(island.getUniqueId()); islandsByUUID.computeIfAbsent(island.getOwner(), k -> new HashSet<>()).add(island.getUniqueId());
@ -120,7 +120,7 @@ public class IslandCache {
* associated per world. * associated per world.
*/ */
public void addPlayer(@NonNull UUID uuid, @NonNull Island island) { public void addPlayer(@NonNull UUID uuid, @NonNull Island island) {
this.islandsById.put(island.getUniqueId(), island); this.setIslandById(island);
this.islandsByUUID.computeIfAbsent(uuid, k -> new HashSet<>()).add(island.getUniqueId()); this.islandsByUUID.computeIfAbsent(uuid, k -> new HashSet<>()).add(island.getUniqueId());
} }
@ -166,7 +166,7 @@ public class IslandCache {
*/ */
public void deleteIslandFromCache(@NonNull String uniqueId) { public void deleteIslandFromCache(@NonNull String uniqueId) {
if (islandsById.containsKey(uniqueId)) { if (islandsById.containsKey(uniqueId)) {
deleteIslandFromCache(islandsById.get(uniqueId)); deleteIslandFromCache(getIslandById(uniqueId));
} }
} }
@ -182,7 +182,6 @@ public class IslandCache {
public Island get(@NonNull World world, @NonNull UUID uuid) { public Island get(@NonNull World world, @NonNull UUID uuid) {
List<Island> islands = getIslands(world, uuid); List<Island> islands = getIslands(world, uuid);
if (islands.isEmpty()) { if (islands.isEmpty()) {
System.out.println("empty");
return null; return null;
} }
for (Island island : islands) { for (Island island : islands) {
@ -208,7 +207,7 @@ public class IslandCache {
if (w == null) { if (w == null) {
return new ArrayList<>(); return new ArrayList<>();
} }
return islandsByUUID.computeIfAbsent(uuid, k -> new HashSet<>()).stream().map(islandsById::get) return islandsByUUID.computeIfAbsent(uuid, k -> new HashSet<>()).stream().map(this::getIslandById)
.filter(Objects::nonNull).filter(island -> w.equals(island.getWorld())) .filter(Objects::nonNull).filter(island -> w.equals(island.getWorld()))
.sorted(Comparator.comparingLong(Island::getCreatedDate)) .sorted(Comparator.comparingLong(Island::getCreatedDate))
.collect(Collectors.toList()); .collect(Collectors.toList());
@ -384,7 +383,7 @@ public class IslandCache {
islandsByUUID.computeIfAbsent(newOwnerUUID, k -> new HashSet<>()).add(island.getUniqueId()); islandsByUUID.computeIfAbsent(newOwnerUUID, k -> new HashSet<>()).add(island.getUniqueId());
} }
island.setRank(newOwnerUUID, RanksManager.OWNER_RANK); island.setRank(newOwnerUUID, RanksManager.OWNER_RANK);
islandsById.put(island.getUniqueId(), island); setIslandById(island);
} }
/** /**
@ -399,6 +398,10 @@ public class IslandCache {
return islandsById.get(uniqueId); return islandsById.get(uniqueId);
} }
private Island setIslandById(Island island) {
return islandsById.put(island.getUniqueId(), island);
}
/** /**
* Resets all islands in this game mode to default flag settings * Resets all islands in this game mode to default flag settings
* *