Added an admin fix command to fix cross-island ownership.

https://github.com/BentoBoxWorld/BentoBox/issues/1556
This commit is contained in:
tastybento 2020-11-01 15:53:52 -08:00
parent ba903bdaca
commit 774b57b168
4 changed files with 93 additions and 0 deletions

View File

@ -11,6 +11,7 @@ import world.bentobox.bentobox.api.commands.admin.range.AdminRangeCommand;
import world.bentobox.bentobox.api.commands.admin.resets.AdminResetsCommand;
import world.bentobox.bentobox.api.commands.admin.team.AdminTeamAddCommand;
import world.bentobox.bentobox.api.commands.admin.team.AdminTeamDisbandCommand;
import world.bentobox.bentobox.api.commands.admin.team.AdminTeamFixCommand;
import world.bentobox.bentobox.api.commands.admin.team.AdminTeamKickCommand;
import world.bentobox.bentobox.api.commands.admin.team.AdminTeamSetownerCommand;
import world.bentobox.bentobox.api.localization.TextVariables;
@ -59,6 +60,7 @@ public abstract class DefaultAdminCommand extends CompositeCommand {
new AdminTeamKickCommand(this);
new AdminTeamDisbandCommand(this);
new AdminTeamSetownerCommand(this);
new AdminTeamFixCommand(this);
// Schems
new AdminBlueprintCommand(this);
// Register/unregister islands

View File

@ -0,0 +1,35 @@
package world.bentobox.bentobox.api.commands.admin.team;
import java.util.List;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.user.User;
public class AdminTeamFixCommand extends CompositeCommand {
public AdminTeamFixCommand(CompositeCommand parent) {
super(parent, "fix");
}
@Override
public void setup() {
setPermission("mod.team");
setDescription("commands.admin.team.fix.description");
}
@Override
public boolean canExecute(User user, String label, List<String> args) {
// If args are not right, show help
if (!args.isEmpty()) {
showHelp(this, user);
return false;
}
return true;
}
@Override
public boolean execute(User user, String label, List<String> args) {
getIslands().checkTeams(user, getWorld());
return true;
}
}

View File

@ -1511,4 +1511,50 @@ public class IslandsManager {
.anyMatch(n -> ChatColor.stripColor(n).equals(ChatColor.stripColor(name)));
}
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<>();
handler.loadObjects()
.stream().filter(i -> i.getOwner() != null)
.filter(i -> i.getWorld().equals(world))
.forEach(i -> {
int count = freq.containsKey(i.getOwner()) ? freq.get(i.getOwner()) : 0;
freq.put(i.getOwner(), count + 1);
if (owners.containsKey(i.getOwner())) {
user.sendMessage("commands.admin.team.fix.duplicate-owner" , TextVariables.NAME, plugin.getPlayers().getName(i.getOwner()));
} else {
owners.put(i.getOwner(), 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()));
});
owners.entrySet().stream().forEach(en -> {
en.getValue().getMemberSet().stream()
// Filter out owners
.filter(u-> owners.containsKey(u) && !owners.get(u).equals(en.getValue()))
.forEach(u -> {
user.sendMessage("commands.admin.team.fix.member-and-owner", TextVariables.NAME, plugin.getPlayers().getName(u));
user.sendMessage("commands.admin.team.fix.member-of", "[xyz]", Util.xyz(en.getValue().getCenter().toVector()));
user.sendMessage("commands.admin.team.fix.owner-of", "[xyz]", Util.xyz(owners.get(u).getCenter().toVector()));
// Remove membership of this island
Island i = islandCache.getIslandById(en.getValue().getUniqueId());
i.removeMember(u);
// Correct island cache
islandCache.setOwner(islandCache.getIslandById(owners.get(u).getUniqueId()), u);
// Save to database
handler.saveObjectAsync(i).thenRun(() -> user.sendMessage("commands.admin.team.fix.fixed"));
});
});
user.sendMessage("commands.admin.team.fix.done");
r.complete(true);
});
return r;
}
}

View File

@ -113,6 +113,16 @@ commands:
use-disband-owner: "&c Not owner! Use disband [owner]."
disbanded: "&c Admin disbanded your team!"
success: "&b [name]&a 's team has been disbanded."
fix:
description: "scans and fixes cross island membership in database"
scanning: "Scanning database..."
duplicate-owner: "&c Player owns more than one island in database: [name]"
player-has: "&c Player [name] has [number] islands"
member-and-owner: "&c Cross-membership found: Player [name] is an island owner and member"
owner-of: "&c Owner of island at [xyz]"
member-of: "&c Member of island at [xyz]"
fixed: "&a Fixed"
done: "&a Scan completed"
kick:
parameters: "<team player>"
description: "kick a player from a team"