-
-
Notifications
You must be signed in to change notification settings - Fork 134
/
AdminDeleteCommand.java
211 lines (186 loc) · 8.07 KB
/
AdminDeleteCommand.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
package world.bentobox.bentobox.api.commands.admin;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.commands.ConfirmableCommand;
import world.bentobox.bentobox.api.events.island.IslandEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.Reason;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.util.Util;
public class AdminDeleteCommand extends ConfirmableCommand {
private @Nullable UUID targetUUID;
private Island island;
public AdminDeleteCommand(CompositeCommand parent) {
super(parent, "delete");
}
@Override
public void setup() {
setPermission("admin.delete");
setParametersHelp("commands.admin.delete.parameters");
setDescription("commands.admin.delete.description");
}
@Override
public boolean canExecute(User user, String label, List<String> args) {
if (args.isEmpty()) {
this.showHelp(this, user);
return false;
}
// Convert name to a UUID
targetUUID = Util.getUUID(args.get(0));
if (targetUUID == null) {
user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
return false;
}
// Check island exists
if (!getIslands().hasIsland(getWorld(), targetUUID) && !getIslands().inTeam(getWorld(), targetUUID)) {
user.sendMessage("general.errors.player-has-no-island");
return false;
}
if (args.size() == 1) {
// Check if player is owner of any islands
if (getIslands().getIslands(getWorld(), targetUUID).stream().filter(Island::hasTeam)
.anyMatch(is -> targetUUID.equals(is.getOwner()))) {
user.sendMessage("commands.admin.delete.cannot-delete-owner");
return false;
}
// This is a delete everything request
return true;
}
// Get the island
User target = User.getInstance(targetUUID);
// They named the island to go to
Map<String, IslandInfo> names = getNameIslandMap(target);
final String name = String.join(" ", args.subList(1, args.size()));
if (!names.containsKey(name)) {
// Failed home name check
user.sendMessage("commands.island.go.unknown-home");
user.sendMessage("commands.island.sethome.homes-are");
names.keySet()
.forEach(n -> user.sendMessage("commands.island.sethome.home-list-syntax", TextVariables.NAME, n));
return false;
} else {
IslandInfo info = names.get(name);
island = info.island;
}
// Team members should be kicked before deleting otherwise the whole team will become weird
if (island.hasTeam() && targetUUID.equals(island.getOwner())) {
user.sendMessage("commands.admin.delete.cannot-delete-owner");
return false;
}
if (names.size() == 1) {
// This is the only island they have so, no need to specify it
island = null;
}
return true;
}
@Override
public boolean execute(User user, String label, List<String> args) {
// Confirm
if (island == null) {
// Delete the player entirely
askConfirmation(user, () -> deletePlayer(user));
} else {
// Just delete the player's island
askConfirmation(user, () -> deleteIsland(user, island));
}
return true;
}
private void deleteIsland(User user, Island oldIsland) {
// Fire island preclear event
IslandEvent.builder().involvedPlayer(user.getUniqueId()).reason(Reason.PRECLEAR).island(oldIsland)
.oldIsland(oldIsland).location(oldIsland.getCenter()).build();
user.sendMessage("commands.admin.delete.deleted-island", TextVariables.XYZ,
Util.xyz(oldIsland.getCenter().toVector()));
getIslands().deleteIsland(oldIsland, true, targetUUID);
}
private void deletePlayer(User user) {
// Delete player and island
for (Island oldIsland : getIslands().getIslands(getWorld(), targetUUID)) {
deleteIsland(user, oldIsland);
}
// Check if player is online and on the island
User target = User.getInstance(targetUUID);
// Remove target from any and all islands in the world
getIslands().removePlayer(getWorld(), targetUUID);
if (target.isPlayer() && target.isOnline()) {
cleanUp(target);
}
user.sendMessage("general.success");
}
private void cleanUp(User target) {
// Remove money inventory etc.
if (getIWM().isOnLeaveResetEnderChest(getWorld())) {
target.getPlayer().getEnderChest().clear();
}
if (getIWM().isOnLeaveResetInventory(getWorld())) {
target.getPlayer().getInventory().clear();
}
if (getSettings().isUseEconomy() && getIWM().isOnLeaveResetMoney(getWorld())) {
getPlugin().getVault().ifPresent(vault -> vault.withdraw(target, vault.getBalance(target)));
}
// Reset the health
if (getIWM().isOnLeaveResetHealth(getWorld())) {
Util.resetHealth(target.getPlayer());
}
// Reset the hunger
if (getIWM().isOnLeaveResetHunger(getWorld())) {
target.getPlayer().setFoodLevel(20);
}
// Reset the XP
if (getIWM().isOnLeaveResetXP(getWorld())) {
// Player collected XP (displayed)
target.getPlayer().setLevel(0);
target.getPlayer().setExp(0);
// Player total XP (not displayed)
target.getPlayer().setTotalExperience(0);
}
// Execute commands when leaving
Util.runCommands(target, target.getName(), getIWM().getOnLeaveCommands(getWorld()), "leave");
}
private record IslandInfo(Island island, boolean islandName) {
}
private Map<String, IslandInfo> getNameIslandMap(User target) {
Map<String, IslandInfo> islandMap = new HashMap<>();
int index = 0;
for (Island island : getIslands().getIslands(getWorld(), target.getUniqueId())) {
index++;
if (island.getName() != null && !island.getName().isBlank()) {
// Name has been set
islandMap.put(island.getName(), new IslandInfo(island, true));
} else {
// Name has not been set
String text = target.getTranslation("protection.flags.ENTER_EXIT_MESSAGES.island", TextVariables.NAME,
target.getName(), TextVariables.DISPLAY_NAME, target.getDisplayName()) + " " + index;
islandMap.put(text, new IslandInfo(island, true));
}
// Add homes. Homes do not need an island specified
island.getHomes().keySet().forEach(n -> islandMap.put(n, new IslandInfo(island, false)));
}
return islandMap;
}
@Override
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
String lastArg = !args.isEmpty() ? args.get(args.size()-1) : "";
if (args.isEmpty()) {
// Don't show every player on the server. Require at least the first letter
return Optional.empty();
}
if (args.size() == 2) {
return Optional.of(Util.tabLimit(new ArrayList<>(Util.getOnlinePlayerList(user)), lastArg));
}
if (args.size() == 3) {
UUID target = Util.getUUID(args.get(1));
return target == null ? Optional.empty()
: Optional.of(Util.tabLimit(new ArrayList<>(getNameIslandMap(User.getInstance(target)).keySet()),
lastArg));
}
return Optional.empty();
}
}