Merge branch 'develop' of https://github.com/BentoBoxWorld/BentoBox.git into develop

This commit is contained in:
tastybento 2019-09-30 15:38:15 -07:00
commit 7bf0de9eda
29 changed files with 936 additions and 103 deletions

View File

@ -3,6 +3,7 @@ package world.bentobox.bentobox.api.addons;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -12,6 +13,7 @@ import java.util.logging.Logger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@ -244,8 +246,9 @@ public abstract class Addon {
* - if true, will overwrite previous file * - if true, will overwrite previous file
* @param noPath * @param noPath
* - if true, the resource's path will be ignored when saving * - if true, the resource's path will be ignored when saving
* @return file written, or null if none
*/ */
public void saveResource(String jarResource, File destinationFolder, boolean replace, boolean noPath) { public File saveResource(String jarResource, File destinationFolder, boolean replace, boolean noPath) {
if (jarResource == null || jarResource.equals("")) { if (jarResource == null || jarResource.equals("")) {
throw new IllegalArgumentException("ResourcePath cannot be null or empty"); throw new IllegalArgumentException("ResourcePath cannot be null or empty");
} }
@ -269,6 +272,7 @@ public abstract class Addon {
if (!outFile.exists() || replace) { if (!outFile.exists() || replace) {
java.nio.file.Files.copy(in, outFile.toPath()); java.nio.file.Files.copy(in, outFile.toPath());
} }
return outFile;
} }
} else { } else {
// No file in the jar // No file in the jar
@ -279,6 +283,31 @@ public abstract class Addon {
BentoBox.getInstance().logError( BentoBox.getInstance().logError(
"Could not save from jar file. From " + jarResource + " to " + destinationFolder.getAbsolutePath()); "Could not save from jar file. From " + jarResource + " to " + destinationFolder.getAbsolutePath());
} }
return null;
}
/**
* Tries to load a YAML file from the Jar
* @param jarResource - YAML file in jar
* @return YamlConfiguration - may be empty
* @throws IOException - if the file cannot be found or loaded from the Jar
* @throws InvalidConfigurationException - if the yaml is malformed
*/
public YamlConfiguration getYamlFromJar(String jarResource) throws IOException, InvalidConfigurationException {
if (jarResource == null || jarResource.equals("")) {
throw new IllegalArgumentException("jarResource cannot be null or empty");
}
YamlConfiguration result = new YamlConfiguration();
jarResource = jarResource.replace('\\', '/');
try (JarFile jar = new JarFile(file)) {
JarEntry jarConfig = jar.getJarEntry(jarResource);
if (jarConfig != null) {
try (InputStreamReader in = new InputStreamReader(jar.getInputStream(jarConfig))) {
result.load(in);
}
}
}
return result;
} }
/** /**

View File

@ -5,6 +5,7 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.commands.CompositeCommand;
@ -76,6 +77,17 @@ public class AdminDeleteCommand extends ConfirmableCommand {
// Remove them from this island (it still exists and will be deleted later) // Remove them from this island (it still exists and will be deleted later)
getIslands().removePlayer(getWorld(), targetUUID); getIslands().removePlayer(getWorld(), targetUUID);
if (target.isOnline()) { if (target.isOnline()) {
// Execute commands when leaving
getIWM().getOnLeaveCommands(getWorld()).forEach(command -> {
command = command.replace("[player]", target.getName());
if (command.startsWith("[SUDO]")) {
// Execute the command by the player
target.performCommand(command.substring(6));
} else {
// Otherwise execute as the server console
getPlugin().getServer().dispatchCommand(Bukkit.getConsoleSender(), command);
}
});
// Remove money inventory etc. // Remove money inventory etc.
if (getIWM().isOnLeaveResetEnderChest(getWorld())) { if (getIWM().isOnLeaveResetEnderChest(getWorld())) {
target.getPlayer().getEnderChest().clear(); target.getPlayer().getEnderChest().clear();

View File

@ -1,10 +1,17 @@
package world.bentobox.bentobox.api.commands.admin; package world.bentobox.bentobox.api.commands.admin;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.stream.Collectors;
import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.commands.ConfirmableCommand; import world.bentobox.bentobox.api.commands.ConfirmableCommand;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.flags.Flag.Type;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.util.Util;
/** /**
* Admin command to reset all islands in a world to the default flag setting in the game mode config.yml * Admin command to reset all islands in a world to the default flag setting in the game mode config.yml
@ -13,25 +20,47 @@ import world.bentobox.bentobox.api.user.User;
*/ */
public class AdminResetFlagsCommand extends ConfirmableCommand { public class AdminResetFlagsCommand extends ConfirmableCommand {
private List<String> options;
public AdminResetFlagsCommand(CompositeCommand parent) { public AdminResetFlagsCommand(CompositeCommand parent) {
super(parent, "resetflags"); super(parent, "resetflags");
options = getPlugin().getFlagsManager().getFlags().stream()
.filter(f -> f.getType().equals(Type.PROTECTION) || f.getType().equals(Type.SETTING))
.map(Flag::getID).collect(Collectors.toList());
} }
@Override @Override
public void setup() { public void setup() {
setPermission("admin.resetflags"); setPermission("admin.resetflags");
setOnlyPlayer(false); setOnlyPlayer(false);
setParametersHelp("commands.admin.resetflags.parameters");
setDescription("commands.admin.resetflags.description"); setDescription("commands.admin.resetflags.description");
} }
@Override @Override
public boolean execute(User user, String label, List<String> args) { public boolean execute(User user, String label, List<String> args) {
// Everything's fine, we can set the island as spawn :) if (args.isEmpty()) {
askConfirmation(user, () -> { askConfirmation(user, user.getTranslation("commands.admin.resetflags.confirm"), () -> {
getIslands().resetAllFlags(getWorld()); getIslands().resetAllFlags(getWorld());
user.sendMessage("commands.admin.resetflags.success"); user.sendMessage("commands.admin.resetflags.success");
}); });
return true; return true;
} else if (args.size() == 1 && options.contains(args.get(0).toUpperCase(Locale.ENGLISH))) {
getPlugin().getFlagsManager().getFlag(args.get(0).toUpperCase(Locale.ENGLISH)).ifPresent(flag ->
askConfirmation(user, user.getTranslation("commands.admin.resetflags.confirm"), () -> {
getIslands().resetFlag(getWorld(), flag);
user.sendMessage("commands.admin.resetflags.success-one", TextVariables.NAME, flag.getID());
}));
return true;
}
// Show help
showHelp(this, user);
return false;
} }
@Override
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
String lastArg = !args.isEmpty() ? args.get(args.size()-1) : "";
return Optional.of(Util.tabLimit(options, lastArg));
}
} }

View File

@ -0,0 +1,50 @@
package world.bentobox.bentobox.api.commands.admin.deaths;
import org.apache.commons.lang.math.NumberUtils;
import org.eclipse.jdt.annotation.NonNull;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User;
import java.util.List;
import java.util.UUID;
/**
* @since 1.8.0
* @author Poslovitch
*/
public class AdminDeathsAddCommand extends CompositeCommand {
public AdminDeathsAddCommand(AdminDeathsCommand parent) {
super(parent, "add");
}
@Override
public void setup() {
setDescription("commands.admin.deaths.add.description");
setParametersHelp("commands.admin.deaths.add.parameters");
}
@Override
public boolean execute(User user, String label, @NonNull List<String> args) {
if (args.size() != 2) {
showHelp(this, user);
return false;
}
UUID target = getPlayers().getUUID(args.get(0));
if (target == null) {
user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
} else if (!NumberUtils.isNumber(args.get(1)) || Integer.valueOf(args.get(1)) < 0) {
user.sendMessage("general.errors.must-be-positive-number", TextVariables.NUMBER, args.get(1));
} else {
getPlayers().setDeaths(getWorld(), target, getPlayers().getDeaths(getWorld(), target) + Integer.valueOf(args.get(1)));
user.sendMessage("commands.admin.deaths.add.success",
TextVariables.NAME, args.get(0), TextVariables.NUMBER, args.get(1),
"[total]", String.valueOf(getPlayers().getDeaths(getWorld(), target)));
return true;
}
return false;
}
}

