mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2025-01-25 01:21:21 +01:00
Rework blueprint and blueprint bundle names. (#2026)
* Fixes issue when blueprint clipboard was stuck after saving. The issue was that Map#putIfAbsent still creates a new task, even if object is already in map. The usage requires to use Map#computeIfAbsent. * Rework blueprint and blueprint bundle names. There was an issue with using non-english characters in blueprint names. It was not possible, as all chars for names were converted to lower cased english letters. It included display names. I reworked it a bit and now it should be possible to set non-english names for bundles and blueprints. Fixes #1954
This commit is contained in:
parent
12926f9ee7
commit
35ce1a7d81
@ -62,20 +62,30 @@ public class AdminBlueprintCommand extends ConfirmableCommand {
|
||||
return clipboards;
|
||||
}
|
||||
|
||||
protected void showClipboard(User user) {
|
||||
displayClipboards.putIfAbsent(user, Bukkit.getScheduler().scheduleSyncRepeatingTask(getPlugin(), () -> {
|
||||
if (!user.isPlayer() || !user.getPlayer().isOnline()) {
|
||||
hideClipboard(user);
|
||||
}
|
||||
|
||||
if (clipboards.containsKey(user.getUniqueId())) {
|
||||
BlueprintClipboard clipboard = clipboards.get(user.getUniqueId());
|
||||
paintAxis(user, clipboard);
|
||||
}
|
||||
/**
|
||||
* This method shows clipboard for requested user.
|
||||
* @param user User who need to see clipboard.
|
||||
*/
|
||||
protected void showClipboard(User user)
|
||||
{
|
||||
this.displayClipboards.computeIfAbsent(user,
|
||||
key -> Bukkit.getScheduler().scheduleSyncRepeatingTask(this.getPlugin(), () ->
|
||||
{
|
||||
if (!key.isPlayer() || !key.getPlayer().isOnline())
|
||||
{
|
||||
this.hideClipboard(key);
|
||||
}
|
||||
|
||||
}, 20, 20));
|
||||
if (this.clipboards.containsKey(key.getUniqueId()))
|
||||
{
|
||||
BlueprintClipboard clipboard = this.clipboards.get(key.getUniqueId());
|
||||
this.paintAxis(key, clipboard);
|
||||
}
|
||||
}, 20, 20));
|
||||
}
|
||||
|
||||
|
||||
private void paintAxis(User user, BlueprintClipboard clipboard) {
|
||||
if (clipboard.getPos1() == null || clipboard.getPos2() == null) {
|
||||
return;
|
||||
|
@ -8,49 +8,63 @@ import java.util.Optional;
|
||||
import world.bentobox.bentobox.api.commands.ConfirmableCommand;
|
||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
|
||||
/**
|
||||
* Command that deletes a Blueprint.
|
||||
* @author Poslovitch
|
||||
* @since 1.9.0
|
||||
*/
|
||||
public class AdminBlueprintDeleteCommand extends ConfirmableCommand {
|
||||
|
||||
public AdminBlueprintDeleteCommand(AdminBlueprintCommand parent) {
|
||||
public class AdminBlueprintDeleteCommand extends ConfirmableCommand
|
||||
{
|
||||
public AdminBlueprintDeleteCommand(AdminBlueprintCommand parent)
|
||||
{
|
||||
super(parent, "delete", "remove");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
inheritPermission();
|
||||
setParametersHelp("commands.admin.blueprint.delete.parameters");
|
||||
setDescription("commands.admin.blueprint.delete.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
if (args.size() != 1) {
|
||||
showHelp(this, user);
|
||||
public void setup()
|
||||
{
|
||||
this.inheritPermission();
|
||||
this.setParametersHelp("commands.admin.blueprint.delete.parameters");
|
||||
this.setDescription("commands.admin.blueprint.delete.description");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args)
|
||||
{
|
||||
if (args.size() != 1)
|
||||
{
|
||||
this.showHelp(this, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
String blueprintName = args.get(0).toLowerCase(Locale.ENGLISH);
|
||||
String blueprintName = Util.sanitizeInput(args.get(0));
|
||||
|
||||
// Check if blueprint exist
|
||||
if (getPlugin().getBlueprintsManager().getBlueprints(getAddon()).containsKey(blueprintName)) {
|
||||
askConfirmation(user, user.getTranslation("commands.admin.blueprint.delete.confirmation"), () -> {
|
||||
getPlugin().getBlueprintsManager().deleteBlueprint(getAddon(), blueprintName);
|
||||
user.sendMessage("commands.admin.blueprint.delete.success", TextVariables.NAME, blueprintName);
|
||||
});
|
||||
if (this.getPlugin().getBlueprintsManager().getBlueprints(this.getAddon()).containsKey(blueprintName))
|
||||
{
|
||||
this.askConfirmation(user, user.getTranslation("commands.admin.blueprint.delete.confirmation"),
|
||||
() -> {
|
||||
this.getPlugin().getBlueprintsManager().deleteBlueprint(this.getAddon(), blueprintName);
|
||||
user.sendMessage("commands.admin.blueprint.delete.success", TextVariables.NAME, blueprintName);
|
||||
});
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
user.sendMessage("commands.admin.blueprint.delete.no-blueprint", TextVariables.NAME, blueprintName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
|
||||
return Optional.of(new LinkedList<>(getPlugin().getBlueprintsManager().getBlueprints(getAddon()).keySet()));
|
||||
public Optional<List<String>> tabComplete(User user, String alias, List<String> args)
|
||||
{
|
||||
return Optional.of(new LinkedList<>(this.getPlugin().getBlueprintsManager().getBlueprints(this.getAddon()).keySet()));
|
||||
}
|
||||
}
|
||||
}
|
@ -5,51 +5,66 @@ import java.io.FilenameFilter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.managers.BlueprintsManager;
|
||||
|
||||
public class AdminBlueprintListCommand extends CompositeCommand {
|
||||
public class AdminBlueprintListCommand extends CompositeCommand
|
||||
{
|
||||
|
||||
public AdminBlueprintListCommand(AdminBlueprintCommand parent) {
|
||||
public AdminBlueprintListCommand(AdminBlueprintCommand parent)
|
||||
{
|
||||
super(parent, "list");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
inheritPermission();
|
||||
setDescription("commands.admin.blueprint.list.description");
|
||||
public void setup()
|
||||
{
|
||||
this.inheritPermission();
|
||||
this.setDescription("commands.admin.blueprint.list.description");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canExecute(User user, String label, List<String> args) {
|
||||
if (!args.isEmpty()) {
|
||||
showHelp(this, user);
|
||||
public boolean canExecute(User user, String label, List<String> args)
|
||||
{
|
||||
if (!args.isEmpty())
|
||||
{
|
||||
this.showHelp(this, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
File blueprints = new File(getAddon().getDataFolder(), BlueprintsManager.FOLDER_NAME);
|
||||
if (!blueprints.exists()) {
|
||||
public boolean execute(User user, String label, List<String> args)
|
||||
{
|
||||
File blueprints = new File(this.getAddon().getDataFolder(), BlueprintsManager.FOLDER_NAME);
|
||||
|
||||
if (!blueprints.exists())
|
||||
{
|
||||
user.sendMessage("commands.admin.blueprint.list.no-blueprints");
|
||||
return false;
|
||||
}
|
||||
FilenameFilter blueprintFilter = (File dir, String name) -> name.toLowerCase(java.util.Locale.ENGLISH).endsWith(BlueprintsManager.BLUEPRINT_SUFFIX);
|
||||
List<String> blueprintList = Arrays.stream(Objects.requireNonNull(blueprints.list(blueprintFilter))).map(name -> name.substring(0, name.length() - BlueprintsManager.BLUEPRINT_SUFFIX.length())).collect(Collectors.toList());
|
||||
if (blueprintList.isEmpty()) {
|
||||
|
||||
FilenameFilter blueprintFilter = (File dir, String name) -> name.endsWith(BlueprintsManager.BLUEPRINT_SUFFIX);
|
||||
|
||||
List<String> blueprintList = Arrays.stream(Objects.requireNonNull(blueprints.list(blueprintFilter))).
|
||||
map(name -> name.substring(0, name.length() - BlueprintsManager.BLUEPRINT_SUFFIX.length())).
|
||||
toList();
|
||||
|
||||
if (blueprintList.isEmpty())
|
||||
{
|
||||
user.sendMessage("commands.admin.blueprint.list.no-blueprints");
|
||||
return false;
|
||||
}
|
||||
|
||||
user.sendMessage("commands.admin.blueprint.list.available-blueprints");
|
||||
blueprintList.forEach(user::sendRawMessage);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public class AdminBlueprintLoadCommand extends CompositeCommand {
|
||||
AdminBlueprintCommand parent = (AdminBlueprintCommand) getParent();
|
||||
|
||||
BlueprintClipboardManager bp = new BlueprintClipboardManager(getPlugin(), parent.getBlueprintsFolder());
|
||||
if (bp.load(user, args.get(0))) {
|
||||
if (bp.load(user, Util.sanitizeInput(args.get(0)))) {
|
||||
parent.getClipboards().put(user.getUniqueId(), bp.getClipboard());
|
||||
return true;
|
||||
}
|
||||
|
@ -8,66 +8,107 @@ import world.bentobox.bentobox.api.commands.ConfirmableCommand;
|
||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.Blueprint;
|
||||
import world.bentobox.bentobox.blueprints.BlueprintClipboard;
|
||||
import world.bentobox.bentobox.managers.BlueprintsManager;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
|
||||
/**
|
||||
* Renames an existing blueprint.
|
||||
* @author Poslovitch
|
||||
* @since 1.10.0
|
||||
*/
|
||||
public class AdminBlueprintRenameCommand extends ConfirmableCommand {
|
||||
|
||||
public AdminBlueprintRenameCommand(AdminBlueprintCommand parent) {
|
||||
public class AdminBlueprintRenameCommand extends ConfirmableCommand
|
||||
{
|
||||
public AdminBlueprintRenameCommand(AdminBlueprintCommand parent)
|
||||
{
|
||||
super(parent, "rename");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
inheritPermission();
|
||||
setParametersHelp("commands.admin.blueprint.rename.parameters");
|
||||
setDescription("commands.admin.blueprint.rename.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
if (args.size() != 2) {
|
||||
showHelp(this, user);
|
||||
public void setup()
|
||||
{
|
||||
this.inheritPermission();
|
||||
this.setParametersHelp("commands.admin.blueprint.rename.parameters");
|
||||
this.setDescription("commands.admin.blueprint.rename.description");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canExecute(User user, String label, List<String> args)
|
||||
{
|
||||
if (args.size() != 2)
|
||||
{
|
||||
// Blueprint must have a name.
|
||||
this.showHelp(this, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
AdminBlueprintCommand parent = (AdminBlueprintCommand) getParent();
|
||||
String from = Util.sanitizeInput(args.get(0));
|
||||
String to = Util.sanitizeInput(args.get(1));
|
||||
|
||||
// Check if the names are the same
|
||||
String from = args.get(0).toLowerCase(Locale.ENGLISH);
|
||||
String to = args.get(1).toLowerCase(Locale.ENGLISH);
|
||||
|
||||
if (from.equals(to)) {
|
||||
// Check if name is changed.
|
||||
if (from.equals(to))
|
||||
{
|
||||
user.sendMessage("commands.admin.blueprint.rename.pick-different-name");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the 'from' file exists
|
||||
AdminBlueprintCommand parent = (AdminBlueprintCommand) this.getParent();
|
||||
File fromFile = new File(parent.getBlueprintsFolder(), from + BlueprintsManager.BLUEPRINT_SUFFIX);
|
||||
if (!fromFile.exists()) {
|
||||
|
||||
if (!fromFile.exists())
|
||||
{
|
||||
user.sendMessage("commands.admin.blueprint.no-such-file");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the 'to' file exists
|
||||
|
||||
File toFile = new File(parent.getBlueprintsFolder(), to + BlueprintsManager.BLUEPRINT_SUFFIX);
|
||||
if (toFile.exists()) {
|
||||
// Ask for confirmation to overwrite
|
||||
askConfirmation(user, user.getTranslation("commands.admin.blueprint.file-exists"), () -> rename(user, from, to));
|
||||
} else {
|
||||
askConfirmation(user, () -> rename(user, from, to));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void rename(User user, String blueprintName, String newName) {
|
||||
Blueprint blueprint = getPlugin().getBlueprintsManager().getBlueprints(getAddon()).get(blueprintName);
|
||||
getPlugin().getBlueprintsManager().renameBlueprint(getAddon(), blueprint, newName);
|
||||
user.sendMessage("commands.admin.blueprint.rename.success", "[old]", blueprintName, TextVariables.NAME, blueprint.getName());
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args)
|
||||
{
|
||||
AdminBlueprintCommand parent = (AdminBlueprintCommand) getParent();
|
||||
|
||||
// Check if the names are the same
|
||||
String from = Util.sanitizeInput(args.get(0));
|
||||
String to = Util.sanitizeInput(args.get(1));
|
||||
|
||||
// Check if the 'to' file exists
|
||||
File toFile = new File(parent.getBlueprintsFolder(), to + BlueprintsManager.BLUEPRINT_SUFFIX);
|
||||
|
||||
if (toFile.exists())
|
||||
{
|
||||
// Ask for confirmation to overwrite
|
||||
this.askConfirmation(user,
|
||||
user.getTranslation("commands.admin.blueprint.file-exists"),
|
||||
() -> this.rename(user, from, to, args.get(1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.askConfirmation(user, () -> this.rename(user, from, to, args.get(1)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void rename(User user, String blueprintName, String fileName, String displayName)
|
||||
{
|
||||
Blueprint blueprint = this.getPlugin().getBlueprintsManager().getBlueprints(this.getAddon()).get(blueprintName);
|
||||
|
||||
this.getPlugin().getBlueprintsManager().renameBlueprint(this.getAddon(), blueprint, fileName, displayName);
|
||||
|
||||
user.sendMessage("commands.admin.blueprint.rename.success",
|
||||
"[old]",
|
||||
blueprintName,
|
||||
TextVariables.NAME,
|
||||
blueprint.getName(),
|
||||
"[display]",
|
||||
blueprint.getDisplayName());
|
||||
}
|
||||
}
|
||||
|
@ -2,62 +2,115 @@ package world.bentobox.bentobox.api.commands.admin.blueprints;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.ConfirmableCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.BlueprintClipboard;
|
||||
import world.bentobox.bentobox.managers.BlueprintClipboardManager;
|
||||
import world.bentobox.bentobox.managers.BlueprintsManager;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
public class AdminBlueprintSaveCommand extends ConfirmableCommand {
|
||||
|
||||
public AdminBlueprintSaveCommand(AdminBlueprintCommand parent) {
|
||||
/**
|
||||
* This method allows to save blueprint from the clipboard.
|
||||
*/
|
||||
public class AdminBlueprintSaveCommand extends ConfirmableCommand
|
||||
{
|
||||
public AdminBlueprintSaveCommand(AdminBlueprintCommand parent)
|
||||
{
|
||||
super(parent, "save");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
inheritPermission();
|
||||
setParametersHelp("commands.admin.blueprint.save.parameters");
|
||||
setDescription("commands.admin.blueprint.save.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
if (args.size() != 1) {
|
||||
showHelp(this, user);
|
||||
public void setup()
|
||||
{
|
||||
this.inheritPermission();
|
||||
this.setParametersHelp("commands.admin.blueprint.save.parameters");
|
||||
this.setDescription("commands.admin.blueprint.save.description");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canExecute(User user, String label, List<String> args)
|
||||
{
|
||||
if (args.size() != 1)
|
||||
{
|
||||
// Blueprint must have a name.
|
||||
this.showHelp(this, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
AdminBlueprintCommand parent = (AdminBlueprintCommand) getParent();
|
||||
BlueprintClipboard clipboard = parent.getClipboards().computeIfAbsent(user.getUniqueId(), v -> new BlueprintClipboard());
|
||||
String fileName = args.get(0).toLowerCase(Locale.ENGLISH);
|
||||
if (clipboard.isFull()) {
|
||||
// Check if blueprint had bedrock
|
||||
if (clipboard.getBlueprint().getBedrock() == null) {
|
||||
user.sendMessage("commands.admin.blueprint.bedrock-required");
|
||||
return false;
|
||||
}
|
||||
// Check if file exists
|
||||
File newFile = new File(parent.getBlueprintsFolder(), fileName + BlueprintsManager.BLUEPRINT_SUFFIX);
|
||||
if (newFile.exists()) {
|
||||
this.askConfirmation(user, user.getTranslation("commands.admin.blueprint.file-exists"), () -> hideAndSave(user, parent, clipboard, fileName));
|
||||
return false;
|
||||
}
|
||||
return hideAndSave(user, parent, clipboard, fileName);
|
||||
} else {
|
||||
BlueprintClipboard clipboard = ((AdminBlueprintCommand) this.getParent()).getClipboards().
|
||||
computeIfAbsent(user.getUniqueId(), v -> new BlueprintClipboard());
|
||||
|
||||
if (!clipboard.isFull())
|
||||
{
|
||||
// Clipboard is not set up.
|
||||
user.sendMessage("commands.admin.blueprint.copy-first");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (clipboard.getBlueprint().getBedrock() == null)
|
||||
{
|
||||
// Bedrock is required for all blueprints.
|
||||
user.sendMessage("commands.admin.blueprint.bedrock-required");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean hideAndSave(User user, AdminBlueprintCommand parent, BlueprintClipboard clipboard, String name) {
|
||||
parent.hideClipboard(user);
|
||||
boolean result = new BlueprintClipboardManager(getPlugin(), parent.getBlueprintsFolder(), clipboard).save(user, name);
|
||||
if (result && clipboard.getBlueprint() != null) {
|
||||
getPlugin().getBlueprintsManager().addBlueprint(getAddon(), clipboard.getBlueprint());
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args)
|
||||
{
|
||||
AdminBlueprintCommand parent = (AdminBlueprintCommand) this.getParent();
|
||||
BlueprintClipboard clipboard = parent.getClipboards().
|
||||
computeIfAbsent(user.getUniqueId(), v -> new BlueprintClipboard());
|
||||
|
||||
String fileName = Util.sanitizeInput(args.get(0));
|
||||
|
||||
// Check if file exists
|
||||
File newFile = new File(parent.getBlueprintsFolder(), fileName + BlueprintsManager.BLUEPRINT_SUFFIX);
|
||||
|
||||
if (newFile.exists())
|
||||
{
|
||||
this.askConfirmation(user,
|
||||
user.getTranslation("commands.admin.blueprint.file-exists"),
|
||||
() -> this.hideAndSave(user, parent, clipboard, fileName, args.get(0)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.hideAndSave(user, parent, clipboard, fileName, args.get(0));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method saves given blueprint.
|
||||
* @param user User that triggers blueprint save.
|
||||
* @param parent Parent command that contains clipboard.
|
||||
* @param clipboard Active clipboard.
|
||||
* @param name Filename for the blueprint
|
||||
* @param displayName Display name for the blueprint.
|
||||
* @return {@code true} if blueprint is saved, {@code false} otherwise.
|
||||
*/
|
||||
private boolean hideAndSave(User user,
|
||||
AdminBlueprintCommand parent,
|
||||
BlueprintClipboard clipboard,
|
||||
String name,
|
||||
String displayName)
|
||||
{
|
||||
parent.hideClipboard(user);
|
||||
boolean result = new BlueprintClipboardManager(this.getPlugin(),
|
||||
parent.getBlueprintsFolder(), clipboard).
|
||||
save(user, name, displayName);
|
||||
|
||||
if (result && clipboard.isFull())
|
||||
{
|
||||
this.getPlugin().getBlueprintsManager().addBlueprint(this.getAddon(), clipboard.getBlueprint());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.managers.BlueprintsManager;
|
||||
import world.bentobox.bentobox.managers.island.NewIsland;
|
||||
import world.bentobox.bentobox.panels.IslandCreationPanel;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
|
||||
/**
|
||||
* /island create - Create an island.
|
||||
@ -63,13 +65,13 @@ public class IslandCreateCommand extends CompositeCommand {
|
||||
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(), args.get(0).toLowerCase(java.util.Locale.ENGLISH));
|
||||
String name = getPlugin().getBlueprintsManager().validate(getAddon(), Util.sanitizeInput(args.get(0)));
|
||||
if (name == null) {
|
||||
// The blueprint name is not valid.
|
||||
user.sendMessage("commands.island.create.unknown-blueprint");
|
||||
return false;
|
||||
}
|
||||
if (!getPlugin().getBlueprintsManager().checkPerm(getAddon(), user, args.get(0))) {
|
||||
if (!getPlugin().getBlueprintsManager().checkPerm(getAddon(), user, Util.sanitizeInput(args.get(0)))) {
|
||||
return false;
|
||||
}
|
||||
// Make island
|
||||
|
@ -17,6 +17,8 @@ import world.bentobox.bentobox.managers.BlueprintsManager;
|
||||
import world.bentobox.bentobox.managers.island.NewIsland;
|
||||
import world.bentobox.bentobox.managers.island.NewIsland.Builder;
|
||||
import world.bentobox.bentobox.panels.IslandCreationPanel;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
@ -78,13 +80,13 @@ public class IslandResetCommand extends ConfirmableCommand {
|
||||
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(), args.get(0).toLowerCase(java.util.Locale.ENGLISH));
|
||||
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, args.get(0))) {
|
||||
if (!getPlugin().getBlueprintsManager().checkPerm(getAddon(), user, Util.sanitizeInput(args.get(0)))) {
|
||||
return false;
|
||||
}
|
||||
return resetIsland(user, name);
|
||||
|
@ -53,14 +53,14 @@ public class Blueprint {
|
||||
public String getName() {
|
||||
if (name == null) name = "unnamed";
|
||||
// Force lower case
|
||||
return name.toLowerCase(Locale.ENGLISH);
|
||||
return name;
|
||||
}
|
||||
/**
|
||||
* @param name the name to set
|
||||
*/
|
||||
public Blueprint setName(@NonNull String name) {
|
||||
// Force lowercase
|
||||
this.name = name.toLowerCase(Locale.ENGLISH);
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
|
@ -1,7 +1,5 @@
|
||||
package world.bentobox.bentobox.blueprints.conversation;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.conversations.ConversationContext;
|
||||
import org.bukkit.conversations.Prompt;
|
||||
import org.bukkit.conversations.StringPrompt;
|
||||
@ -18,67 +16,74 @@ import world.bentobox.bentobox.managers.BlueprintsManager;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
|
||||
public class NamePrompt extends StringPrompt {
|
||||
|
||||
public class NamePrompt extends StringPrompt
|
||||
{
|
||||
private final GameModeAddon addon;
|
||||
|
||||
@Nullable
|
||||
private final BlueprintBundle bb;
|
||||
|
||||
@Nullable
|
||||
private Blueprint bp;
|
||||
|
||||
public NamePrompt(@NonNull GameModeAddon addon, @Nullable BlueprintBundle bb) {
|
||||
|
||||
public NamePrompt(@NonNull GameModeAddon addon, @Nullable BlueprintBundle bb)
|
||||
{
|
||||
this.addon = addon;
|
||||
this.bb = bb;
|
||||
}
|
||||
|
||||
public NamePrompt(@NonNull GameModeAddon addon, @Nullable Blueprint bp, @Nullable BlueprintBundle bb) {
|
||||
|
||||
public NamePrompt(@NonNull GameModeAddon addon, @Nullable Blueprint bp, @Nullable BlueprintBundle bb)
|
||||
{
|
||||
this.addon = addon;
|
||||
this.bp = bp;
|
||||
this.bb = bb;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NonNull String getPromptText(ConversationContext context) {
|
||||
User user = User.getInstance((Player)context.getForWhom());
|
||||
public @NonNull String getPromptText(ConversationContext context)
|
||||
{
|
||||
User user = User.getInstance((Player) context.getForWhom());
|
||||
return user.getTranslation("commands.admin.blueprint.management.name.prompt");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Prompt acceptInput(ConversationContext context, String input) {
|
||||
User user = User.getInstance((Player)context.getForWhom());
|
||||
// Convert color codes
|
||||
input = Util.translateColorCodes(input);
|
||||
if (ChatColor.stripColor(input).length() > 32) {
|
||||
context.getForWhom().sendRawMessage("Too long");
|
||||
return this;
|
||||
|
||||
/*Check if unique name contains chars not supported in regex expression
|
||||
Cannot start, contain, or end with special char, cannot contain any numbers.
|
||||
Can only contain - for word separation*/
|
||||
}else if (!ChatColor.stripColor(input).matches("^[a-zA-Z]+(?:-[a-zA-Z]+)*$")) {
|
||||
context.getForWhom().sendRawMessage(user.getTranslation("commands.admin.blueprint.management.name.invalid-char-in-unique-name"));
|
||||
@Override
|
||||
public Prompt acceptInput(ConversationContext context, String input)
|
||||
{
|
||||
User user = User.getInstance((Player) context.getForWhom());
|
||||
String uniqueId = Util.sanitizeInput(input);
|
||||
|
||||
// Convert color codes
|
||||
if (ChatColor.stripColor(Util.translateColorCodes(input)).length() > 32)
|
||||
{
|
||||
context.getForWhom().sendRawMessage(
|
||||
user.getTranslation("commands.admin.blueprint.management.name.too-long"));
|
||||
return this;
|
||||
}
|
||||
if (bb == null || !bb.getUniqueId().equals(BlueprintsManager.DEFAULT_BUNDLE_NAME)) {
|
||||
// Make a uniqueid
|
||||
StringBuilder uniqueId = new StringBuilder(ChatColor.stripColor(input).toLowerCase(Locale.ENGLISH).replace(" ", "_"));
|
||||
|
||||
if (this.bb == null || !this.bb.getUniqueId().equals(BlueprintsManager.DEFAULT_BUNDLE_NAME))
|
||||
{
|
||||
// Check if this name is unique
|
||||
int max = 0;
|
||||
while (max++ < 32 && addon.getPlugin().getBlueprintsManager().getBlueprintBundles(addon).containsKey(uniqueId.toString())) {
|
||||
uniqueId.append("x");
|
||||
}
|
||||
if (max == 32) {
|
||||
context.getForWhom().sendRawMessage(user.getTranslation("commands.admin.blueprint.management.name.pick-a-unique-name"));
|
||||
if (this.addon.getPlugin().getBlueprintsManager().getBlueprintBundles(this.addon).containsKey(uniqueId))
|
||||
{
|
||||
context.getForWhom().sendRawMessage(
|
||||
user.getTranslation("commands.admin.blueprint.management.name.pick-a-unique-name"));
|
||||
return this;
|
||||
}
|
||||
context.setSessionData("uniqueId", uniqueId.toString());
|
||||
} else {
|
||||
// Default stays as default
|
||||
context.setSessionData("uniqueId", bb.getUniqueId());
|
||||
|
||||
context.setSessionData("uniqueId", uniqueId);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default stays as default
|
||||
context.setSessionData("uniqueId", this.bb.getUniqueId());
|
||||
}
|
||||
|
||||
context.setSessionData("name", input);
|
||||
return new NameSuccessPrompt(addon, bb, bp);
|
||||
|
||||
return new NameSuccessPrompt(this.addon, this.bb, this.bp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -15,58 +15,76 @@ import world.bentobox.bentobox.blueprints.Blueprint;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle;
|
||||
import world.bentobox.bentobox.panels.BlueprintManagementPanel;
|
||||
|
||||
public class NameSuccessPrompt extends MessagePrompt {
|
||||
public class NameSuccessPrompt extends MessagePrompt
|
||||
{
|
||||
|
||||
private final GameModeAddon addon;
|
||||
|
||||
private BlueprintBundle bb;
|
||||
|
||||
private final Blueprint bp;
|
||||
|
||||
|
||||
/**
|
||||
* Handles the name processing
|
||||
*
|
||||
* @param addon - Game Mode addon
|
||||
* @param bb - Blueprint Bundle
|
||||
* @param bp - blueprint
|
||||
*/
|
||||
public NameSuccessPrompt(@NonNull GameModeAddon addon, @Nullable BlueprintBundle bb, @Nullable Blueprint bp) {
|
||||
public NameSuccessPrompt(@NonNull GameModeAddon addon, @Nullable BlueprintBundle bb, @Nullable Blueprint bp)
|
||||
{
|
||||
this.addon = addon;
|
||||
this.bb = bb;
|
||||
this.bp = bp;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NonNull String getPromptText(ConversationContext context) {
|
||||
public @NonNull String getPromptText(ConversationContext context)
|
||||
{
|
||||
String name = (String) context.getSessionData("name");
|
||||
String uniqueId = (String) context.getSessionData("uniqueId");
|
||||
User user = User.getInstance((Player)context.getForWhom());
|
||||
// Rename blueprint
|
||||
if (bp != null) {
|
||||
BentoBox.getInstance().getBlueprintsManager().renameBlueprint(addon, bp, name);
|
||||
new BlueprintManagementPanel(BentoBox.getInstance(), user, addon).openBB(bb);
|
||||
} else {
|
||||
// Blueprint Bundle
|
||||
if (bb == null) {
|
||||
// New Blueprint bundle
|
||||
bb = new BlueprintBundle();
|
||||
bb.setIcon(Material.RED_WOOL);
|
||||
} else {
|
||||
// Rename - remove old named file
|
||||
BentoBox.getInstance().getBlueprintsManager().deleteBlueprintBundle(addon, bb);
|
||||
}
|
||||
bb.setDisplayName(name);
|
||||
bb.setUniqueId(uniqueId);
|
||||
BentoBox.getInstance().getBlueprintsManager().addBlueprintBundle(addon, bb);
|
||||
BentoBox.getInstance().getBlueprintsManager().saveBlueprintBundle(addon, bb);
|
||||
|
||||
new BlueprintManagementPanel(BentoBox.getInstance(), user, addon).openPanel();
|
||||
// Set the name
|
||||
// if successfully
|
||||
User user = User.getInstance((Player) context.getForWhom());
|
||||
|
||||
// Rename blueprint
|
||||
if (this.bp != null)
|
||||
{
|
||||
this.addon.getPlugin().getBlueprintsManager().renameBlueprint(this.addon, this.bp, uniqueId, name);
|
||||
new BlueprintManagementPanel(this.addon.getPlugin(), user, this.addon).openBB(this.bb);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Blueprint Bundle
|
||||
if (this.bb == null)
|
||||
{
|
||||
// New Blueprint bundle
|
||||
this.bb = new BlueprintBundle();
|
||||
this.bb.setIcon(Material.RED_WOOL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Rename - remove old named file
|
||||
this.addon.getPlugin().getBlueprintsManager().deleteBlueprintBundle(this.addon, this.bb);
|
||||
}
|
||||
|
||||
this.bb.setDisplayName(name);
|
||||
this.bb.setUniqueId(uniqueId);
|
||||
this.addon.getPlugin().getBlueprintsManager().addBlueprintBundle(this.addon, this.bb);
|
||||
this.addon.getPlugin().getBlueprintsManager().saveBlueprintBundle(this.addon, this.bb);
|
||||
|
||||
new BlueprintManagementPanel(this.addon.getPlugin(), user, this.addon).openPanel();
|
||||
// Set the name
|
||||
}
|
||||
|
||||
return user.getTranslation("commands.admin.blueprint.management.description.success");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Prompt getNextPrompt(@NonNull ConversationContext context) {
|
||||
protected Prompt getNextPrompt(@NonNull ConversationContext context)
|
||||
{
|
||||
return Prompt.END_OF_CONVERSATION;
|
||||
}
|
||||
|
||||
}
|
@ -69,7 +69,7 @@ public class BlueprintBundle implements DataObject {
|
||||
*/
|
||||
@Override
|
||||
public String getUniqueId() {
|
||||
return uniqueId.toLowerCase(Locale.ENGLISH);
|
||||
return uniqueId;
|
||||
}
|
||||
/**
|
||||
* @param uniqueId the uniqueId to set
|
||||
|
@ -7,6 +7,7 @@ import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@ -86,24 +87,24 @@ public class BlueprintClipboardManager {
|
||||
|
||||
/**
|
||||
* Loads a blueprint
|
||||
* @param fileName - the filename without the suffix
|
||||
* @param fileName - the sanitized filename without the suffix
|
||||
* @return the blueprint
|
||||
* @throws IOException exception if there's an issue loading or unzipping
|
||||
*/
|
||||
public Blueprint loadBlueprint(String fileName) throws IOException {
|
||||
File zipFile = new File(blueprintFolder, BlueprintsManager.sanitizeFileName(fileName) + BlueprintsManager.BLUEPRINT_SUFFIX);
|
||||
File zipFile = new File(blueprintFolder, fileName + BlueprintsManager.BLUEPRINT_SUFFIX);
|
||||
if (!zipFile.exists()) {
|
||||
plugin.logError(LOAD_ERROR + zipFile.getName());
|
||||
throw new IOException(LOAD_ERROR + zipFile.getName());
|
||||
}
|
||||
unzip(zipFile.getCanonicalPath());
|
||||
File file = new File(blueprintFolder, BlueprintsManager.sanitizeFileName(fileName));
|
||||
File file = new File(blueprintFolder, fileName);
|
||||
if (!file.exists()) {
|
||||
plugin.logError(LOAD_ERROR + file.getName());
|
||||
throw new IOException(LOAD_ERROR + file.getName() + " temp file");
|
||||
}
|
||||
Blueprint bp;
|
||||
try (FileReader fr = new FileReader(file)) {
|
||||
try (FileReader fr = new FileReader(file, StandardCharsets.UTF_8)) {
|
||||
bp = gson.fromJson(fr, Blueprint.class);
|
||||
} catch (Exception e) {
|
||||
plugin.logError("Blueprint has JSON error: " + zipFile.getName());
|
||||
@ -114,7 +115,7 @@ public class BlueprintClipboardManager {
|
||||
if (bp.getBedrock() == null) {
|
||||
bp.setBedrock(new Vector(bp.getxSize() / 2, bp.getySize() / 2, bp.getzSize() / 2));
|
||||
bp.getBlocks().put(bp.getBedrock(), new BlueprintBlock(Material.BEDROCK.createBlockData().getAsString()));
|
||||
plugin.logWarning("Blueprint " + BlueprintsManager.sanitizeFileName(fileName) + BlueprintsManager.BLUEPRINT_SUFFIX + " had no bedrock block in it so one was added automatically in the center. You should check it.");
|
||||
plugin.logWarning("Blueprint " + fileName + BlueprintsManager.BLUEPRINT_SUFFIX + " had no bedrock block in it so one was added automatically in the center. You should check it.");
|
||||
}
|
||||
return bp;
|
||||
}
|
||||
@ -130,7 +131,7 @@ public class BlueprintClipboardManager {
|
||||
load(fileName);
|
||||
} catch (IOException e1) {
|
||||
user.sendMessage("commands.admin.blueprint.could-not-load");
|
||||
plugin.logError("Could not load blueprint file: " + BlueprintsManager.sanitizeFileName(fileName) + BlueprintsManager.BLUEPRINT_SUFFIX + " " + e1.getMessage());
|
||||
plugin.logError("Could not load blueprint file: " + fileName + BlueprintsManager.BLUEPRINT_SUFFIX + " " + e1.getMessage());
|
||||
return false;
|
||||
}
|
||||
user.sendMessage("general.success");
|
||||
@ -143,14 +144,20 @@ public class BlueprintClipboardManager {
|
||||
* @param newName - new name of this blueprint
|
||||
* @return - true if successful, false if error
|
||||
*/
|
||||
public boolean save(User user, String newName) {
|
||||
if (clipboard.getBlueprint() != null) {
|
||||
clipboard.getBlueprint().setName(newName);
|
||||
if (saveBlueprint(clipboard.getBlueprint())) {
|
||||
public boolean save(User user, String newName, String displayName)
|
||||
{
|
||||
if (this.clipboard.isFull())
|
||||
{
|
||||
this.clipboard.getBlueprint().setName(newName);
|
||||
this.clipboard.getBlueprint().setDisplayName(displayName);
|
||||
|
||||
if (this.saveBlueprint(this.clipboard.getBlueprint()))
|
||||
{
|
||||
user.sendMessage("general.success");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
user.sendMessage("commands.admin.blueprint.could-not-save", "[message]", "Could not save temp blueprint file.");
|
||||
return false;
|
||||
}
|
||||
@ -165,9 +172,9 @@ public class BlueprintClipboardManager {
|
||||
plugin.logError("Blueprint name was empty - could not save it");
|
||||
return false;
|
||||
}
|
||||
File file = new File(blueprintFolder, BlueprintsManager.sanitizeFileName(blueprint.getName()));
|
||||
File file = new File(blueprintFolder, blueprint.getName());
|
||||
String toStore = gson.toJson(blueprint, Blueprint.class);
|
||||
try (FileWriter fileWriter = new FileWriter(file)) {
|
||||
try (FileWriter fileWriter = new FileWriter(file, StandardCharsets.UTF_8)) {
|
||||
fileWriter.write(toStore);
|
||||
} catch (IOException e) {
|
||||
plugin.logError("Could not save temporary blueprint file: " + file.getName());
|
||||
|
@ -1,11 +1,9 @@
|
||||
package world.bentobox.bentobox.managers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@ -207,13 +205,24 @@ public class BlueprintsManager {
|
||||
bpf.mkdirs();
|
||||
}
|
||||
boolean loaded = false;
|
||||
File[] bundles = bpf.listFiles((dir, name) -> name.toLowerCase(Locale.ENGLISH).endsWith(BLUEPRINT_BUNDLE_SUFFIX));
|
||||
File[] bundles = bpf.listFiles((dir, name) -> name.endsWith(BLUEPRINT_BUNDLE_SUFFIX));
|
||||
|
||||
if (bundles == null || bundles.length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (File file : bundles) {
|
||||
try {
|
||||
BlueprintBundle bb = gson.fromJson(new FileReader(file), BlueprintBundle.class);
|
||||
|
||||
try (FileReader fileReader = new FileReader(file, StandardCharsets.UTF_8))
|
||||
{
|
||||
if (!file.getName().equals(Util.sanitizeInput(file.getName())))
|
||||
{
|
||||
// fail on all blueprints with incorrect names.
|
||||
throw new InputMismatchException(file.getName());
|
||||
}
|
||||
|
||||
BlueprintBundle bb = gson.fromJson(fileReader, BlueprintBundle.class);
|
||||
|
||||
if (bb != null) {
|
||||
// Make sure there is no existing bundle with the same uniqueId
|
||||
if (blueprintBundles.get(addon).stream().noneMatch(bundle -> bundle.getUniqueId().equals(bb.getUniqueId()))) {
|
||||
@ -290,13 +299,17 @@ public class BlueprintsManager {
|
||||
plugin.logError("There is no blueprint folder for addon " + addon.getDescription().getName());
|
||||
bpf.mkdirs();
|
||||
}
|
||||
File[] bps = bpf.listFiles((dir, name) -> name.toLowerCase(Locale.ENGLISH).endsWith(BLUEPRINT_SUFFIX));
|
||||
File[] bps = bpf.listFiles((dir, name) -> name.endsWith(BLUEPRINT_SUFFIX));
|
||||
|
||||
if (bps == null || bps.length == 0) {
|
||||
plugin.logError("No blueprints found for " + addon.getDescription().getName());
|
||||
return;
|
||||
}
|
||||
for (File file : bps) {
|
||||
String fileName = file.getName().substring(0, file.getName().length() - BLUEPRINT_SUFFIX.length());
|
||||
|
||||
// Input sanitization is required for weirdos that edit files manually.
|
||||
String fileName = Util.sanitizeInput(file.getName().substring(0, file.getName().length() - BLUEPRINT_SUFFIX.length()));
|
||||
|
||||
try {
|
||||
Blueprint bp = new BlueprintClipboardManager(plugin, bpf).loadBlueprint(fileName);
|
||||
bp.setName(fileName);
|
||||
@ -345,9 +358,9 @@ public class BlueprintsManager {
|
||||
if (!bpf.exists()) {
|
||||
bpf.mkdirs();
|
||||
}
|
||||
File fileName = new File(bpf, sanitizeFileName(bb.getUniqueId()) + BLUEPRINT_BUNDLE_SUFFIX);
|
||||
File fileName = new File(bpf, bb.getUniqueId() + BLUEPRINT_BUNDLE_SUFFIX);
|
||||
String toStore = gson.toJson(bb, BlueprintBundle.class);
|
||||
try (FileWriter fileWriter = new FileWriter(fileName)) {
|
||||
try (FileWriter fileWriter = new FileWriter(fileName, StandardCharsets.UTF_8)) {
|
||||
fileWriter.write(toStore);
|
||||
} catch (IOException e) {
|
||||
plugin.logError("Could not save blueprint bundle file: " + e.getMessage());
|
||||
@ -355,20 +368,6 @@ public class BlueprintsManager {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes a filename as much as possible retaining the original name
|
||||
* @param name - filename to sanitize
|
||||
* @return sanitized name
|
||||
*/
|
||||
public static String sanitizeFileName(String name) {
|
||||
return name
|
||||
.chars()
|
||||
.mapToObj(i -> (char) i)
|
||||
.map(c -> Character.isWhitespace(c) ? '_' : c)
|
||||
.filter(c -> Character.isLetterOrDigit(c) || c == '-' || c == '_')
|
||||
.map(String::valueOf)
|
||||
.collect(Collectors.joining());
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves all the blueprint bundles
|
||||
@ -396,26 +395,35 @@ public class BlueprintsManager {
|
||||
* @param name name of the Blueprint to delete
|
||||
* @since 1.9.0
|
||||
*/
|
||||
public void deleteBlueprint(GameModeAddon addon, String name) {
|
||||
List<Blueprint> addonBlueprints = blueprints.get(addon);
|
||||
public void deleteBlueprint(GameModeAddon addon, String name)
|
||||
{
|
||||
List<Blueprint> addonBlueprints = this.blueprints.get(addon);
|
||||
Iterator<Blueprint> it = addonBlueprints.iterator();
|
||||
while (it.hasNext()) {
|
||||
Blueprint b = it.next();
|
||||
if (b.getName().equalsIgnoreCase(name)) {
|
||||
it.remove();
|
||||
blueprints.put(addon, addonBlueprints);
|
||||
|
||||
File file = new File(getBlueprintsFolder(addon), b.getName() + BLUEPRINT_SUFFIX);
|
||||
while (it.hasNext())
|
||||
{
|
||||
Blueprint b = it.next();
|
||||
|
||||
if (b.getName().equalsIgnoreCase(name))
|
||||
{
|
||||
it.remove();
|
||||
|
||||
File file = new File(this.getBlueprintsFolder(addon), b.getName() + BLUEPRINT_SUFFIX);
|
||||
|
||||
// Delete the file
|
||||
try {
|
||||
try
|
||||
{
|
||||
Files.deleteIfExists(file.toPath());
|
||||
} catch (IOException e) {
|
||||
plugin.logError("Could not delete Blueprint " + e.getLocalizedMessage());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
this.plugin.logError("Could not delete Blueprint " + e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Paste the islands to world
|
||||
*
|
||||
@ -441,7 +449,7 @@ public class BlueprintsManager {
|
||||
plugin.logError("Tried to paste '" + name + "' but the bundle is not loaded!");
|
||||
return false;
|
||||
}
|
||||
BlueprintBundle bb = getBlueprintBundles(addon).get(name.toLowerCase(Locale.ENGLISH));
|
||||
BlueprintBundle bb = getBlueprintBundles(addon).get(name.toLowerCase());
|
||||
if (!blueprints.containsKey(addon) || blueprints.get(addon).isEmpty()) {
|
||||
plugin.logError("No blueprints loaded for bundle '" + name + "'!");
|
||||
return false;
|
||||
@ -514,7 +522,7 @@ public class BlueprintsManager {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
if (blueprintBundles.containsKey(addon) && getBlueprintBundles(addon).containsKey(name.toLowerCase(Locale.ENGLISH))) {
|
||||
if (blueprintBundles.containsKey(addon) && getBlueprintBundles(addon).containsKey(name)) {
|
||||
return name;
|
||||
}
|
||||
return null;
|
||||
@ -546,7 +554,7 @@ public class BlueprintsManager {
|
||||
// Permission
|
||||
String permission = addon.getPermissionPrefix() + "island.create." + name;
|
||||
// Get Blueprint bundle
|
||||
BlueprintBundle bb = getBlueprintBundles((GameModeAddon) addon).get(name.toLowerCase(Locale.ENGLISH));
|
||||
BlueprintBundle bb = getBlueprintBundles((GameModeAddon) addon).get(name.toLowerCase());
|
||||
if (bb == null || (bb.isRequirePermission() && !name.equals(DEFAULT_BUNDLE_NAME) && !user.hasPermission(permission))) {
|
||||
user.sendMessage("general.errors.no-permission", TextVariables.PERMISSION, permission);
|
||||
return false;
|
||||
@ -565,7 +573,7 @@ public class BlueprintsManager {
|
||||
blueprintBundles.get(addon).removeIf(k -> k.getUniqueId().equals(bb.getUniqueId()));
|
||||
}
|
||||
File bpf = getBlueprintsFolder(addon);
|
||||
File fileName = new File(bpf, sanitizeFileName(bb.getUniqueId()) + BLUEPRINT_BUNDLE_SUFFIX);
|
||||
File fileName = new File(bpf, bb.getUniqueId() + BLUEPRINT_BUNDLE_SUFFIX);
|
||||
try {
|
||||
Files.deleteIfExists(fileName.toPath());
|
||||
} catch (IOException e) {
|
||||
@ -579,25 +587,39 @@ public class BlueprintsManager {
|
||||
* @param addon - Game Mode Addon
|
||||
* @param bp - blueprint
|
||||
* @param name - new name
|
||||
* @param displayName - display name for blueprint
|
||||
*/
|
||||
public void renameBlueprint(GameModeAddon addon, Blueprint bp, String name) {
|
||||
if (bp.getName().equalsIgnoreCase(name)) {
|
||||
public void renameBlueprint(GameModeAddon addon, Blueprint bp, String name, String displayName)
|
||||
{
|
||||
if (bp.getName().equalsIgnoreCase(name))
|
||||
{
|
||||
// If the name is the same, do not do anything
|
||||
return;
|
||||
}
|
||||
File bpf = getBlueprintsFolder(addon);
|
||||
// Get the filename
|
||||
File fileName = new File(bpf, sanitizeFileName(bp.getName()) + BLUEPRINT_SUFFIX);
|
||||
// Delete the old file
|
||||
try {
|
||||
Files.deleteIfExists(fileName.toPath());
|
||||
} catch (IOException e) {
|
||||
plugin.logError("Could not delete old Blueprint " + e.getLocalizedMessage());
|
||||
}
|
||||
// Set new name
|
||||
bp.setName(name.toLowerCase(Locale.ENGLISH));
|
||||
// Save it
|
||||
saveBlueprint(addon, bp);
|
||||
}
|
||||
|
||||
File bpf = this.getBlueprintsFolder(addon);
|
||||
// Get the filename
|
||||
File fileName = new File(bpf, bp.getName() + BLUEPRINT_SUFFIX);
|
||||
// Delete the old file
|
||||
|
||||
try
|
||||
{
|
||||
Files.deleteIfExists(fileName.toPath());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
this.plugin.logError("Could not delete old Blueprint " + e.getLocalizedMessage());
|
||||
}
|
||||
|
||||
// Remove blueprint from the blueprints.
|
||||
this.blueprints.get(addon).remove(bp);
|
||||
|
||||
// Set new name
|
||||
bp.setName(name);
|
||||
bp.setDisplayName(displayName);
|
||||
|
||||
// Save it
|
||||
this.saveBlueprint(addon, bp);
|
||||
this.addBlueprint(addon, bp);
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,7 @@ package world.bentobox.bentobox.util;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
@ -761,4 +757,19 @@ public class Util {
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method removes all special characters that are not allowed in filenames (windows).
|
||||
* It also includes any white-spaces, as for some reason, I do like it more without them.
|
||||
* Also, all cases are lower cased for easier blueprint mapping.
|
||||
* @param input Input that need to be sanitized.
|
||||
* @return A sanitized input without illegal characters in names.
|
||||
*/
|
||||
public static String sanitizeInput(String input)
|
||||
{
|
||||
return ChatColor.stripColor(
|
||||
Util.translateColorCodes(input.replaceAll("[\\\\/:*?\"<>|\s]", "_"))).
|
||||
toLowerCase();
|
||||
}
|
||||
}
|
||||
|
@ -332,7 +332,7 @@ commands:
|
||||
rename:
|
||||
parameters: "<blueprint name> <new name>"
|
||||
description: "rename a blueprint"
|
||||
success: "&a Blueprint &b [old] &a has been successfully renamed to &b [name]&a."
|
||||
success: "&a Blueprint &b [old] &a has been successfully renamed to &b [display]&a. Filename now is &b [name]&a."
|
||||
pick-different-name: "&c Please specify a name that is different from the blueprint's current name."
|
||||
management:
|
||||
back: "Back"
|
||||
@ -366,9 +366,9 @@ commands:
|
||||
name:
|
||||
quit: "quit"
|
||||
prompt: "Enter a name, or 'quit' to quit"
|
||||
too-long: "&c Too long"
|
||||
too-long: "&c Too long name. Only 32 chars are allowed."
|
||||
pick-a-unique-name: "Please pick a more unique name"
|
||||
invalid-char-in-unique-name: "Unique name cannot contain, start, or end with special characters, neither contain number! "
|
||||
stripped-char-in-unique-name: "&c Some chars were removed because they are not allowed. &a New ID will be &b [name]&a."
|
||||
success: "Success!"
|
||||
conversation-prefix: ">"
|
||||
description:
|
||||
|
@ -39,6 +39,8 @@ import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.Blueprint;
|
||||
import world.bentobox.bentobox.blueprints.BlueprintClipboard;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
@ -345,7 +347,7 @@ public class BlueprintClipboardManagerTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#save(world.bentobox.bentobox.api.user.User, java.lang.String)}.
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#save(world.bentobox.bentobox.api.user.User, java.lang.String, java.lang.String)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
@ -361,14 +363,14 @@ public class BlueprintClipboardManagerTest {
|
||||
BlueprintClipboardManager bcm = new BlueprintClipboardManager(plugin, blueprintFolder);
|
||||
bcm.load(BLUEPRINT);
|
||||
User user = mock(User.class);
|
||||
assertTrue(bcm.save(user, "test1234"));
|
||||
assertTrue(bcm.save(user, "test1234", ""));
|
||||
File bp = new File(blueprintFolder, "test1234.blu");
|
||||
assertTrue(bp.exists());
|
||||
verify(user).sendMessage("general.success");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#save(world.bentobox.bentobox.api.user.User, java.lang.String)}.
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#save(world.bentobox.bentobox.api.user.User, java.lang.String, java.lang.String)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
@ -384,14 +386,14 @@ public class BlueprintClipboardManagerTest {
|
||||
BlueprintClipboardManager bcm = new BlueprintClipboardManager(plugin, blueprintFolder);
|
||||
bcm.load(BLUEPRINT);
|
||||
User user = mock(User.class);
|
||||
assertTrue(bcm.save(user, "test.1234/../../film"));
|
||||
File bp = new File(blueprintFolder, "test1234film.blu");
|
||||
assertTrue(bcm.save(user, Util.sanitizeInput("test.1234/../../film"), ""));
|
||||
File bp = new File(blueprintFolder, "test.1234_.._.._film.blu");
|
||||
assertTrue(bp.exists());
|
||||
verify(user).sendMessage("general.success");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#save(world.bentobox.bentobox.api.user.User, java.lang.String)}.
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#save(world.bentobox.bentobox.api.user.User, java.lang.String, java.lang.String)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
@ -407,14 +409,14 @@ public class BlueprintClipboardManagerTest {
|
||||
BlueprintClipboardManager bcm = new BlueprintClipboardManager(plugin, blueprintFolder);
|
||||
bcm.load(BLUEPRINT);
|
||||
User user = mock(User.class);
|
||||
assertTrue(bcm.save(user, "日本語の言葉"));
|
||||
assertTrue(bcm.save(user, "日本語の言葉", ""));
|
||||
File bp = new File(blueprintFolder, "日本語の言葉.blu");
|
||||
assertTrue(bp.exists());
|
||||
verify(user).sendMessage("general.success");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#save(world.bentobox.bentobox.api.user.User, java.lang.String)}.
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#save(world.bentobox.bentobox.api.user.User, java.lang.String, java.lang.String)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
@ -430,8 +432,9 @@ public class BlueprintClipboardManagerTest {
|
||||
BlueprintClipboardManager bcm = new BlueprintClipboardManager(plugin, blueprintFolder);
|
||||
bcm.load(BLUEPRINT);
|
||||
User user = mock(User.class);
|
||||
assertTrue(bcm.save(user, "日本語の言葉/../../../config"));
|
||||
File bp = new File(blueprintFolder, "日本語の言葉config.blu");
|
||||
|
||||
assertTrue(bcm.save(user, Util.sanitizeInput("日本語の言葉/../../../config"), ""));
|
||||
File bp = new File(blueprintFolder, "日本語の言葉_.._.._.._config.blu");
|
||||
assertTrue(bp.exists());
|
||||
verify(user).sendMessage("general.success");
|
||||
}
|
||||
|
@ -526,8 +526,6 @@ public class BlueprintsManagerTest {
|
||||
BlueprintsManager bpm = new BlueprintsManager(plugin);
|
||||
bpm.addBlueprintBundle(addon, bb);
|
||||
assertEquals("bundle", bpm.validate(addon, "bundle"));
|
||||
// Mixed case
|
||||
assertEquals("buNdle", bpm.validate(addon, "buNdle"));
|
||||
// Not there
|
||||
assertNull(bpm.validate(addon, "buNdle2"));
|
||||
}
|
||||
@ -651,18 +649,19 @@ public class BlueprintsManagerTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintsManager#renameBlueprint(world.bentobox.bentobox.api.addons.GameModeAddon, world.bentobox.bentobox.blueprints.Blueprint, java.lang.String)}.
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintsManager#renameBlueprint(world.bentobox.bentobox.api.addons.GameModeAddon, world.bentobox.bentobox.blueprints.Blueprint, java.lang.String, java.lang.String)}.
|
||||
*/
|
||||
@Test
|
||||
public void testRenameBlueprint() {
|
||||
// Save it
|
||||
BlueprintsManager bpm = new BlueprintsManager(plugin);
|
||||
bpm.saveBlueprint(addon, defaultBp);
|
||||
bpm.addBlueprint(addon, defaultBp);
|
||||
File blueprints = new File(dataFolder, BlueprintsManager.FOLDER_NAME);
|
||||
File d = new File(blueprints, "bedrock.blu");
|
||||
assertTrue(d.exists());
|
||||
// Rename it
|
||||
bpm.renameBlueprint(addon, defaultBp, "bedrock2");
|
||||
bpm.renameBlueprint(addon, defaultBp, "bedrock2", "");
|
||||
assertFalse(d.exists());
|
||||
d = new File(blueprints, "bedrock2.blu");
|
||||
assertTrue(d.exists());
|
||||
|
Loading…
Reference in New Issue
Block a user