Skip to content

Commit

Permalink
Fix island resetting. #2223
Browse files Browse the repository at this point in the history
Islands were being deleted in all worlds, and all islands were being
deleted from the player instead of just the one island.
  • Loading branch information
tastybento committed Nov 11, 2023
1 parent c63de27 commit 19d7e2f
Show file tree
Hide file tree
Showing 4 changed files with 1,259 additions and 1,135 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,181 +19,176 @@
import world.bentobox.bentobox.panels.IslandCreationPanel;
import world.bentobox.bentobox.util.Util;


/**
* @author tastybento
*/
public class IslandResetCommand extends ConfirmableCommand {

private boolean noPaste;

public IslandResetCommand(CompositeCommand islandCommand) {
super(islandCommand, "reset", "restart");
}

/**
* Creates the island reset command
* @param islandCommand - parent command
* @param noPaste - true if resetting should not paste a new island
*/
public IslandResetCommand(CompositeCommand islandCommand, boolean noPaste) {
super(islandCommand, "reset", "restart");
this.noPaste = noPaste;
}

@Override
public void setup() {
setPermission("island.reset");
setOnlyPlayer(true);
setParametersHelp("commands.island.reset.parameters");
setDescription("commands.island.reset.description");
}

@Override
public boolean canExecute(User user, String label, List<String> args) {
// Check cooldown
if (getSettings().getResetCooldown() > 0 && checkCooldown(user)) {
return false;
}
if (!getIslands().hasIsland(getWorld(), user.getUniqueId())) {
user.sendMessage("general.errors.no-island");
return false;
}
int resetsLeft = getPlayers().getResetsLeft(getWorld(), user.getUniqueId());
if (resetsLeft != -1) {
// Resets are not unlimited here
if (resetsLeft == 0) {
// No resets allowed
user.sendMessage("commands.island.reset.none-left");
return false;
} else {
// Still some resets left
// Notify how many resets are left
user.sendMessage("commands.island.reset.resets-left", TextVariables.NUMBER, String.valueOf(resetsLeft));
}
}

return true;
}

@Override
public boolean execute(User user, String label, List<String> args) {
// Permission check if the name is not the default one
if (!args.isEmpty()) {
String name = getPlugin().getBlueprintsManager().validate(getAddon(), Util.sanitizeInput(args.get(0)));
if (name == null || name.isEmpty()) {
// The blueprint name is not valid.
user.sendMessage("commands.island.create.unknown-blueprint");
return false;
}
if (!getPlugin().getBlueprintsManager().checkPerm(getAddon(), user, Util.sanitizeInput(args.get(0)))) {
return false;
}
return resetIsland(user, name);
} else {
// Show panel after confirmation
if (getPlugin().getSettings().isResetConfirmation()) {
this.askConfirmation(user, user.getTranslation("commands.island.reset.confirmation"), () -> selectBundle(user, label));
} else {
selectBundle(user, label);
}
return true;
}
}

/**
* Either selects the bundle to use or asks the user to choose.
* @since 1.5.1
*/
private void selectBundle(@NonNull User user, @NonNull String label) {
// Show panel only if there are multiple bundles available
if (getPlugin().getBlueprintsManager().getBlueprintBundles(getAddon()).size() > 1) {
// Show panel - once the player selected a bundle, this will re-run this command
IslandCreationPanel.openPanel(this, user, label);
} else {
resetIsland(user, BlueprintsManager.DEFAULT_BUNDLE_NAME);
}
}

/**
* Reset island
* @param user user
* @param name name of Blueprint Bundle
* @return true if successful
*/
private boolean resetIsland(User user, String name) {
// Get the player's old island
Island oldIsland = getIslands().getIsland(getWorld(), user);
deleteOldIsland(user, oldIsland);

user.sendMessage("commands.island.create.creating-island");
// Create new island and then delete the old one
try {
Builder builder = NewIsland.builder()
.player(user)
.reason(Reason.RESET)
.addon(getAddon())
.oldIsland(oldIsland)
.name(name);
if (noPaste) builder.noPaste();
builder.build();
} catch (IOException e) {
getPlugin().logError("Could not create island for player. " + e.getMessage());
user.sendMessage(e.getMessage());
return false;
}
setCooldown(user.getUniqueId(), getSettings().getResetCooldown());
return true;
}

private void deleteOldIsland(User user, Island oldIsland) {
// Fire island preclear event
IslandEvent.builder()
.involvedPlayer(user.getUniqueId())
.reason(Reason.PRECLEAR)
.island(oldIsland)
.oldIsland(oldIsland)
.location(oldIsland.getCenter())
.build();

// Reset the island

// Kick all island members (including the owner)
kickMembers(oldIsland);

// Add a reset
getPlayers().addReset(getWorld(), user.getUniqueId());
}

/**
* Kicks the members (incl. owner) of the island.
* @since 1.7.0
*/
private void kickMembers(Island island) {
/*
* We cannot assume the island owner can run /[cmd] team kick (it might be disabled, or there could be permission restrictions...)
* Therefore, we need to do it manually.
* Plus, a more specific team event (TeamDeleteEvent) is called by this method.
*/
island.getMemberSet().forEach(memberUUID -> {

User member = User.getInstance(memberUUID);
// Send a "you're kicked" message if the member is not the island owner (send before removing!)
if (!memberUUID.equals(island.getOwner())) {
member.sendMessage("commands.island.reset.kicked-from-island", TextVariables.GAMEMODE, getAddon().getDescription().getName());
}
// Remove player
getIslands().removePlayer(getWorld(), memberUUID);

// Clean player
getPlayers().cleanLeavingPlayer(getWorld(), member, false, island);

// Fire event
TeamEvent.builder()
.island(island)
.reason(TeamEvent.Reason.DELETE)
.involvedPlayer(memberUUID)
.build();
});
}
private boolean noPaste;

public IslandResetCommand(CompositeCommand islandCommand) {
super(islandCommand, "reset", "restart");
}

/**
* Creates the island reset command
*
* @param islandCommand - parent command
* @param noPaste - true if resetting should not paste a new island
*/
public IslandResetCommand(CompositeCommand islandCommand, boolean noPaste) {
super(islandCommand, "reset", "restart");
this.noPaste = noPaste;
}

@Override
public void setup() {
setPermission("island.reset");
setOnlyPlayer(true);
setParametersHelp("commands.island.reset.parameters");
setDescription("commands.island.reset.description");
}

@Override
public boolean canExecute(User user, String label, List<String> args) {
// Check cooldown
if (getSettings().getResetCooldown() > 0 && checkCooldown(user)) {
return false;
}
if (!getIslands().hasIsland(getWorld(), user.getUniqueId())) {
user.sendMessage("general.errors.no-island");
return false;
}
int resetsLeft = getPlayers().getResetsLeft(getWorld(), user.getUniqueId());
if (resetsLeft != -1) {
// Resets are not unlimited here
if (resetsLeft == 0) {
// No resets allowed
user.sendMessage("commands.island.reset.none-left");
return false;
} else {
// Still some resets left
// Notify how many resets are left
user.sendMessage("commands.island.reset.resets-left", TextVariables.NUMBER, String.valueOf(resetsLeft));
}
}

return true;
}

@Override
public boolean execute(User user, String label, List<String> args) {
// Permission check if the name is not the default one
if (!args.isEmpty()) {
String name = getPlugin().getBlueprintsManager().validate(getAddon(), Util.sanitizeInput(args.get(0)));
if (name == null || name.isEmpty()) {
// The blueprint name is not valid.
user.sendMessage("commands.island.create.unknown-blueprint");
return false;
}
if (!getPlugin().getBlueprintsManager().checkPerm(getAddon(), user, Util.sanitizeInput(args.get(0)))) {
return false;
}
return resetIsland(user, name);
} else {
// Show panel after confirmation
if (getPlugin().getSettings().isResetConfirmation()) {
this.askConfirmation(user, user.getTranslation("commands.island.reset.confirmation"),
() -> selectBundle(user, label));
} else {
selectBundle(user, label);
}
return true;
}
}

/**
* Either selects the bundle to use or asks the user to choose.
*
* @since 1.5.1
*/
private void selectBundle(@NonNull User user, @NonNull String label) {
// Show panel only if there are multiple bundles available
if (getPlugin().getBlueprintsManager().getBlueprintBundles(getAddon()).size() > 1) {
// Show panel - once the player selected a bundle, this will re-run this command
IslandCreationPanel.openPanel(this, user, label);
} else {
resetIsland(user, BlueprintsManager.DEFAULT_BUNDLE_NAME);
}
}

/**
* Reset island
*
* @param user user
* @param name name of Blueprint Bundle
* @return true if successful
*/
private boolean resetIsland(User user, String name) {
// Get the player's old island
Island oldIsland = getIslands().getIsland(getWorld(), user);
deleteOldIsland(user, oldIsland);

user.sendMessage("commands.island.create.creating-island");
// Create new island and then delete the old one
try {
Builder builder = NewIsland.builder().player(user).reason(Reason.RESET).addon(getAddon())
.oldIsland(oldIsland).name(name);
if (noPaste)
builder.noPaste();
builder.build();
} catch (IOException e) {
getPlugin().logError("Could not create island for player. " + e.getMessage());
user.sendMessage(e.getMessage());
return false;
}
setCooldown(user.getUniqueId(), getSettings().getResetCooldown());
return true;
}

private void deleteOldIsland(User user, Island oldIsland) {
// Fire island preclear event
IslandEvent.builder().involvedPlayer(user.getUniqueId()).reason(Reason.PRECLEAR).island(oldIsland)
.oldIsland(oldIsland).location(oldIsland.getCenter()).build();

// Reset the island

// Kick all island members (including the owner)
kickMembers(oldIsland);

// Add a reset
getPlayers().addReset(getWorld(), user.getUniqueId());
}

/**
* Kicks the members (incl. owner) of the island.
*
* @since 1.7.0
*/
private void kickMembers(Island island) {
/*
* We cannot assume the island owner can run /[cmd] team kick (it might be
* disabled, or there could be permission restrictions...) Therefore, we need to
* do it manually. Plus, a more specific team event (TeamDeleteEvent) is called
* by this method.
*/
island.getMemberSet().forEach(memberUUID -> {

User member = User.getInstance(memberUUID);
// Send a "you're kicked" message if the member is not the island owner (send
// before removing!)
if (!memberUUID.equals(island.getOwner())) {
member.sendMessage("commands.island.reset.kicked-from-island", TextVariables.GAMEMODE,
getAddon().getDescription().getName());
}
// Remove player
getIslands().removePlayer(island, memberUUID);

// Clean player
getPlayers().cleanLeavingPlayer(getWorld(), member, false, island);

// Fire event
TeamEvent.builder().island(island).reason(TeamEvent.Reason.DELETE).involvedPlayer(memberUUID).build();
});
}
}
Loading

0 comments on commit 19d7e2f

Please sign in to comment.