View File

@ -21,6 +21,8 @@ public class AdminDeathsCommand extends CompositeCommand {
new AdminDeathsResetCommand(this); new AdminDeathsResetCommand(this);
new AdminDeathsSetCommand(this); new AdminDeathsSetCommand(this);
new AdminDeathsAddCommand(this);
new AdminDeathsRemoveCommand(this);
} }
@Override @Override

View File

@ -0,0 +1,52 @@
package world.bentobox.bentobox.api.commands.admin.deaths;
import org.apache.commons.lang.math.NumberUtils;
import org.eclipse.jdt.annotation.NonNull;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User;
import java.util.List;
import java.util.UUID;
/**
* @since 1.8.0
* @author Poslovitch
*/
public class AdminDeathsRemoveCommand extends CompositeCommand {
public AdminDeathsRemoveCommand(AdminDeathsCommand parent) {
super(parent, "remove");
}
@Override
public void setup() {
setDescription("commands.admin.deaths.remove.description");
setParametersHelp("commands.admin.deaths.remove.parameters");
}
@Override
public boolean execute(User user, String label, @NonNull List<String> args) {
if (args.size() != 2) {
showHelp(this, user);
return false;
}
UUID target = getPlayers().getUUID(args.get(0));
if (target == null) {
user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
} else if (!NumberUtils.isNumber(args.get(1)) || Integer.valueOf(args.get(1)) < 0) {
user.sendMessage("general.errors.must-be-positive-number", TextVariables.NUMBER, args.get(1));
} else {
// Make sure it cannot go under 0.
int newDeaths = Math.max(getPlayers().getDeaths(getWorld(), target) - Integer.valueOf(args.get(1)), 0);
getPlayers().setDeaths(getWorld(), target, newDeaths);
user.sendMessage("commands.admin.deaths.remove.success",
TextVariables.NAME, args.get(0), TextVariables.NUMBER, args.get(1),
"[total]", String.valueOf(newDeaths));
return true;
}
return false;
}
}

View File

@ -0,0 +1,50 @@
package world.bentobox.bentobox.api.commands.admin.resets;
import org.apache.commons.lang.math.NumberUtils;
import org.eclipse.jdt.annotation.NonNull;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User;
import java.util.List;
import java.util.UUID;
/**
* @author Poslovitch
* @since 1.8.0
*/
public class AdminResetsAddCommand extends CompositeCommand {
public AdminResetsAddCommand(AdminResetsCommand parent) {
super(parent, "add");
}
@Override
public void setup() {
setDescription("commands.admin.resets.add.description");
setParametersHelp("commands.admin.resets.add.parameters");
}
@Override
public boolean execute(User user, String label, @NonNull List<String> args) {
if (args.size() != 2) {
showHelp(this, user);
return false;
}
UUID target = getPlayers().getUUID(args.get(0));
if (target == null) {
user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
} else if (!NumberUtils.isNumber(args.get(1)) || Integer.valueOf(args.get(1)) < 0) {
user.sendMessage("general.errors.must-be-positive-number", TextVariables.NUMBER, args.get(1));
} else {
getPlayers().setResets(getWorld(), target, getPlayers().getResets(getWorld(), target) + Integer.valueOf(args.get(1)));
user.sendMessage("commands.admin.resets.add.success",
TextVariables.NAME, args.get(0), TextVariables.NUMBER, args.get(1),
"[total]", String.valueOf(getPlayers().getResets(getWorld(), target)));
return true;
}
return false;
}
}

View File

@ -18,6 +18,8 @@ public class AdminResetsCommand extends CompositeCommand {
new AdminResetsSetCommand(this); new AdminResetsSetCommand(this);
new AdminResetsResetCommand(this); new AdminResetsResetCommand(this);
new AdminResetsAddCommand(this);
new AdminResetsRemoveCommand(this);
} }
@Override @Override

View File

@ -0,0 +1,52 @@
package world.bentobox.bentobox.api.commands.admin.resets;
import org.apache.commons.lang.math.NumberUtils;
import org.eclipse.jdt.annotation.NonNull;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User;
import java.util.List;
import java.util.UUID;
/**
* @author Poslovitch
* @since 1.8.0
*/
public class AdminResetsRemoveCommand extends CompositeCommand {
public AdminResetsRemoveCommand(AdminResetsCommand parent) {
super(parent, "remove");
}
@Override
public void setup() {
setDescription("commands.admin.resets.remove.description");
setParametersHelp("commands.admin.resets.remove.parameters");
}
@Override
public boolean execute(User user, String label, @NonNull List<String> args) {
if (args.size() != 2) {
showHelp(this, user);
return false;
}
UUID target = getPlayers().getUUID(args.get(0));
if (target == null) {
user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
} else if (!NumberUtils.isNumber(args.get(1)) || Integer.valueOf(args.get(1)) < 0) {
user.sendMessage("general.errors.must-be-positive-number", TextVariables.NUMBER, args.get(1));
} else {
// Make sure it cannot go under 0.
int newResets = Math.max(getPlayers().getResets(getWorld(), target) - Integer.valueOf(args.get(1)), 0);
getPlayers().setResets(getWorld(), target, newResets);
user.sendMessage("commands.admin.resets.remove.success",
TextVariables.NAME, args.get(0), TextVariables.NUMBER, args.get(1),
"[total]", String.valueOf(newResets));
return true;
}
return false;
}
}

View File

@ -39,7 +39,7 @@ public class AdminResetsResetCommand extends ConfirmableCommand {
getIWM().setResetEpoch(getWorld()); getIWM().setResetEpoch(getWorld());
// Reset all current players // Reset all current players
Bukkit.getOnlinePlayers().stream().map(Player::getUniqueId).filter(getPlayers()::isKnown).forEach(u -> getPlayers().setResets(getWorld(), u, 0)); Bukkit.getOnlinePlayers().stream().map(Player::getUniqueId).filter(getPlayers()::isKnown).forEach(u -> getPlayers().setResets(getWorld(), u, 0));
user.sendMessage("general.success"); user.sendMessage("commands.admin.resets.reset.success-everyone");
}); });
return true; return true;
} else { } else {
@ -50,7 +50,7 @@ public class AdminResetsResetCommand extends ConfirmableCommand {
return false; return false;
} else { } else {
getPlayers().setResets(getWorld(), target, 0); getPlayers().setResets(getWorld(), target, 0);
user.sendMessage("general.success"); user.sendMessage("commands.admin.resets.reset.success", TextVariables.NAME, args.get(0));
return true; return true;
} }
} }

View File

