mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-11-24 11:45:31 +01:00
Added confirmation to IslandResetCommand
Added test class.
This commit is contained in:
parent
72306035f6
commit
0bdc146da3
@ -98,6 +98,9 @@ general:
|
||||
acid-blocked-commands:
|
||||
- home
|
||||
|
||||
# Time in seconds that players have to confirm sensitive commands, e.g. island reset
|
||||
confimation-time: 20
|
||||
|
||||
### World Settings ###
|
||||
world:
|
||||
# Name of the world - if it does not exist then it will be generated.
|
||||
|
@ -34,6 +34,7 @@ general:
|
||||
unknown-command: "&cUnknown command. Do &b/[label] help &cfor help."
|
||||
warp-not-safe: "&cThat warp is not safe right now!"
|
||||
wrong-world: "&cYou are not in the right world to do that!"
|
||||
you-must-wait: "&cYou must wait [seconds]s before you can do that command again"
|
||||
tips:
|
||||
changing-obsidian-to-lava: "Changing obsidian back into lava. Be careful!"
|
||||
|
||||
@ -80,6 +81,9 @@ commands:
|
||||
reset:
|
||||
description: "restart your island and remove the old one"
|
||||
must-remove-members: "You must remove all members from your island before you can restart it (/island kick <player>)."
|
||||
none-left: "&cYou have no more resets left!"
|
||||
resets-left: "&cYou have [number] resets left"
|
||||
confirm: "&cType [label] reset confirm within [seconds]s to confirm reset"
|
||||
sethome:
|
||||
description: "set your teleport point for /island"
|
||||
must-be-on-your-island: "You must be on your island to set home!"
|
||||
|
@ -14,6 +14,7 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import us.tastybento.bskyblock.Constants.GameType;
|
||||
import us.tastybento.bskyblock.api.configuration.ConfigComment;
|
||||
import us.tastybento.bskyblock.api.configuration.ConfigEntry;
|
||||
import us.tastybento.bskyblock.api.configuration.ISettings;
|
||||
import us.tastybento.bskyblock.api.configuration.StoreAt;
|
||||
@ -78,6 +79,10 @@ public class Settings implements ISettings<Settings> {
|
||||
|
||||
@ConfigEntry(path = "general.allow-obsidian-scooping")
|
||||
private boolean allowObsidianScooping = true;
|
||||
|
||||
@ConfigComment("Time in seconds that players have to confirm sensitive commands, e.g. island reset")
|
||||
@ConfigEntry(path = "general.confirmation-time")
|
||||
private int confirmationTime = 20;
|
||||
|
||||
// ---------------------------------------------
|
||||
|
||||
@ -1242,6 +1247,18 @@ public class Settings implements ISettings<Settings> {
|
||||
public void setFakePlayers(Set<String> fakePlayers) {
|
||||
this.fakePlayers = fakePlayers;
|
||||
}
|
||||
/**
|
||||
* @return the confirmationTime
|
||||
*/
|
||||
public int getConfirmationTime() {
|
||||
return confirmationTime;
|
||||
}
|
||||
/**
|
||||
* @param confirmationTime the confirmationTime to set
|
||||
*/
|
||||
public void setConfirmationTime(int confirmationTime) {
|
||||
this.confirmationTime = confirmationTime;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -127,7 +127,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi
|
||||
subCommandAliases = new LinkedHashMap<>();
|
||||
// Add aliases to the parent for this command
|
||||
for (String alias : aliases) {
|
||||
parent.subCommandAliases.put(alias, this);
|
||||
parent.getSubCommandAliases().put(alias, this);
|
||||
}
|
||||
setUsage("");
|
||||
setup();
|
||||
@ -434,4 +434,11 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi
|
||||
protected boolean showHelp(CompositeCommand command, User user) {
|
||||
return command.getSubCommand("help").map(helpCommand -> helpCommand.execute(user, new ArrayList<>())).orElse(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the subCommandAliases
|
||||
*/
|
||||
public Map<String, CompositeCommand> getSubCommandAliases() {
|
||||
return subCommandAliases;
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,14 @@
|
||||
package us.tastybento.bskyblock.commands.island;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -15,7 +21,8 @@ import us.tastybento.bskyblock.managers.island.NewIsland;
|
||||
|
||||
public class IslandResetCommand extends CompositeCommand {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
private Map<UUID, Long> cooldown;
|
||||
private Set<UUID> confirm;
|
||||
|
||||
public IslandResetCommand(CompositeCommand islandCommand) {
|
||||
super(islandCommand, "reset", "restart");
|
||||
@ -23,6 +30,8 @@ public class IslandResetCommand extends CompositeCommand {
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
cooldown = new HashMap<>();
|
||||
confirm = new HashSet<>();
|
||||
setPermission(Constants.PERMPREFIX + "island.create");
|
||||
setOnlyPlayer(true);
|
||||
setDescription("commands.island.reset.description");
|
||||
@ -30,36 +39,71 @@ public class IslandResetCommand extends CompositeCommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, List<String> args) {
|
||||
// Check cooldown
|
||||
if (getSettings().getResetWait() > 0 && onRestartWaitTime(user) > 0 && !user.isOp()) {
|
||||
user.sendMessage("general.errors.you-must-wait", "[seconds]", String.valueOf(onRestartWaitTime(user)));
|
||||
return false;
|
||||
}
|
||||
if (!getIslands().hasIsland(user.getUniqueId())) {
|
||||
user.sendMessage("general.errors.no-island");
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
if (!getIslands().isOwner(user.getUniqueId())) {
|
||||
user.sendMessage("general.errors.not-leader");
|
||||
return false;
|
||||
}
|
||||
if (getPlugin().getPlayers().inTeam(user.getUniqueId())) {
|
||||
if (getPlayers().inTeam(user.getUniqueId())) {
|
||||
user.sendMessage("commands.island.reset.must-remove-members");
|
||||
return false;
|
||||
}
|
||||
if (getSettings().getResetLimit() >= 0 ) {
|
||||
if (getPlayers().getResetsLeft(user.getUniqueId()) == 0) {
|
||||
user.sendMessage("commands.island.reset.none-left");
|
||||
return false;
|
||||
} else {
|
||||
// Notify how many resets are left
|
||||
user.sendMessage("commands.island.reset.resets-left", "[number]", String.valueOf(getPlayers().getResetsLeft(user.getUniqueId())));
|
||||
}
|
||||
}
|
||||
// Check confirmation or reset immediately if no confirmation required
|
||||
if (!getSettings().isResetConfirmation() || (confirm.contains(user.getUniqueId()) && args.size() == 1 && args.get(0).equalsIgnoreCase("confirm"))) {
|
||||
// Reset the island
|
||||
Player player = user.getPlayer();
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
// Get the player's old island
|
||||
Island oldIsland = getIslands().getIsland(player.getUniqueId());
|
||||
// Remove them from this island (it still exists and will be deleted later)
|
||||
getIslands().removePlayer(player.getUniqueId());
|
||||
// Create new island and then delete the old one
|
||||
try {
|
||||
NewIsland.builder()
|
||||
.player(player)
|
||||
.reason(Reason.RESET)
|
||||
.oldIsland(oldIsland)
|
||||
.build();
|
||||
} catch (IOException e) {
|
||||
getPlugin().logError("Could not create island for player. " + e.getMessage());
|
||||
user.sendMessage("commands.island.create.unable-create-island");
|
||||
}
|
||||
setCooldown(user);
|
||||
return true;
|
||||
} else {
|
||||
// Require confirmation
|
||||
user.sendMessage("commands.island.reset.confirm", "[label]", Constants.ISLANDCOMMAND, "[seconds]", String.valueOf(getSettings().getConfirmationTime()));
|
||||
confirm.add(user.getUniqueId());
|
||||
Bukkit.getScheduler().runTaskLater(getPlugin(), () -> confirm.remove(user.getUniqueId()), getSettings().getConfirmationTime() * 20L);
|
||||
return true;
|
||||
}
|
||||
Player player = user.getPlayer();
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
// Get the player's old island
|
||||
Island oldIsland = getIslands().getIsland(player.getUniqueId());
|
||||
// Remove them from this island (it still exists and will be deleted later)
|
||||
getIslands().removePlayer(player.getUniqueId());
|
||||
// Create new island and then delete the old one
|
||||
try {
|
||||
NewIsland.builder()
|
||||
.player(player)
|
||||
.reason(Reason.RESET)
|
||||
.oldIsland(oldIsland)
|
||||
.build();
|
||||
} catch (IOException e) {
|
||||
getPlugin().logError("Could not create island for player. " + e.getMessage());
|
||||
user.sendMessage("commands.island.create.unable-create-island");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private int onRestartWaitTime(User user) {
|
||||
if (!cooldown.containsKey(user.getUniqueId())) {
|
||||
return 0;
|
||||
}
|
||||
return (int) ((System.currentTimeMillis() - cooldown.get(user.getUniqueId()) / 1000));
|
||||
}
|
||||
|
||||
private void setCooldown(User user) {
|
||||
cooldown.put(user.getUniqueId(), System.currentTimeMillis() + (getSettings().getResetLimit() * 1000L));
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ import us.tastybento.bskyblock.managers.IslandsManager;
|
||||
import us.tastybento.bskyblock.managers.PlayersManager;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest( { BSkyBlock.class })
|
||||
@PrepareForTest(BSkyBlock.class)
|
||||
public class IslandCommandTest {
|
||||
|
||||
@Mock
|
||||
|
@ -0,0 +1,158 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package us.tastybento.bskyblock.commands.island;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.reflect.Whitebox;
|
||||
|
||||
import us.tastybento.bskyblock.BSkyBlock;
|
||||
import us.tastybento.bskyblock.Settings;
|
||||
import us.tastybento.bskyblock.api.user.User;
|
||||
import us.tastybento.bskyblock.commands.IslandCommand;
|
||||
import us.tastybento.bskyblock.database.objects.Island;
|
||||
import us.tastybento.bskyblock.managers.CommandsManager;
|
||||
import us.tastybento.bskyblock.managers.IslandsManager;
|
||||
import us.tastybento.bskyblock.managers.PlayersManager;
|
||||
import us.tastybento.bskyblock.managers.island.NewIsland;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({BSkyBlock.class, NewIsland.class })
|
||||
public class IslandResetCommandTest {
|
||||
|
||||
private static BSkyBlock plugin;
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
plugin = mock(BSkyBlock.class);
|
||||
Whitebox.setInternalState(BSkyBlock.class, "instance", plugin);
|
||||
/*
|
||||
NewIsland.Builder builder = mock(NewIsland.Builder.class);
|
||||
when(builder.player(Mockito.any())).thenReturn(builder);
|
||||
when(builder.oldIsland(Mockito.any())).thenReturn(builder);
|
||||
when(builder.reason(Mockito.any())).thenReturn(builder);
|
||||
when(builder.build()).thenReturn(mock(Island.class));
|
||||
PowerMockito.mockStatic(NewIsland.class);
|
||||
when(NewIsland.builder()).thenReturn(builder);
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
CommandsManager cm = mock(CommandsManager.class);
|
||||
when(plugin.getCommandsManager()).thenReturn(cm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link us.tastybento.bskyblock.commands.island.IslandResetCommand#execute(us.tastybento.bskyblock.api.user.User, java.util.List)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteUserListOfString() throws IOException {
|
||||
Settings s = mock(Settings.class);
|
||||
when(s.getResetWait()).thenReturn(0L);
|
||||
when(plugin.getSettings()).thenReturn(s);
|
||||
|
||||
Player p = mock(Player.class);
|
||||
User user = mock(User.class, Mockito.withSettings().verboseLogging());
|
||||
when(user.isOp()).thenReturn(false);
|
||||
UUID uuid = UUID.randomUUID();
|
||||
when(user.getUniqueId()).thenReturn(uuid);
|
||||
when(user.getPlayer()).thenReturn(p);
|
||||
|
||||
IslandCommand ic = mock(IslandCommand.class);
|
||||
when(ic.getSubCommandAliases()).thenReturn(new HashMap<>());
|
||||
|
||||
IslandResetCommand irc = new IslandResetCommand(ic);
|
||||
|
||||
// No island
|
||||
IslandsManager im = mock(IslandsManager.class);
|
||||
when(im.hasIsland(Mockito.eq(uuid))).thenReturn(false);
|
||||
when(im.isOwner(Mockito.eq(uuid))).thenReturn(false);
|
||||
when(plugin.getIslands()).thenReturn(im);
|
||||
|
||||
// Has team
|
||||
PlayersManager pm = mock(PlayersManager.class);
|
||||
when(pm.inTeam(Mockito.eq(uuid))).thenReturn(true);
|
||||
when(plugin.getPlayers()).thenReturn(pm);
|
||||
|
||||
// Test the reset command
|
||||
// Does not have island
|
||||
assertFalse(irc.execute(user, new ArrayList<>()));
|
||||
Mockito.verify(user).sendMessage("general.errors.no-island");
|
||||
|
||||
// Now has island, but is not the leader
|
||||
when(im.hasIsland(Mockito.eq(uuid))).thenReturn(true);
|
||||
assertFalse(irc.execute(user, new ArrayList<>()));
|
||||
Mockito.verify(user).sendMessage("general.errors.not-leader");
|
||||
|
||||
// Now is owner, but still has team
|
||||
when(im.isOwner(Mockito.eq(uuid))).thenReturn(true);
|
||||
assertFalse(irc.execute(user, new ArrayList<>()));
|
||||
Mockito.verify(user).sendMessage("commands.island.reset.must-remove-members");
|
||||
|
||||
// Now has no team
|
||||
when(pm.inTeam(Mockito.eq(uuid))).thenReturn(false);
|
||||
|
||||
// Block based on no resets left
|
||||
when(s.getResetLimit()).thenReturn(1);
|
||||
when(pm.getResetsLeft(Mockito.eq(uuid))).thenReturn(0);
|
||||
assertFalse(irc.execute(user, new ArrayList<>()));
|
||||
Mockito.verify(user).sendMessage("commands.island.reset.none-left");
|
||||
|
||||
// Give the user some resets
|
||||
when(pm.getResetsLeft(Mockito.eq(uuid))).thenReturn(1);
|
||||
|
||||
// No confirmation required
|
||||
when(s.isResetConfirmation()).thenReturn(false);
|
||||
|
||||
// Old island
|
||||
Island oldIsland = mock(Island.class);
|
||||
when(im.getIsland(Mockito.eq(uuid))).thenReturn(oldIsland);
|
||||
|
||||
// Mock up NewIsland
|
||||
NewIsland.Builder builder = mock(NewIsland.Builder.class);
|
||||
when(builder.player(Mockito.any())).thenReturn(builder);
|
||||
when(builder.oldIsland(Mockito.any())).thenReturn(builder);
|
||||
when(builder.reason(Mockito.any())).thenReturn(builder);
|
||||
when(builder.build()).thenReturn(mock(Island.class));
|
||||
PowerMockito.mockStatic(NewIsland.class);
|
||||
when(NewIsland.builder()).thenReturn(builder);
|
||||
|
||||
// Reset
|
||||
assertTrue(irc.execute(user, new ArrayList<>()));
|
||||
Mockito.verify(builder).build();
|
||||
Mockito.verify(user).sendMessage("commands.island.reset.resets-left", "[number]", "1");
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user