@ -23,7 +23,7 @@ public class AdminResetsSetCommand extends CompositeCommand {
@Override @Override
public boolean execute(User user, String label, List<String> args) { public boolean execute(User user, String label, List<String> args) {
if (args.isEmpty() || args.size() != 2) { if (args.size() != 2) {
showHelp(this, user); showHelp(this, user);
return false; return false;
} }
@ -31,11 +31,12 @@ public class AdminResetsSetCommand extends CompositeCommand {
UUID target = getPlayers().getUUID(args.get(0)); UUID target = getPlayers().getUUID(args.get(0));
if (target == null) { if (target == null) {
user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0)); user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
} else if (!NumberUtils.isNumber(args.get(1)) || Integer.valueOf(args.get(1)) < 0) { } else if (!NumberUtils.isNumber(args.get(1)) || Integer.valueOf(args.get(1)) <= 0) {
user.sendMessage("general.errors.must-be-positive-number", TextVariables.NUMBER, args.get(1)); user.sendMessage("general.errors.must-be-positive-number", TextVariables.NUMBER, args.get(1));
} else { } else {
getPlayers().setResets(getWorld(), target, Integer.valueOf(args.get(1))); getPlayers().setResets(getWorld(), target, Integer.valueOf(args.get(1)));
user.sendMessage("general.success"); user.sendMessage("commands.admin.resets.set.success",
TextVariables.NAME, args.get(0), TextVariables.NUMBER, args.get(1));
return true; return true;
} }

View File

@ -165,6 +165,18 @@ public class IslandResetCommand extends ConfirmableCommand {
// Remove player // Remove player
getIslands().removePlayer(getWorld(), memberUUID); getIslands().removePlayer(getWorld(), memberUUID);
// Execute commands when leaving
getIWM().getOnLeaveCommands(island.getWorld()).forEach(command -> {
command = command.replace("[player]", member.getName());
if (command.startsWith("[SUDO]") && member.isOnline()) {
// Execute the command by the player
member.performCommand(command.substring(6));
} else {
// Otherwise execute as the server console
getPlugin().getServer().dispatchCommand(Bukkit.getConsoleSender(), command);
}
});
// Remove money inventory etc. // Remove money inventory etc.
if (getIWM().isOnLeaveResetEnderChest(getWorld())) { if (getIWM().isOnLeaveResetEnderChest(getWorld())) {
if (member.isOnline()) { if (member.isOnline()) {

View File

@ -78,6 +78,17 @@ public class IslandTeamKickCommand extends ConfirmableCommand {
target.sendMessage("commands.island.team.kick.owner-kicked", "[gamemode]", getAddon().getDescription().getName()); target.sendMessage("commands.island.team.kick.owner-kicked", "[gamemode]", getAddon().getDescription().getName());
Island oldIsland = getIslands().getIsland(getWorld(), targetUUID); Island oldIsland = getIslands().getIsland(getWorld(), targetUUID);
getIslands().removePlayer(getWorld(), targetUUID); getIslands().removePlayer(getWorld(), targetUUID);
// Execute commands when leaving
getIWM().getOnLeaveCommands(oldIsland.getWorld()).forEach(command -> {
command = command.replace("[player]", target.getName());
if (command.startsWith("[SUDO]") && target.isOnline()) {
// Execute the command by the player
target.performCommand(command.substring(6));
} else {
// Otherwise execute as the server console
getPlugin().getServer().dispatchCommand(Bukkit.getConsoleSender(), command);
}
});
// Remove money inventory etc. // Remove money inventory etc.
if (getIWM().isOnLeaveResetEnderChest(getWorld())) { if (getIWM().isOnLeaveResetEnderChest(getWorld())) {
if (target.isOnline()) { if (target.isOnline()) {

View File

@ -72,6 +72,17 @@ public class IslandTeamLeaveCommand extends ConfirmableCommand {
User.getInstance(ownerUUID).sendMessage("commands.island.team.leave.left-your-island", TextVariables.NAME, user.getName()); User.getInstance(ownerUUID).sendMessage("commands.island.team.leave.left-your-island", TextVariables.NAME, user.getName());
} }
getIslands().setLeaveTeam(getWorld(), user.getUniqueId()); getIslands().setLeaveTeam(getWorld(), user.getUniqueId());
// Execute commands when leaving
getIWM().getOnLeaveCommands(island.getWorld()).forEach(command -> {
command = command.replace("[player]", user.getName());
if (command.startsWith("[SUDO]") && user.isOnline()) {
// Execute the command by the player
user.performCommand(command.substring(6));
} else {
// Otherwise execute as the server console
getPlugin().getServer().dispatchCommand(Bukkit.getConsoleSender(), command);
}
});
// Remove money inventory etc. // Remove money inventory etc.
if (getIWM().isOnLeaveResetEnderChest(getWorld())) { if (getIWM().isOnLeaveResetEnderChest(getWorld())) {
user.getPlayer().getEnderChest().clear(); user.getPlayer().getEnderChest().clear();

View File

@ -8,6 +8,7 @@ import org.bukkit.Difficulty;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.eclipse.jdt.annotation.NonNull;
import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.api.flags.Flag;
/** /**
@ -186,6 +187,27 @@ public interface WorldSettings extends ConfigObject {
*/ */
boolean isOnJoinResetMoney(); boolean isOnJoinResetMoney();
/**
* Returns a list of commands that should be executed when the player joins an island or creates one.<br/>
* These commands are executed by the console, unless otherwise stated using the {@code [SUDO]} prefix, in which case they are executed by the player.<br/>
* <br/>
* Available placeholders for the commands are the following:
* <ul>
* <li>{@code [player]}: name of the player</li>
* </ul>
* <br/>
* Here are some examples of valid commands to execute:
* <ul>
* <li>{@code "[SUDO] bbox version"}</li>
* <li>{@code "bsbadmin deaths set [player] 0"}</li>
* </ul>
* @return a list of commands.
* @since 1.8.0
* @see #getOnLeaveCommands()
*/
@NonNull
List<String> getOnJoinCommands();
/** /**
* @return the onLeaveResetEnderChest * @return the onLeaveResetEnderChest
*/ */
@ -201,6 +223,29 @@ public interface WorldSettings extends ConfigObject {
*/ */
boolean isOnLeaveResetMoney(); boolean isOnLeaveResetMoney();
/**
* Returns a list of commands that should be executed when the player leaves an island or resets one.<br/>
* These commands are executed by the console, unless otherwise stated using the {@code [SUDO]} prefix, in which case they are executed by the player.<br/>
* <br/>
* Available placeholders for the commands are the following:
* <ul>
* <li>{@code [player]}: name of the player</li>
* </ul>
* <br/>
* Here are some examples of valid commands to execute:
* <ul>
* <li>{@code "[SUDO] bbox version"}</li>
* <li>{@code "bsbadmin deaths set [player] 0"}</li>
* </ul>
* <br/>
* Note that player-executed commands might not work, as these commands can be run with said player being offline.
* @return a list of commands.
* @since 1.8.0
* @see #getOnJoinCommands()
*/
@NonNull
List<String> getOnLeaveCommands();
/** /**
* @return true if the default world generator should not operate in this world * @return true if the default world generator should not operate in this world
*/ */

View File

@ -14,6 +14,7 @@ import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Banner;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.block.CreatureSpawner; import org.bukkit.block.CreatureSpawner;
@ -288,6 +289,12 @@ public class BlueprintClipboard {
cs.setSpawnRange(spawner.getSpawnRange()); cs.setSpawnRange(spawner.getSpawnRange());
b.setCreatureSpawner(cs); b.setCreatureSpawner(cs);
} }
// Banners
if (blockState instanceof Banner) {
b.setBannerPatterns(((Banner) blockState).getPatterns());
}
this.bpBlocks.put(pos, b); this.bpBlocks.put(pos, b);
return true; return true;
} }

View File

@ -11,6 +11,7 @@ import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Banner;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
@ -246,6 +247,12 @@ public class BlueprintPaster {
spawner.setSpawnRange(s.getSpawnRange()); spawner.setSpawnRange(s.getSpawnRange());
bs.update(true, false); bs.update(true, false);
} }
// Banners
if (bs instanceof Banner) {
Banner banner = (Banner) bs;
banner.setPatterns(bpBlock.getBannerPatterns());
banner.update(true, false);
}
} }
/** /**

View File

@ -4,6 +4,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.bukkit.block.banner.Pattern;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
@ -22,6 +23,11 @@ public class BlueprintBlock {
private Map<Integer, ItemStack> inventory; private Map<Integer, ItemStack> inventory;
@Expose @Expose
private BlueprintCreatureSpawner creatureSpawner; private BlueprintCreatureSpawner creatureSpawner;
/**
* @since 1.8.0
*/
@Expose
private List<Pattern> bannerPatterns;
public BlueprintBlock(String blockData) { public BlueprintBlock(String blockData) {
this.blockData = blockData; this.blockData = blockData;
@ -82,4 +88,20 @@ public class BlueprintBlock {
public void setCreatureSpawner(BlueprintCreatureSpawner creatureSpawner) { public void setCreatureSpawner(BlueprintCreatureSpawner creatureSpawner) {
this.creatureSpawner = creatureSpawner; this.creatureSpawner = creatureSpawner;
} }
/**
* @return list of the banner patterns
* @since 1.8.0
*/
public List<Pattern> getBannerPatterns() {
return bannerPatterns;
}
/**
* @param bannerPatterns the banner Patterns to set
* @since 1.8.0
*/
public void setBannerPatterns(List<Pattern> bannerPatterns) {
this.bannerPatterns = bannerPatterns;
}
} }

View File

@ -41,6 +41,9 @@ public class BlueprintEntity {
@Expose @Expose
private Style style; private Style style;
/**
* @since 1.8.0
*/
public void configureEntity(Entity e) { public void configureEntity(Entity e) {
if (e instanceof Colorable) { if (e instanceof Colorable) {
((Colorable) e).setColor(color); ((Colorable) e).setColor(color);

View File

@ -562,6 +562,18 @@ public class IslandWorldManager {
return gameModes.get(world).getWorldSettings().isOnJoinResetEnderChest(); return gameModes.get(world).getWorldSettings().isOnJoinResetEnderChest();
} }
/**
* Returns a list of commands to execute when the player creates or joins an island.
* @param world the World
* @return a list of commands
* @since 1.8.0
* @see #getOnLeaveCommands(World)
*/
@NonNull
public List<String> getOnJoinCommands(@NonNull World world) {
return gameModes.get(world).getWorldSettings().getOnJoinCommands();
}
/** /**
* @return the onLeaveResetMoney * @return the onLeaveResetMoney
*/ */
@ -583,6 +595,18 @@ public class IslandWorldManager {
return gameModes.get(world).getWorldSettings().isOnLeaveResetEnderChest(); return gameModes.get(world).getWorldSettings().isOnLeaveResetEnderChest();
} }
/**
* Returns a list of commands to execute when the player resets or leaves an island.
* @param world the World
* @return a list of commands
* @since 1.8.0
* @see #getOnJoinCommands(World)
*/
@NonNull
public List<String> getOnLeaveCommands(@NonNull World world) {
return gameModes.get(world).getWorldSettings().getOnLeaveCommands();
}
/** /**
* Get data folder for the addon that registered this world * Get data folder for the addon that registered this world
* *

View File

@ -38,6 +38,7 @@ import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.api.events.IslandBaseEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent; import world.bentobox.bentobox.api.events.island.IslandEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.Reason; import world.bentobox.bentobox.api.events.island.IslandEvent.Reason;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.logs.LogEntry; import world.bentobox.bentobox.api.logs.LogEntry;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
@ -670,7 +671,17 @@ public class IslandsManager {
} }
// If this is a new island, then run commands and do resets // If this is a new island, then run commands and do resets
if (newIsland) { if (newIsland) {
// TODO add command running // Execute commands
plugin.getIWM().getOnJoinCommands(world).forEach(command -> {
command = command.replace("[player]", player.getName());
if (command.startsWith("[SUDO]")) {
// Execute the command by the player
player.performCommand(command.substring(6));
} else {
// Otherwise execute as the server console
plugin.getServer().dispatchCommand(Bukkit.getConsoleSender(), command);
}
});
// Remove money inventory etc. // Remove money inventory etc.
if (plugin.getIWM().isOnJoinResetEnderChest(world)) { if (plugin.getIWM().isOnJoinResetEnderChest(world)) {
@ -1201,6 +1212,17 @@ public class IslandsManager {
this.saveAll(); this.saveAll();
} }
/**
* Resets a flag to gamemode config.yml default
* @param world - world
* @param flag - flag to reset
* @since 1.8.0
*/
public void resetFlag(World world, Flag flag) {
islandCache.resetFlag(world, flag);
this.saveAll();
}
/** /**
* Returns whether the specified island custom name exists in this world. * Returns whether the specified island custom name exists in this world.
* @param world World of the gamemode * @param world World of the gamemode
@ -1212,4 +1234,5 @@ public class IslandsManager {
return getIslands(world).stream().filter(island -> island.getName() != null).map(Island::getName) return getIslands(world).stream().filter(island -> island.getName() != null).map(Island::getName)
.anyMatch(n -> ChatColor.stripColor(n).equals(ChatColor.stripColor(name))); .anyMatch(n -> ChatColor.stripColor(n).equals(ChatColor.stripColor(name)));
} }
} }

View File

@ -4,6 +4,7 @@ import java.io.File;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
@ -15,6 +16,7 @@ import java.util.jar.JarFile;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.BentoBox;
@ -108,7 +110,7 @@ public class LocalesManager {
} }
/** /**
* Copies locale files from the addon jar to the file system * Copies locale files from the addon jar to the file system and updates current locales with the latest references
* @param addon - addon * @param addon - addon
*/ */
void copyLocalesFromAddonJar(Addon addon) { void copyLocalesFromAddonJar(Addon addon) {
@ -116,14 +118,39 @@ public class LocalesManager {
File localeDir = new File(plugin.getDataFolder(), LOCALE_FOLDER + File.separator + addon.getDescription().getName()); File localeDir = new File(plugin.getDataFolder(), LOCALE_FOLDER + File.separator + addon.getDescription().getName());
if (!localeDir.exists()) { if (!localeDir.exists()) {
localeDir.mkdirs(); localeDir.mkdirs();
// Obtain any locale files and save them
Util.listJarFiles(jar, LOCALE_FOLDER, ".yml").forEach(lf -> addon.saveResource(lf, localeDir, false, true));
} }
// Obtain any locale files, save them and update
Util.listJarFiles(jar, LOCALE_FOLDER, ".yml").forEach(lf -> {
File file = addon.saveResource(lf, localeDir, false, true);
// Update
if (file != null) {
updateLocale(addon, file, lf);
}
});
} catch (Exception e) { } catch (Exception e) {
plugin.logError(e.getMessage()); plugin.logError(e.getMessage());
} }
} }
private void updateLocale(Addon addon, File fileLocaleFile, String lf) {
try {
// Load the JAR locale file
YamlConfiguration jarLocale = addon.getYamlFromJar(lf);
// Load the locale file system locale file
YamlConfiguration fileLocale = new YamlConfiguration();
fileLocale.load(fileLocaleFile);
// Copy new keys to file
jarLocale.getKeys(true).stream().filter(k -> !fileLocale.contains(k, false)).forEach(k -> fileLocale.set(k, jarLocale.get(k)));
// Save file
fileLocale.save(fileLocaleFile);
} catch (Exception e) {
plugin.logError("Error updating locale file: " + lf + " : " + e.getMessage());
plugin.logStacktrace(e);
}
}
/** /**
* Copies all the locale files from the plugin jar to the filesystem. * Copies all the locale files from the plugin jar to the filesystem.
* Only done if the locale folder does not already exist. * Only done if the locale folder does not already exist.
@ -135,18 +162,36 @@ public class LocalesManager {
// If it does exist, then new files will NOT be written! // If it does exist, then new files will NOT be written!
if (!localeDir.exists()) { if (!localeDir.exists()) {
localeDir.mkdirs(); localeDir.mkdirs();
FileLister lister = new FileLister(plugin); }
try { FileLister lister = new FileLister(plugin);
for (String name : lister.listJar(LOCALE_FOLDER)) { try {
// We cannot use Bukkit's saveResource, because we want it to go into a specific folder, so... for (String name : lister.listJar(LOCALE_FOLDER)) {
// Get the last part of the name // We cannot use Bukkit's saveResource, because we want it to go into a specific folder, so...
int lastIndex = name.lastIndexOf('/'); // Get the last part of the name
File targetFile = new File(localeDir, name.substring(lastIndex >= 0 ? lastIndex : 0)); int lastIndex = name.lastIndexOf('/');
copyFile(name, targetFile); File targetFile = new File(localeDir, name.substring(lastIndex >= 0 ? lastIndex : 0));
copyFile(name, targetFile);
// Update the locale file if it exists already
try (InputStreamReader in = new InputStreamReader(plugin.getResource(name))) {
YamlConfiguration jarLocale = new YamlConfiguration();
jarLocale.load(in);
YamlConfiguration fileLocale = new YamlConfiguration();
fileLocale.load(targetFile);
for (String k : jarLocale.getKeys(true)) {
if (!fileLocale.contains(k, false)) {
fileLocale.set(k, jarLocale.get(k));
}
}
// Save it
fileLocale.save(targetFile);
} catch (InvalidConfigurationException e) {
plugin.logError("Could not update locale files from jar " + e.getMessage());
} }
} catch (IOException e) {
plugin.logError("Could not copy locale files from jar " + e.getMessage());
} }
} catch (IOException e) {
plugin.logError("Could not copy locale files from jar " + e.getMessage());
} }
} }
@ -180,9 +225,9 @@ public class LocalesManager {
languages.put(localeObject, new BentoBoxLocale(localeObject, languageYaml)); languages.put(localeObject, new BentoBoxLocale(localeObject, languageYaml));
} }
} catch (Exception e) { } catch (Exception e) {
BentoBox.getInstance().logError("Could not load '" + language.getName() + "' : " + e.getMessage() plugin.logError("Could not load '" + language.getName() + "' : " + e.getMessage()
+ " with the following cause '" + e.getCause() + "'." + + " with the following cause '" + e.getCause() + "'." +
" The file has likely an invalid YML format or has been made unreadable during the process."); " The file has likely an invalid YML format or has been made unreadable during the process.");
} }
} }
} }
@ -256,7 +301,11 @@ public class LocalesManager {
plugin.log(ChatColor.AQUA + "Analyzing BentoBox locale files"); plugin.log(ChatColor.AQUA + "Analyzing BentoBox locale files");
user.sendRawMessage(ChatColor.AQUA + SPACER); user.sendRawMessage(ChatColor.AQUA + SPACER);
loadLocalesFromFile(BENTOBOX); loadLocalesFromFile(BENTOBOX);
analyze(fix); if (languages.containsKey(Locale.US)) {
analyze(user, fix);
} else {
user.sendRawMessage(ChatColor.RED + "No US English in BentoBox to use for analysis!");
}
user.sendRawMessage(ChatColor.AQUA + "Analyzing Addon locale files"); user.sendRawMessage(ChatColor.AQUA + "Analyzing Addon locale files");
plugin.getAddonsManager().getAddons().forEach(addon -> { plugin.getAddonsManager().getAddons().forEach(addon -> {
user.sendRawMessage(ChatColor.AQUA + SPACER); user.sendRawMessage(ChatColor.AQUA + SPACER);
@ -264,22 +313,23 @@ public class LocalesManager {
user.sendRawMessage(ChatColor.AQUA + SPACER); user.sendRawMessage(ChatColor.AQUA + SPACER);
languages.clear(); languages.clear();
loadLocalesFromFile(addon.getDescription().getName()); loadLocalesFromFile(addon.getDescription().getName());
analyze(fix); if (languages.containsKey(Locale.US)) {
analyze(user, fix);
} else {
user.sendRawMessage(ChatColor.RED + "No US English to use for analysis!");
}
}); });
reloadLanguages(); reloadLanguages();
} }
/** /**
* *
* @param user
* @param fix whether or not locale files with missing translations should be fixed. * @param fix whether or not locale files with missing translations should be fixed.
* Not currently supported. * Not currently supported.
* @since 1.5.0 * @since 1.5.0
*/ */
private void analyze(boolean fix) { private void analyze(User user, boolean fix) {
if (!languages.containsKey(Locale.US)) {
return;
}
User user = User.getInstance(Bukkit.getConsoleSender());
user.sendRawMessage(ChatColor.GREEN + "The following locales are supported:"); user.sendRawMessage(ChatColor.GREEN + "The following locales are supported:");
languages.forEach((k,v) -> user.sendRawMessage(ChatColor.GOLD + k.toLanguageTag() + " " + k.getDisplayLanguage() + " " + k.getDisplayCountry())); languages.forEach((k,v) -> user.sendRawMessage(ChatColor.GOLD + k.toLanguageTag() + " " + k.getDisplayLanguage() + " " + k.getDisplayCountry()));

View File

@ -59,36 +59,27 @@ public class WebManager {
if (plugin.getSettings().isLogGithubDownloadData()) { if (plugin.getSettings().isLogGithubDownloadData()) {
plugin.log("Downloading data from GitHub..."); plugin.log("Downloading data from GitHub...");
} }
GitHubRepository repo = new GitHubRepository(gh, "BentoBoxWorld/weblink"); GitHubRepository repo;
try {
repo = new GitHubRepository(gh, "BentoBoxWorld/weblink");
} catch (Exception e) {
plugin.logError("An unhandled exception occurred when trying to connect to GitHub...");
plugin.logStacktrace(e);
String tagsContent = ""; // Stop the execution of the method right away.
String topicsContent = ""; return;
String catalogContent = ""; }
// Downloading the data // Downloading the data
try { String tagsContent = getContent(repo, "catalog/tags.json");
tagsContent = repo.getContent("catalog/tags.json").getContent().replaceAll("\\n", ""); String topicsContent = getContent(repo, "catalog/topics.json");
topicsContent = repo.getContent("catalog/topics.json").getContent().replaceAll("\\n", ""); String catalogContent = getContent(repo, "catalog/catalog.json");
catalogContent = repo.getContent("catalog/catalog.json").getContent().replaceAll("\\n", "");
} catch (IllegalAccessException e) {
if (plugin.getSettings().isLogGithubDownloadData()) {
plugin.log("Could not connect to GitHub.");
}
} catch (Exception e) {
plugin.logError("An unhandled exception occurred when downloading data from GitHub...");
plugin.logStacktrace(e);
}
// People were concerned that the download took ages, so we need to tell them it's over now. // People were concerned that the download took ages, so we need to tell them it's over now.
if (plugin.getSettings().isLogGithubDownloadData()) { if (plugin.getSettings().isLogGithubDownloadData()) {
plugin.log("Successfully downloaded data from GitHub."); plugin.log("Successfully downloaded data from GitHub.");
} }
// Decoding the Base64 encoded contents
tagsContent = new String(Base64.getDecoder().decode(tagsContent), StandardCharsets.UTF_8);
topicsContent = new String(Base64.getDecoder().decode(topicsContent), StandardCharsets.UTF_8);
catalogContent = new String(Base64.getDecoder().decode(catalogContent), StandardCharsets.UTF_8);
/* Parsing the data */ /* Parsing the data */
// Register the tags translations in the locales // Register the tags translations in the locales
@ -140,6 +131,29 @@ public class WebManager {
}); });
} }
/**
*
* @param repo
* @param fileName
* @return
* @since 1.8.0
*/
@NonNull
private String getContent(@NonNull GitHubRepository repo, String fileName) {
try {
String content = repo.getContent(fileName).getContent().replaceAll("\\n", "");
return new String(Base64.getDecoder().decode(content), StandardCharsets.UTF_8);
} catch (IllegalAccessException e) {
if (plugin.getSettings().isLogGithubDownloadData()) {
plugin.log("Could not connect to GitHub.");
}
} catch (Exception e) {
plugin.logError("An unhandled exception occurred when downloading '" + fileName + "' from GitHub...");
plugin.logStacktrace(e);
}
return "";
}
/** /**
* Returns the contents of the addons catalog (may be an empty list). * Returns the contents of the addons catalog (may be an empty list).
* @return the contents of the addons catalog. * @return the contents of the addons catalog.

View File

@ -16,6 +16,8 @@ import org.bukkit.World;
import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.util.Util; import world.bentobox.bentobox.util.Util;
@ -312,4 +314,16 @@ public class IslandCache {
World w = Util.getWorld(world); World w = Util.getWorld(world);
islandsById.values().stream().filter(i -> i.getWorld().equals(w)).forEach(Island::setFlagsDefaults); islandsById.values().stream().filter(i -> i.getWorld().equals(w)).forEach(Island::setFlagsDefaults);
} }
/**
* Resets a specific flag on all game mode islands in world to default setting
* @param world - world
* @param flag - flag to reset
* @since 1.8.0
*/
public void resetFlag(World world, Flag flag) {
World w = Util.getWorld(world);
int setting = BentoBox.getInstance().getIWM().getDefaultIslandFlags(w).getOrDefault(flag, flag.getDefaultRank());
islandsById.values().stream().filter(i -> i.getWorld().equals(w)).forEach(i -> i.setFlag(flag, setting));
}
} }

View File

@ -54,9 +54,20 @@ commands:
set: set:
description: "sets the resets of this player" description: "sets the resets of this player"
parameters: "<player> <resets>" parameters: "<player> <resets>"
success: "&aSuccessfully set &b[name]&a's resets to &b[number]&a."
reset: reset:
description: "resets the resets of this player to 0" description: "resets the resets of this player to 0"
parameters: "<player>" parameters: "<player>"
success-everyone: "&aSuccessfully reset &beveryone&a's resets to &b0&a."
success: "&aSuccessfully reset &b[name]&a's resets to &b0&a."
add:
description: "adds resets to the player"
parameters: "<player> <resets>"
success: "&aSuccessfully added &b[number] &aresets to &b[name], increasing the total to &b[total]&a resets."
remove:
description: "removes resets to the player"
parameters: "<player> <resets>"
success: "&aSuccessfully removed &b[number] &aresets to &b[name], decreasing the total to &b[total]&a resets."
purge: purge:
parameters: "[days]" parameters: "[days]"
description: "purge islands abandoned for more than [days]" description: "purge islands abandoned for more than [days]"
@ -310,8 +321,11 @@ commands:
&aLeft click to increment &aLeft click to increment
&aRight click to decrement &aRight click to decrement
resetflags: resetflags:
parameters: "[flag]"
description: "Reset all islands to default flag settings in config.yml" description: "Reset all islands to default flag settings in config.yml"
confirm: "&4This will reset the flag(s) to default for all islands!"
success: "&aSuccessfully reset all islands' flags to the default settings." success: "&aSuccessfully reset all islands' flags to the default settings."
success-one: "&a[name] flag set to default for all islands."
world: world:
description: "Manage world settings" description: "Manage world settings"
delete: delete:
@ -334,6 +348,14 @@ commands:
description: "sets deaths of the player" description: "sets deaths of the player"
parameters: "<player> <deaths>" parameters: "<player> <deaths>"
success: "&aSuccessfully set &b[name]&a's deaths to &b[number]&a." success: "&aSuccessfully set &b[name]&a's deaths to &b[number]&a."
add:
description: "adds deaths to the player"
parameters: "<player> <deaths>"
success: "&aSuccessfully added &b[number] &adeaths to &b[name], increasing the total to &b[total]&a deaths."
remove:
description: "removes deaths to the player"
parameters: "<player> <deaths>"
success: "&aSuccessfully removed &b[number] &adeaths to &b[name], decreasing the total to &b[total]&a deaths."
bentobox: bentobox:
description: "BentoBox admin command" description: "BentoBox admin command"
about: about:

View File

@ -0,0 +1,227 @@
package world.bentobox.bentobox.api.commands.admin;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitScheduler;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.stubbing.Answer;
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 world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.Settings;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.flags.Flag.Type;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.managers.CommandsManager;
import world.bentobox.bentobox.managers.FlagsManager;
import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.managers.LocalesManager;
import world.bentobox.bentobox.managers.PlaceholdersManager;
import world.bentobox.bentobox.managers.PlayersManager;
/**
* @author tastybento
*
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({Bukkit.class, BentoBox.class, User.class })
public class AdminResetFlagsCommandTest {
@Mock
private CompositeCommand ac;
private UUID uuid = UUID.randomUUID();
@Mock
private IslandsManager im;
@Mock
private PlayersManager pm;
@Mock
private FlagsManager fm;
@Mock
private Flag flag;
@Mock
private Flag flag2;
@Mock
private Flag flag3;
@Mock
private Player player;
private AdminResetFlagsCommand arf;
private @Nullable User user;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
// Set up plugin
BentoBox plugin = mock(BentoBox.class);
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
// Command manager
CommandsManager cm = mock(CommandsManager.class);
when(plugin.getCommandsManager()).thenReturn(cm);
// Parent command has no aliases
ac = mock(CompositeCommand.class);
when(ac.getSubCommandAliases()).thenReturn(new HashMap<>());
when(ac.getPermissionPrefix()).thenReturn("bskyblock.");
// Player
when(player.getUniqueId()).thenReturn(uuid);
user = User.getInstance(player);
// Flags manager
when(plugin.getFlagsManager()).thenReturn(fm);
when(flag.getType()).thenReturn(Type.PROTECTION);
when(flag2.getType()).thenReturn(Type.SETTING);
when(flag3.getType()).thenReturn(Type.WORLD_SETTING);
when(flag.getID()).thenReturn("FLAG1");
when(flag2.getID()).thenReturn("FLAG2");
when(flag3.getID()).thenReturn("FLAG3");
@NonNull
List<Flag> list = new ArrayList<>();
list.add(flag);
list.add(flag2);
list.add(flag3);
when(fm.getFlags()).thenReturn(list);
// Locales & Placeholders
LocalesManager lm = mock(LocalesManager.class);
when(lm.get(any(), any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(1, String.class));
PlaceholdersManager phm = mock(PlaceholdersManager.class);
when(plugin.getPlaceholdersManager()).thenReturn(phm);
when(phm.replacePlaceholders(any(), any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(1, String.class));
when(plugin.getLocalesManager()).thenReturn(lm);
// Confirmation
Settings settings = mock(Settings.class);
when(settings.getConfirmationTime()).thenReturn(10);
when(plugin.getSettings()).thenReturn(settings);
// Server & Scheduler
BukkitScheduler sch = mock(BukkitScheduler.class);
PowerMockito.mockStatic(Bukkit.class);
when(Bukkit.getScheduler()).thenReturn(sch);
// Class
arf = new AdminResetFlagsCommand(ac);
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {
User.clearUsers();
}
/**
* Test method for {@link world.bentobox.bentobox.api.commands.admin.AdminResetFlagsCommand#AdminResetFlagsCommand(world.bentobox.bentobox.api.commands.CompositeCommand)}.
*/
@Test
public void testAdminResetFlagsCommand() {
assertEquals("resetflags", arf.getLabel());
verify(flag).getID();
verify(flag2).getID();
verify(flag3, never()).getID();
}
/**
* Test method for {@link world.bentobox.bentobox.api.commands.admin.AdminResetFlagsCommand#setup()}.
*/
@Test
public void testSetup() {
assertFalse(arf.isOnlyPlayer());
assertEquals("bskyblock.admin.resetflags", arf.getPermission());
assertEquals("commands.admin.resetflags.parameters", arf.getParameters());
assertEquals("commands.admin.resetflags.description", arf.getDescription());
}
/**
* Test method for {@link world.bentobox.bentobox.api.commands.admin.AdminResetFlagsCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
*/
@Test
public void testExecuteUserStringListOfStringTwoArgs() {
List<String> args = Arrays.asList("sdfsd", "werwerw");
assertFalse(arf.execute(user, "", args));
verify(player).sendMessage(eq("commands.help.header"));
}
/**
* Test method for {@link world.bentobox.bentobox.api.commands.admin.AdminResetFlagsCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
*/
@Test
public void testExecuteUserStringListOfStringOneArgNotFlag() {
assertFalse(arf.execute(user, "", Collections.singletonList("FLAG3")));
verify(player).sendMessage(eq("commands.help.header"));
}
/**
* Test method for {@link world.bentobox.bentobox.api.commands.admin.AdminResetFlagsCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
*/
@Test
public void testExecuteUserStringListOfStringOneArgFlag2() {
assertTrue(arf.execute(user, "", Collections.singletonList("FLAG2")));
}
/**
* Test method for {@link world.bentobox.bentobox.api.commands.admin.AdminResetFlagsCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
*/
@Test
public void testExecuteUserStringListOfStringOneArgFlag1() {
assertTrue(arf.execute(user, "", Collections.singletonList("FLAG1")));
}
/**
* Test method for {@link world.bentobox.bentobox.api.commands.admin.AdminResetFlagsCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
*/
@Test
public void testExecuteUserStringListOfString() {
assertTrue(arf.execute(user, "", Collections.emptyList()));
}
/**
* Test method for {@link world.bentobox.bentobox.api.commands.admin.AdminResetFlagsCommand#tabComplete(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
*/
@Test
public void testTabCompleteUserStringListOfString() {
Optional<List<String>> list = arf.tabComplete(user, "", Collections.emptyList());
assertTrue(list.isPresent());
assertTrue(list.get().size() == 2);
assertTrue(list.get().contains("FLAG1"));
assertTrue(list.get().contains("FLAG2"));
assertFalse(list.get().contains("FLAG3"));
}
}

View File

@ -30,6 +30,7 @@ import org.bukkit.plugin.PluginManager;
import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@ -701,5 +702,14 @@ public class IslandGoCommandTest {
return false; return false;
} }
@Override
public @NonNull List<String> getOnJoinCommands() {
return null;
}
@Override
public @NonNull List<String> getOnLeaveCommands() {
return null;
}
} }
} }

View File

@ -29,6 +29,7 @@ import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@ -275,6 +276,15 @@ public class BlockEndDragonTest {
private Map<String, Boolean> worldFlags = new HashMap<>(); private Map<String, Boolean> worldFlags = new HashMap<>();
@Override
public @NonNull List<String> getOnLeaveCommands() {
return null;
}
@Override
public @NonNull List<String> getOnJoinCommands() {
return null;
}
@Override @Override
public GameMode getDefaultGameMode() { public GameMode getDefaultGameMode() {

View File

@ -2,14 +2,16 @@ package world.bentobox.bentobox.managers.island;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;
import java.util.Collections;
import java.util.UUID; import java.util.UUID;
import org.bukkit.Location; import org.bukkit.Location;
@ -17,15 +19,18 @@ import org.bukkit.World;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito; import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder; import com.google.common.collect.ImmutableSet.Builder;
import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.managers.IslandWorldManager; import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.managers.IslandsManager;
@ -33,25 +38,37 @@ import world.bentobox.bentobox.managers.RanksManager;
import world.bentobox.bentobox.util.Util; import world.bentobox.bentobox.util.Util;
@RunWith(PowerMockRunner.class) @RunWith(PowerMockRunner.class)
@PrepareForTest(Util.class) @PrepareForTest({BentoBox.class, Util.class})
public class IslandCacheTest { public class IslandCacheTest {
@Mock
private BentoBox plugin; private BentoBox plugin;
private static World world; @Mock
private World world;
@Mock
private Island island; private Island island;
// UUID
private UUID owner = UUID.randomUUID(); private UUID owner = UUID.randomUUID();
@Mock
private Location location; private Location location;
// Test class
private IslandCache ic;
@Mock
private IslandWorldManager iwm;
@Mock
private Flag flag;
@Mock
private IslandsManager im;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
plugin = mock(BentoBox.class); // Plugin
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
world = mock(World.class);
// Worlds // Worlds
IslandWorldManager iwm = mock(IslandWorldManager.class);
when(plugin.getIWM()).thenReturn(iwm); when(plugin.getIWM()).thenReturn(iwm);
// IWM
when(iwm.getDefaultIslandFlags(any())).thenReturn(Collections.singletonMap(flag, 400));
when(iwm.inWorld(any(World.class))).thenReturn(true); when(iwm.inWorld(any(World.class))).thenReturn(true);
when(iwm.inWorld(any(Location.class))).thenReturn(true); when(iwm.inWorld(any(Location.class))).thenReturn(true);
@ -59,14 +76,11 @@ public class IslandCacheTest {
when(Util.getWorld(Mockito.any())).thenReturn(world); when(Util.getWorld(Mockito.any())).thenReturn(world);
// Mock up IslandsManager // Mock up IslandsManager
IslandsManager im = mock(IslandsManager.class);
when(plugin.getIslands()).thenReturn(im); when(plugin.getIslands()).thenReturn(im);
// Island
island = mock(Island.class);
when(island.getWorld()).thenReturn(world); when(island.getWorld()).thenReturn(world);
location = mock(Location.class); // Location
when(location.getWorld()).thenReturn(world); when(location.getWorld()).thenReturn(world);
when(location.getBlockX()).thenReturn(0); when(location.getBlockX()).thenReturn(0);
when(location.getBlockY()).thenReturn(0); when(location.getBlockY()).thenReturn(0);
@ -82,25 +96,26 @@ public class IslandCacheTest {
when(island.getMinX()).thenReturn(-200); when(island.getMinX()).thenReturn(-200);
when(island.getMinZ()).thenReturn(-200); when(island.getMinZ()).thenReturn(-200);
// New cache
ic = new IslandCache();
} }
@Test /**
public void testIslandCache() { * Test for {@link IslandCache#addIsland(Island)}
assertNotNull(new IslandCache()); */
}
@Test @Test
public void testAddIsland() { public void testAddIsland() {
IslandCache ic = new IslandCache();
assertTrue(ic.addIsland(island)); assertTrue(ic.addIsland(island));
// Check if they are added // Check if they are added
assertEquals(island, ic.get(world, owner)); assertEquals(island, ic.get(world, owner));
assertEquals(island, ic.get(location)); assertEquals(island, ic.get(location));
} }
/**
* Test for {@link IslandCache#addPlayer(UUID, Island)}
*/
@Test @Test
public void testAddPlayer() { public void testAddPlayer() {
IslandCache ic = new IslandCache();
UUID playerUUID = UUID.randomUUID(); UUID playerUUID = UUID.randomUUID();
ic.addPlayer(playerUUID, island); ic.addPlayer(playerUUID, island);
// Check if they are added // Check if they are added
@ -109,9 +124,11 @@ public class IslandCacheTest {
} }
/**
* Test for {@link IslandCache#clear()}
*/
@Test @Test
public void testClear() { public void testClear() {
IslandCache ic = new IslandCache();
ic.addIsland(island); ic.addIsland(island);
// Check if they are added // Check if they are added
assertEquals(island, ic.get(world, owner)); assertEquals(island, ic.get(world, owner));
@ -121,10 +138,11 @@ public class IslandCacheTest {
assertNull(ic.get(location)); assertNull(ic.get(location));
} }
/**
* Test for {@link IslandCache#deleteIslandFromCache(Island)}
*/
@Test @Test
public void testDeleteIslandFromCache() { public void testDeleteIslandFromCache() {
IslandCache ic = new IslandCache();
ic.addIsland(island); ic.addIsland(island);
// Check if they are added // Check if they are added
assertEquals(island, ic.get(world, owner)); assertEquals(island, ic.get(world, owner));
@ -156,31 +174,35 @@ public class IslandCacheTest {
} }
/**
* Test for {@link IslandCache#get(Location)}
*/
@Test @Test
public void testGetLocation() { public void testGetLocation() {
IslandCache ic = new IslandCache();
ic.addIsland(island); ic.addIsland(island);
// Check if they are added // Check if they are added
assertEquals(island, ic.get(location)); assertEquals(island, ic.get(location));
} }
/**
* Test for {@link IslandCache#get(World, UUID)}
*/
@Test @Test
public void testGetUUID() { public void testGetUUID() {
IslandCache ic = new IslandCache();
ic.addIsland(island); ic.addIsland(island);
// Check if they are added // Check if they are added
assertEquals(island, ic.get(world, owner)); assertEquals(island, ic.get(world, owner));
} }
/**
* Test for {@link IslandCache#getIslandAt(Location)}
*/
@Test @Test
public void testGetIslandAtLocation() { public void testGetIslandAtLocation() {
// Set coords to be in island space // Set coords to be in island space
when(island.inIslandSpace(Mockito.any(Integer.class), Mockito.any(Integer.class))).thenReturn(true); when(island.inIslandSpace(Mockito.any(Integer.class), Mockito.any(Integer.class))).thenReturn(true);
// Set plugin // Set plugin
Util.setPlugin(plugin); Util.setPlugin(plugin);
// New cache
IslandCache ic = new IslandCache();
ic.addIsland(island); ic.addIsland(island);
// Check exact match for location // Check exact match for location
@ -199,16 +221,11 @@ public class IslandCacheTest {
assertNull(ic.getIslandAt(location2)); assertNull(ic.getIslandAt(location2));
} }
/* /**
@Test * Test for {@link IslandCache#getMembers(World, UUID, int)}
public void testGetIslands() {
fail("Not yet implemented"); // TODO
}
*/ */
@Test @Test
public void testGetMembers() { public void testGetMembers() {
// New cache
IslandCache ic = new IslandCache();
ic.addIsland(island); ic.addIsland(island);
assertTrue(ic.getMembers(world, null, RanksManager.MEMBER_RANK).isEmpty()); assertTrue(ic.getMembers(world, null, RanksManager.MEMBER_RANK).isEmpty());
@ -217,10 +234,12 @@ public class IslandCacheTest {
assertEquals(3, ic.getMembers(world, island.getOwner(), RanksManager.MEMBER_RANK).size()); assertEquals(3, ic.getMembers(world, island.getOwner(), RanksManager.MEMBER_RANK).size());
} }
/**
* Test for {@link IslandCache#getOwner(World, UUID)}
*/
@Test @Test
public void testGetOwner() { public void testGetOwner() {
// New cache
IslandCache ic = new IslandCache();
ic.addIsland(island); ic.addIsland(island);
assertEquals(owner, ic.getOwner(world, owner)); assertEquals(owner, ic.getOwner(world, owner));
@ -228,10 +247,11 @@ public class IslandCacheTest {
assertNull(ic.getOwner(world, UUID.randomUUID())); assertNull(ic.getOwner(world, UUID.randomUUID()));
} }
/**
* Test for {@link IslandCache#hasIsland(World, UUID)}
*/
@Test @Test
public void testHasIsland() { public void testHasIsland() {
// New cache
IslandCache ic = new IslandCache();
ic.addIsland(island); ic.addIsland(island);
assertTrue(ic.hasIsland(world, owner)); assertTrue(ic.hasIsland(world, owner));
@ -239,12 +259,12 @@ public class IslandCacheTest {
assertFalse(ic.hasIsland(world, null)); assertFalse(ic.hasIsland(world, null));
} }
/**
* Test for {@link IslandCache#removePlayer(World, UUID)}
*/
@Test @Test
public void testRemovePlayer() { public void testRemovePlayer() {
// New cache
IslandCache ic = new IslandCache();
ic.addIsland(island); ic.addIsland(island);
assertTrue(ic.hasIsland(world, owner)); assertTrue(ic.hasIsland(world, owner));
ic.removePlayer(world, null); ic.removePlayer(world, null);
assertTrue(ic.hasIsland(world, owner)); assertTrue(ic.hasIsland(world, owner));
@ -254,18 +274,20 @@ public class IslandCacheTest {
assertFalse(ic.hasIsland(world, owner)); assertFalse(ic.hasIsland(world, owner));
} }
/**
* Test for {@link IslandCache#size()}
*/
@Test @Test
public void testSize() { public void testSize() {
// New cache
IslandCache ic = new IslandCache();
ic.addIsland(island); ic.addIsland(island);
assertEquals(1, ic.size()); assertEquals(1, ic.size());
} }
/**
* Test for {@link IslandCache#setOwner(Island, UUID)}
*/
@Test @Test
public void testSetOwner() { public void testSetOwner() {
// New cache
IslandCache ic = new IslandCache();
ic.addIsland(island); ic.addIsland(island);
UUID newOwnerUUID = UUID.randomUUID(); UUID newOwnerUUID = UUID.randomUUID();
ic.setOwner(island, newOwnerUUID); ic.setOwner(island, newOwnerUUID);
@ -274,4 +296,24 @@ public class IslandCacheTest {
assertEquals(island, ic.get(world, newOwnerUUID)); assertEquals(island, ic.get(world, newOwnerUUID));
assertEquals(island, ic.get(island.getCenter())); assertEquals(island, ic.get(island.getCenter()));
} }
/**
* Test for {@link IslandCache#resetFlag(World, world.bentobox.bentobox.api.flags.Flag)}
*/
@Test
public void testResetFlag() {
ic.addIsland(island);
ic.resetFlag(world, flag);
verify(island).setFlag(eq(flag), eq(400));
}
/**
* Test for {@link IslandCache#resetAllFlags(World)}
*/
@Test
public void testResetAllFlags() {
ic.addIsland(island);
ic.resetAllFlags(world);
verify(island).setFlagsDefaults();
}
} }