mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-11-27 13:15:28 +01:00
Implemeted Blueprint bundles and blueprints (#672)
* A prototype for Blueprint bundles and blueprints This stores blueprints inside bundles. Each bundle can have up to 3 blueprints defines by the World.Environment. This is not a finished manager. It just handles all the saving and loading side of things. I thought this would help you so you can then concentrate on the UI. * WIP: Copy blocks to Blueprint done. * WIP Pasting done. * WIP: Added BlueprintsManager to ultimately replace SchemsManager. * Moved blueprint suffix and changed to .blu * Fixed unit test. * Now tested and working. Integrated with new island and resetting island. If there are no blueprint bundles or blueprints then a default bedrock set will be made and put in the game mode addon's blueprints folder. Still to do: enable schems to be loaded and pasted for legacy support. Add blueprints and a bundle to GameModeAddons like BSkyBlock. * Renamed most of the classes * Cleaned up clipboard and paster. * Further cleanup on blueprint clipboard and paster. * Merged blueprint classes into one package. * Put Blueprint data objects in their own package. Isolated schems classes for later removal. * Renamed admin command classes and changed locale files. * More clean up to remove schems * Schem to blueprints converter done. Converts schems to blueprint bundles and sets up a default set. Tested the happy-path. Need to do more testing on edge cases. * Added basic UI for development. Fixed bug with schem conversion. * Adds permissions into the blueprints. Fixes tests, cleans up some naming * Added IslandCreationPanel and created BlueprintManagementPanel * Fixed JSONDatabaseHandler's constructor being public * Made the Blueprints button in ManagementPanel open the Blueprint management panel * Fixed tests and ignored one (NPE)
This commit is contained in:
parent
d19caa82ca
commit
700043fe40
@ -1,5 +1,7 @@
|
||||
package world.bentobox.bentobox;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
@ -7,6 +9,7 @@ import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import world.bentobox.bentobox.api.configuration.Config;
|
||||
import world.bentobox.bentobox.api.events.BentoBoxReadyEvent;
|
||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
@ -37,13 +40,10 @@ import world.bentobox.bentobox.managers.LocalesManager;
|
||||
import world.bentobox.bentobox.managers.PlaceholdersManager;
|
||||
import world.bentobox.bentobox.managers.PlayersManager;
|
||||
import world.bentobox.bentobox.managers.RanksManager;
|
||||
import world.bentobox.bentobox.managers.SchemsManager;
|
||||
import world.bentobox.bentobox.managers.WebManager;
|
||||
import world.bentobox.bentobox.util.heads.HeadGetter;
|
||||
import world.bentobox.bentobox.versions.ServerCompatibility;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Main BentoBox class
|
||||
* @author tastybento, Poslovitch
|
||||
@ -62,7 +62,6 @@ public class BentoBox extends JavaPlugin {
|
||||
private FlagsManager flagsManager;
|
||||
private IslandWorldManager islandWorldManager;
|
||||
private RanksManager ranksManager;
|
||||
private SchemsManager schemsManager;
|
||||
private BlueprintsManager blueprintsManager;
|
||||
private HooksManager hooksManager;
|
||||
private PlaceholdersManager placeholdersManager;
|
||||
@ -135,8 +134,8 @@ public class BentoBox extends JavaPlugin {
|
||||
|
||||
// Start Island Worlds Manager
|
||||
islandWorldManager = new IslandWorldManager(this);
|
||||
// Load schems manager
|
||||
schemsManager = new SchemsManager(this);
|
||||
|
||||
// Load blueprints manager
|
||||
blueprintsManager = new BlueprintsManager(this);
|
||||
|
||||
// Locales manager must be loaded before addons
|
||||
@ -385,13 +384,6 @@ public class BentoBox extends JavaPlugin {
|
||||
getLogger().warning(() -> warning);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the schemsManager
|
||||
*/
|
||||
public SchemsManager getSchemsManager() {
|
||||
return schemsManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the instance of the {@link BlueprintsManager}.
|
||||
* @return the {@link BlueprintsManager}.
|
||||
|
@ -143,7 +143,7 @@ public class Settings implements ConfigObject {
|
||||
@ConfigEntry(path = "island.name.max-length")
|
||||
private int nameMaxLength = 20;
|
||||
|
||||
@ConfigComment("Number of blocks to paste per tick when pasting a schem")
|
||||
@ConfigComment("Number of blocks to paste per tick when pasting blueprints")
|
||||
@ConfigComment("Smaller values will help reduce noticeable lag but will make pasting take longer")
|
||||
@ConfigEntry(path = "island.paste-speed")
|
||||
private int pasteSpeed = 1000;
|
||||
|
@ -14,7 +14,7 @@ import world.bentobox.bentobox.util.Util;
|
||||
|
||||
/**
|
||||
* Defines the addon as a game mode.
|
||||
* A game mode creates worlds, registers world settings and has schems in a jar folder.
|
||||
* A game mode creates worlds, registers world settings and has blueprints in a jar folder.
|
||||
* @author tastybento, Poslovitch
|
||||
*/
|
||||
public abstract class GameModeAddon extends Addon {
|
||||
|
@ -1,80 +0,0 @@
|
||||
package world.bentobox.bentobox.api.blueprints;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
/**
|
||||
* @since 1.5.0
|
||||
* @author Poslovitch
|
||||
*/
|
||||
public class Blueprint {
|
||||
|
||||
public static final @NonNull String FILE_EXTENSION = "blueprint";
|
||||
|
||||
private @NonNull String name;
|
||||
private String displayName;
|
||||
private @NonNull Material icon = Material.PAPER;
|
||||
private List<String> description; //TODO
|
||||
private World.Environment environment;
|
||||
|
||||
public Blueprint(@NonNull String name, @NonNull ZipFile zip) throws IOException {
|
||||
this.name = name;
|
||||
try (JsonReader reader = new Gson().newJsonReader(new InputStreamReader(zip.getInputStream(zip.getEntry("properties.json"))))) {
|
||||
readProperties(reader);
|
||||
}
|
||||
|
||||
//System.out.println(new Gson().toJson(this));
|
||||
}
|
||||
|
||||
private void readProperties(@NonNull JsonReader reader) throws IOException {
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
String field = reader.nextName();
|
||||
switch (field) {
|
||||
case "displayName":
|
||||
displayName = reader.nextString();
|
||||
break;
|
||||
case "icon":
|
||||
icon = Material.valueOf(reader.nextString());
|
||||
break;
|
||||
case "environment":
|
||||
environment = World.Environment.valueOf(reader.nextString());
|
||||
break;
|
||||
default:
|
||||
reader.skipValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
reader.endObject();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Material getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public List<String> getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public World.Environment getEnvironment() {
|
||||
return environment;
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package world.bentobox.bentobox.api.blueprints;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a bundle of three {@link Blueprint}s.
|
||||
* This is what the player will choose when creating his island.
|
||||
* @since 1.5.0
|
||||
* @author Poslovitch
|
||||
*/
|
||||
public class BlueprintBundle {
|
||||
|
||||
private Material icon;
|
||||
private String displayName;
|
||||
private List<String> description;
|
||||
private Blueprint overworldBlueprint;
|
||||
private Blueprint netherBlueprint;
|
||||
private Blueprint endBlueprint;
|
||||
}
|
@ -1,4 +1,13 @@
|
||||
package world.bentobox.bentobox.api.commands.admin.schem;
|
||||
package world.bentobox.bentobox.api.commands.admin.blueprints;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Particle;
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
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.BlueprintsManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
@ -6,47 +15,37 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Particle;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.commands.ConfirmableCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.Clipboard;
|
||||
import world.bentobox.bentobox.managers.SchemsManager;
|
||||
|
||||
public class AdminSchemCommand extends ConfirmableCommand {
|
||||
public class AdminBlueprintCommand extends ConfirmableCommand {
|
||||
// Clipboards
|
||||
private Map<UUID, Clipboard> clipboards;
|
||||
private Map<UUID, BlueprintClipboard> clipboards;
|
||||
|
||||
// Map containing selection cuboid display tasks
|
||||
private Map<User, Integer> displayClipboards;
|
||||
private static final Particle PARTICLE = Particle.REDSTONE;
|
||||
private static final Particle.DustOptions PARTICLE_DUST_OPTIONS = new Particle.DustOptions(Color.RED, 1.0F);
|
||||
|
||||
public AdminSchemCommand(CompositeCommand parent) {
|
||||
super(parent, "schem");
|
||||
public AdminBlueprintCommand(CompositeCommand parent) {
|
||||
super(parent, "bp", "blueprint");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
setPermission("admin.schem");
|
||||
setParametersHelp("commands.admin.schem.parameters");
|
||||
setDescription("commands.admin.schem.description");
|
||||
setPermission("admin.blueprint");
|
||||
setParametersHelp("commands.admin.blueprint.parameters");
|
||||
setDescription("commands.admin.blueprint.description");
|
||||
setOnlyPlayer(true);
|
||||
|
||||
clipboards = new HashMap<>();
|
||||
displayClipboards = new HashMap<>();
|
||||
|
||||
new AdminSchemLoadCommand(this);
|
||||
new AdminSchemPasteCommand(this);
|
||||
new AdminSchemOriginCommand(this);
|
||||
new AdminSchemCopyCommand(this);
|
||||
new AdminSchemSaveCommand(this);
|
||||
new AdminSchemPos1Command(this);
|
||||
new AdminSchemPos2Command(this);
|
||||
new AdminSchemListCommand(this);
|
||||
new AdminBlueprintLoadCommand(this);
|
||||
new AdminBlueprintPasteCommand(this);
|
||||
new AdminBlueprintOriginCommand(this);
|
||||
new AdminBlueprintCopyCommand(this);
|
||||
new AdminBlueprintSaveCommand(this);
|
||||
new AdminBlueprintPos1Command(this);
|
||||
new AdminBlueprintPos2Command(this);
|
||||
new AdminBlueprintListCommand(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -55,7 +54,7 @@ public class AdminSchemCommand extends ConfirmableCommand {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected Map<UUID, Clipboard> getClipboards() {
|
||||
protected Map<UUID, BlueprintClipboard> getClipboards() {
|
||||
return clipboards;
|
||||
}
|
||||
|
||||
@ -66,7 +65,7 @@ public class AdminSchemCommand extends ConfirmableCommand {
|
||||
}
|
||||
|
||||
if (clipboards.containsKey(user.getUniqueId())) {
|
||||
Clipboard clipboard = clipboards.get(user.getUniqueId());
|
||||
BlueprintClipboard clipboard = clipboards.get(user.getUniqueId());
|
||||
if (clipboard.getPos1() != null && clipboard.getPos2() != null) {
|
||||
paintAxis(user, clipboard);
|
||||
}
|
||||
@ -75,7 +74,7 @@ public class AdminSchemCommand extends ConfirmableCommand {
|
||||
}, 20, 20));
|
||||
}
|
||||
|
||||
private void paintAxis(User user, Clipboard clipboard) {
|
||||
private void paintAxis(User user, BlueprintClipboard clipboard) {
|
||||
int minX = Math.min(clipboard.getPos1().getBlockX(), clipboard.getPos2().getBlockX());
|
||||
int minY = Math.min(clipboard.getPos1().getBlockY(), clipboard.getPos2().getBlockY());
|
||||
int minZ = Math.min(clipboard.getPos1().getBlockZ(), clipboard.getPos2().getBlockZ());
|
||||
@ -121,7 +120,7 @@ public class AdminSchemCommand extends ConfirmableCommand {
|
||||
}
|
||||
}
|
||||
|
||||
protected File getSchemsFolder() {
|
||||
return new File(getIWM().getDataFolder(getWorld()), SchemsManager.FOLDER_NAME);
|
||||
protected File getBlueprintsFolder() {
|
||||
return new File(getIWM().getDataFolder(getWorld()), BlueprintsManager.FOLDER_NAME);
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package world.bentobox.bentobox.api.commands.admin.blueprints;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.BlueprintClipboard;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AdminBlueprintCopyCommand extends CompositeCommand {
|
||||
|
||||
public AdminBlueprintCopyCommand(AdminBlueprintCommand parent) {
|
||||
super(parent, "copy");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
setParametersHelp("commands.admin.blueprint.copy.parameters");
|
||||
setDescription("commands.admin.blueprint.copy.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
if (args.size() > 1) {
|
||||
showHelp(this, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
AdminBlueprintCommand parent = (AdminBlueprintCommand) getParent();
|
||||
|
||||
BlueprintClipboard clipboard = parent.getClipboards().computeIfAbsent(user.getUniqueId(), v -> new BlueprintClipboard());
|
||||
boolean copyAir = (args.size() == 1 && args.get(0).equalsIgnoreCase("air"));
|
||||
return clipboard.copy(user, copyAir);
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package world.bentobox.bentobox.api.commands.admin.blueprints;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.managers.BlueprintsManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class AdminBlueprintListCommand extends CompositeCommand {
|
||||
|
||||
public AdminBlueprintListCommand(AdminBlueprintCommand parent) {
|
||||
super(parent, "list");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
setDescription("commands.admin.blueprint.list.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExecute(User user, String label, List<String> args) {
|
||||
if (!args.isEmpty()) {
|
||||
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()) {
|
||||
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()) {
|
||||
user.sendMessage("commands.admin.blueprint.list.no-blueprints");
|
||||
return false;
|
||||
}
|
||||
user.sendMessage("commands.admin.blueprint.list.available-blueprints");
|
||||
blueprintList.forEach(user::sendRawMessage);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,24 +1,24 @@
|
||||
package world.bentobox.bentobox.api.commands.admin.schem;
|
||||
package world.bentobox.bentobox.api.commands.admin.blueprints;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.managers.BlueprintClipboardManager;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.managers.ClipboardManager;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
public class AdminBlueprintLoadCommand extends CompositeCommand {
|
||||
|
||||
public class AdminSchemLoadCommand extends CompositeCommand {
|
||||
|
||||
public AdminSchemLoadCommand(AdminSchemCommand parent) {
|
||||
public AdminBlueprintLoadCommand(AdminBlueprintCommand parent) {
|
||||
super(parent, "load");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
setParametersHelp("commands.admin.schem.load.parameters");
|
||||
setDescription("commands.admin.schem.load.description");
|
||||
setParametersHelp("commands.admin.blueprint.load.parameters");
|
||||
setDescription("commands.admin.blueprint.load.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -28,9 +28,9 @@ public class AdminSchemLoadCommand extends CompositeCommand {
|
||||
return false;
|
||||
}
|
||||
|
||||
AdminSchemCommand parent = (AdminSchemCommand) getParent();
|
||||
AdminBlueprintCommand parent = (AdminBlueprintCommand) getParent();
|
||||
|
||||
ClipboardManager bp = new ClipboardManager(getPlugin(), parent.getSchemsFolder());
|
||||
BlueprintClipboardManager bp = new BlueprintClipboardManager(getPlugin(), parent.getBlueprintsFolder());
|
||||
if (bp.load(user, args.get(0))) {
|
||||
parent.getClipboards().put(user.getUniqueId(), bp.getClipboard());
|
||||
return true;
|
@ -1,34 +1,33 @@
|
||||
package world.bentobox.bentobox.api.commands.admin.schem;
|
||||
|
||||
import java.util.List;
|
||||
package world.bentobox.bentobox.api.commands.admin.blueprints;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.Clipboard;
|
||||
import world.bentobox.bentobox.blueprints.BlueprintClipboard;
|
||||
|
||||
public class AdminSchemOriginCommand extends CompositeCommand {
|
||||
import java.util.List;
|
||||
|
||||
public AdminSchemOriginCommand(AdminSchemCommand parent) {
|
||||
public class AdminBlueprintOriginCommand extends CompositeCommand {
|
||||
|
||||
public AdminBlueprintOriginCommand(AdminBlueprintCommand parent) {
|
||||
super(parent, "origin");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
setParametersHelp("commands.admin.schem.origin.parameters");
|
||||
setDescription("commands.admin.schem.origin.description");
|
||||
setParametersHelp("commands.admin.blueprint.origin.parameters");
|
||||
setDescription("commands.admin.blueprint.origin.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
AdminSchemCommand parent = (AdminSchemCommand) getParent();
|
||||
AdminBlueprintCommand parent = (AdminBlueprintCommand) getParent();
|
||||
|
||||
Clipboard clipboard = parent.getClipboards().computeIfAbsent(user.getUniqueId(), v -> new Clipboard());
|
||||
BlueprintClipboard clipboard = parent.getClipboards().computeIfAbsent(user.getUniqueId(), v -> new BlueprintClipboard());
|
||||
if (clipboard.getPos1() == null || clipboard.getPos2() == null) {
|
||||
user.sendMessage("commands.admin.schem.need-pos1-pos2");
|
||||
user.sendMessage("commands.admin.blueprint.need-pos1-pos2");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -44,7 +43,7 @@ public class AdminSchemOriginCommand extends CompositeCommand {
|
||||
return true;
|
||||
}
|
||||
|
||||
user.sendMessage("commands.admin.schem.look-at-a-block");
|
||||
user.sendMessage("commands.admin.blueprint.look-at-a-block");
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package world.bentobox.bentobox.api.commands.admin.blueprints;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.BlueprintClipboard;
|
||||
import world.bentobox.bentobox.blueprints.BlueprintPaster;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AdminBlueprintPasteCommand extends CompositeCommand {
|
||||
|
||||
public AdminBlueprintPasteCommand(AdminBlueprintCommand parent) {
|
||||
super(parent, "paste");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
setParametersHelp("commands.admin.blueprint.paste.parameters");
|
||||
setDescription("commands.admin.blueprint.paste.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
AdminBlueprintCommand parent = (AdminBlueprintCommand) getParent();
|
||||
BlueprintClipboard clipboard = parent.getClipboards().computeIfAbsent(user.getUniqueId(), v -> new BlueprintClipboard());
|
||||
if (clipboard.isFull()) {
|
||||
new BlueprintPaster(getPlugin(), clipboard, user.getLocation(), () -> user.sendMessage("general.success"));
|
||||
user.sendMessage("commands.admin.blueprint.paste.pasting");
|
||||
return true;
|
||||
}
|
||||
|
||||
user.sendMessage("commands.admin.blueprint.copy-first");
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package world.bentobox.bentobox.api.commands.admin.blueprints;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.BlueprintClipboard;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AdminBlueprintPos1Command extends CompositeCommand {
|
||||
|
||||
public AdminBlueprintPos1Command(AdminBlueprintCommand parent) {
|
||||
super(parent, "pos1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
setParametersHelp("commands.admin.blueprint.pos1.parameters");
|
||||
setDescription("commands.admin.blueprint.pos1.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
AdminBlueprintCommand parent = (AdminBlueprintCommand) getParent();
|
||||
BlueprintClipboard clipboard = parent.getClipboards().computeIfAbsent(user.getUniqueId(), v -> new BlueprintClipboard());
|
||||
|
||||
if (user.getLocation().equals(clipboard.getPos2())) {
|
||||
user.sendMessage("commands.admin.blueprint.set-different-pos");
|
||||
return false;
|
||||
}
|
||||
clipboard.setPos1(user.getLocation());
|
||||
user.sendMessage("commands.admin.blueprint.set-pos1", "[vector]", Util.xyz(clipboard.getPos1().toVector()));
|
||||
parent.getClipboards().put(user.getUniqueId(), clipboard);
|
||||
parent.showClipboard(user);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package world.bentobox.bentobox.api.commands.admin.blueprints;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.BlueprintClipboard;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AdminBlueprintPos2Command extends CompositeCommand {
|
||||
|
||||
public AdminBlueprintPos2Command(AdminBlueprintCommand parent) {
|
||||
super(parent, "pos2");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
setParametersHelp("commands.admin.blueprint.pos2.parameters");
|
||||
setDescription("commands.admin.blueprint.pos2.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
AdminBlueprintCommand parent = (AdminBlueprintCommand) getParent();
|
||||
BlueprintClipboard clipboard = parent.getClipboards().computeIfAbsent(user.getUniqueId(), v -> new BlueprintClipboard());
|
||||
|
||||
if (user.getLocation().equals(clipboard.getPos1())) {
|
||||
user.sendMessage("commands.admin.blueprint.set-different-pos");
|
||||
return false;
|
||||
}
|
||||
clipboard.setPos2(user.getLocation());
|
||||
user.sendMessage("commands.admin.blueprint.set-pos2", "[vector]", Util.xyz((clipboard.getPos2()).toVector()));
|
||||
parent.getClipboards().put(user.getUniqueId(), clipboard);
|
||||
parent.showClipboard(user);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package world.bentobox.bentobox.api.commands.admin.blueprints;
|
||||
|
||||
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 java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class AdminBlueprintSaveCommand extends ConfirmableCommand {
|
||||
|
||||
public AdminBlueprintSaveCommand(AdminBlueprintCommand parent) {
|
||||
super(parent, "save");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
|
||||
AdminBlueprintCommand parent = (AdminBlueprintCommand) getParent();
|
||||
BlueprintClipboard clipboard = parent.getClipboards().computeIfAbsent(user.getUniqueId(), v -> new BlueprintClipboard());
|
||||
|
||||
if (clipboard.isFull()) {
|
||||
// Check if file exists
|
||||
File newFile = new File(parent.getBlueprintsFolder(), args.get(0) + BlueprintsManager.BLUEPRINT_SUFFIX);
|
||||
if (newFile.exists()) {
|
||||
this.askConfirmation(user, user.getTranslation("commands.admin.blueprint.file-exists"), () -> {
|
||||
parent.hideClipboard(user);
|
||||
new BlueprintClipboardManager(getPlugin(), parent.getBlueprintsFolder(), clipboard).save(user, args.get(0));
|
||||
});
|
||||
return false;
|
||||
} else {
|
||||
parent.hideClipboard(user);
|
||||
return new BlueprintClipboardManager(getPlugin(), parent.getBlueprintsFolder(), clipboard).save(user, args.get(0));
|
||||
}
|
||||
} else {
|
||||
user.sendMessage("commands.admin.blueprint.copy-first");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package world.bentobox.bentobox.api.commands.admin.schem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.Clipboard;
|
||||
|
||||
public class AdminSchemCopyCommand extends CompositeCommand {
|
||||
|
||||
public AdminSchemCopyCommand(AdminSchemCommand parent) {
|
||||
super(parent, "copy");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
setParametersHelp("commands.admin.schem.copy.parameters");
|
||||
setDescription("commands.admin.schem.copy.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
if (args.size() > 1) {
|
||||
showHelp(this, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
AdminSchemCommand parent = (AdminSchemCommand) getParent();
|
||||
|
||||
Clipboard clipboard = parent.getClipboards().computeIfAbsent(user.getUniqueId(), v -> new Clipboard());
|
||||
boolean copyAir = (args.size() == 1 && args.get(0).equalsIgnoreCase("air"));
|
||||
return clipboard.copy(user, copyAir);
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package world.bentobox.bentobox.api.commands.admin.schem;
|
||||
|
||||
import java.io.File;
|
||||
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;
|
||||
|
||||
public class AdminSchemListCommand extends CompositeCommand {
|
||||
|
||||
public AdminSchemListCommand(AdminSchemCommand parent) {
|
||||
super(parent, "list");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
setDescription("commands.admin.schem.list.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExecute(User user, String label, List<String> args) {
|
||||
if (!args.isEmpty()) {
|
||||
showHelp(this, user);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
File schems = new File(getAddon().getDataFolder(), "schems");
|
||||
if (!schems.exists()) {
|
||||
user.sendMessage("commands.admin.schem.list.no-schems");
|
||||
return false;
|
||||
}
|
||||
FilenameFilter schemFilter = (File dir, String name) -> name.toLowerCase(java.util.Locale.ENGLISH).endsWith(".schem");
|
||||
List<String> schemList = Arrays.stream(Objects.requireNonNull(schems.list(schemFilter))).map(name -> name.substring(0, name.length() - 6)).collect(Collectors.toList());
|
||||
if (schemList.isEmpty()) {
|
||||
user.sendMessage("commands.admin.schem.list.no-schems");
|
||||
return false;
|
||||
}
|
||||
user.sendMessage("commands.admin.schem.list.available-schems");
|
||||
schemList.forEach(user::sendRawMessage);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package world.bentobox.bentobox.api.commands.admin.schem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.Clipboard;
|
||||
import world.bentobox.bentobox.blueprints.Paster;
|
||||
|
||||
public class AdminSchemPasteCommand extends CompositeCommand {
|
||||
|
||||
public AdminSchemPasteCommand(AdminSchemCommand parent) {
|
||||
super(parent, "paste");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
setParametersHelp("commands.admin.schem.paste.parameters");
|
||||
setDescription("commands.admin.schem.paste.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
AdminSchemCommand parent = (AdminSchemCommand) getParent();
|
||||
Clipboard clipboard = parent.getClipboards().computeIfAbsent(user.getUniqueId(), v -> new Clipboard());
|
||||
if (clipboard.isFull()) {
|
||||
new Paster(getPlugin(), clipboard, user.getLocation(), () -> user.sendMessage("general.success"));
|
||||
user.sendMessage("commands.admin.schem.paste.pasting");
|
||||
return true;
|
||||
}
|
||||
|
||||
user.sendMessage("commands.admin.schem.copy-first");
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package world.bentobox.bentobox.api.commands.admin.schem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.Clipboard;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
public class AdminSchemPos1Command extends CompositeCommand {
|
||||
|
||||
public AdminSchemPos1Command(AdminSchemCommand parent) {
|
||||
super(parent, "pos1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
setParametersHelp("commands.admin.schem.pos1.parameters");
|
||||
setDescription("commands.admin.schem.pos1.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
AdminSchemCommand parent = (AdminSchemCommand) getParent();
|
||||
Clipboard clipboard = parent.getClipboards().computeIfAbsent(user.getUniqueId(), v -> new Clipboard());
|
||||
|
||||
if (user.getLocation().equals(clipboard.getPos2())) {
|
||||
user.sendMessage("commands.admin.schem.set-different-pos");
|
||||
return false;
|
||||
}
|
||||
clipboard.setPos1(user.getLocation());
|
||||
user.sendMessage("commands.admin.schem.set-pos1", "[vector]", Util.xyz(clipboard.getPos1().toVector()));
|
||||
parent.getClipboards().put(user.getUniqueId(), clipboard);
|
||||
parent.showClipboard(user);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package world.bentobox.bentobox.api.commands.admin.schem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.Clipboard;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
public class AdminSchemPos2Command extends CompositeCommand {
|
||||
|
||||
public AdminSchemPos2Command(AdminSchemCommand parent) {
|
||||
super(parent, "pos2");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
setParametersHelp("commands.admin.schem.pos2.parameters");
|
||||
setDescription("commands.admin.schem.pos2.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
AdminSchemCommand parent = (AdminSchemCommand) getParent();
|
||||
Clipboard clipboard = parent.getClipboards().computeIfAbsent(user.getUniqueId(), v -> new Clipboard());
|
||||
|
||||
if (user.getLocation().equals(clipboard.getPos1())) {
|
||||
user.sendMessage("commands.admin.schem.set-different-pos");
|
||||
return false;
|
||||
}
|
||||
clipboard.setPos2(user.getLocation());
|
||||
user.sendMessage("commands.admin.schem.set-pos2", "[vector]", Util.xyz((clipboard.getPos2()).toVector()));
|
||||
parent.getClipboards().put(user.getUniqueId(), clipboard);
|
||||
parent.showClipboard(user);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package world.bentobox.bentobox.api.commands.admin.schem;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.ConfirmableCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.Clipboard;
|
||||
import world.bentobox.bentobox.managers.ClipboardManager;
|
||||
|
||||
public class AdminSchemSaveCommand extends ConfirmableCommand {
|
||||
|
||||
public AdminSchemSaveCommand(AdminSchemCommand parent) {
|
||||
super(parent, "save");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
setParametersHelp("commands.admin.schem.save.parameters");
|
||||
setDescription("commands.admin.schem.save.description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
if (args.size() != 1) {
|
||||
showHelp(this, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
AdminSchemCommand parent = (AdminSchemCommand) getParent();
|
||||
Clipboard clipboard = parent.getClipboards().computeIfAbsent(user.getUniqueId(), v -> new Clipboard());
|
||||
|
||||
if (clipboard.isFull()) {
|
||||
// Check if file exists
|
||||
File newFile = new File(parent.getSchemsFolder(), args.get(0) + ".schem");
|
||||
if (newFile.exists()) {
|
||||
this.askConfirmation(user, user.getTranslation("commands.admin.schem.file-exists"), () -> {
|
||||
parent.hideClipboard(user);
|
||||
new ClipboardManager(getPlugin(), parent.getSchemsFolder(), clipboard).save(user, args.get(0));
|
||||
});
|
||||
return false;
|
||||
} else {
|
||||
parent.hideClipboard(user);
|
||||
return new ClipboardManager(getPlugin(), parent.getSchemsFolder(), clipboard).save(user, args.get(0));
|
||||
}
|
||||
} else {
|
||||
user.sendMessage("commands.admin.schem.copy-first");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,11 +3,12 @@ package world.bentobox.bentobox.api.commands.island;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.events.island.IslandEvent.Reason;
|
||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.managers.island.NewIsland;
|
||||
import world.bentobox.bentobox.panels.IslandCreationPanel;
|
||||
|
||||
/**
|
||||
* /island create - Create an island.
|
||||
@ -50,28 +51,33 @@ public class IslandCreateCommand extends CompositeCommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
// Default schem is 'island'
|
||||
String name = "island";
|
||||
// Permission check if the name is not the default one
|
||||
if (!args.isEmpty()) {
|
||||
name = args.get(0).toLowerCase(java.util.Locale.ENGLISH);
|
||||
// Permission check
|
||||
String permission = this.getPermissionPrefix() + "island.create." + name;
|
||||
if (!user.hasPermission(permission)) {
|
||||
user.sendMessage("general.errors.no-permission", TextVariables.PERMISSION, permission);
|
||||
return false;
|
||||
}
|
||||
// Check the schem name exists
|
||||
name = getPlugin().getSchemsManager().validate(getWorld(), name);
|
||||
String name = getPlugin().getBlueprintsManager().validate((GameModeAddon)getAddon(), args.get(0).toLowerCase(java.util.Locale.ENGLISH));
|
||||
if (name == null) {
|
||||
user.sendMessage("commands.island.create.unknown-schem");
|
||||
// The blueprint name is not valid.
|
||||
user.sendMessage("commands.island.create.unknown-blueprint");
|
||||
return false;
|
||||
}
|
||||
if (!getPlugin().getBlueprintsManager().checkPerm(getAddon(), user, args.get(0))) {
|
||||
return false;
|
||||
}
|
||||
// Make island
|
||||
return makeIsland(user, name);
|
||||
} else {
|
||||
// Show panel
|
||||
//getPlugin().getBlueprintsManager().showPanel(this, user, label);
|
||||
IslandCreationPanel.openPanel(user, (GameModeAddon) getAddon());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean makeIsland(User user, String name) {
|
||||
user.sendMessage("commands.island.create.creating-island");
|
||||
try {
|
||||
NewIsland.builder()
|
||||
.player(user)
|
||||
.world(getWorld())
|
||||
.addon((GameModeAddon)getAddon())
|
||||
.reason(Reason.CREATE)
|
||||
.name(name)
|
||||
.build();
|
||||
|
@ -1,19 +1,20 @@
|
||||
package world.bentobox.bentobox.api.commands.island;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.commands.ConfirmableCommand;
|
||||
import world.bentobox.bentobox.api.events.island.IslandEvent.Reason;
|
||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.managers.SchemsManager;
|
||||
import world.bentobox.bentobox.managers.island.NewIsland;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import world.bentobox.bentobox.panels.IslandCreationPanel;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
@ -33,7 +34,7 @@ public class IslandResetCommand extends ConfirmableCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
public boolean canExecute(User user, String label, List<String> args) {
|
||||
// Check cooldown
|
||||
if (getSettings().getResetCooldown() > 0 && checkCooldown(user, null)) {
|
||||
return false;
|
||||
@ -65,45 +66,35 @@ public class IslandResetCommand extends ConfirmableCommand {
|
||||
}
|
||||
}
|
||||
|
||||
// Default schem is 'island'
|
||||
String name = getSchemName(args);
|
||||
if (name == null) {
|
||||
// The schem name is not valid.
|
||||
user.sendMessage("commands.island.create.unknown-schem");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args) {
|
||||
// Permission check if the name is not the default one
|
||||
String permission = getPermissionPrefix() + "island.create." + name;
|
||||
if (!name.equals(SchemsManager.DEFAULT_SCHEM_NAME) && !user.hasPermission(permission)) {
|
||||
user.sendMessage("general.errors.no-permission", TextVariables.PERMISSION, permission);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Request confirmation
|
||||
if (getSettings().isResetConfirmation()) {
|
||||
this.askConfirmation(user, () -> resetIsland(user, name));
|
||||
return true;
|
||||
} else {
|
||||
if (!args.isEmpty()) {
|
||||
String name = getPlugin().getBlueprintsManager().validate((GameModeAddon)getAddon(), args.get(0).toLowerCase(java.util.Locale.ENGLISH));
|
||||
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))) {
|
||||
return false;
|
||||
}
|
||||
return resetIsland(user, name);
|
||||
} else {
|
||||
// Show panel after confirmation
|
||||
if (getPlugin().getSettings().isResetConfirmation()) {
|
||||
this.askConfirmation(user, () -> getPlugin().getBlueprintsManager().showPanel(this, user, label));
|
||||
} else {
|
||||
//getPlugin().getBlueprintsManager().showPanel(this, user, label);
|
||||
IslandCreationPanel.openPanel(user, (GameModeAddon) getAddon());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the schem name from the args.
|
||||
* {@link SchemsManager#DEFAULT_SCHEM_NAME} is the default.
|
||||
* May be null if the schem does not exist.
|
||||
* @param args args of the command
|
||||
* @return schem name or null
|
||||
* @since 1.1
|
||||
*/
|
||||
@Nullable
|
||||
private String getSchemName(List<String> args) {
|
||||
if (args.isEmpty()) {
|
||||
return SchemsManager.DEFAULT_SCHEM_NAME;
|
||||
}
|
||||
return getPlugin().getSchemsManager().validate(getWorld(), args.get(0).toLowerCase(java.util.Locale.ENGLISH));
|
||||
}
|
||||
|
||||
private boolean resetIsland(User user, String name) {
|
||||
// Reset the island
|
||||
@ -131,6 +122,7 @@ public class IslandResetCommand extends ConfirmableCommand {
|
||||
NewIsland.builder()
|
||||
.player(user)
|
||||
.reason(Reason.RESET)
|
||||
.addon((GameModeAddon)getAddon())
|
||||
.oldIsland(oldIsland)
|
||||
.name(name)
|
||||
.build();
|
||||
|
183
src/main/java/world/bentobox/bentobox/blueprints/Blueprint.java
Normal file
183
src/main/java/world/bentobox/bentobox/blueprints/Blueprint.java
Normal file
@ -0,0 +1,183 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package world.bentobox.bentobox.blueprints;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
|
||||
|
||||
/**
|
||||
* Stores all details of a blueprint
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
public class Blueprint {
|
||||
|
||||
/**
|
||||
* Unique name for this blueprint. The filename will be this plus the blueprint suffix
|
||||
*/
|
||||
@Expose
|
||||
private @NonNull String name;
|
||||
@Expose
|
||||
private String displayName;
|
||||
@Expose
|
||||
private @NonNull Material icon;
|
||||
@Expose
|
||||
private List<String> description;
|
||||
@Expose
|
||||
private Map<Vector, BlueprintBlock> attached;
|
||||
@Expose
|
||||
private Map<Vector, List<BlueprintEntity>> entities;
|
||||
@Expose
|
||||
private Map<Vector, BlueprintBlock> blocks;
|
||||
@Expose
|
||||
private int xSize;
|
||||
@Expose
|
||||
private int ySize;
|
||||
@Expose
|
||||
private int zSize;
|
||||
@Expose
|
||||
private Vector bedrock;
|
||||
/**
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
/**
|
||||
* @param name the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
/**
|
||||
* @return the displayName
|
||||
*/
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
/**
|
||||
* @param displayName the displayName to set
|
||||
*/
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
/**
|
||||
* @return the icon
|
||||
*/
|
||||
public Material getIcon() {
|
||||
return icon;
|
||||
}
|
||||
/**
|
||||
* @param icon the icon to set
|
||||
*/
|
||||
public void setIcon(Material icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
/**
|
||||
* @return the description
|
||||
*/
|
||||
public List<String> getDescription() {
|
||||
return description;
|
||||
}
|
||||
/**
|
||||
* @param description the description to set
|
||||
*/
|
||||
public void setDescription(List<String> description) {
|
||||
this.description = description;
|
||||
}
|
||||
/**
|
||||
* @return the attached
|
||||
*/
|
||||
public Map<Vector, BlueprintBlock> getAttached() {
|
||||
return attached;
|
||||
}
|
||||
/**
|
||||
* @param attached the attached to set
|
||||
*/
|
||||
public void setAttached(Map<Vector, BlueprintBlock> attached) {
|
||||
this.attached = attached;
|
||||
}
|
||||
/**
|
||||
* @return the entities
|
||||
*/
|
||||
public Map<Vector, List<BlueprintEntity>> getEntities() {
|
||||
return entities;
|
||||
}
|
||||
/**
|
||||
* @param entities the entities to set
|
||||
*/
|
||||
public void setEntities(Map<Vector, List<BlueprintEntity>> entities) {
|
||||
this.entities = entities;
|
||||
}
|
||||
/**
|
||||
* @return the blocks
|
||||
*/
|
||||
public Map<Vector, BlueprintBlock> getBlocks() {
|
||||
return blocks;
|
||||
}
|
||||
/**
|
||||
* @param blocks the blocks to set
|
||||
*/
|
||||
public void setBlocks(Map<Vector, BlueprintBlock> blocks) {
|
||||
this.blocks = blocks;
|
||||
}
|
||||
/**
|
||||
* @return the xSize
|
||||
*/
|
||||
public int getxSize() {
|
||||
return xSize;
|
||||
}
|
||||
/**
|
||||
* @param xSize the xSize to set
|
||||
*/
|
||||
public void setxSize(int xSize) {
|
||||
this.xSize = xSize;
|
||||
}
|
||||
/**
|
||||
* @return the ySize
|
||||
*/
|
||||
public int getySize() {
|
||||
return ySize;
|
||||
}
|
||||
/**
|
||||
* @param ySize the ySize to set
|
||||
*/
|
||||
public void setySize(int ySize) {
|
||||
this.ySize = ySize;
|
||||
}
|
||||
/**
|
||||
* @return the zSize
|
||||
*/
|
||||
public int getzSize() {
|
||||
return zSize;
|
||||
}
|
||||
/**
|
||||
* @param zSize the zSize to set
|
||||
*/
|
||||
public void setzSize(int zSize) {
|
||||
this.zSize = zSize;
|
||||
}
|
||||
/**
|
||||
* @return the bedrock
|
||||
*/
|
||||
public Vector getBedrock() {
|
||||
return bedrock;
|
||||
}
|
||||
/**
|
||||
* @param bedrock the bedrock to set
|
||||
*/
|
||||
public void setBedrock(Vector bedrock) {
|
||||
this.bedrock = bedrock;
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +1,5 @@
|
||||
package world.bentobox.bentobox.blueprints;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@ -15,9 +8,6 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.CreatureSpawner;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.AbstractHorse;
|
||||
import org.bukkit.entity.Ageable;
|
||||
import org.bukkit.entity.ChestedHorse;
|
||||
@ -34,26 +24,33 @@ import org.bukkit.util.BoundingBox;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintCreatureSpawner;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* The clipboard provides the holding spot for an active blueprint that is being
|
||||
* manipulated by a user. It supports copying from the world and setting of coordinates
|
||||
* such as the bounding box around the cuboid copy area.
|
||||
* Pasting is done by the {@link BlueprintPaster} class.
|
||||
* @author tastybento
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class Clipboard {
|
||||
public class BlueprintClipboard {
|
||||
|
||||
// Commonly used texts along this class.
|
||||
private static final String ATTACHED_YAML_PREFIX = "attached.";
|
||||
private static final String ENTITIES_YAML_PREFIX = "entities.";
|
||||
private static final String BLOCKS_YAML_PREFIX = "blocks.";
|
||||
private static final String BEDROCK = "bedrock";
|
||||
private static final String COLOR = "color";
|
||||
private static final String LINES = "lines";
|
||||
|
||||
private @Nullable YamlConfiguration blockConfig;
|
||||
private @Nullable Blueprint blueprint;
|
||||
private @Nullable Location pos1;
|
||||
private @Nullable Location pos2;
|
||||
private @Nullable Location origin;
|
||||
@ -62,18 +59,19 @@ public class Clipboard {
|
||||
private boolean copying;
|
||||
private int index;
|
||||
private int lastPercentage;
|
||||
private Map<Vector, List<BlueprintEntity>> bpEntities = new HashMap<>();
|
||||
private Map<Vector, BlueprintBlock> bpAttachable = new HashMap<>();
|
||||
private Map<Vector, BlueprintBlock> bpBlocks = new HashMap<>();
|
||||
|
||||
public Clipboard(String contents) throws InvalidConfigurationException {
|
||||
set(contents);
|
||||
/**
|
||||
* Create a clipboard for blueprint
|
||||
* @param blueprint - the blueprint to load into the clipboard
|
||||
*/
|
||||
public BlueprintClipboard(@NonNull Blueprint blueprint) {
|
||||
this.blueprint = blueprint;
|
||||
}
|
||||
|
||||
public Clipboard(@NonNull YamlConfiguration config) {
|
||||
this.blockConfig = config;
|
||||
}
|
||||
|
||||
public Clipboard() {
|
||||
super();
|
||||
}
|
||||
public BlueprintClipboard() { }
|
||||
|
||||
/**
|
||||
* Copy the blocks between pos1 and pos2 into the clipboard for a user.
|
||||
@ -84,29 +82,29 @@ public class Clipboard {
|
||||
*/
|
||||
public boolean copy(User user, boolean copyAir) {
|
||||
if (copying) {
|
||||
user.sendMessage("commands.admin.schem.mid-copy");
|
||||
user.sendMessage("commands.admin.blueprint.mid-copy");
|
||||
return false;
|
||||
}
|
||||
origin = origin == null ? user.getLocation() : origin;
|
||||
if (pos1 == null || pos2 == null) {
|
||||
user.sendMessage("commands.admin.schem.need-pos1-pos2");
|
||||
user.sendMessage("commands.admin.blueprint.need-pos1-pos2");
|
||||
return false;
|
||||
}
|
||||
|
||||
user.sendMessage("commands.admin.schem.copying");
|
||||
user.sendMessage("commands.admin.blueprint.copying");
|
||||
|
||||
// World
|
||||
World world = pos1.getWorld();
|
||||
// Clear the clipboard
|
||||
blockConfig = new YamlConfiguration();
|
||||
blueprint = new Blueprint();
|
||||
|
||||
count = 0;
|
||||
index = 0;
|
||||
lastPercentage = 0;
|
||||
BoundingBox toCopy = BoundingBox.of(pos1, pos2);
|
||||
blockConfig.set("size.xsize", toCopy.getWidthX());
|
||||
blockConfig.set("size.ysize", toCopy.getHeight());
|
||||
blockConfig.set("size.zsize", toCopy.getWidthZ());
|
||||
blueprint.setxSize((int)toCopy.getWidthX());
|
||||
blueprint.setySize((int)toCopy.getHeight());
|
||||
blueprint.setzSize((int)toCopy.getWidthZ());
|
||||
|
||||
BentoBox plugin = BentoBox.getInstance();
|
||||
|
||||
@ -120,26 +118,30 @@ public class Clipboard {
|
||||
}
|
||||
copying = true;
|
||||
vectorsToCopy.stream().skip(index).limit(speed).forEach(v -> {
|
||||
if (copyBlock(v.toLocation(world),
|
||||
origin,
|
||||
copyAir,
|
||||
world.getLivingEntities().stream()
|
||||
List<LivingEntity> ents = world.getLivingEntities().stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter(e -> !(e instanceof Player) && e.getLocation().equals(v.toLocation(world)))
|
||||
.collect(Collectors.toList()))) {
|
||||
.filter(e -> !(e instanceof Player))
|
||||
.filter(e -> new Vector(e.getLocation().getBlockX(),
|
||||
e.getLocation().getBlockY(),
|
||||
e.getLocation().getBlockZ()).equals(v))
|
||||
.collect(Collectors.toList());
|
||||
if (copyBlock(v.toLocation(world), origin, copyAir, ents)) {
|
||||
count++;
|
||||
}
|
||||
});
|
||||
index += speed;
|
||||
int percent = (int)(index * 100 / (double)vectorsToCopy.size());
|
||||
if (percent != lastPercentage && percent % 10 == 0) {
|
||||
user.sendMessage("commands.admin.schem.copied-percent", TextVariables.NUMBER, String.valueOf(percent));
|
||||
user.sendMessage("commands.admin.blueprint.copied-percent", TextVariables.NUMBER, String.valueOf(percent));
|
||||
lastPercentage = percent;
|
||||
}
|
||||
if (index > vectorsToCopy.size()) {
|
||||
copyTask.cancel();
|
||||
blueprint.setAttached(bpAttachable);
|
||||
blueprint.setBlocks(bpBlocks);
|
||||
blueprint.setEntities(bpEntities);
|
||||
user.sendMessage("general.success");
|
||||
user.sendMessage("commands.admin.schem.copied-blocks", TextVariables.NUMBER, String.valueOf(count));
|
||||
user.sendMessage("commands.admin.blueprint.copied-blocks", TextVariables.NUMBER, String.valueOf(count));
|
||||
}
|
||||
copying = false;
|
||||
}, 0L, 1L);
|
||||
@ -173,46 +175,51 @@ public class Clipboard {
|
||||
int x = l.getBlockX() - copyOrigin.getBlockX();
|
||||
int y = l.getBlockY() - copyOrigin.getBlockY();
|
||||
int z = l.getBlockZ() - copyOrigin.getBlockZ();
|
||||
String pos = x + "," + y + "," + z;
|
||||
|
||||
// Position defines the section
|
||||
ConfigurationSection blocksSection = blockConfig.createSection(BLOCKS_YAML_PREFIX + "." + pos);
|
||||
Vector pos = new Vector(x, y, z);
|
||||
|
||||
// Set entities
|
||||
List<BlueprintEntity> bpEnts = new ArrayList<>();
|
||||
for (LivingEntity entity: entities) {
|
||||
ConfigurationSection entitySection = blockConfig.createSection(ENTITIES_YAML_PREFIX + pos + "." + entity.getUniqueId());
|
||||
entitySection.set("type", entity.getType().name());
|
||||
entitySection.set("name", entity.getCustomName());
|
||||
BlueprintEntity bpe = new BlueprintEntity();
|
||||
bpe.setType(entity.getType());
|
||||
bpe.setCustomName(entity.getCustomName());
|
||||
if (entity instanceof Colorable) {
|
||||
Colorable c = (Colorable)entity;
|
||||
if (c.getColor() != null) {
|
||||
entitySection.set(COLOR, c.getColor().name());
|
||||
bpe.setColor(c.getColor());
|
||||
}
|
||||
}
|
||||
if (entity instanceof Tameable && ((Tameable)entity).isTamed()) {
|
||||
entitySection.set("tamed", true);
|
||||
if (entity instanceof Tameable) {
|
||||
bpe.setTamed(((Tameable)entity).isTamed());
|
||||
}
|
||||
if (entity instanceof ChestedHorse && ((ChestedHorse)entity).isCarryingChest()) {
|
||||
entitySection.set("chest", true);
|
||||
if (entity instanceof ChestedHorse) {
|
||||
bpe.setChest(((ChestedHorse)entity).isCarryingChest());
|
||||
}
|
||||
if (entity instanceof Ageable) {
|
||||
entitySection.set("adult", ((Ageable)entity).isAdult());
|
||||
// Only set if child. Most animals are adults
|
||||
if (!((Ageable)entity).isAdult()) bpe.setAdult(false);
|
||||
}
|
||||
if (entity instanceof AbstractHorse) {
|
||||
AbstractHorse horse = (AbstractHorse)entity;
|
||||
entitySection.set("domestication", horse.getDomestication());
|
||||
bpe.setDomestication(horse.getDomestication());
|
||||
bpe.setInventory(new HashMap<>());
|
||||
for (int index = 0; index < horse.getInventory().getSize(); index++) {
|
||||
ItemStack i = horse.getInventory().getItem(index);
|
||||
if (i != null) {
|
||||
entitySection.set("inventory." + index, i);
|
||||
bpe.getInventory().put(index, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entity instanceof Horse) {
|
||||
Horse horse = (Horse)entity;
|
||||
entitySection.set("style", horse.getStyle().name());
|
||||
bpe.setStyle(horse.getStyle());
|
||||
}
|
||||
bpEnts.add(bpe);
|
||||
}
|
||||
// Store
|
||||
if (!bpEnts.isEmpty()) {
|
||||
bpEntities.put(pos, bpEnts);
|
||||
}
|
||||
|
||||
// Return if this is just air block
|
||||
@ -222,64 +229,52 @@ public class Clipboard {
|
||||
|
||||
// Block state
|
||||
BlockState blockState = block.getState();
|
||||
|
||||
BlueprintBlock b = new BlueprintBlock(block.getBlockData().getAsString());
|
||||
// Signs
|
||||
if (blockState instanceof Sign) {
|
||||
Sign sign = (Sign)blockState;
|
||||
b.setSignLines(Arrays.asList(sign.getLines()));
|
||||
}
|
||||
// Set block data
|
||||
if (blockState.getData() instanceof Attachable) {
|
||||
ConfigurationSection attachedSection = blockConfig.createSection(ATTACHED_YAML_PREFIX + pos);
|
||||
attachedSection.set("bd", block.getBlockData().getAsString());
|
||||
// Placeholder for attachment
|
||||
blocksSection.set("bd", "minecraft:air");
|
||||
// Signs
|
||||
if (blockState instanceof Sign) {
|
||||
Sign sign = (Sign)blockState;
|
||||
attachedSection.set(LINES, Arrays.asList(sign.getLines()));
|
||||
}
|
||||
bpBlocks.put(pos, new BlueprintBlock("minecraft:air"));
|
||||
bpAttachable.put(pos, b);
|
||||
return true;
|
||||
} else {
|
||||
blocksSection.set("bd", block.getBlockData().getAsString());
|
||||
// Signs
|
||||
if (blockState instanceof Sign) {
|
||||
Sign sign = (Sign)blockState;
|
||||
blocksSection.set(LINES, Arrays.asList(sign.getLines()));
|
||||
}
|
||||
}
|
||||
|
||||
if (block.getType().equals(Material.BEDROCK)) {
|
||||
blockConfig.set(BEDROCK, x + "," + y + "," + z);
|
||||
blueprint.setBedrock(pos);
|
||||
}
|
||||
|
||||
// Chests
|
||||
if (blockState instanceof InventoryHolder) {
|
||||
b.setInventory(new HashMap<>());
|
||||
InventoryHolder ih = (InventoryHolder)blockState;
|
||||
for (int index = 0; index < ih.getInventory().getSize(); index++) {
|
||||
ItemStack i = ih.getInventory().getItem(index);
|
||||
if (i != null) {
|
||||
blocksSection.set("inventory." + index, i);
|
||||
b.getInventory().put(index, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (blockState instanceof CreatureSpawner) {
|
||||
CreatureSpawner spawner = (CreatureSpawner)blockState;
|
||||
blocksSection.set("spawnedType",spawner.getSpawnedType().name());
|
||||
blocksSection.set("delay", spawner.getDelay());
|
||||
blocksSection.set("maxNearbyEntities", spawner.getMaxNearbyEntities());
|
||||
blocksSection.set("maxSpawnDelay", spawner.getMaxSpawnDelay());
|
||||
blocksSection.set("minSpawnDelay", spawner.getMinSpawnDelay());
|
||||
blocksSection.set("requiredPlayerRange", spawner.getRequiredPlayerRange());
|
||||
blocksSection.set("spawnRange", spawner.getSpawnRange());
|
||||
BlueprintCreatureSpawner cs = new BlueprintCreatureSpawner();
|
||||
cs.setSpawnedType(spawner.getSpawnedType());
|
||||
cs.setDelay(spawner.getDelay());
|
||||
cs.setMaxNearbyEntities(spawner.getMaxNearbyEntities());
|
||||
cs.setMaxSpawnDelay(spawner.getMaxSpawnDelay());
|
||||
cs.setMinSpawnDelay(spawner.getMinSpawnDelay());
|
||||
cs.setRequiredPlayerRange(spawner.getRequiredPlayerRange());
|
||||
cs.setSpawnRange(spawner.getSpawnRange());
|
||||
b.setCreatureSpawner(cs);
|
||||
}
|
||||
this.bpBlocks.put(pos, b);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the blockConfig
|
||||
*/
|
||||
@Nullable
|
||||
public YamlConfiguration getBlockConfig() {
|
||||
return blockConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the origin
|
||||
*/
|
||||
@ -303,31 +298,7 @@ public class Clipboard {
|
||||
}
|
||||
|
||||
public boolean isFull() {
|
||||
return blockConfig != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the clipboard from a YAML string
|
||||
* @param contents - YAML config as a string
|
||||
* @return clipboard
|
||||
* @throws InvalidConfigurationException - if YAML config is bad
|
||||
*/
|
||||
public Clipboard set(String contents) throws InvalidConfigurationException {
|
||||
this.blockConfig.loadFromString(contents);
|
||||
setPos1(null);
|
||||
setPos2(null);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the clipboard contents from a YAML configuration
|
||||
* @param blockConfig the blockConfig
|
||||
*/
|
||||
public Clipboard set(@NonNull YamlConfiguration blockConfig) {
|
||||
this.blockConfig = blockConfig;
|
||||
setPos1(null);
|
||||
setPos2(null);
|
||||
return this;
|
||||
return blueprint != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -366,11 +337,17 @@ public class Clipboard {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the clipboard as a String using {@link YamlConfiguration#saveToString()}.
|
||||
* @return the clipboard as a String.
|
||||
* @return the blueprint
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return blockConfig.saveToString();
|
||||
public Blueprint getBlueprint() {
|
||||
return blueprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param blueprint the blueprint to set
|
||||
*/
|
||||
public BlueprintClipboard setBlueprint(Blueprint blueprint) {
|
||||
this.blueprint = blueprint;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,11 +1,7 @@
|
||||
package world.bentobox.bentobox.blueprints;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
@ -13,35 +9,40 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.CreatureSpawner;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.AbstractHorse;
|
||||
import org.bukkit.entity.Ageable;
|
||||
import org.bukkit.entity.ChestedHorse;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Horse;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.Colorable;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintCreatureSpawner;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* This class pastes the clipboard it is given
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
public class Paster {
|
||||
public class BlueprintPaster {
|
||||
|
||||
enum PasteState {
|
||||
BLOCKS,
|
||||
@ -51,18 +52,6 @@ public class Paster {
|
||||
CANCEL
|
||||
}
|
||||
|
||||
private static final String BEDROCK = "bedrock";
|
||||
|
||||
// Commonly used texts along this class.
|
||||
private static final String ATTACHED_YAML_PREFIX = "attached.";
|
||||
private static final String ENTITIES_YAML_PREFIX = "entities.";
|
||||
private static final String BLOCKS_YAML_PREFIX = "blocks.";
|
||||
|
||||
private static final String INVENTORY = "inventory";
|
||||
private static final String ENTITY = "entity";
|
||||
private static final String COLOR = "color";
|
||||
|
||||
private static final String LINES = "lines";
|
||||
private BentoBox plugin;
|
||||
// The minimum block position (x,y,z)
|
||||
private Location pos1;
|
||||
@ -72,57 +61,57 @@ public class Paster {
|
||||
private int pasteSpeed;
|
||||
private PasteState pasteState;
|
||||
private BukkitTask pastingTask;
|
||||
private BlueprintClipboard clipboard;
|
||||
|
||||
/**
|
||||
* Paste a clipboard
|
||||
* Paste a clipboard to a location and run task
|
||||
* @param plugin - BentoBox
|
||||
* @param clipboard - clipboard to paste
|
||||
* @param location - location to paste to
|
||||
* @param task - task to run after pasting, null if none
|
||||
*/
|
||||
public Paster(@NonNull BentoBox plugin, @NonNull Clipboard clipboard, @NonNull Location location) {
|
||||
public BlueprintPaster(@NonNull BentoBox plugin, @NonNull BlueprintClipboard clipboard, @NonNull Location location, @Nullable Runnable task) {
|
||||
this.plugin = plugin;
|
||||
paste(location.getWorld(), null, location, clipboard, null);
|
||||
this.clipboard = clipboard;
|
||||
// Calculate location for pasting
|
||||
Location loc = location.toVector().subtract(clipboard.getOrigin().toVector()).toLocation(location.getWorld());
|
||||
paste(location.getWorld(), null, loc, clipboard.getBlueprint(), task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paste a clipboard
|
||||
* Pastes a blueprint to an island
|
||||
* @param plugin - BentoBox
|
||||
* @param clipboard - clipboard to paste
|
||||
* @param location - location to paste to
|
||||
* @param task - task to run after pasting
|
||||
*/
|
||||
public Paster(@NonNull BentoBox plugin, @NonNull Clipboard clipboard, @NonNull Location location, @Nullable Runnable task) {
|
||||
this.plugin = plugin;
|
||||
paste(location.getWorld(), null, location, clipboard, task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pastes a clipboard
|
||||
* @param plugin - BentoBox
|
||||
* @param clipboard - clipboard to paste
|
||||
* @param bp - blueprint to paste
|
||||
* @param world - world to paste to
|
||||
* @param island - island related to this paste
|
||||
* @param task - task to run after pasting
|
||||
*/
|
||||
public Paster(@NonNull BentoBox plugin, @NonNull Clipboard clipboard, @NonNull World world, @NonNull Island island, @Nullable Runnable task) {
|
||||
public BlueprintPaster(@NonNull BentoBox plugin, Blueprint bp, World world, Island island, Runnable task) {
|
||||
this.plugin = plugin;
|
||||
// Offset due to bedrock
|
||||
Vector off = new Vector(0,0,0);
|
||||
if (clipboard.getBlockConfig().contains(BEDROCK)) {
|
||||
String[] offset = clipboard.getBlockConfig().getString(BEDROCK).split(",");
|
||||
off = new Vector(Integer.valueOf(offset[0]), Integer.valueOf(offset[1]), Integer.valueOf(offset[2]));
|
||||
}
|
||||
Vector off = bp.getBedrock() != null ? bp.getBedrock() : new Vector(0,0,0);
|
||||
// Calculate location for pasting
|
||||
Location loc = island.getCenter().toVector().subtract(off).toLocation(world);
|
||||
// Paste
|
||||
paste(world, island, loc, clipboard, task);
|
||||
paste(world, island, loc, bp, task);
|
||||
}
|
||||
|
||||
private void paste(@NonNull World world, @Nullable Island island, @NonNull Location loc, @NonNull Clipboard clipboard, @Nullable Runnable task) {
|
||||
// Iterators for the various schem sections
|
||||
Iterator<String> it = clipboard.getBlockConfig().getConfigurationSection(BLOCKS_YAML_PREFIX).getKeys(false).iterator();
|
||||
Iterator<String> it2 = clipboard.getBlockConfig().contains(ATTACHED_YAML_PREFIX) ? clipboard.getBlockConfig().getConfigurationSection(ATTACHED_YAML_PREFIX).getKeys(false).iterator() : null;
|
||||
Iterator<String> it3 = clipboard.getBlockConfig().contains(ENTITIES_YAML_PREFIX) ? clipboard.getBlockConfig().getConfigurationSection(ENTITIES_YAML_PREFIX).getKeys(false).iterator() : null;
|
||||
/**
|
||||
* The main pasting method
|
||||
* @param world - world to paste to
|
||||
* @param island - the island related to this pasting - may be null
|
||||
* @param loc - the location to paste to
|
||||
* @param blueprint - the blueprint to paste
|
||||
* @param task - task to run after pasting
|
||||
*/
|
||||
private void paste(@NonNull World world, @Nullable Island island, @NonNull Location loc, @NonNull Blueprint blueprint, @Nullable Runnable task) {
|
||||
// Iterators for the various maps to paste
|
||||
Map<Vector, BlueprintBlock> blocks = blueprint.getBlocks() == null ? new HashMap<>() : blueprint.getBlocks();
|
||||
Map<Vector, BlueprintBlock> attached = blueprint.getAttached() == null ? new HashMap<>() : blueprint.getAttached();
|
||||
Map<Vector, List<BlueprintEntity>> entities = blueprint.getEntities() == null ? new HashMap<>() : blueprint.getEntities();
|
||||
Iterator<Entry<Vector, BlueprintBlock>> it = blocks.entrySet().iterator();
|
||||
Iterator<Entry<Vector, BlueprintBlock>> it2 = attached.entrySet().iterator();
|
||||
Iterator<Entry<Vector, List<BlueprintEntity>>> it3 = entities.entrySet().iterator();
|
||||
|
||||
// Initial state & speed
|
||||
pasteState = PasteState.BLOCKS;
|
||||
@ -131,15 +120,15 @@ public class Paster {
|
||||
pastingTask = Bukkit.getScheduler().runTaskTimer(plugin, () -> {
|
||||
int count = 0;
|
||||
while (pasteState.equals(PasteState.BLOCKS) && count < pasteSpeed && it.hasNext()) {
|
||||
pasteBlock(world, island, loc, clipboard.getBlockConfig().getConfigurationSection(BLOCKS_YAML_PREFIX + it.next()));
|
||||
pasteBlock(world, island, loc, it.next());
|
||||
count++;
|
||||
}
|
||||
while (it2 != null && pasteState.equals(PasteState.ATTACHMENTS) && count < pasteSpeed && it2.hasNext()) {
|
||||
pasteBlock(world, island, loc, clipboard.getBlockConfig().getConfigurationSection(ATTACHED_YAML_PREFIX + it2.next()));
|
||||
pasteBlock(world, island, loc, it2.next());
|
||||
count++;
|
||||
}
|
||||
while (it3 != null && pasteState.equals(PasteState.ENTITIES) && count < pasteSpeed && it3.hasNext()) {
|
||||
pasteEntity(world, loc, clipboard.getBlockConfig().getConfigurationSection(ENTITIES_YAML_PREFIX + it3.next()));
|
||||
pasteEntity(world, loc, it3.next());
|
||||
count++;
|
||||
}
|
||||
// STATE SHIFT
|
||||
@ -163,7 +152,7 @@ public class Paster {
|
||||
if (pasteState.equals(PasteState.DONE)) {
|
||||
// All done. Cancel task
|
||||
// Set pos1 and 2 if this was a clipboard paste
|
||||
if (island == null && (clipboard.getPos1() == null || clipboard.getPos2() == null)) {
|
||||
if (island == null && clipboard != null &&(clipboard.getPos1() == null || clipboard.getPos2() == null)) {
|
||||
clipboard.setPos1(pos1);
|
||||
clipboard.setPos2(pos2);
|
||||
}
|
||||
@ -180,77 +169,55 @@ public class Paster {
|
||||
|
||||
}
|
||||
|
||||
private void pasteBlock(World world, Island island, Location location, ConfigurationSection config) {
|
||||
String[] pos = config.getName().split(",");
|
||||
int x = location.getBlockX() + Integer.valueOf(pos[0]);
|
||||
int y = location.getBlockY() + Integer.valueOf(pos[1]);
|
||||
int z = location.getBlockZ() + Integer.valueOf(pos[2]);
|
||||
|
||||
Block block = world.getBlockAt(x, y, z);
|
||||
String blockData = config.getString("bd");
|
||||
if (blockData != null) {
|
||||
setBlock(island, block, config, blockData);
|
||||
}
|
||||
// Entities (legacy)
|
||||
if (config.isConfigurationSection(ENTITY)) {
|
||||
setEntity(block.getLocation(), config.getConfigurationSection(ENTITY));
|
||||
}
|
||||
// pos1 and pos2 update
|
||||
updatePos(world, x,y,z);
|
||||
}
|
||||
|
||||
private void pasteEntity(World world, Location location, ConfigurationSection config) {
|
||||
String[] pos = config.getName().split(",");
|
||||
int x = location.getBlockX() + Integer.valueOf(pos[0]);
|
||||
int y = location.getBlockY() + Integer.valueOf(pos[1]);
|
||||
int z = location.getBlockZ() + Integer.valueOf(pos[2]);
|
||||
setEntity(new Location(world, x, y, z), config);
|
||||
}
|
||||
|
||||
private void setBlock(Island island, Block block, ConfigurationSection config, String blockData) {
|
||||
private void pasteBlock(World world, Island island, Location location, Entry<Vector, BlueprintBlock> entry) {
|
||||
Location pasteTo = location.clone().add(entry.getKey());
|
||||
BlueprintBlock bpBlock = entry.getValue();
|
||||
Block block = pasteTo.getBlock();
|
||||
// Set the block data
|
||||
block.setBlockData(Bukkit.createBlockData(blockData));
|
||||
// Set the block state for chests, signs and mob spawners
|
||||
setBlockState(island, block, config);
|
||||
block.setBlockData(Bukkit.createBlockData(bpBlock.getBlockData()));
|
||||
setBlockState(island, block, bpBlock);
|
||||
// pos1 and pos2 update
|
||||
updatePos(world, entry.getKey());
|
||||
}
|
||||
|
||||
private void pasteEntity(World world, Location location, Entry<Vector, List<BlueprintEntity>> entry) {
|
||||
int x = location.getBlockX() + entry.getKey().getBlockX();
|
||||
int y = location.getBlockY() + entry.getKey().getBlockY();
|
||||
int z = location.getBlockZ() + entry.getKey().getBlockZ();
|
||||
setEntity(new Location(world, x, y, z), entry.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles signs, chests and mob spawner blocks
|
||||
* @param island - island
|
||||
* @param block - block
|
||||
* @param config - config
|
||||
* @param bpBlock - config
|
||||
*/
|
||||
private void setBlockState(Island island, Block block, ConfigurationSection config) {
|
||||
private void setBlockState(Island island, Block block, BlueprintBlock bpBlock) {
|
||||
// Get the block state
|
||||
BlockState bs = block.getState();
|
||||
// Signs
|
||||
if (bs instanceof Sign) {
|
||||
List<String> lines = config.getStringList(LINES);
|
||||
writeSign(island, block, lines);
|
||||
writeSign(island, block, bpBlock.getSignLines());
|
||||
}
|
||||
// Chests, in general
|
||||
if (bs instanceof InventoryHolder) {
|
||||
bs.update(true, false);
|
||||
Inventory ih = ((InventoryHolder)bs).getInventory();
|
||||
if (config.isConfigurationSection(INVENTORY)) {
|
||||
ConfigurationSection inv = config.getConfigurationSection(INVENTORY);
|
||||
// Double chests are pasted as two blocks so inventory is filled twice. This code stops over filling for the first block.
|
||||
inv.getKeys(false).stream()
|
||||
.filter(i -> Integer.valueOf(i) < ih.getSize())
|
||||
.forEach(i -> ih.setItem(Integer.valueOf(i), (ItemStack)inv.get(i)));
|
||||
}
|
||||
// Double chests are pasted as two blocks so inventory is filled twice. This code stops over filling for the first block.
|
||||
bpBlock.getInventory().forEach(ih::setItem);
|
||||
}
|
||||
// Mob spawners
|
||||
if (bs instanceof CreatureSpawner) {
|
||||
CreatureSpawner spawner = ((CreatureSpawner) bs);
|
||||
spawner.setSpawnedType(EntityType.valueOf(config.getString("spawnedType", "PIG")));
|
||||
spawner.setMaxNearbyEntities(config.getInt("maxNearbyEntities", 16));
|
||||
spawner.setMaxSpawnDelay(config.getInt("maxSpawnDelay", 2*60*20));
|
||||
spawner.setMinSpawnDelay(config.getInt("minSpawnDelay", 5*20));
|
||||
|
||||
spawner.setDelay(config.getInt("delay", -1));
|
||||
spawner.setRequiredPlayerRange(config.getInt("requiredPlayerRange", 16));
|
||||
spawner.setSpawnRange(config.getInt("spawnRange", 4));
|
||||
BlueprintCreatureSpawner s = bpBlock.getCreatureSpawner();
|
||||
spawner.setSpawnedType(s.getSpawnedType());
|
||||
spawner.setMaxNearbyEntities(s.getMaxNearbyEntities());
|
||||
spawner.setMaxSpawnDelay(s.getMaxSpawnDelay());
|
||||
spawner.setMinSpawnDelay(s.getMinSpawnDelay());
|
||||
spawner.setDelay(s.getDelay());
|
||||
spawner.setRequiredPlayerRange(s.getRequiredPlayerRange());
|
||||
spawner.setSpawnRange(s.getSpawnRange());
|
||||
bs.update(true, false);
|
||||
}
|
||||
}
|
||||
@ -258,28 +225,27 @@ public class Paster {
|
||||
/**
|
||||
* Sets any entity that is in this location
|
||||
* @param location - location
|
||||
* @param en - config section
|
||||
* @param list - list of entities to paste
|
||||
*/
|
||||
private void setEntity(Location location, ConfigurationSection en) {
|
||||
en.getKeys(false).forEach(k -> {
|
||||
ConfigurationSection ent = en.getConfigurationSection(k);
|
||||
private void setEntity(Location location, List<BlueprintEntity> list) {
|
||||
list.forEach(k -> {
|
||||
// Center, and just a bit high
|
||||
Location center = location.add(new Vector(0.5, 0.5, 0.5));
|
||||
LivingEntity e = (LivingEntity)location.getWorld().spawnEntity(center, EntityType.valueOf(ent.getString("type", "PIG")));
|
||||
if (e != null) {
|
||||
e.setCustomName(ent.getString("name"));
|
||||
LivingEntity e = (LivingEntity)location.getWorld().spawnEntity(center, k.getType());
|
||||
if (k.getCustomName() != null) {
|
||||
e.setCustomName(k.getCustomName());
|
||||
}
|
||||
if (e instanceof Colorable && ent.contains(COLOR)) {
|
||||
((Colorable) e).setColor(DyeColor.valueOf(ent.getString(COLOR)));
|
||||
if (e instanceof Colorable && k.getColor() != null) {
|
||||
((Colorable) e).setColor(k.getColor());
|
||||
}
|
||||
if (e instanceof Tameable) {
|
||||
((Tameable)e).setTamed(ent.getBoolean("tamed"));
|
||||
if (e instanceof Tameable && k.getTamed() != null) {
|
||||
((Tameable)e).setTamed(k.getTamed());
|
||||
}
|
||||
if (e instanceof ChestedHorse) {
|
||||
((ChestedHorse)e).setCarryingChest(ent.getBoolean("chest"));
|
||||
if (e instanceof ChestedHorse && k.getChest() != null) {
|
||||
((ChestedHorse)e).setCarryingChest(k.getChest());
|
||||
}
|
||||
if (e instanceof Ageable) {
|
||||
if (ent.getBoolean("adult")) {
|
||||
if (e instanceof Ageable && k.getAdult() != null) {
|
||||
if (k.getAdult()) {
|
||||
((Ageable)e).setAdult();
|
||||
} else {
|
||||
((Ageable)e).setBaby();
|
||||
@ -287,14 +253,13 @@ public class Paster {
|
||||
}
|
||||
if (e instanceof AbstractHorse) {
|
||||
AbstractHorse horse = (AbstractHorse)e;
|
||||
horse.setDomestication(ent.getInt("domestication"));
|
||||
if (ent.isConfigurationSection(INVENTORY)) {
|
||||
ConfigurationSection inv = ent.getConfigurationSection(INVENTORY);
|
||||
inv.getKeys(false).forEach(i -> horse.getInventory().setItem(Integer.valueOf(i), (ItemStack)inv.get(i)));
|
||||
if (k.getDomestication() != null) horse.setDomestication(k.getDomestication());
|
||||
if (k.getInventory() != null) {
|
||||
k.getInventory().forEach(horse.getInventory()::setItem);
|
||||
}
|
||||
}
|
||||
if (e instanceof Horse) {
|
||||
((Horse)e).setStyle(Horse.Style.valueOf(ent.getString("style", "NONE")));
|
||||
if (e instanceof Horse && k.getStyle() != null) {
|
||||
((Horse)e).setStyle(k.getStyle());
|
||||
}
|
||||
});
|
||||
|
||||
@ -303,34 +268,32 @@ public class Paster {
|
||||
/**
|
||||
* Tracks the minimum and maximum block positions
|
||||
* @param world - world
|
||||
* @param x - x
|
||||
* @param y - y
|
||||
* @param z - z
|
||||
* @param v - vector
|
||||
*/
|
||||
private void updatePos(World world, int x, int y, int z) {
|
||||
private void updatePos(World world, Vector v) {
|
||||
if (pos1 == null) {
|
||||
pos1 = new Location(world, x, y, z);
|
||||
pos1 = v.toLocation(world);
|
||||
}
|
||||
if (pos2 == null) {
|
||||
pos2 = new Location(world, x, y, z);
|
||||
pos2 = v.toLocation(world);
|
||||
}
|
||||
if (x < pos1.getBlockX()) {
|
||||
pos1.setX(x);
|
||||
if (v.getBlockX() < pos1.getBlockX()) {
|
||||
pos1.setX(v.getBlockX());
|
||||
}
|
||||
if (x > pos2.getBlockX()) {
|
||||
pos2.setX(x);
|
||||
if (v.getBlockX() > pos2.getBlockX()) {
|
||||
pos2.setX(v.getBlockX());
|
||||
}
|
||||
if (y < pos1.getBlockY()) {
|
||||
pos1.setY(y);
|
||||
if (v.getBlockY() < pos1.getBlockY()) {
|
||||
pos1.setY(v.getBlockY());
|
||||
}
|
||||
if (y > pos2.getBlockY()) {
|
||||
pos2.setY(y);
|
||||
if (v.getBlockY() > pos2.getBlockY()) {
|
||||
pos2.setY(v.getBlockY());
|
||||
}
|
||||
if (z < pos1.getBlockZ()) {
|
||||
pos1.setZ(z);
|
||||
if (v.getBlockZ() < pos1.getBlockZ()) {
|
||||
pos1.setZ(v.getBlockZ());
|
||||
}
|
||||
if (z > pos2.getBlockZ()) {
|
||||
pos2.setZ(z);
|
||||
if (v.getBlockZ() > pos2.getBlockZ()) {
|
||||
pos2.setZ(v.getBlockZ());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,84 @@
|
||||
package world.bentobox.bentobox.blueprints.dataobjects;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class BlueprintBlock {
|
||||
|
||||
@Expose
|
||||
private String blockData;
|
||||
@Expose
|
||||
private List<String> signLines;
|
||||
@Expose
|
||||
private Map<Integer, ItemStack> inventory;
|
||||
@Expose
|
||||
private BlueprintCreatureSpawner creatureSpawner;
|
||||
|
||||
public BlueprintBlock(String blockData) {
|
||||
this.blockData = blockData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the blockData
|
||||
*/
|
||||
public String getBlockData() {
|
||||
return blockData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param blockData the blockData to set
|
||||
*/
|
||||
public void setBlockData(String blockData) {
|
||||
this.blockData = blockData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the signLines
|
||||
*/
|
||||
public List<String> getSignLines() {
|
||||
return signLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param signLines the signLines to set
|
||||
*/
|
||||
public void setSignLines(List<String> signLines) {
|
||||
this.signLines = signLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the inventory
|
||||
*/
|
||||
public Map<Integer, ItemStack> getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param inventory the inventory to set
|
||||
*/
|
||||
public void setInventory(Map<Integer, ItemStack> inventory) {
|
||||
this.inventory = inventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the creatureSpawner
|
||||
*/
|
||||
public BlueprintCreatureSpawner getCreatureSpawner() {
|
||||
return creatureSpawner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param creatureSpawner the creatureSpawner to set
|
||||
*/
|
||||
public void setCreatureSpawner(BlueprintCreatureSpawner creatureSpawner) {
|
||||
this.creatureSpawner = creatureSpawner;
|
||||
}
|
||||
}
|
@ -0,0 +1,161 @@
|
||||
package world.bentobox.bentobox.blueprints.dataobjects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import world.bentobox.bentobox.blueprints.Blueprint;
|
||||
import world.bentobox.bentobox.database.objects.DataObject;
|
||||
|
||||
/**
|
||||
* Represents a bundle of three {@link Blueprint}s.
|
||||
* This is what the player will choose when creating his island.
|
||||
* @since 1.5.0
|
||||
* @author Poslovitch, tastybento
|
||||
*/
|
||||
public class BlueprintBundle implements DataObject {
|
||||
|
||||
/**
|
||||
* The unique id of this bundle
|
||||
*/
|
||||
@Expose
|
||||
private String uniqueId;
|
||||
/**
|
||||
* Icon of the bundle
|
||||
*/
|
||||
@Expose
|
||||
private Material icon = Material.PAPER;
|
||||
/**
|
||||
* Name on the icon
|
||||
*/
|
||||
@Expose
|
||||
private String displayName = "";
|
||||
/**
|
||||
* Description to show players
|
||||
*/
|
||||
@Expose
|
||||
private List<String> description = new ArrayList<>();
|
||||
/**
|
||||
* If true, then the player needs to have a permission to view or use this bundle
|
||||
* The permission is GameModeAddon.island.create.uniqueId of blueprint bundle.
|
||||
* e.g. bskyblock.island.create.vip
|
||||
*/
|
||||
@Expose
|
||||
private boolean requirePermission;
|
||||
|
||||
/**
|
||||
* Reference to the blueprint
|
||||
*/
|
||||
@Expose
|
||||
private EnumMap<World.Environment, String> blueprints = new EnumMap<>(World.Environment.class);
|
||||
/**
|
||||
* @return the uniqueId
|
||||
*/
|
||||
@Override
|
||||
public String getUniqueId() {
|
||||
return uniqueId;
|
||||
}
|
||||
/**
|
||||
* @param uniqueId the uniqueId to set
|
||||
*/
|
||||
@Override
|
||||
public void setUniqueId(String uniqueId) {
|
||||
this.uniqueId = uniqueId;
|
||||
}
|
||||
/**
|
||||
* @return the icon
|
||||
*/
|
||||
public Material getIcon() {
|
||||
return icon;
|
||||
}
|
||||
/**
|
||||
* @param icon the icon to set
|
||||
*/
|
||||
public void setIcon(Material icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
/**
|
||||
* @return the displayName
|
||||
*/
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
/**
|
||||
* @param displayName the displayName to set
|
||||
*/
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
/**
|
||||
* @return the description
|
||||
*/
|
||||
public List<String> getDescription() {
|
||||
return description;
|
||||
}
|
||||
/**
|
||||
* @param description the description to set
|
||||
*/
|
||||
public void setDescription(List<String> description) {
|
||||
this.description = description;
|
||||
}
|
||||
/**
|
||||
* @return the blueprints
|
||||
*/
|
||||
public EnumMap<World.Environment, String> getBlueprints() {
|
||||
return blueprints;
|
||||
}
|
||||
/**
|
||||
* @param blueprints the blueprints to set
|
||||
*/
|
||||
public void setBlueprints(EnumMap<World.Environment, String> blueprints) {
|
||||
this.blueprints = blueprints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a blueprint to the blueprint bundle. It will replace any blueprint that already exists of the same {@link World.Environment} type.
|
||||
* @param env - the {@link World#Environment}
|
||||
* @param bp - blueprint
|
||||
*/
|
||||
public void setBlueprint(World.Environment env, Blueprint bp) {
|
||||
this.blueprints.put(env, bp.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the blueprint for the environment type
|
||||
* @param env - {@link World#Environment} type
|
||||
* @return Blueprint or null if one does not exist
|
||||
*/
|
||||
public String getBlueprint(World.Environment env) {
|
||||
return this.blueprints.get(env);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a line to the description
|
||||
*
|
||||
* @param string
|
||||
*/
|
||||
public void setDescription(String string) {
|
||||
if (description == null)
|
||||
description = new ArrayList<>();
|
||||
this.description.add(string);
|
||||
|
||||
}
|
||||
/**
|
||||
* @return the requirePermission
|
||||
*/
|
||||
public boolean isRequirePermission() {
|
||||
return requirePermission;
|
||||
}
|
||||
/**
|
||||
* @param requirePermission the requirePermission to set
|
||||
*/
|
||||
public void setRequirePermission(boolean requirePermission) {
|
||||
this.requirePermission = requirePermission;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
package world.bentobox.bentobox.blueprints.dataobjects;
|
||||
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class BlueprintCreatureSpawner {
|
||||
|
||||
@Expose
|
||||
private EntityType spawnedType;
|
||||
@Expose
|
||||
private int delay;
|
||||
@Expose
|
||||
private int maxNearbyEntities;
|
||||
@Expose
|
||||
private int maxSpawnDelay;
|
||||
@Expose
|
||||
private int minSpawnDelay;
|
||||
@Expose
|
||||
private int requiredPlayerRange;
|
||||
@Expose
|
||||
private int spawnRange;
|
||||
/**
|
||||
* @return the spawnedType
|
||||
*/
|
||||
public EntityType getSpawnedType() {
|
||||
return spawnedType;
|
||||
}
|
||||
/**
|
||||
* @param spawnedType the spawnedType to set
|
||||
*/
|
||||
public void setSpawnedType(EntityType spawnedType) {
|
||||
this.spawnedType = spawnedType;
|
||||
}
|
||||
/**
|
||||
* @return the delay
|
||||
*/
|
||||
public int getDelay() {
|
||||
return delay;
|
||||
}
|
||||
/**
|
||||
* @param delay the delay to set
|
||||
*/
|
||||
public void setDelay(int delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
/**
|
||||
* @return the maxNearbyEntities
|
||||
*/
|
||||
public int getMaxNearbyEntities() {
|
||||
return maxNearbyEntities;
|
||||
}
|
||||
/**
|
||||
* @param maxNearbyEntities the maxNearbyEntities to set
|
||||
*/
|
||||
public void setMaxNearbyEntities(int maxNearbyEntities) {
|
||||
this.maxNearbyEntities = maxNearbyEntities;
|
||||
}
|
||||
/**
|
||||
* @return the maxSpawnDelay
|
||||
*/
|
||||
public int getMaxSpawnDelay() {
|
||||
return maxSpawnDelay;
|
||||
}
|
||||
/**
|
||||
* @param maxSpawnDelay the maxSpawnDelay to set
|
||||
*/
|
||||
public void setMaxSpawnDelay(int maxSpawnDelay) {
|
||||
this.maxSpawnDelay = maxSpawnDelay;
|
||||
}
|
||||
/**
|
||||
* @return the minSpawnDelay
|
||||
*/
|
||||
public int getMinSpawnDelay() {
|
||||
return minSpawnDelay;
|
||||
}
|
||||
/**
|
||||
* @param minSpawnDelay the minSpawnDelay to set
|
||||
*/
|
||||
public void setMinSpawnDelay(int minSpawnDelay) {
|
||||
this.minSpawnDelay = minSpawnDelay;
|
||||
}
|
||||
/**
|
||||
* @return the requiredPlayerRange
|
||||
*/
|
||||
public int getRequiredPlayerRange() {
|
||||
return requiredPlayerRange;
|
||||
}
|
||||
/**
|
||||
* @param requiredPlayerRange the requiredPlayerRange to set
|
||||
*/
|
||||
public void setRequiredPlayerRange(int requiredPlayerRange) {
|
||||
this.requiredPlayerRange = requiredPlayerRange;
|
||||
}
|
||||
/**
|
||||
* @return the spawnRange
|
||||
*/
|
||||
public int getSpawnRange() {
|
||||
return spawnRange;
|
||||
}
|
||||
/**
|
||||
* @param spawnRange the spawnRange to set
|
||||
*/
|
||||
public void setSpawnRange(int spawnRange) {
|
||||
this.spawnRange = spawnRange;
|
||||
}
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
package world.bentobox.bentobox.blueprints.dataobjects;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Horse.Style;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class BlueprintEntity {
|
||||
|
||||
@Expose
|
||||
private DyeColor color;
|
||||
@Expose
|
||||
private EntityType type;
|
||||
@Expose
|
||||
private String customName;
|
||||
@Expose
|
||||
private Boolean tamed;
|
||||
@Expose
|
||||
private Boolean chest;
|
||||
@Expose
|
||||
private Boolean adult;
|
||||
@Expose
|
||||
private Integer domestication;
|
||||
@Expose
|
||||
private Map<Integer, ItemStack> inventory;
|
||||
@Expose
|
||||
private Style style;
|
||||
|
||||
/**
|
||||
* @return the color
|
||||
*/
|
||||
public DyeColor getColor() {
|
||||
return color;
|
||||
}
|
||||
/**
|
||||
* @param color the color to set
|
||||
*/
|
||||
public void setColor(DyeColor color) {
|
||||
this.color = color;
|
||||
}
|
||||
/**
|
||||
* @return the type
|
||||
*/
|
||||
public EntityType getType() {
|
||||
return type;
|
||||
}
|
||||
/**
|
||||
* @param type the type to set
|
||||
*/
|
||||
public void setType(EntityType type) {
|
||||
this.type = type;
|
||||
}
|
||||
/**
|
||||
* @return the customName
|
||||
*/
|
||||
public String getCustomName() {
|
||||
return customName;
|
||||
}
|
||||
/**
|
||||
* @param customName the customName to set
|
||||
*/
|
||||
public void setCustomName(String customName) {
|
||||
this.customName = customName;
|
||||
}
|
||||
/**
|
||||
* @return the tamed
|
||||
*/
|
||||
public Boolean getTamed() {
|
||||
return tamed;
|
||||
}
|
||||
/**
|
||||
* @param tamed the tamed to set
|
||||
*/
|
||||
public void setTamed(Boolean tamed) {
|
||||
this.tamed = tamed;
|
||||
}
|
||||
/**
|
||||
* @return the chest
|
||||
*/
|
||||
public Boolean getChest() {
|
||||
return chest;
|
||||
}
|
||||
/**
|
||||
* @param chest the chest to set
|
||||
*/
|
||||
public void setChest(Boolean chest) {
|
||||
this.chest = chest;
|
||||
}
|
||||
/**
|
||||
* @return the adult
|
||||
*/
|
||||
public Boolean getAdult() {
|
||||
return adult;
|
||||
}
|
||||
/**
|
||||
* @param adult the adult to set
|
||||
*/
|
||||
public void setAdult(Boolean adult) {
|
||||
this.adult = adult;
|
||||
}
|
||||
/**
|
||||
* @return the domestication
|
||||
*/
|
||||
public Integer getDomestication() {
|
||||
return domestication;
|
||||
}
|
||||
/**
|
||||
* @param domestication the domestication to set
|
||||
*/
|
||||
public void setDomestication(int domestication) {
|
||||
this.domestication = domestication;
|
||||
}
|
||||
/**
|
||||
* @return the inventory
|
||||
*/
|
||||
public Map<Integer, ItemStack> getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
/**
|
||||
* @param inventory the inventory to set
|
||||
*/
|
||||
public void setInventory(Map<Integer, ItemStack> inventory) {
|
||||
this.inventory = inventory;
|
||||
}
|
||||
/**
|
||||
* @return the style
|
||||
*/
|
||||
public Style getStyle() {
|
||||
return style;
|
||||
}
|
||||
/**
|
||||
* @param style the style to set
|
||||
*/
|
||||
public void setStyle(Style style) {
|
||||
this.style = style;
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ import org.bukkit.World;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.TypeAdapter;
|
||||
@ -23,6 +24,7 @@ import world.bentobox.bentobox.database.json.adapters.FlagTypeAdapter;
|
||||
import world.bentobox.bentobox.database.json.adapters.ItemStackTypeAdapter;
|
||||
import world.bentobox.bentobox.database.json.adapters.LocationTypeAdapter;
|
||||
import world.bentobox.bentobox.database.json.adapters.PotionEffectTypeAdapter;
|
||||
import world.bentobox.bentobox.database.json.adapters.VectorTypeAdapter;
|
||||
import world.bentobox.bentobox.database.json.adapters.WorldTypeAdapter;
|
||||
|
||||
/**
|
||||
@ -61,6 +63,8 @@ public class BentoboxTypeAdapterFactory implements TypeAdapterFactory {
|
||||
return (TypeAdapter<T>) new PotionEffectTypeAdapter();
|
||||
} else if (World.class.isAssignableFrom(rawType)) {
|
||||
return (TypeAdapter<T>) new WorldTypeAdapter();
|
||||
} else if (Vector.class.isAssignableFrom(rawType)) {
|
||||
return (TypeAdapter<T>) new VectorTypeAdapter();
|
||||
} else if (ConfigurationSerializable.class.isAssignableFrom(rawType)) {
|
||||
// This covers a lot of Bukkit objects
|
||||
return (TypeAdapter<T>) new BukkitObjectTypeAdapter(gson.getAdapter(Map.class));
|
||||
|
@ -0,0 +1,40 @@
|
||||
package world.bentobox.bentobox.database.json.adapters;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
public class VectorTypeAdapter extends TypeAdapter<Vector> {
|
||||
|
||||
@Override
|
||||
public void write(JsonWriter out, Vector value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
out.beginArray();
|
||||
out.value(value.getX());
|
||||
out.value(value.getY());
|
||||
out.value(value.getZ());
|
||||
out.endArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
in.beginArray();
|
||||
double x = in.nextDouble();
|
||||
double y = in.nextDouble();
|
||||
double z = in.nextDouble();
|
||||
in.endArray();
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
}
|
@ -154,17 +154,15 @@ public class AddonsManager {
|
||||
*/
|
||||
private void enableAddon(Addon addon) {
|
||||
try {
|
||||
// If this is a GameModeAddon create the worlds, register it and load the schems
|
||||
// If this is a GameModeAddon create the worlds, register it and load the blueprints
|
||||
if (addon instanceof GameModeAddon) {
|
||||
GameModeAddon gameMode = (GameModeAddon) addon;
|
||||
// Create the gameWorlds
|
||||
gameMode.createWorlds();
|
||||
plugin.getIWM().addGameMode(gameMode);
|
||||
// Register the schems
|
||||
plugin.getSchemsManager().loadIslands(gameMode);
|
||||
|
||||
// Save and load blueprints
|
||||
plugin.getBlueprintsManager().extractDefaultBlueprints(gameMode);
|
||||
plugin.getBlueprintsManager().loadBlueprints(gameMode);
|
||||
plugin.getBlueprintsManager().loadBlueprintBundles(gameMode);
|
||||
}
|
||||
addon.onEnable();
|
||||
if (addon instanceof GameModeAddon) {
|
||||
|
@ -4,6 +4,8 @@ import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@ -12,92 +14,97 @@ import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.Clipboard;
|
||||
import world.bentobox.bentobox.blueprints.Paster;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.blueprints.Blueprint;
|
||||
import world.bentobox.bentobox.blueprints.BlueprintClipboard;
|
||||
import world.bentobox.bentobox.database.json.BentoboxTypeAdapterFactory;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class ClipboardManager {
|
||||
public class BlueprintClipboardManager {
|
||||
|
||||
private static final String LOAD_ERROR = "Could not load schems file - does not exist : ";
|
||||
private static final String LOAD_ERROR = "Could not load blueprint file - does not exist : ";
|
||||
|
||||
private static void unzipFiles(final ZipInputStream zipInputStream, final Path unzipFilePath) throws IOException {
|
||||
private File blueprintFolder;
|
||||
|
||||
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(unzipFilePath.toAbsolutePath().toString()))) {
|
||||
byte[] bytesIn = new byte[1024];
|
||||
int read;
|
||||
while ((read = zipInputStream.read(bytesIn)) != -1) {
|
||||
bos.write(bytesIn, 0, read);
|
||||
}
|
||||
}
|
||||
private BlueprintClipboard clipboard;
|
||||
|
||||
}
|
||||
private Gson gson;
|
||||
|
||||
private BentoBox plugin;
|
||||
|
||||
private File schemFolder;
|
||||
|
||||
private Clipboard clipboard;
|
||||
|
||||
public ClipboardManager(BentoBox plugin, File schemFolder) {
|
||||
this(plugin, schemFolder, null);
|
||||
public BlueprintClipboardManager(BentoBox plugin, File blueprintFolder) {
|
||||
this(plugin, blueprintFolder, null);
|
||||
}
|
||||
|
||||
public ClipboardManager(BentoBox plugin, File schemFolder, Clipboard clipboard) {
|
||||
public BlueprintClipboardManager(BentoBox plugin, File blueprintFolder, BlueprintClipboard clipboard) {
|
||||
super();
|
||||
this.plugin = plugin;
|
||||
if (!schemFolder.exists()) {
|
||||
schemFolder.mkdirs();
|
||||
if (!blueprintFolder.exists()) {
|
||||
blueprintFolder.mkdirs();
|
||||
}
|
||||
this.schemFolder = schemFolder;
|
||||
this.blueprintFolder = blueprintFolder;
|
||||
this.clipboard = clipboard;
|
||||
getGson();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the clipboard
|
||||
*/
|
||||
public Clipboard getClipboard() {
|
||||
public BlueprintClipboard getClipboard() {
|
||||
return clipboard;
|
||||
}
|
||||
|
||||
private void getGson() {
|
||||
GsonBuilder builder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().enableComplexMapKeySerialization();
|
||||
// Disable <>'s escaping etc.
|
||||
builder.disableHtmlEscaping();
|
||||
// Register adapter factory
|
||||
builder.registerTypeAdapterFactory(new BentoboxTypeAdapterFactory(plugin));
|
||||
gson = builder.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a file to clipboard
|
||||
* @param fileName - filename in schems folder
|
||||
* @param fileName - filename in blueprints folder
|
||||
* @throws IOException - if there's a load error with unziping or name
|
||||
* @throws InvalidConfigurationException - the YAML of the schem is at fault
|
||||
*/
|
||||
public void load(String fileName) throws IOException, InvalidConfigurationException {
|
||||
File zipFile = new File(schemFolder, fileName + ".schem");
|
||||
public void load(String fileName) throws IOException {
|
||||
clipboard = new BlueprintClipboard(loadBlueprint(fileName));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a blueprint
|
||||
* @param fileName - the filename without the suffix
|
||||
* @return the blueprint
|
||||
* @throws IOException
|
||||
*/
|
||||
public Blueprint loadBlueprint(String fileName) throws IOException {
|
||||
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.getAbsolutePath());
|
||||
File file = new File(schemFolder, fileName);
|
||||
File file = new File(blueprintFolder, fileName);
|
||||
if (!file.exists()) {
|
||||
plugin.logError(LOAD_ERROR + file.getName());
|
||||
throw new IOException(LOAD_ERROR + file.getName());
|
||||
throw new IOException(LOAD_ERROR + file.getName() + " temp file");
|
||||
}
|
||||
|
||||
YamlConfiguration blockConfig = new YamlConfiguration();
|
||||
blockConfig.load(file);
|
||||
clipboard = new Clipboard(blockConfig);
|
||||
Blueprint bp = gson.fromJson(new FileReader(file), Blueprint.class);
|
||||
Files.delete(file.toPath());
|
||||
return bp;
|
||||
}
|
||||
|
||||
/*
|
||||
Load a file to clipboard
|
||||
*/
|
||||
/**
|
||||
* Load a blueprint to the clipboard for a user
|
||||
* @param user - user trying to load
|
||||
* @param fileName - filename
|
||||
* @return - <tt>true</tt> if load is successful, <tt>false</tt> if not
|
||||
@ -106,66 +113,57 @@ public class ClipboardManager {
|
||||
try {
|
||||
load(fileName);
|
||||
} catch (IOException e1) {
|
||||
user.sendMessage("commands.admin.schem.could-not-load");
|
||||
plugin.logError("Could not load schems file: " + fileName + " " + e1.getMessage());
|
||||
return false;
|
||||
} catch (InvalidConfigurationException e1) {
|
||||
user.sendMessage("commands.admin.schem.could-not-load");
|
||||
plugin.logError("Could not load schems file - YAML error : " + fileName + " " + e1.getMessage());
|
||||
user.sendMessage("commands.admin.blueprint.could-not-load");
|
||||
plugin.logError("Could not load blueprint file: " + fileName + " " + e1.getMessage());
|
||||
return false;
|
||||
}
|
||||
user.sendMessage("general.success");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paste clipboard to this location
|
||||
* @param location - location
|
||||
*/
|
||||
public void pasteClipboard(Location location) {
|
||||
if (clipboard != null) {
|
||||
new Paster(plugin, clipboard, location);
|
||||
} else {
|
||||
plugin.logError("Clipboard has no block data in it to paste!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pastes the clipboard to island location.
|
||||
* If pos1 and pos2 are not set already, they are automatically set to the pasted coordinates
|
||||
* @param world - world in which to paste
|
||||
* @param island - location to paste
|
||||
* @param task - task to run after pasting
|
||||
*/
|
||||
public void pasteIsland(World world, Island island, Runnable task) {
|
||||
new Paster(plugin, clipboard, world, island, task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the clipboard to a file
|
||||
* @param user - user who is copying
|
||||
* @param newFile - filename
|
||||
* @param newName - new name of this blueprint
|
||||
* @return - true if successful, false if error
|
||||
*/
|
||||
public boolean save(User user, String newFile) {
|
||||
File file = new File(schemFolder, newFile);
|
||||
try {
|
||||
clipboard.getBlockConfig().save(file);
|
||||
public boolean save(User user, String newName) {
|
||||
clipboard.getBlueprint().setName(newName);
|
||||
if (saveBlueprint(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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a blueprint
|
||||
* @param blueprint - blueprint
|
||||
* @return true if successful, false if not
|
||||
*/
|
||||
public boolean saveBlueprint(Blueprint blueprint) {
|
||||
if (blueprint.getName().isEmpty()) {
|
||||
plugin.logError("Blueprint name was empty - could not save it");
|
||||
return false;
|
||||
}
|
||||
File file = new File(blueprintFolder, blueprint.getName());
|
||||
String toStore = gson.toJson(blueprint, Blueprint.class);
|
||||
try (FileWriter fileWriter = new FileWriter(file)) {
|
||||
fileWriter.write(toStore);
|
||||
} catch (IOException e) {
|
||||
user.sendMessage("commands.admin.schem.could-not-save", "[message]", "Could not save temp schems file.");
|
||||
plugin.logError("Could not save temporary schems file: " + file.getName());
|
||||
plugin.logError("Could not save temporary blueprint file: " + file.getName());
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
zip(file);
|
||||
} catch (IOException e) {
|
||||
user.sendMessage("commands.admin.schem.could-not-save", "[message]", "Could not zip temp schems file.");
|
||||
plugin.logError("Could not zip temporary schems file: " + file.getName());
|
||||
plugin.logError("Could not zip temporary blueprint file: " + file.getName());
|
||||
return false;
|
||||
}
|
||||
user.sendMessage("general.success");
|
||||
return true;
|
||||
}
|
||||
|
||||
private void unzip(final String zipFilePath) throws IOException {
|
||||
Path path = Paths.get(zipFilePath);
|
||||
if (!(path.toFile().exists())) {
|
||||
@ -187,8 +185,18 @@ public class ClipboardManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void unzipFiles(final ZipInputStream zipInputStream, final Path unzipFilePath) throws IOException {
|
||||
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(unzipFilePath.toAbsolutePath().toString()))) {
|
||||
byte[] bytesIn = new byte[1024];
|
||||
int read;
|
||||
while ((read = zipInputStream.read(bytesIn)) != -1) {
|
||||
bos.write(bytesIn, 0, read);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void zip(File targetFile) throws IOException {
|
||||
try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(targetFile.getAbsolutePath() + ".schem"))) {
|
||||
try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(targetFile.getAbsolutePath() + BlueprintsManager.BLUEPRINT_SUFFIX))) {
|
||||
zipOutputStream.putNextEntry(new ZipEntry(targetFile.getName()));
|
||||
try (FileInputStream inputStream = new FileInputStream(targetFile)) {
|
||||
final byte[] buffer = new byte[1024];
|
@ -1,43 +1,110 @@
|
||||
package world.bentobox.bentobox.managers;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||
import world.bentobox.bentobox.api.blueprints.Blueprint;
|
||||
import world.bentobox.bentobox.api.blueprints.BlueprintBundle;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.Arrays;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.InstanceCreator;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.addons.Addon;
|
||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
import world.bentobox.bentobox.api.panels.PanelItem;
|
||||
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
|
||||
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.Blueprint;
|
||||
import world.bentobox.bentobox.blueprints.BlueprintPaster;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle;
|
||||
import world.bentobox.bentobox.database.json.BentoboxTypeAdapterFactory;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.schems.SchemToBlueprint;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
/**
|
||||
* Handles {@link world.bentobox.bentobox.api.blueprints.Blueprint Blueprints}.
|
||||
* Handles Blueprints
|
||||
* @since 1.5.0
|
||||
* @author Poslovitch
|
||||
* @author Poslovitch, tastybento
|
||||
*/
|
||||
public class BlueprintsManager {
|
||||
|
||||
private static final String BLUEPRINT_BUNDLE_SUFFIX = ".json";
|
||||
public static final String BLUEPRINT_SUFFIX = ".blu";
|
||||
public static final String DEFAULT_BUNDLE_NAME = "default";
|
||||
|
||||
public static final @NonNull String FOLDER_NAME = "blueprints";
|
||||
|
||||
/**
|
||||
* Map of blueprint bundles to game mode addon.
|
||||
* Inner map's key is the uniqueId of the blueprint bundle so it's
|
||||
* easy to get from a UI
|
||||
*/
|
||||
private @NonNull Map<GameModeAddon, Map<String, BlueprintBundle>> blueprintBundles;
|
||||
|
||||
/**
|
||||
* Map of blueprints. There can be many blueprints per game mode addon
|
||||
* Inner map's key is the blueprint's name so it's easy to get from a UI
|
||||
*/
|
||||
private @NonNull Map<GameModeAddon, Map<String, Blueprint>> blueprints;
|
||||
|
||||
/**
|
||||
* Gson used for serializing/deserializing the bundle class
|
||||
*/
|
||||
private final Gson gson;
|
||||
|
||||
private @NonNull BentoBox plugin;
|
||||
|
||||
private @NonNull Map<GameModeAddon, List<Blueprint>> blueprints;
|
||||
private @NonNull Map<GameModeAddon, List<BlueprintBundle>> blueprintBundles;
|
||||
|
||||
public BlueprintsManager(@NonNull BentoBox plugin) {
|
||||
this.plugin = plugin;
|
||||
this.blueprints = new HashMap<>();
|
||||
this.blueprintBundles = new HashMap<>();
|
||||
this.blueprints = new HashMap<>();
|
||||
@SuppressWarnings("rawtypes")
|
||||
GsonBuilder builder = new GsonBuilder()
|
||||
.excludeFieldsWithoutExposeAnnotation()
|
||||
.enableComplexMapKeySerialization()
|
||||
.setPrettyPrinting()
|
||||
// This enables gson to deserialize enum maps
|
||||
.registerTypeAdapter(EnumMap.class, new InstanceCreator<EnumMap>() {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public EnumMap createInstance(Type type) {
|
||||
Type[] types = (((ParameterizedType) type).getActualTypeArguments());
|
||||
return new EnumMap((Class<?>) types[0]);
|
||||
}
|
||||
});
|
||||
// Disable <>'s escaping etc.
|
||||
builder.disableHtmlEscaping();
|
||||
// Register adapter factory
|
||||
builder.registerTypeAdapterFactory(new BentoboxTypeAdapterFactory(plugin));
|
||||
gson = builder.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the blueprints provided by this {@link GameModeAddon} in its .jar file.
|
||||
* Extracts the blueprints and bundles provided by this {@link GameModeAddon} in its .jar file.
|
||||
* This will do nothing if the blueprints folder already exists for this GameModeAddon.
|
||||
* @param addon the {@link GameModeAddon} to extract the blueprints from.
|
||||
*/
|
||||
@ -54,61 +121,21 @@ public class BlueprintsManager {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get any blueprints from the jar and save them.
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the blueprints of this addon from its blueprints folder.
|
||||
* @param addon the {@link GameModeAddon} to load the blueprints of.
|
||||
*/
|
||||
public void loadBlueprints(@NonNull GameModeAddon addon) {
|
||||
File folder = getBlueprintsFolder(addon);
|
||||
// Create the empty list if not already there
|
||||
blueprints.putIfAbsent(addon, new LinkedList<>());
|
||||
// Look through the folder
|
||||
FilenameFilter filter = (dir, name) -> name.toLowerCase().endsWith("." + Blueprint.FILE_EXTENSION);
|
||||
Arrays.stream(Objects.requireNonNull(folder.list(filter))).map(name -> name.split("\\.")[0]).forEach(name -> loadBlueprint(addon, name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the blueprint of this addon corresponding to this name.
|
||||
* @param addon the {@link GameModeAddon} to load the blueprint from.
|
||||
* @param name the name of the blueprint to load, without the file extension.
|
||||
* E.g: {@code "island"}.
|
||||
*/
|
||||
public void loadBlueprint(@NonNull GameModeAddon addon, @NonNull String name) {
|
||||
File folder = getBlueprintsFolder(addon);
|
||||
// Create the empty list if not already there
|
||||
blueprints.putIfAbsent(addon, new LinkedList<>());
|
||||
// Load the blueprint
|
||||
plugin.log("Loading " + name + ".blueprint for " + addon.getDescription().getName());
|
||||
try {
|
||||
Blueprint blueprint = new Blueprint(name, new ZipFile(new File(folder, name + "." + Blueprint.FILE_EXTENSION)));
|
||||
blueprints.get(addon).add(blueprint);
|
||||
} catch (Exception e) {
|
||||
// TODO: add error debug
|
||||
// Get any blueprints or bundles from the jar and save them.
|
||||
try (JarFile jar = new JarFile(addon.getFile())) {
|
||||
Util.listJarFiles(jar, FOLDER_NAME, BLUEPRINT_BUNDLE_SUFFIX).forEach(name -> addon.saveResource(name, false));
|
||||
Util.listJarFiles(jar, FOLDER_NAME, BLUEPRINT_SUFFIX).forEach(name -> addon.saveResource(name, false));
|
||||
} catch (IOException e) {
|
||||
plugin.logError("Could not load blueprint files from addon jar " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Map<GameModeAddon, List<Blueprint>> getBlueprints() {
|
||||
return blueprints;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public List<Blueprint> getBlueprints(@NonNull GameModeAddon addon) {
|
||||
return blueprints.getOrDefault(addon, new LinkedList<>());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Map<GameModeAddon, List<BlueprintBundle>> getBlueprintBundles() {
|
||||
return blueprintBundles;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public List<BlueprintBundle> getBlueprintBundles(@NonNull GameModeAddon addon) {
|
||||
return blueprintBundles.getOrDefault(addon, new LinkedList<>());
|
||||
/**
|
||||
* Get the blueprint bundles of this addon.
|
||||
* @param addon the {@link GameModeAddon} to get the blueprint bundles.
|
||||
*/
|
||||
public Map<String, BlueprintBundle> getBlueprintBundles(@NonNull GameModeAddon addon) {
|
||||
return blueprintBundles.getOrDefault(addon, new HashMap<>());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -117,7 +144,278 @@ public class BlueprintsManager {
|
||||
* @return a {@link File} instance of the blueprints folder of this GameModeAddon.
|
||||
*/
|
||||
@NonNull
|
||||
public File getBlueprintsFolder(@NonNull GameModeAddon addon) {
|
||||
private File getBlueprintsFolder(@NonNull GameModeAddon addon) {
|
||||
return new File(addon.getDataFolder(), FOLDER_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the blueprint bundles of this addon from its blueprints folder.
|
||||
* @param addon the {@link GameModeAddon} to load the blueprints of.
|
||||
*/
|
||||
public void loadBlueprintBundles(@NonNull GameModeAddon addon) {
|
||||
blueprintBundles.put(addon, new HashMap<>());
|
||||
|
||||
// See if there are any schems that need converting
|
||||
new SchemToBlueprint(plugin).convertSchems(addon);
|
||||
|
||||
if (!loadBundles(addon)) {
|
||||
makeDefaults(addon);
|
||||
loadBundles(addon);
|
||||
}
|
||||
// Load blueprints
|
||||
loadBlueprints(addon);
|
||||
}
|
||||
|
||||
private boolean loadBundles(@NonNull GameModeAddon addon) {
|
||||
File bpf = getBlueprintsFolder(addon);
|
||||
boolean loaded = false;
|
||||
for (File file: Objects.requireNonNull(bpf.listFiles((dir, name) -> name.toLowerCase(Locale.ENGLISH).endsWith(BLUEPRINT_BUNDLE_SUFFIX)))) {
|
||||
try {
|
||||
BlueprintBundle bb = gson.fromJson(new FileReader(file), BlueprintBundle.class);
|
||||
blueprintBundles.get(addon).put(bb.getUniqueId(), bb);
|
||||
plugin.log("Loaded Blueprint Bundle '" + bb.getUniqueId() + "' for " + addon.getDescription().getName());
|
||||
loaded = true;
|
||||
} catch (Exception e) {
|
||||
plugin.logError("Could not load blueprint bundle " + file.getName() + " " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* This should never be needed and is just a boot strap
|
||||
* @param addon
|
||||
*/
|
||||
private void makeDefaults(@NonNull GameModeAddon addon) {
|
||||
plugin.logError("No blueprint bundles found! Creating a default one.");
|
||||
BlueprintBundle bb = new BlueprintBundle();
|
||||
bb.setIcon(Material.PAPER);
|
||||
bb.setUniqueId(DEFAULT_BUNDLE_NAME);
|
||||
bb.setDisplayName("Default bundle");
|
||||
bb.setDescription(Collections.singletonList(ChatColor.AQUA + "Default bundle of blueprints"));
|
||||
// Default blueprints
|
||||
Blueprint defaultBp = new Blueprint();
|
||||
defaultBp.setName("bedrock");
|
||||
defaultBp.setDescription(Collections.singletonList(ChatColor.AQUA + "A bedrock block"));
|
||||
defaultBp.setBedrock(new Vector(0,0,0));
|
||||
Map<Vector, BlueprintBlock> map = new HashMap<>();
|
||||
map.put(new Vector(0,0,0), new BlueprintBlock("minecraft:bedrock"));
|
||||
defaultBp.setBlocks(map);
|
||||
// Save a default "bedrock" blueprint
|
||||
new BlueprintClipboardManager(plugin, getBlueprintsFolder(addon)).saveBlueprint(defaultBp);
|
||||
// This blueprint is used for all environments
|
||||
bb.setBlueprint(World.Environment.NORMAL, defaultBp);
|
||||
bb.setBlueprint(World.Environment.NETHER, defaultBp);
|
||||
bb.setBlueprint(World.Environment.THE_END, defaultBp);
|
||||
blueprintBundles.get(addon).put(DEFAULT_BUNDLE_NAME, bb);
|
||||
this.saveBlueprintBundles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all the blueprints of this addon from its blueprints folder.
|
||||
* @param addon the {@link GameModeAddon} to load the blueprints of.
|
||||
*/
|
||||
public void loadBlueprints(@NonNull GameModeAddon addon) {
|
||||
blueprints.put(addon, new HashMap<>());
|
||||
File bpf = getBlueprintsFolder(addon);
|
||||
for (File file: Objects.requireNonNull(bpf.listFiles((dir, name) -> name.toLowerCase(Locale.ENGLISH).endsWith(BLUEPRINT_SUFFIX)))) {
|
||||
String fileName = file.getName().substring(0, file.getName().length() - BLUEPRINT_SUFFIX.length());
|
||||
try {
|
||||
Blueprint bp = new BlueprintClipboardManager(plugin, bpf).loadBlueprint(fileName);
|
||||
blueprints.get(addon).put(bp.getName(), bp);
|
||||
plugin.log("Loaded blueprint '" + bp.getName() + "' for " + addon.getDescription().getName());
|
||||
} catch (Exception e) {
|
||||
plugin.logError("Could not load blueprint " + fileName + " " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a blueprint to addon's list of blueprints
|
||||
* @param addon - the {@link GameModeAddon}
|
||||
* @param bp - blueprint
|
||||
*/
|
||||
public void addBlueprint(@NonNull GameModeAddon addon, @NonNull Blueprint bp) {
|
||||
blueprints.putIfAbsent(addon, new HashMap<>());
|
||||
blueprints.get(addon).put(bp.getName(), bp);
|
||||
plugin.log("Added blueprint '" + bp.getName() + "' for " + addon.getDescription().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a blueprint into addon's blueprint folder
|
||||
* @param addon - the {@link GameModeAddon}
|
||||
* @param bp - blueprint to save
|
||||
*/
|
||||
public boolean saveBlueprint(@NonNull GameModeAddon addon, @NonNull Blueprint bp) {
|
||||
return new BlueprintClipboardManager(plugin, getBlueprintsFolder(addon)).saveBlueprint(bp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save blueprint bundles for game mode
|
||||
* @param addon - gamemode addon
|
||||
* @param bundleList - list of bundles
|
||||
*/
|
||||
public void saveBlueprintBundle(GameModeAddon addon, BlueprintBundle bb) {
|
||||
File bpf = getBlueprintsFolder(addon);
|
||||
File fileName = new File(bpf, bb.getUniqueId() + BLUEPRINT_BUNDLE_SUFFIX);
|
||||
String toStore = gson.toJson(bb, BlueprintBundle.class);
|
||||
try (FileWriter fileWriter = new FileWriter(fileName)) {
|
||||
fileWriter.write(toStore);
|
||||
} catch (IOException e) {
|
||||
plugin.logError("Could not save blueprint bundle file: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves all the blueprint bundles
|
||||
*/
|
||||
public void saveBlueprintBundles() {
|
||||
blueprintBundles.forEach((k,v) -> v.values().forEach(m -> saveBlueprintBundle(k, m)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the bundles for this addon
|
||||
* @param addon - {@link GameModeAddon}
|
||||
* @param map - map of bundles, key is the bundle unique id, value is the bundle
|
||||
*/
|
||||
public void setBlueprintBundles(@NonNull GameModeAddon addon, Map<String, BlueprintBundle> map) {
|
||||
blueprintBundles.put(addon, map);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the blueprints
|
||||
*/
|
||||
public Map<GameModeAddon, Map<String, Blueprint>> getBlueprints() {
|
||||
return blueprints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paste the islands to world
|
||||
* @param addon - GameModeAddon
|
||||
* @param island - island
|
||||
* @param name - bundle name
|
||||
*/
|
||||
public void paste(GameModeAddon addon, Island island, String name) {
|
||||
paste(addon, island, name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paste islands to the world and run task afterwards
|
||||
* @param addon - the game mode addon
|
||||
* @param island - the island
|
||||
* @param name - name of bundle to paste
|
||||
* @param task - task to run after pasting is completed
|
||||
* @return true if okay, false is there is a problem
|
||||
*/
|
||||
public boolean paste(GameModeAddon addon, Island island, String name, Runnable task) {
|
||||
if (validate(addon, name) == null) {
|
||||
plugin.logError("Tried to paste '" + name + "' but the bundle is not loaded!");
|
||||
return false;
|
||||
}
|
||||
BlueprintBundle bb = blueprintBundles.get(addon).get(name.toLowerCase(Locale.ENGLISH));
|
||||
if (!blueprints.containsKey(addon) || blueprints.get(addon).isEmpty()) {
|
||||
plugin.logError("No blueprints loaded for bundle '" + name + "'!");
|
||||
return false;
|
||||
}
|
||||
Blueprint bp = blueprints.get(addon).get(bb.getBlueprint(World.Environment.NORMAL));
|
||||
// Paste overworld
|
||||
new BlueprintPaster(plugin, bp, addon.getOverWorld(), island, task);
|
||||
// Make nether island
|
||||
if (bb.getBlueprint(World.Environment.NETHER) != null
|
||||
&& addon.getWorldSettings().isNetherGenerate()
|
||||
&& addon.getWorldSettings().isNetherIslands()
|
||||
&& addon.getNetherWorld() != null) {
|
||||
bp = blueprints.get(addon).get(bb.getBlueprint(World.Environment.NETHER));
|
||||
new BlueprintPaster(plugin, bp, addon.getNetherWorld(), island, null);
|
||||
}
|
||||
// Make end island
|
||||
if (bb.getBlueprint(World.Environment.THE_END) != null
|
||||
&& addon.getWorldSettings().isEndGenerate()
|
||||
&& addon.getWorldSettings().isEndIslands()
|
||||
&& addon.getEndWorld() != null) {
|
||||
bp = blueprints.get(addon).get(bb.getBlueprint(World.Environment.THE_END));
|
||||
new BlueprintPaster(plugin, bp, addon.getEndWorld(), island, null);
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate if the bundle name is valid or not
|
||||
* @param addon - game mode addon
|
||||
* @param name - bundle name
|
||||
* @return bundle name or null if it's invalid
|
||||
*/
|
||||
public @Nullable String validate(GameModeAddon addon, String name) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
if (blueprintBundles.containsKey(addon) && blueprintBundles.get(addon).containsKey(name.toLowerCase(Locale.ENGLISH))) {
|
||||
return name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a blueprint bundle
|
||||
* @param addon - the game mode addon
|
||||
* @param bb - the blueprint bundle
|
||||
*/
|
||||
public void addBlueprintBundle(GameModeAddon addon, BlueprintBundle bb) {
|
||||
blueprintBundles.computeIfAbsent(addon, k -> new HashMap<>()).put(bb.getUniqueId(), bb);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a player a panel of selectable blueprint bundles. Checks user's permission
|
||||
* @param command - the command requesting the panel, e.g., create or reset
|
||||
* @param user - the user
|
||||
* @param label - label
|
||||
*/
|
||||
public void showPanel(CompositeCommand command, User user, String label) {
|
||||
// Create the panel
|
||||
PanelBuilder pb = new PanelBuilder().name(user.getTranslation("commands.island.create.pick")).user(user);
|
||||
// Get the bundles
|
||||
Collection<BlueprintBundle> bbs = getBlueprintBundles((@NonNull GameModeAddon) command.getAddon()).values();
|
||||
// Loop through them and create items in the panel
|
||||
for (BlueprintBundle bb : bbs) {
|
||||
String perm = command.getPermissionPrefix() + "island.create." + bb.getUniqueId();
|
||||
if (!bb.getUniqueId().equals(BlueprintsManager.DEFAULT_BUNDLE_NAME)
|
||||
&& bb.isRequirePermission()
|
||||
&& !user.hasPermission(perm)) {
|
||||
// Skip bundles that the user has no permission for
|
||||
continue;
|
||||
}
|
||||
PanelItem pi = new PanelItemBuilder().name(bb.getDisplayName()).description(bb.getDescription())
|
||||
.icon(bb.getIcon()).name(bb.getUniqueId()).clickHandler((panel, user1, clickType, slot1) -> {
|
||||
user1.closeInventory();
|
||||
command.execute(user1, label, Collections.singletonList(bb.getUniqueId()));
|
||||
return true;
|
||||
}).build();
|
||||
pb.item(pi);
|
||||
}
|
||||
pb.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player has permission to see or use this blueprint bundle.
|
||||
* @param addon - addon making the request
|
||||
* @param user - user making the request
|
||||
* @param name - name of the blueprint bundle
|
||||
* @return <tt>true</tt> if allowed
|
||||
*/
|
||||
public boolean checkPerm(Addon addon, User user, String name) {
|
||||
// Permission
|
||||
String permission = addon.getPermissionPrefix() + "island.create." + name;
|
||||
// Get Blueprint bundle
|
||||
BlueprintBundle bb = getBlueprintBundles((GameModeAddon)addon).get(name.toLowerCase(Locale.ENGLISH));
|
||||
if (bb == null || (bb.isRequirePermission() && !name.equals(DEFAULT_BUNDLE_NAME) && !user.hasPermission(permission))) {
|
||||
user.sendMessage("general.errors.no-permission", TextVariables.PERMISSION, permission);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ public class IslandsManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an island with owner. Note this does not create the schematic. It just creates the island data object.
|
||||
* Create an island with owner. Note this does not paste blocks. It just creates the island data object.
|
||||
* @param location the location, not null
|
||||
* @param owner the island owner UUID, may be null
|
||||
* @return Island or null if the island could not be created for some reason
|
||||
|
@ -1,179 +0,0 @@
|
||||
package world.bentobox.bentobox.managers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.addons.Addon;
|
||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||
import world.bentobox.bentobox.blueprints.Clipboard;
|
||||
import world.bentobox.bentobox.blueprints.Paster;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
public class SchemsManager {
|
||||
|
||||
/**
|
||||
* Name of the schem that is expected to be the default one.
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public static final @NonNull String DEFAULT_SCHEM_NAME = "island";
|
||||
|
||||
/**
|
||||
* File extension of the schems file.
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public static final @NonNull String FILE_EXTENSION = ".schem";
|
||||
|
||||
/**
|
||||
* Name of the folder containing schems.
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public static final @NonNull String FOLDER_NAME = "schems";
|
||||
|
||||
private BentoBox plugin;
|
||||
private Map<World, Map<String, Clipboard>> islandSchems;
|
||||
|
||||
/**
|
||||
* @param plugin - plugin
|
||||
*/
|
||||
public SchemsManager(BentoBox plugin) {
|
||||
this.plugin = plugin;
|
||||
islandSchems = new HashMap<>();
|
||||
}
|
||||
|
||||
private void copySchems(Addon addon, File folder) {
|
||||
if (folder.exists()) {
|
||||
// If the folder exists, do not copy anything from the jar
|
||||
return;
|
||||
}
|
||||
if (!folder.exists() && !folder.mkdirs()) {
|
||||
plugin.logError("Could not make '" + FOLDER_NAME + "' folder!");
|
||||
return;
|
||||
}
|
||||
// Save any schems that are in the jar
|
||||
try (JarFile jar = new JarFile(addon.getFile())) {
|
||||
Util.listJarFiles(jar, FOLDER_NAME, FILE_EXTENSION).forEach(name -> addon.saveResource(name, false));
|
||||
} catch (IOException e) {
|
||||
plugin.logError("Could not load schem files from addon jar " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the blueprints for this world
|
||||
* @param world world
|
||||
* @return map of blueprints for this world or an empty map if there are none registered
|
||||
*/
|
||||
public Map<String, Clipboard> get(World world) {
|
||||
return islandSchems.getOrDefault(world, new TreeMap<>(String.CASE_INSENSITIVE_ORDER));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load schems for addon. Will try and load nether and end schems too if settings are set.
|
||||
* @param addon - GameModeAddon
|
||||
*/
|
||||
public void loadIslands(GameModeAddon addon) {
|
||||
File schems = new File(addon.getDataFolder(), FOLDER_NAME);
|
||||
// Copy any schems fould in the jar
|
||||
copySchems(addon, schems);
|
||||
// Load all schems in folder
|
||||
// Look through the folder
|
||||
FilenameFilter schemFilter = (File dir, String name) -> name.toLowerCase(java.util.Locale.ENGLISH).endsWith(FILE_EXTENSION)
|
||||
&& !name.toLowerCase(java.util.Locale.ENGLISH).startsWith("nether-")
|
||||
&& !name.toLowerCase(java.util.Locale.ENGLISH).startsWith("end-");
|
||||
Arrays.stream(Objects.requireNonNull(schems.list(schemFilter))).map(name -> name.substring(0, name.length() - 6)).forEach(name -> importSchem(addon, schems, name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports one schem to the game mode
|
||||
* @param addon
|
||||
* @param schems
|
||||
* @param name
|
||||
*/
|
||||
private void importSchem(GameModeAddon addon, File schems, String name) {
|
||||
if (!plugin.getSchemsManager().loadSchem(addon.getOverWorld(), schems, name)) {
|
||||
plugin.logError("Could not load " + name + ".schem for " + addon.getWorldSettings().getFriendlyName());
|
||||
}
|
||||
if (addon.getWorldSettings().isNetherGenerate() && addon.getWorldSettings().isNetherIslands()
|
||||
&& !plugin.getSchemsManager().loadSchem(addon.getNetherWorld(), schems, "nether-" + name)) {
|
||||
plugin.logError("Could not load nether-" + name + ".schem for " + addon.getWorldSettings().getFriendlyName());
|
||||
}
|
||||
if (addon.getWorldSettings().isEndGenerate() && addon.getWorldSettings().isEndIslands()
|
||||
&& !plugin.getSchemsManager().loadSchem(addon.getEndWorld(), schems, "end-" + name)) {
|
||||
plugin.logError("Could not load end-" + name + ".schem for " + addon.getWorldSettings().getFriendlyName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean loadSchem(World world, File schems, String name) {
|
||||
plugin.log("Loading " + name + ".schem for " + world.getName());
|
||||
Map<String, Clipboard> schemList = islandSchems.getOrDefault(world, new TreeMap<>(String.CASE_INSENSITIVE_ORDER));
|
||||
try {
|
||||
ClipboardManager cb = new ClipboardManager(plugin, schems);
|
||||
cb.load(name);
|
||||
schemList.put(name, cb.getClipboard());
|
||||
islandSchems.put(world, schemList);
|
||||
} catch (IOException | InvalidConfigurationException e) {
|
||||
plugin.logError("Could not load " + name + " schem, skipping!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paste the schem to world for island
|
||||
* @param world - world
|
||||
* @param island - island
|
||||
* @param name - file name of schematic (without the .schem suffix)
|
||||
*/
|
||||
public void paste(World world, Island island, String name) {
|
||||
paste(world, island, name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paste the schem for world to the island center location and run task afterwards
|
||||
* @param world - world to paste to
|
||||
* @param island - the island who owns this schem
|
||||
* @param name - file name of schematic (without the .schem suffix)
|
||||
* @param task - task to run after pasting is completed
|
||||
*/
|
||||
public void paste(World world, Island island, String name, Runnable task) {
|
||||
if (islandSchems.containsKey(world) && islandSchems.get(world).containsKey(name)) {
|
||||
new Paster(plugin, islandSchems.get(world).get(name), world, island, task);
|
||||
} else {
|
||||
plugin.logError("Tried to paste schem '" + name + "' for " + world.getName() + " but the schem is not loaded!");
|
||||
plugin.log("This might be due to an invalid schem format. Keep in mind that schems are not schematics.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a schem is valid for this game mode or not
|
||||
* @param world - the world to check
|
||||
* @param name - name of schem (not including .schem)
|
||||
* @return name if valid, <tt>null</tt> if not
|
||||
*/
|
||||
public @Nullable String validate(World world, String name) {
|
||||
Set<String> validNames = get(world).keySet();
|
||||
if (!name.equals(SchemsManager.DEFAULT_SCHEM_NAME) && !validNames.contains(name)) {
|
||||
// See if it has not been loaded yet
|
||||
|
||||
return null;
|
||||
}
|
||||
return name;
|
||||
|
||||
}
|
||||
}
|
@ -14,11 +14,13 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import world.bentobox.bentobox.BStats;
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||
import world.bentobox.bentobox.api.events.IslandBaseEvent;
|
||||
import world.bentobox.bentobox.api.events.island.IslandEvent;
|
||||
import world.bentobox.bentobox.api.events.island.IslandEvent.Reason;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.managers.BlueprintsManager;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
/**
|
||||
@ -35,6 +37,7 @@ public class NewIsland {
|
||||
private final World world;
|
||||
private final String name;
|
||||
private final boolean noPaste;
|
||||
private GameModeAddon addon;
|
||||
|
||||
private enum Result {
|
||||
ISLAND_FOUND,
|
||||
@ -43,15 +46,15 @@ public class NewIsland {
|
||||
FREE
|
||||
}
|
||||
|
||||
private NewIsland(Island oldIsland, User user, Reason reason, World world, String name, boolean noPaste) {
|
||||
super();
|
||||
public NewIsland(Builder builder) {
|
||||
plugin = BentoBox.getInstance();
|
||||
this.user = user;
|
||||
this.reason = reason;
|
||||
this.world = world;
|
||||
this.name = name;
|
||||
this.noPaste = noPaste;
|
||||
newIsland(oldIsland);
|
||||
this.user = builder.user2;
|
||||
this.reason = builder.reason2;
|
||||
this.world = builder.world2;
|
||||
this.name = builder.name2;
|
||||
this.noPaste = builder.noPaste2;
|
||||
this.addon = builder.addon2;
|
||||
newIsland(builder.oldIsland2);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,8 +81,9 @@ public class NewIsland {
|
||||
private User user2;
|
||||
private Reason reason2;
|
||||
private World world2;
|
||||
private String name2 = "island";
|
||||
private String name2 = BlueprintsManager.DEFAULT_BUNDLE_NAME;
|
||||
private boolean noPaste2;
|
||||
private GameModeAddon addon2;
|
||||
|
||||
public Builder oldIsland(Island oldIsland) {
|
||||
this.oldIsland2 = oldIsland;
|
||||
@ -98,13 +102,28 @@ public class NewIsland {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param world
|
||||
* @deprecated use {@link #addon} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public Builder world(World world) {
|
||||
this.world2 = world;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* No schematics will be pasted
|
||||
* Set the addon
|
||||
* @param addon a game mode addon
|
||||
*/
|
||||
public Builder addon(GameModeAddon addon) {
|
||||
this.addon2 = addon;
|
||||
this.world2 = addon.getOverWorld();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* No blocks will be pasted
|
||||
*/
|
||||
public Builder noPaste() {
|
||||
this.noPaste2 = true;
|
||||
@ -112,7 +131,7 @@ public class NewIsland {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name - filename of schematic
|
||||
* @param name - name of Blueprint bundle
|
||||
*/
|
||||
public Builder name(String name) {
|
||||
this.name2 = name;
|
||||
@ -125,10 +144,10 @@ public class NewIsland {
|
||||
*/
|
||||
public Island build() throws IOException {
|
||||
if (user2 != null) {
|
||||
NewIsland newIsland = new NewIsland(oldIsland2, user2, reason2, world2, name2, noPaste2);
|
||||
NewIsland newIsland = new NewIsland(this);
|
||||
return newIsland.getIsland();
|
||||
}
|
||||
throw new IOException("Insufficient parameters. Must have a schematic and a player");
|
||||
throw new IOException("Insufficient parameters. Must have a user!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,17 +232,8 @@ public class NewIsland {
|
||||
if (noPaste) {
|
||||
Bukkit.getScheduler().runTask(plugin, task);
|
||||
} else {
|
||||
// Create island
|
||||
plugin.getSchemsManager().paste(world, island, name, task);
|
||||
// Make nether island
|
||||
if (plugin.getIWM().isNetherGenerate(world) && plugin.getIWM().isNetherIslands(world) && plugin.getIWM().getNetherWorld(world) != null) {
|
||||
plugin.getSchemsManager().paste(plugin.getIWM().getNetherWorld(world), island, "nether-" + name);
|
||||
}
|
||||
|
||||
// Make end island
|
||||
if (plugin.getIWM().isEndGenerate(world) && plugin.getIWM().isEndIslands(world) && plugin.getIWM().getEndWorld(world) != null) {
|
||||
plugin.getSchemsManager().paste(plugin.getIWM().getEndWorld(world), island, "end-" + name);
|
||||
}
|
||||
// Create islands
|
||||
plugin.getBlueprintsManager().paste(addon, island, name, task);
|
||||
}
|
||||
// Set default settings
|
||||
island.setFlagsDefaults();
|
||||
|
@ -0,0 +1,27 @@
|
||||
package world.bentobox.bentobox.panels;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
|
||||
/**
|
||||
* @author tastybento, Poslovitch
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class BlueprintManagementPanel {
|
||||
|
||||
private static final String LOCALE_REF = "blueprint-management";
|
||||
|
||||
private BlueprintManagementPanel() {}
|
||||
|
||||
public static void openPanel(@NonNull User user, @NonNull GameModeAddon addon) {
|
||||
PanelBuilder builder = new PanelBuilder()
|
||||
.name(user.getTranslation(LOCALE_REF + "title"))
|
||||
.size(54);
|
||||
|
||||
|
||||
|
||||
builder.build().open(user);
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package world.bentobox.bentobox.panels;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
|
||||
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle;
|
||||
|
||||
/**
|
||||
* Displays the available BlueprintBundles to pick up as the island.
|
||||
* @author Poslovitch, tastybento
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class IslandCreationPanel {
|
||||
|
||||
private static final String LOCALE_REF = "island-creation.";
|
||||
|
||||
private IslandCreationPanel() {}
|
||||
|
||||
/**
|
||||
* Shows the island creation panel for this Gamemode to this User.
|
||||
* @param user the User to show the panel to.
|
||||
* @param addon the addon to display the blueprint bundles from.
|
||||
*/
|
||||
public static void openPanel(@NonNull User user, @NonNull GameModeAddon addon) {
|
||||
BentoBox plugin = BentoBox.getInstance();
|
||||
PanelBuilder builder = new PanelBuilder()
|
||||
.name(user.getTranslation(LOCALE_REF + "title"));
|
||||
|
||||
plugin.getBlueprintsManager().getBlueprintBundles(addon).forEach((id, bundle) -> {
|
||||
PanelItemBuilder itemBuilder = new PanelItemBuilder()
|
||||
.icon(bundle.getIcon())
|
||||
.name(bundle.getDisplayName())
|
||||
.description(bundle.getDescription())
|
||||
.clickHandler((panel, user1, clickType, slot) -> {
|
||||
user1.closeInventory();
|
||||
// TODO create the island;
|
||||
return true;
|
||||
});
|
||||
|
||||
builder.item(itemBuilder.build());
|
||||
});
|
||||
|
||||
builder.build().open(user);
|
||||
}
|
||||
}
|
@ -50,74 +50,74 @@ public class ManagementPanel {
|
||||
int i = 0;
|
||||
List<? extends Addon> addons;
|
||||
switch (view) {
|
||||
case GAMEMODES:
|
||||
addons = plugin.getAddonsManager().getGameModeAddons();
|
||||
if (addons.isEmpty()) {
|
||||
looksEmpty(builder, user);
|
||||
break;
|
||||
}
|
||||
for (Addon addon : addons) {
|
||||
GameModeAddon gameModeAddon = (GameModeAddon) addon;
|
||||
PanelItem addonItem = new PanelItemBuilder()
|
||||
.icon(addon.getDescription().getIcon())
|
||||
.name(user.getTranslation(LOCALE_REF + "views.gamemodes.gamemode.name", TextVariables.NAME, addon.getDescription().getName()))
|
||||
.description(user.getTranslation(LOCALE_REF + "views.gamemodes.gamemode.description",
|
||||
"[islands]", String.valueOf(addon.getIslands().getIslandCount(gameModeAddon.getOverWorld()))))
|
||||
.build();
|
||||
|
||||
builder.item(startSlot + i, addonItem);
|
||||
|
||||
PanelItem schems = new PanelItemBuilder()
|
||||
.icon(Material.STRUCTURE_BLOCK)
|
||||
.name(user.getTranslation(LOCALE_REF + "views.gamemodes.schems.name"))
|
||||
.description(user.getTranslation(LOCALE_REF + "views.gamemodes.schems.description"))
|
||||
.clickHandler((panel, user1, clickType, slot) -> {
|
||||
user1.sendRawMessage("opening the admin schems menu (not implemented yet)");
|
||||
return true;
|
||||
})
|
||||
.build();
|
||||
|
||||
builder.item(startSlot + i + 9, schems);
|
||||
i++;
|
||||
}
|
||||
case GAMEMODES:
|
||||
addons = plugin.getAddonsManager().getGameModeAddons();
|
||||
if (addons.isEmpty()) {
|
||||
looksEmpty(builder, user);
|
||||
break;
|
||||
case ADDONS:
|
||||
addons = plugin.getAddonsManager().getEnabledAddons().stream().filter(addon -> !(addon instanceof GameModeAddon)).collect(Collectors.toList());
|
||||
if (addons.isEmpty()) {
|
||||
looksEmpty(builder, user);
|
||||
break;
|
||||
}
|
||||
for (Addon addon : addons) {
|
||||
PanelItem addonItem = new PanelItemBuilder()
|
||||
.icon(addon.getDescription().getIcon())
|
||||
.name(ChatColor.WHITE + addon.getDescription().getName())
|
||||
.build();
|
||||
}
|
||||
for (Addon addon : addons) {
|
||||
GameModeAddon gameModeAddon = (GameModeAddon) addon;
|
||||
PanelItem addonItem = new PanelItemBuilder()
|
||||
.icon(addon.getDescription().getIcon())
|
||||
.name(user.getTranslation(LOCALE_REF + "views.gamemodes.gamemode.name", TextVariables.NAME, addon.getDescription().getName()))
|
||||
.description(user.getTranslation(LOCALE_REF + "views.gamemodes.gamemode.description",
|
||||
"[islands]", String.valueOf(addon.getIslands().getIslandCount(gameModeAddon.getOverWorld()))))
|
||||
.build();
|
||||
|
||||
builder.item(startSlot + i, addonItem);
|
||||
i++;
|
||||
if (builder.slotOccupied(startSlot + i)) {
|
||||
i = i+2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HOOKS:
|
||||
if (plugin.getHooks().getHooks().isEmpty()) {
|
||||
looksEmpty(builder, user);
|
||||
break;
|
||||
}
|
||||
for (Hook hook : plugin.getHooks().getHooks()) {
|
||||
PanelItem hookItem = new PanelItemBuilder()
|
||||
.icon(hook.getIcon())
|
||||
.name(ChatColor.WHITE + hook.getPluginName())
|
||||
.build();
|
||||
builder.item(startSlot + i, addonItem);
|
||||
|
||||
builder.item(startSlot + i, hookItem);
|
||||
i++;
|
||||
if (builder.slotOccupied(startSlot + i)) {
|
||||
i = i+2;
|
||||
}
|
||||
}
|
||||
PanelItem blueprints = new PanelItemBuilder()
|
||||
.icon(Material.STRUCTURE_BLOCK)
|
||||
.name(user.getTranslation(LOCALE_REF + "views.gamemodes.blueprints.name"))
|
||||
.description(user.getTranslation(LOCALE_REF + "views.gamemodes.blueprints.description"))
|
||||
.clickHandler((panel, user1, clickType, slot) -> {
|
||||
BlueprintManagementPanel.openPanel(user, gameModeAddon);
|
||||
return true;
|
||||
})
|
||||
.build();
|
||||
|
||||
builder.item(startSlot + i + 9, blueprints);
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
case ADDONS:
|
||||
addons = plugin.getAddonsManager().getEnabledAddons().stream().filter(addon -> !(addon instanceof GameModeAddon)).collect(Collectors.toList());
|
||||
if (addons.isEmpty()) {
|
||||
looksEmpty(builder, user);
|
||||
break;
|
||||
}
|
||||
for (Addon addon : addons) {
|
||||
PanelItem addonItem = new PanelItemBuilder()
|
||||
.icon(addon.getDescription().getIcon())
|
||||
.name(ChatColor.WHITE + addon.getDescription().getName())
|
||||
.build();
|
||||
|
||||
builder.item(startSlot + i, addonItem);
|
||||
i++;
|
||||
if (builder.slotOccupied(startSlot + i)) {
|
||||
i = i+2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HOOKS:
|
||||
if (plugin.getHooks().getHooks().isEmpty()) {
|
||||
looksEmpty(builder, user);
|
||||
break;
|
||||
}
|
||||
for (Hook hook : plugin.getHooks().getHooks()) {
|
||||
PanelItem hookItem = new PanelItemBuilder()
|
||||
.icon(hook.getIcon())
|
||||
.name(ChatColor.WHITE + hook.getPluginName())
|
||||
.build();
|
||||
|
||||
builder.item(startSlot + i, hookItem);
|
||||
i++;
|
||||
if (builder.slotOccupied(startSlot + i)) {
|
||||
i = i+2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Setup a few more buttons
|
||||
@ -168,15 +168,15 @@ public class ManagementPanel {
|
||||
});
|
||||
|
||||
switch (view) {
|
||||
case GAMEMODES:
|
||||
gamemodesIconBuilder.glow(true);
|
||||
break;
|
||||
case ADDONS:
|
||||
addonsIconBuilder.glow(true);
|
||||
break;
|
||||
case HOOKS:
|
||||
hooksIconBuilder.glow(true);
|
||||
break;
|
||||
case GAMEMODES:
|
||||
gamemodesIconBuilder.glow(true);
|
||||
break;
|
||||
case ADDONS:
|
||||
addonsIconBuilder.glow(true);
|
||||
break;
|
||||
case HOOKS:
|
||||
hooksIconBuilder.glow(true);
|
||||
break;
|
||||
}
|
||||
|
||||
builder.item(1, gamemodesIconBuilder.build());
|
||||
@ -216,19 +216,19 @@ public class ManagementPanel {
|
||||
.name(user.getTranslation(LOCALE_REF + "information.state.name"))
|
||||
.description(user.getTranslation(LOCALE_REF + "information.state.description." + compatibility,
|
||||
TextVariables.NAME, serverSoftware != null ? serverSoftware.toString() : user.getTranslation("general.invalid"),
|
||||
TextVariables.VERSION, serverVersion != null ? serverVersion.toString() : user.getTranslation("general.invalid")));
|
||||
TextVariables.VERSION, serverVersion != null ? serverVersion.toString() : user.getTranslation("general.invalid")));
|
||||
|
||||
switch (compatibility) {
|
||||
case COMPATIBLE:
|
||||
case SUPPORTED:
|
||||
compatibilityItemBuilder.icon(Material.GREEN_CONCRETE);
|
||||
break;
|
||||
case NOT_SUPPORTED:
|
||||
compatibilityItemBuilder.icon(Material.ORANGE_CONCRETE);
|
||||
break;
|
||||
case INCOMPATIBLE:
|
||||
compatibilityItemBuilder.icon(Material.RED_CONCRETE);
|
||||
break;
|
||||
case COMPATIBLE:
|
||||
case SUPPORTED:
|
||||
compatibilityItemBuilder.icon(Material.GREEN_CONCRETE);
|
||||
break;
|
||||
case NOT_SUPPORTED:
|
||||
compatibilityItemBuilder.icon(Material.ORANGE_CONCRETE);
|
||||
break;
|
||||
case INCOMPATIBLE:
|
||||
compatibilityItemBuilder.icon(Material.RED_CONCRETE);
|
||||
break;
|
||||
}
|
||||
|
||||
builder.item(7, compatibilityItemBuilder.build());
|
||||
|
185
src/main/java/world/bentobox/bentobox/schems/Converter.java
Normal file
185
src/main/java/world/bentobox/bentobox/schems/Converter.java
Normal file
@ -0,0 +1,185 @@
|
||||
package world.bentobox.bentobox.schems;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Horse;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
|
||||
import world.bentobox.bentobox.blueprints.Blueprint;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintCreatureSpawner;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintEntity;
|
||||
|
||||
/**
|
||||
* This class converts a schem to a blueprint
|
||||
* @author tastybento
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class Converter {
|
||||
|
||||
private static final String ATTACHED_YAML_PREFIX = "attached.";
|
||||
private static final String BEDROCK = "bedrock";
|
||||
private static final String BLOCKS_YAML_PREFIX = "blocks.";
|
||||
private static final String COLOR = "color";
|
||||
private static final String ENTITIES_YAML_PREFIX = "entities.";
|
||||
private static final String INVENTORY = "inventory";
|
||||
private static final String LINES = "lines";
|
||||
|
||||
public Blueprint convert(@NonNull YamlConfiguration bc) {
|
||||
Blueprint bp = new Blueprint();
|
||||
// Bedrock
|
||||
if (bc.contains(BEDROCK)) {
|
||||
bp.setBedrock(getVector(bc.getString(BEDROCK)));
|
||||
}
|
||||
// Normal blocks
|
||||
if (bc.isConfigurationSection(BLOCKS_YAML_PREFIX)) {
|
||||
bp.setBlocks(bc.getConfigurationSection(BLOCKS_YAML_PREFIX).getKeys(false).stream()
|
||||
// make configuration section from key
|
||||
.map(k -> bc.getConfigurationSection(BLOCKS_YAML_PREFIX + k))
|
||||
// Check the config section contains block data key "bd"
|
||||
.filter(cs -> cs.contains("bd"))
|
||||
// Convert it
|
||||
.map(this::convertBlock)
|
||||
// Collect into a map
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
|
||||
}
|
||||
// Attached blocks
|
||||
if (bc.isConfigurationSection(ATTACHED_YAML_PREFIX)) {
|
||||
bp.setAttached(bc.getConfigurationSection(ATTACHED_YAML_PREFIX).getKeys(false).stream()
|
||||
// make configuration section from key
|
||||
.map(k -> bc.getConfigurationSection(ATTACHED_YAML_PREFIX + k))
|
||||
// Check the config section contains block data key "bd"
|
||||
.filter(cs -> cs.contains("bd"))
|
||||
// Convert it
|
||||
.map(this::convertBlock)
|
||||
// Collect into a map
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
|
||||
}
|
||||
// Entities
|
||||
if (bc.isConfigurationSection(ENTITIES_YAML_PREFIX)) {
|
||||
bp.setEntities(bc.getConfigurationSection(ENTITIES_YAML_PREFIX).getKeys(false).stream()
|
||||
// make configuration section from key
|
||||
.map(k -> bc.getConfigurationSection(ENTITIES_YAML_PREFIX + k))
|
||||
// Convert it
|
||||
.map(this::convertEntity)
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
|
||||
}
|
||||
return bp;
|
||||
|
||||
}
|
||||
|
||||
private Entry<Vector, BlueprintBlock> convertBlock(ConfigurationSection config) {
|
||||
String blockData = config.getString("bd");
|
||||
// Make block
|
||||
BlueprintBlock block = new BlueprintBlock(blockData);
|
||||
// Signs
|
||||
if (config.contains(LINES)) {
|
||||
block.setSignLines(config.getStringList(LINES));
|
||||
}
|
||||
// Chests, in general
|
||||
if (config.isConfigurationSection(INVENTORY)) {
|
||||
ConfigurationSection inv = config.getConfigurationSection(INVENTORY);
|
||||
block.setInventory(
|
||||
inv.getKeys(false).stream()
|
||||
.collect(Collectors.toMap(i -> Integer.valueOf(i), i -> (ItemStack)inv.get(i)))
|
||||
);
|
||||
}
|
||||
// Mob spawners
|
||||
if (blockData.equals("minecraft:spawner")) {
|
||||
BlueprintCreatureSpawner spawner = new BlueprintCreatureSpawner();
|
||||
spawner.setSpawnedType(EntityType.valueOf(config.getString("spawnedType", "PIG")));
|
||||
spawner.setMaxNearbyEntities(config.getInt("maxNearbyEntities", 16));
|
||||
spawner.setMaxSpawnDelay(config.getInt("maxSpawnDelay", 2*60*20));
|
||||
spawner.setMinSpawnDelay(config.getInt("minSpawnDelay", 5*20));
|
||||
spawner.setDelay(config.getInt("delay", -1));
|
||||
spawner.setRequiredPlayerRange(config.getInt("requiredPlayerRange", 16));
|
||||
spawner.setSpawnRange(config.getInt("spawnRange", 4));
|
||||
block.setCreatureSpawner(spawner);
|
||||
}
|
||||
// Vector
|
||||
Vector vector = getVector(config.getName());
|
||||
// Return entry
|
||||
return new AbstractMap.SimpleEntry<>(vector, block);
|
||||
|
||||
}
|
||||
|
||||
private Entry<Vector, List<BlueprintEntity>> convertEntity(ConfigurationSection en) {
|
||||
// Position
|
||||
Vector vector = getVector(en.getName());
|
||||
// Create a list of entities at this position
|
||||
List<BlueprintEntity> list = en.getKeys(false).stream()
|
||||
.map(en::getConfigurationSection)
|
||||
.map(this::createEntity)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return new AbstractMap.SimpleEntry<>(vector, list);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to create a blueprint entity
|
||||
* @param cs - yaml configuration section
|
||||
* @return blueprint entity, or null if it fails
|
||||
*/
|
||||
private BlueprintEntity createEntity(ConfigurationSection cs) {
|
||||
try {
|
||||
BlueprintEntity be = new BlueprintEntity();
|
||||
if (cs.contains("type")) {
|
||||
be.setType(EntityType.valueOf(cs.getString("type")));
|
||||
}
|
||||
if (cs.contains("name")) {
|
||||
be.setCustomName(cs.getString("name"));
|
||||
}
|
||||
if (cs.contains(COLOR)) {
|
||||
be.setColor(DyeColor.valueOf(cs.getString(COLOR)));
|
||||
}
|
||||
if (cs.contains("tamed")) {
|
||||
be.setTamed(cs.getBoolean("tamed"));
|
||||
}
|
||||
if (cs.contains("chest")) {
|
||||
be.setChest(cs.getBoolean("chest"));
|
||||
}
|
||||
if (!cs.getBoolean("adult")) {
|
||||
be.setAdult(false);
|
||||
}
|
||||
if (cs.contains("style")) {
|
||||
be.setStyle(Horse.Style.valueOf(cs.getString("style", "NONE")));
|
||||
}
|
||||
if (cs.contains("domestication")) {
|
||||
be.setDomestication(cs.getInt("domestication"));
|
||||
}
|
||||
if (cs.isConfigurationSection(INVENTORY)) {
|
||||
ConfigurationSection inv = cs.getConfigurationSection(INVENTORY);
|
||||
be.setInventory(inv.getKeys(false).stream()
|
||||
.collect(Collectors.toMap(i -> Integer.valueOf(i), i -> (ItemStack)inv.get(i))));
|
||||
}
|
||||
return be;
|
||||
} catch (Exception e) {
|
||||
Bukkit.getLogger().severe("Failed to import entity, skipping...");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Vector getVector(String name) {
|
||||
String[] pos = name.split(",");
|
||||
int x = Integer.valueOf(pos[0]);
|
||||
int y = Integer.valueOf(pos[1]);
|
||||
int z = Integer.valueOf(pos[2]);
|
||||
return new Vector(x,y,z);
|
||||
}
|
||||
|
||||
}
|
102
src/main/java/world/bentobox/bentobox/schems/SchemLoader.java
Normal file
102
src/main/java/world/bentobox/bentobox/schems/SchemLoader.java
Normal file
@ -0,0 +1,102 @@
|
||||
package world.bentobox.bentobox.schems;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
|
||||
/**
|
||||
* This class loads schems so they can be converted to blueprints
|
||||
* @author tastybento
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class SchemLoader {
|
||||
|
||||
private static final String LOAD_ERROR = "Could not load schems file - does not exist : ";
|
||||
|
||||
private YamlConfiguration blockConfig;
|
||||
|
||||
private BentoBox plugin;
|
||||
|
||||
private File schemFolder;
|
||||
|
||||
public SchemLoader(BentoBox plugin, File schemFolder) {
|
||||
this.plugin = plugin;
|
||||
this.schemFolder = schemFolder;
|
||||
blockConfig = new YamlConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the blockConfig
|
||||
*/
|
||||
public YamlConfiguration getBlockConfig() {
|
||||
return blockConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a file to clipboard
|
||||
* @param fileName - filename in schems folder
|
||||
* @throws FileNotFoundException - if a file cannot be found
|
||||
* @throws IOException - if there's a load error with unziping or name
|
||||
* @throws InvalidConfigurationException - the YAML of the schem is at fault
|
||||
*/
|
||||
public void load(String fileName) throws FileNotFoundException, IOException, InvalidConfigurationException {
|
||||
File zipFile = new File(schemFolder, fileName + ".schem");
|
||||
if (!zipFile.exists()) {
|
||||
plugin.logError(LOAD_ERROR + zipFile.getName());
|
||||
throw new FileNotFoundException(LOAD_ERROR + zipFile.getName());
|
||||
}
|
||||
unzip(zipFile.getAbsolutePath());
|
||||
File file = new File(schemFolder, fileName);
|
||||
if (!file.exists()) {
|
||||
plugin.logError(LOAD_ERROR + file.getName());
|
||||
throw new FileNotFoundException(LOAD_ERROR + file.getName());
|
||||
}
|
||||
blockConfig.load(file);
|
||||
Files.delete(file.toPath());
|
||||
}
|
||||
|
||||
private void unzip(final String zipFilePath) throws IOException {
|
||||
Path path = Paths.get(zipFilePath);
|
||||
if (!(path.toFile().exists())) {
|
||||
throw new FileNotFoundException("No file exists to unzip!");
|
||||
}
|
||||
try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFilePath))) {
|
||||
ZipEntry entry = zipInputStream.getNextEntry();
|
||||
while (entry != null) {
|
||||
Path filePath = Paths.get(path.getParent().toString(), entry.getName());
|
||||
if (!entry.isDirectory()) {
|
||||
unzipFiles(zipInputStream, filePath);
|
||||
} else {
|
||||
Files.createDirectories(filePath);
|
||||
}
|
||||
|
||||
zipInputStream.closeEntry();
|
||||
entry = zipInputStream.getNextEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void unzipFiles(final ZipInputStream zipInputStream, final Path unzipFilePath) throws IOException {
|
||||
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(unzipFilePath.toAbsolutePath().toString()))) {
|
||||
byte[] bytesIn = new byte[1024];
|
||||
int read;
|
||||
while ((read = zipInputStream.read(bytesIn)) != -1) {
|
||||
bos.write(bytesIn, 0, read);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
package world.bentobox.bentobox.schems;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||
import world.bentobox.bentobox.blueprints.Blueprint;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle;
|
||||
import world.bentobox.bentobox.managers.BlueprintsManager;
|
||||
|
||||
public class SchemToBlueprint {
|
||||
|
||||
public static final @NonNull String DEFAULT_SCHEM_NAME = "island";
|
||||
public static final @NonNull String FILE_EXTENSION = ".schem";
|
||||
public static final @NonNull String FOLDER_NAME = "schems";
|
||||
|
||||
private BentoBox plugin;
|
||||
|
||||
/**
|
||||
* @param plugin - plugin
|
||||
*/
|
||||
public SchemToBlueprint(BentoBox plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts schems to blueprints and blueprint bundles
|
||||
* @param addon - GameModeAddon
|
||||
*/
|
||||
public void convertSchems(GameModeAddon addon) {
|
||||
File schems = new File(addon.getDataFolder(), FOLDER_NAME);
|
||||
if (!schems.exists()) {
|
||||
return;
|
||||
}
|
||||
// Convert all schems in folder
|
||||
// Look through the folder
|
||||
FilenameFilter schemFilter = (File dir, String name) -> name.toLowerCase(java.util.Locale.ENGLISH).endsWith(FILE_EXTENSION)
|
||||
&& !name.toLowerCase(java.util.Locale.ENGLISH).startsWith("nether-")
|
||||
&& !name.toLowerCase(java.util.Locale.ENGLISH).startsWith("end-");
|
||||
|
||||
Arrays.stream(Objects.requireNonNull(schems.list(schemFilter)))
|
||||
.map(name -> name.substring(0, name.length() - FILE_EXTENSION.length()))
|
||||
.forEach(name -> importSchemSet(addon, schems, name));
|
||||
|
||||
File newDir = new File(addon.getDataFolder(), FOLDER_NAME + "_converted");
|
||||
try {
|
||||
Files.move(schems.toPath(), newDir.toPath());
|
||||
} catch (IOException e) {
|
||||
plugin.logError("Could not move schems folder: " + e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports one schem set to the game mode
|
||||
* @param addon - game mode addon
|
||||
* @param schems
|
||||
* @param name
|
||||
*/
|
||||
private void importSchemSet(GameModeAddon addon, File schems, String name) {
|
||||
// Make a new blueprint bundle
|
||||
BlueprintBundle bb = new BlueprintBundle();
|
||||
// TODO: This is just placeholder text
|
||||
if (name.equalsIgnoreCase("island")) {
|
||||
bb.setUniqueId(BlueprintsManager.DEFAULT_BUNDLE_NAME);
|
||||
bb.setDisplayName(ChatColor.YELLOW + "The Original");
|
||||
bb.setDescription(ChatColor.AQUA + "Standard set of islands");
|
||||
bb.setIcon(Material.GRASS);
|
||||
} else {
|
||||
bb.setUniqueId(name);
|
||||
bb.setDisplayName(name + " island");
|
||||
bb.setIcon(Material.GRASS_PATH);
|
||||
}
|
||||
Blueprint bp = loadSchemSaveBlueprint(addon, schems, name);
|
||||
if (bp != null) {
|
||||
bb.setBlueprint(World.Environment.NORMAL, bp);
|
||||
plugin.getBlueprintsManager().saveBlueprint(addon, bp);
|
||||
bb.setDescription(ChatColor.GREEN + "Includes an Overworld island");
|
||||
}
|
||||
bp = loadSchemSaveBlueprint(addon, schems, "nether-" + name);
|
||||
if (bp != null) {
|
||||
bb.setBlueprint(World.Environment.NETHER, bp);
|
||||
plugin.getBlueprintsManager().saveBlueprint(addon, bp);
|
||||
bb.setDescription(ChatColor.RED + "Includes a Nether island");
|
||||
}
|
||||
bp = loadSchemSaveBlueprint(addon, schems, "end-" + name);
|
||||
if (bp != null) {
|
||||
bb.setBlueprint(World.Environment.THE_END, bp);
|
||||
plugin.getBlueprintsManager().saveBlueprint(addon, bp);
|
||||
bb.setDescription(ChatColor.GOLD + "Includes an End island");
|
||||
}
|
||||
// Add it to the blueprint manager
|
||||
plugin.getBlueprintsManager().saveBlueprintBundle(addon, bb);
|
||||
|
||||
// Done!
|
||||
}
|
||||
|
||||
private Blueprint loadSchemSaveBlueprint(GameModeAddon addon, File schems, String name) {
|
||||
try {
|
||||
SchemLoader loader = new SchemLoader(plugin, schems);
|
||||
loader.load(name);
|
||||
plugin.log("Loaded " + name + ".schem");
|
||||
// Convert blueprint
|
||||
plugin.log("Converting " + name + ".schem to a blueprint");
|
||||
Blueprint bp = new Converter().convert(loader.getBlockConfig());
|
||||
bp.setName(name);
|
||||
plugin.log("Saving blueprint");
|
||||
plugin.getBlueprintsManager().saveBlueprint(addon, bp);
|
||||
return bp;
|
||||
} catch (FileNotFoundException ignore) {
|
||||
// Ignore
|
||||
} catch (Exception e) {
|
||||
plugin.logError("Could not convert " + name + " schem, skipping!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -80,7 +80,7 @@ island:
|
||||
# These set the minimum and maximum size of a name.
|
||||
min-length: 4
|
||||
max-length: 20
|
||||
# Number of blocks to paste per tick when pasting a schem
|
||||
# Number of blocks to paste per tick when pasting blueprints
|
||||
# Smaller values will help reduce noticeable lag but will make pasting take longer
|
||||
paste-speed: 1000
|
||||
web:
|
||||
|
@ -185,10 +185,10 @@ commands:
|
||||
already-spawn: "&cThis island is already a spawn!"
|
||||
no-island-here: "&cThere is no island here."
|
||||
confirmation: "&cAre you sure you want to set this Island as the spawn for this world?"
|
||||
schem:
|
||||
blueprint:
|
||||
parameters: "<load/copy/paste/pos1/pos2/save>"
|
||||
description: "manipulate schems"
|
||||
copy-first: "&cCopy a schem first!"
|
||||
description: "manipulate blueprints"
|
||||
copy-first: "&cCopy first!"
|
||||
file-exists: "&cFile already exists, overwrite?"
|
||||
no-such-file: "&cNo such file!"
|
||||
could-not-load: "&cCould not load that file!"
|
||||
@ -206,14 +206,14 @@ commands:
|
||||
parameters: "[air]"
|
||||
description: "copy the clipboard set by pos1 and pos2 and optionally the air blocks"
|
||||
load:
|
||||
parameters: "<schem name>"
|
||||
description: "load schem into the clipboard"
|
||||
parameters: "<name>"
|
||||
description: "load blueprint into the clipboard"
|
||||
list:
|
||||
description: "list available schems"
|
||||
no-schems: "&cNo schems in schems folder!"
|
||||
available-schems: "&aThese schems are available for loading:"
|
||||
description: "list available blueprints"
|
||||
no-blueprints: "&cNo blueprints in blueprints folder!"
|
||||
available-blueprints: "&aThese blueprints are available for loading:"
|
||||
origin:
|
||||
description: "set the schem's origin to your position"
|
||||
description: "set the blueprint's origin to your position"
|
||||
paste:
|
||||
description: "paste the clipboard to your location"
|
||||
pasting: "&aPasting..."
|
||||
@ -222,7 +222,7 @@ commands:
|
||||
pos2:
|
||||
description: "set 2nd corner of cuboid clipboard"
|
||||
save:
|
||||
parameters: "<schem name>"
|
||||
parameters: "<blueprint name>"
|
||||
description: "save the copied clipboard"
|
||||
resetflags:
|
||||
description: "Reset all islands to default flag settings in config.yml"
|
||||
@ -307,13 +307,13 @@ commands:
|
||||
teleporting: "&aTeleporting you to the spawn."
|
||||
no-spawn: "&cThere is no spawn in this world."
|
||||
create:
|
||||
description: "create an island, using optional schem (requires permission)"
|
||||
parameters: "<schem>"
|
||||
description: "create an island, using optional blueprint (requires permission)"
|
||||
parameters: "<blueprint>"
|
||||
too-many-islands: "&cThere are too many islands in this world: there isn't enough room for yours to be created."
|
||||
unable-create-island: "&cYour island could not be generated, please contact an administrator."
|
||||
creating-island: "&aCreating your island, please wait a moment..."
|
||||
pick-world: "&cPick a world from [worlds]."
|
||||
unknown-schem: "&cThat schem has not been loaded yet."
|
||||
pick: "&aPick an island"
|
||||
unknown-blueprint: "&cThat blueprint has not been loaded yet."
|
||||
info:
|
||||
description: "display info about your island or the player's island"
|
||||
parameters: "<player>"
|
||||
@ -329,7 +329,7 @@ commands:
|
||||
no-neighbors: "&cYou have no immediate neighboring islands!"
|
||||
reset:
|
||||
description: "restart your island and remove the old one"
|
||||
parameters: "<schem>"
|
||||
parameters: "<blueprint>"
|
||||
must-remove-members: "&cYou must remove all members from your island before you can restart it (/island team kick <player>)."
|
||||
none-left: "&cYou have no more resets left!"
|
||||
resets-left: "&cYou have [number] resets left"
|
||||
@ -1009,9 +1009,9 @@ management:
|
||||
gamemodes:
|
||||
name: "&6Gamemodes"
|
||||
description: "&eClick &ato display currently loaded Gamemodes"
|
||||
schems:
|
||||
name: "&6Schems"
|
||||
description: "&aOpens the Admin Schem menu."
|
||||
blueprints:
|
||||
name: "&6Blueprints"
|
||||
description: "&aOpens the Admin Blueprint menu."
|
||||
gamemode:
|
||||
name: "&f[name]"
|
||||
description: |+
|
||||
|
@ -184,7 +184,7 @@ commands:
|
||||
already-spawn: "&cEsta isla ya es un spawn!"
|
||||
no-island-here: "&cNo hay isla aqui."
|
||||
confirmation: "&cEstás seguro de que quieres establecer esta isla como el spawn de este mundo?"
|
||||
schem:
|
||||
blueprint:
|
||||
parameters: "<load/copy/paste/pos1/pos2/save>"
|
||||
description: "manipular esquemas"
|
||||
copy-first: "&cCopia un esquema primero!"
|
||||
@ -202,12 +202,12 @@ commands:
|
||||
parameters: "[air]"
|
||||
description: "Copie el conjunto de portapapeles por Posición 1 y Posición 2 y, opcionalmente, los bloques de aire."
|
||||
load:
|
||||
parameters: "<schem name>"
|
||||
parameters: "<blueprints name>"
|
||||
description: "Cargar esquema en el portapapeles"
|
||||
list:
|
||||
description: "listar esquemas disponibles"
|
||||
no-schems: "&cNo hay esquemas en la carpeta de esquemas!"
|
||||
available-schems: "&aEstos esquemas están disponibles para cargar:"
|
||||
no-blueprints: "&cNo hay esquemas en la carpeta de esquemas!"
|
||||
available-blueprints: "&aEstos esquemas están disponibles para cargar:"
|
||||
origin:
|
||||
description: "Establece el origen del esquema a tu posición"
|
||||
paste:
|
||||
@ -218,7 +218,7 @@ commands:
|
||||
pos2:
|
||||
description: "establecer la 2da esquina del portapapeles cuboide"
|
||||
save:
|
||||
parameters: "<schem name>"
|
||||
parameters: "<blueprint name>"
|
||||
description: "Guardar el portapapeles copiado"
|
||||
resetflags:
|
||||
description: "Restablecer todas las islas a la configuración de las banderas predeterminadas en config.yml"
|
||||
@ -287,18 +287,18 @@ commands:
|
||||
no-spawn: "&cNo hay un spawn en este mundo."
|
||||
create:
|
||||
description: "crear una isla, usando un esquema opcional (requiere permiso)"
|
||||
parameters: "<schem>"
|
||||
parameters: "<blueprint>"
|
||||
too-many-islands: "&cHay demasiadas islas en este mundo: no hay suficiente espacio para que las tuyas sean creadas."
|
||||
unable-create-island: "&cSu isla no se pudo generar, póngase en contacto con un administrador."
|
||||
creating-island: "&aCreando tu isla, espera un momento..."
|
||||
pick-world: "&cElige un mundo: [worlds]."
|
||||
unknown-schem: "&cEse esquema no se ha cargado todavía."
|
||||
unknown-blueprint: "&cEse esquema no se ha cargado todavía."
|
||||
info:
|
||||
description: "Muestra información sobre tu isla o la isla del jugador."
|
||||
parameters: "<player>"
|
||||
reset:
|
||||
description: "reinicia tu isla y elimina la antigua"
|
||||
parameters: "<schem>"
|
||||
parameters: "<blueprint>"
|
||||
must-remove-members: "&cDebes eliminar todos los miembros de tu isla antes de poder reiniciarla (/island team kick <player>)."
|
||||
none-left: "&cNo te quedan más reinicios.!"
|
||||
resets-left: "&cTienes [number] reinicios mas"
|
||||
@ -959,9 +959,9 @@ management:
|
||||
gamemodes:
|
||||
name: "&6Modos de juegos"
|
||||
description: "&eClick &apara mostrar los modos de juegos cargados actualmente"
|
||||
schems:
|
||||
name: "&6Schems"
|
||||
description: "&aAbre el menú Admin de Schem."
|
||||
blueprints:
|
||||
name: "&6Blueprints"
|
||||
description: "&aAbre el menú Admin de Blueprint."
|
||||
addons:
|
||||
name: "&6Addons"
|
||||
description: "&eClick &apara mostrar los Addons cargados actualmente"
|
||||
|
@ -148,10 +148,10 @@ commands:
|
||||
description: "プレイヤーのランクを設定する"
|
||||
unknown-rank: "&c不明ランク!"
|
||||
rank-set: "&2[from] から [to] に設定されたランク。"
|
||||
schem:
|
||||
blueprint:
|
||||
parameters: "<load><copy><paste><pos1><pos2><save>"
|
||||
description: "schems の操作"
|
||||
copy-first: "&c最初に schem をコピー!"
|
||||
description: "blueprints の操作"
|
||||
copy-first: "&c最初に blueprint をコピー!"
|
||||
file-exists: "&cファイルは既に存在し、上書きしますか?"
|
||||
no-such-file: "&cそのようなファイルはありません!"
|
||||
could-not-load: "&cそのファイルを読み込めませんでした!"
|
||||
|
@ -184,7 +184,7 @@ commands:
|
||||
already-spawn: "&cŠī sala jau ir uzstādīta kā sākuma sala!"
|
||||
no-island-here: "&cŠeit nav neveinas salas."
|
||||
confirmation: "&cVai tiešām vēlies uzstādīt šo salu kā sākuma salu?"
|
||||
schem:
|
||||
blueprint:
|
||||
parameters: "<load/copy/paste/pos1/pos2/save>"
|
||||
description: "manipulē ar shēmām"
|
||||
copy-first: "&cKopē shēmu sākumā!"
|
||||
@ -206,8 +206,8 @@ commands:
|
||||
description: "ielādē shēmu starpliktuvē"
|
||||
list:
|
||||
description: "attaino visas pieejamās shēmas"
|
||||
no-schems: "&cNav shēmas iekš schems mapītes!"
|
||||
available-schems: "&aŠīs shēmas ir pieejamas ielādei:"
|
||||
no-blueprints: "&cNav shēmas iekš blueprints mapītes!"
|
||||
available-blueprints: "&aŠīs shēmas ir pieejamas ielādei:"
|
||||
origin:
|
||||
description: "uzstāda shēmas sākuma punktu tavā pozīcijā"
|
||||
paste:
|
||||
@ -310,7 +310,7 @@ commands:
|
||||
unable-create-island: "&cNeizdevās izveidot tavu salu, ziņo par kļūdu administratoram."
|
||||
creating-island: "&aTiek veidota tava sala. Uzgaidi mirklīti..."
|
||||
pick-world: "&cIzvēkies pasauli no [worlds]."
|
||||
unknown-schem: "&cŠī shēma nav ielādēta vai tā neeksistē."
|
||||
unknown-blueprint: "&cŠī shēma nav ielādēta vai tā neeksistē."
|
||||
info:
|
||||
description: "parāda informāciju par tavu vai spēlētāja salu"
|
||||
parameters: "<spēlētājs>"
|
||||
@ -1022,9 +1022,9 @@ management:
|
||||
gamemodes:
|
||||
name: "&6Spēles režīmi"
|
||||
description: "&eUzspied&a, lai redzētu uzstādītos spēles režīmus."
|
||||
schems:
|
||||
name: "&6Shēmas"
|
||||
description: "&aAtver admina shēmu izvēlni."
|
||||
blueprints:
|
||||
name: "&6Blueprints"
|
||||
description: "&aAtver admina blueprint izvēlni."
|
||||
addons:
|
||||
name: "&6Papildinājumi"
|
||||
description: "&eUzspied&a, lai redzētu uzstādītos spēles papildinājumus."
|
||||
|
@ -121,10 +121,10 @@ commands:
|
||||
description: "ustawia role gracza na swojej wyspie"
|
||||
unknown-rank: "&cNieznana rola!"
|
||||
rank-set: "&aRola ustawiona z [from] na [to]."
|
||||
schem:
|
||||
blueprint:
|
||||
parameters: "<load><copy><paste><pos1><pos2><save>"
|
||||
description: "manipuluj schematem"
|
||||
copy-first: "&cNajpierw skopiuj schemat!"
|
||||
description: "manipuluj blueprint"
|
||||
copy-first: "&cNajpierw skopiuj blueprint!"
|
||||
file-exists: "&cPlik już istnieje, nadpisać?"
|
||||
no-such-file: "&cNie ma takiego pliku!"
|
||||
could-not-load: "&cNie można załadować tego pliku!"
|
||||
|
@ -147,7 +147,7 @@ commands:
|
||||
description: "设置玩家在他们岛屿上的头衔"
|
||||
unknown-rank: "&c未知头衔!"
|
||||
rank-set: "&a头衔由 [from] 设置为 [to]。"
|
||||
schem:
|
||||
blueprint:
|
||||
parameters: "<load/copy/paste/pos1/pos2/save>"
|
||||
description: "调整规划方案"
|
||||
copy-first: "&c请先复制一份规划方案!"
|
||||
@ -165,7 +165,7 @@ commands:
|
||||
parameters: "[air]"
|
||||
description: "复制 pos1 和 pos2 之间设置的方块(或使用空气方块)到剪切板"
|
||||
load:
|
||||
parameters: "<schem name>"
|
||||
parameters: "<blueprint name>"
|
||||
description: "加载规划文件到剪切板"
|
||||
origin:
|
||||
parameters: ""
|
||||
@ -180,7 +180,7 @@ commands:
|
||||
parameters: ""
|
||||
description: "设置立方体剪切板的第二个顶点"
|
||||
save:
|
||||
parameters: "<schem name>"
|
||||
parameters: "<blueprint name>"
|
||||
description: "保存已复制的剪切板"
|
||||
world:
|
||||
description: "管理世界设置"
|
||||
|
@ -159,7 +159,7 @@ commands:
|
||||
already-spawn: "&c這個島嶼早就設定了重生點!"
|
||||
no-island-here: "&c沒有在您的位置找到任何島嶼。"
|
||||
confirmation: "&c您確定要在這個世界中把現在的位置設置為島嶼的重生點?"
|
||||
schem:
|
||||
blueprint:
|
||||
parameters: "<load/copy/paste/pos1/pos2/save>"
|
||||
description: "調整規劃方案"
|
||||
copy-first: "&c請先複製一份規劃方案!"
|
||||
@ -177,7 +177,7 @@ commands:
|
||||
parameters: "[air]"
|
||||
description: "複製 pos1 和 pos2 之間設置的方塊(或使用空氣方塊)到剪切板"
|
||||
load:
|
||||
parameters: "<schem name>"
|
||||
parameters: "<blueprint name>"
|
||||
description: "加載規劃文件到剪切板"
|
||||
origin:
|
||||
parameters: ""
|
||||
@ -192,7 +192,7 @@ commands:
|
||||
parameters: ""
|
||||
description: "設置立方體剪切板的第二個頂點"
|
||||
save:
|
||||
parameters: "<schem name>"
|
||||
parameters: "<blueprint name>"
|
||||
description: "保存已復制的剪切板"
|
||||
world:
|
||||
description: "管理世界設置"
|
||||
@ -250,19 +250,19 @@ commands:
|
||||
teleporting: "&a正在把您傳送到重生點。"
|
||||
no-spawn: "&c這個世界並沒有重生點。"
|
||||
create:
|
||||
description: "創建島嶼, 可以使用指定的Schem (需要權限)"
|
||||
parameters: "<schem>"
|
||||
description: "創建島嶼, 可以使用指定的blueprint (需要權限)"
|
||||
parameters: "<blueprint>"
|
||||
too-many-islands: "&c這個世界已經有太多島嶼了: 所以這裏沒有足夠的空間去創建您的島嶼。"
|
||||
unable-create-island: "&c您的島嶼無法被生成, 請聯繫管理員。"
|
||||
creating-island: "&a正在創建島嶼, 請耐心等候......"
|
||||
pick-world: "&c請從 [worlds] 中選擇世界。"
|
||||
unknown-schem: "&c這一個Schem還未被加載。"
|
||||
unknown-blueprint: "&c這一個blueprint還未被加載。"
|
||||
info:
|
||||
description: "顯示關於您或某一個玩家島嶼的信息"
|
||||
parameters: "<player>"
|
||||
reset:
|
||||
description: "重置您的島嶼, 並且刪除舊的島嶼"
|
||||
parameters: "<schem>"
|
||||
parameters: "<blueprint>"
|
||||
must-remove-members: "&c在您可以重製您的島嶼之前, 您必須移除掉所有的島上成員(/island team kick <player>)。"
|
||||
none-left: "&c您沒有重置次數了!"
|
||||
resets-left: "&c您還有 [number] 次重置機會"
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package world.bentobox.bentobox.api.commands.admin.schem;
|
||||
package world.bentobox.bentobox.api.commands.admin.blueprints;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@ -31,7 +31,10 @@ import org.powermock.reflect.Whitebox;
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.Settings;
|
||||
import world.bentobox.bentobox.api.addons.Addon;
|
||||
import world.bentobox.bentobox.api.commands.admin.blueprints.AdminBlueprintCommand;
|
||||
import world.bentobox.bentobox.api.commands.admin.blueprints.AdminBlueprintListCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.managers.BlueprintsManager;
|
||||
import world.bentobox.bentobox.managers.CommandsManager;
|
||||
import world.bentobox.bentobox.managers.LocalesManager;
|
||||
|
||||
@ -41,15 +44,15 @@ import world.bentobox.bentobox.managers.LocalesManager;
|
||||
*/
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({Bukkit.class, BentoBox.class, User.class })
|
||||
public class AdminSchemListCommandTest {
|
||||
public class AdminBlueprintsListCommandTest {
|
||||
|
||||
@Mock
|
||||
private AdminSchemCommand ac;
|
||||
private AdminBlueprintCommand ac;
|
||||
@Mock
|
||||
private Addon addon;
|
||||
@Mock
|
||||
private User user;
|
||||
private AdminSchemListCommand list;
|
||||
private AdminBlueprintListCommand list;
|
||||
private File dataFolder;
|
||||
|
||||
/**
|
||||
@ -75,7 +78,7 @@ public class AdminSchemListCommandTest {
|
||||
|
||||
// Parent command has no aliases
|
||||
when(ac.getAddon()).thenReturn(addon);
|
||||
when(ac.getLabel()).thenReturn("schem");
|
||||
when(ac.getLabel()).thenReturn("blueprint");
|
||||
when(ac.getSubCommandAliases()).thenReturn(new HashMap<>());
|
||||
when(ac.getTopLabel()).thenReturn("admin");
|
||||
|
||||
@ -90,7 +93,7 @@ public class AdminSchemListCommandTest {
|
||||
|
||||
when(addon.getDataFolder()).thenReturn(dataFolder);
|
||||
// Class
|
||||
list = new AdminSchemListCommand(ac);
|
||||
list = new AdminBlueprintListCommand(ac);
|
||||
|
||||
|
||||
}
|
||||
@ -108,24 +111,24 @@ public class AdminSchemListCommandTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.admin.schem.AdminSchemListCommand#AdminSchemListCommand(world.bentobox.bentobox.api.commands.admin.schem.AdminSchemCommand)}.
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.admin.blueprints.AdminBlueprintListCommand#AdminBlueprintListCommand(world.bentobox.bentobox.api.commands.admin.blueprints.AdminBlueprintCommand)}.
|
||||
*/
|
||||
@Test
|
||||
public void testAdminSchemListCommand() {
|
||||
public void testAdminBlueprintListCommand() {
|
||||
|
||||
assertEquals("list", list.getLabel());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.admin.schem.AdminSchemListCommand#setup()}.
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.admin.blueprints.AdminBlueprintListCommand#setup()}.
|
||||
*/
|
||||
@Test
|
||||
public void testSetup() {
|
||||
assertEquals("commands.admin.schem.list.description", list.getDescription());
|
||||
assertEquals("commands.admin.blueprint.list.description", list.getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.admin.schem.AdminSchemListCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.admin.blueprints.AdminBlueprintListCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
|
||||
*/
|
||||
@Test
|
||||
public void testCanExecute() {
|
||||
@ -134,53 +137,53 @@ public class AdminSchemListCommandTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.admin.schem.AdminSchemListCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.admin.blueprints.AdminBlueprintListCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteUserStringListOfStringNoSchemsFolder() {
|
||||
public void testExecuteUserStringListOfStringNoBlueprintsFolder() {
|
||||
assertFalse(list.execute(user, "", Collections.emptyList()));
|
||||
Mockito.verify(user).sendMessage("commands.admin.schem.list.no-schems");
|
||||
Mockito.verify(user).sendMessage("commands.admin.blueprint.list.no-blueprints");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.admin.schem.AdminSchemListCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.admin.blueprints.AdminBlueprintListCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteUserStringListOfStringNoSchemsFilesEmptyFolder() {
|
||||
File schemFolder = new File(dataFolder, "schems");
|
||||
schemFolder.mkdirs();
|
||||
public void testExecuteUserStringListOfStringNoBlueprintsFilesEmptyFolder() {
|
||||
File blueprintFolder = new File(dataFolder, "blueprints");
|
||||
blueprintFolder.mkdirs();
|
||||
assertFalse(list.execute(user, "", Collections.emptyList()));
|
||||
Mockito.verify(user).sendMessage("commands.admin.schem.list.no-schems");
|
||||
Mockito.verify(user).sendMessage("commands.admin.blueprint.list.no-blueprints");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.admin.schem.AdminSchemListCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.admin.blueprints.AdminBlueprintListCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteUserStringListOfStringNoSchemsFiles() throws IOException {
|
||||
File schemFolder = new File(dataFolder, "schems");
|
||||
schemFolder.mkdirs();
|
||||
new File(schemFolder, "random.txt").createNewFile();
|
||||
public void testExecuteUserStringListOfStringNoBlueprintsFiles() throws IOException {
|
||||
File blueprintFolder = new File(dataFolder, "blueprints");
|
||||
blueprintFolder.mkdirs();
|
||||
new File(blueprintFolder, "random.txt").createNewFile();
|
||||
assertFalse(list.execute(user, "", Collections.emptyList()));
|
||||
Mockito.verify(user).sendMessage("commands.admin.schem.list.no-schems");
|
||||
Mockito.verify(user).sendMessage("commands.admin.blueprint.list.no-blueprints");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.admin.schem.AdminSchemListCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.admin.blueprints.AdminBlueprintListCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteUserStringListOfStringWithSchemsFiles() throws IOException {
|
||||
File schemFolder = new File(dataFolder, "schems");
|
||||
schemFolder.mkdirs();
|
||||
new File(schemFolder, "island.schem").createNewFile();
|
||||
new File(schemFolder, "nether-island.schem").createNewFile();
|
||||
new File(schemFolder, "end-island.schem").createNewFile();
|
||||
new File(schemFolder, "random.txt").createNewFile();
|
||||
public void testExecuteUserStringListOfStringWithBlueprintsFiles() throws IOException {
|
||||
File blueprintFolder = new File(dataFolder, BlueprintsManager.FOLDER_NAME);
|
||||
blueprintFolder.mkdirs();
|
||||
new File(blueprintFolder, "island" + BlueprintsManager.BLUEPRINT_SUFFIX).createNewFile();
|
||||
new File(blueprintFolder, "nether-island" + BlueprintsManager.BLUEPRINT_SUFFIX).createNewFile();
|
||||
new File(blueprintFolder, "end-island" + BlueprintsManager.BLUEPRINT_SUFFIX).createNewFile();
|
||||
new File(blueprintFolder, "random.txt").createNewFile();
|
||||
|
||||
assertTrue(list.execute(user, "", Collections.emptyList()));
|
||||
Mockito.verify(user).sendMessage("commands.admin.schem.list.available-schems");
|
||||
Mockito.verify(user).sendMessage("commands.admin.blueprint.list.available-blueprints");
|
||||
Mockito.verify(user).sendRawMessage("island");
|
||||
Mockito.verify(user).sendRawMessage("nether-island");
|
||||
Mockito.verify(user).sendRawMessage("end-island");
|
@ -6,13 +6,16 @@ package world.bentobox.bentobox.api.commands.island;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.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.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -33,17 +36,16 @@ import org.powermock.reflect.Whitebox;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.Settings;
|
||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.events.island.IslandEvent.Reason;
|
||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.Clipboard;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.managers.BlueprintsManager;
|
||||
import world.bentobox.bentobox.managers.CommandsManager;
|
||||
import world.bentobox.bentobox.managers.IslandWorldManager;
|
||||
import world.bentobox.bentobox.managers.IslandsManager;
|
||||
import world.bentobox.bentobox.managers.PlayersManager;
|
||||
import world.bentobox.bentobox.managers.SchemsManager;
|
||||
import world.bentobox.bentobox.managers.island.NewIsland;
|
||||
import world.bentobox.bentobox.managers.island.NewIsland.Builder;
|
||||
|
||||
@ -65,17 +67,18 @@ public class IslandCreateCommandTest {
|
||||
@Mock
|
||||
private Builder builder;
|
||||
@Mock
|
||||
private SchemsManager sm;
|
||||
@Mock
|
||||
private BentoBox plugin;
|
||||
@Mock
|
||||
private Settings settings;
|
||||
@Mock
|
||||
private CompositeCommand ic;
|
||||
@Mock
|
||||
private BlueprintsManager bpm;
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// Set up plugin
|
||||
@ -101,6 +104,10 @@ public class IslandCreateCommandTest {
|
||||
// Set up user already
|
||||
User.getInstance(player);
|
||||
|
||||
// Addon
|
||||
GameModeAddon addon = mock(GameModeAddon.class);
|
||||
|
||||
|
||||
// Parent command has no aliases
|
||||
when(ic.getSubCommandAliases()).thenReturn(new HashMap<>());
|
||||
when(ic.getParameters()).thenReturn("parameters");
|
||||
@ -108,13 +115,14 @@ public class IslandCreateCommandTest {
|
||||
when(ic.getPermissionPrefix()).thenReturn("permission.");
|
||||
when(ic.getUsage()).thenReturn("");
|
||||
when(ic.getSubCommand(Mockito.anyString())).thenReturn(Optional.empty());
|
||||
when(ic.getAddon()).thenReturn(addon);
|
||||
|
||||
|
||||
// No island for player to begin with (set it later in the tests)
|
||||
when(im.hasIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(false);
|
||||
when(im.isOwner(Mockito.any(), Mockito.eq(uuid))).thenReturn(false);
|
||||
when(im.hasIsland(any(), eq(uuid))).thenReturn(false);
|
||||
when(im.isOwner(any(), eq(uuid))).thenReturn(false);
|
||||
// Has team
|
||||
when(im.inTeam(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
when(im.inTeam(any(), eq(uuid))).thenReturn(true);
|
||||
when(plugin.getIslands()).thenReturn(im);
|
||||
|
||||
|
||||
@ -127,23 +135,21 @@ public class IslandCreateCommandTest {
|
||||
when(Bukkit.getScheduler()).thenReturn(sch);
|
||||
|
||||
// IWM friendly name
|
||||
when(iwm.getFriendlyName(Mockito.any())).thenReturn("BSkyBlock");
|
||||
when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock");
|
||||
when(plugin.getIWM()).thenReturn(iwm);
|
||||
|
||||
// NewIsland
|
||||
PowerMockito.mockStatic(NewIsland.class);
|
||||
when(NewIsland.builder()).thenReturn(builder);
|
||||
when(builder.player(Mockito.any())).thenReturn(builder);
|
||||
when(builder.player(any())).thenReturn(builder);
|
||||
when(builder.name(Mockito.anyString())).thenReturn(builder);
|
||||
when(builder.world(Mockito.any())).thenReturn(builder);
|
||||
when(builder.reason(Mockito.any())).thenReturn(builder);
|
||||
when(builder.world(any())).thenReturn(builder);
|
||||
when(builder.addon(addon)).thenReturn(builder);
|
||||
when(builder.reason(any())).thenReturn(builder);
|
||||
when(builder.build()).thenReturn(mock(Island.class));
|
||||
|
||||
|
||||
// Schems manager
|
||||
Map<String, Clipboard> map = new HashMap<>();
|
||||
when(sm.get(Mockito.any())).thenReturn(map);
|
||||
when(plugin.getSchemsManager()).thenReturn(sm);
|
||||
// Bundles manager
|
||||
when(plugin.getBlueprintsManager()).thenReturn(bpm);
|
||||
|
||||
// Command
|
||||
cc = new IslandCreateCommand(ic);
|
||||
@ -182,9 +188,9 @@ public class IslandCreateCommandTest {
|
||||
*/
|
||||
@Test
|
||||
public void testCanExecuteUserStringListOfStringHasIsland() {
|
||||
when(im.hasIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(true);
|
||||
when(im.hasIsland(any(), Mockito.any(UUID.class))).thenReturn(true);
|
||||
assertFalse(cc.canExecute(user, "", Collections.emptyList()));
|
||||
Mockito.verify(user).sendMessage(Mockito.eq("general.errors.already-have-island"));
|
||||
verify(user).sendMessage(eq("general.errors.already-have-island"));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -192,10 +198,10 @@ public class IslandCreateCommandTest {
|
||||
*/
|
||||
@Test
|
||||
public void testCanExecuteUserStringListOfStringInTeam() {
|
||||
when(im.hasIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(false);
|
||||
when(im.inTeam(Mockito.any(), Mockito.any(UUID.class))).thenReturn(true);
|
||||
when(im.hasIsland(any(), Mockito.any(UUID.class))).thenReturn(false);
|
||||
when(im.inTeam(any(), Mockito.any(UUID.class))).thenReturn(true);
|
||||
assertFalse(cc.canExecute(user, "", Collections.emptyList()));
|
||||
Mockito.verify(user).sendMessage(Mockito.eq("general.errors.already-have-island"));
|
||||
verify(user).sendMessage(eq("general.errors.already-have-island"));
|
||||
|
||||
}
|
||||
|
||||
@ -204,12 +210,12 @@ public class IslandCreateCommandTest {
|
||||
*/
|
||||
@Test
|
||||
public void testCanExecuteUserStringListOfStringTooManyIslands() {
|
||||
when(im.hasIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(false);
|
||||
when(im.inTeam(Mockito.any(), Mockito.any(UUID.class))).thenReturn(false);
|
||||
when(iwm.getMaxIslands(Mockito.any())).thenReturn(100);
|
||||
when(im.getIslandCount(Mockito.any())).thenReturn(100);
|
||||
when(im.hasIsland(any(), Mockito.any(UUID.class))).thenReturn(false);
|
||||
when(im.inTeam(any(), Mockito.any(UUID.class))).thenReturn(false);
|
||||
when(iwm.getMaxIslands(any())).thenReturn(100);
|
||||
when(im.getIslandCount(any())).thenReturn(100);
|
||||
assertFalse(cc.canExecute(user, "", Collections.emptyList()));
|
||||
Mockito.verify(user).sendMessage(Mockito.eq("commands.island.create.too-many-islands"));
|
||||
verify(user).sendMessage(eq("commands.island.create.too-many-islands"));
|
||||
|
||||
}
|
||||
|
||||
@ -219,13 +225,18 @@ public class IslandCreateCommandTest {
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteUserStringListOfStringSuccess() throws IOException {
|
||||
assertTrue(cc.execute(user, "", Collections.emptyList()));
|
||||
Mockito.verify(builder).player(Mockito.eq(user));
|
||||
Mockito.verify(builder).world(Mockito.any());
|
||||
Mockito.verify(builder).reason(Mockito.eq(Reason.CREATE));
|
||||
Mockito.verify(builder).name(Mockito.eq("island"));
|
||||
Mockito.verify(builder).build();
|
||||
Mockito.verify(user).sendMessage("commands.island.create.creating-island");
|
||||
// Bundle exists
|
||||
when(bpm.validate(any(), any())).thenReturn("custom");
|
||||
// Has permission
|
||||
when(bpm.checkPerm(any(), any(), any())).thenReturn(true);
|
||||
|
||||
assertTrue(cc.execute(user, "", Collections.singletonList("custom")));
|
||||
verify(builder).player(eq(user));
|
||||
verify(builder).addon(any());
|
||||
verify(builder).reason(eq(Reason.CREATE));
|
||||
verify(builder).name(eq("custom"));
|
||||
verify(builder).build();
|
||||
verify(user).sendMessage("commands.island.create.creating-island");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -234,32 +245,49 @@ public class IslandCreateCommandTest {
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteUserStringListOfStringThrowException() throws IOException {
|
||||
// Bundle exists
|
||||
when(bpm.validate(any(), any())).thenReturn("custom");
|
||||
// Has permission
|
||||
when(bpm.checkPerm(any(), any(), any())).thenReturn(true);
|
||||
|
||||
when(builder.build()).thenThrow(new IOException("message"));
|
||||
assertFalse(cc.execute(user, "", Collections.emptyList()));
|
||||
Mockito.verify(user).sendMessage("commands.island.create.creating-island");
|
||||
Mockito.verify(user).sendMessage("commands.island.create.unable-create-island");
|
||||
Mockito.verify(plugin).logError("Could not create island for player. message");
|
||||
assertFalse(cc.execute(user, "", Collections.singletonList("custom")));
|
||||
verify(user).sendMessage("commands.island.create.creating-island");
|
||||
verify(user).sendMessage("commands.island.create.unable-create-island");
|
||||
verify(plugin).logError("Could not create island for player. message");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.island.IslandCreateCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteUserStringListOfStringSchemNoPermission() {
|
||||
when(user.hasPermission(Mockito.anyString())).thenReturn(false);
|
||||
public void testExecuteUserStringListOfStringBundleNoPermission() {
|
||||
// Bundle exists
|
||||
when(bpm.validate(any(), any())).thenReturn("custom");
|
||||
// No permission
|
||||
when(bpm.checkPerm(any(), any(), any())).thenReturn(false);
|
||||
assertFalse(cc.execute(user, "", Collections.singletonList("custom")));
|
||||
Mockito.verify(user).sendMessage(Mockito.eq("general.errors.no-permission"), Mockito.eq(TextVariables.PERMISSION), Mockito.eq("permission.island.create.custom"));
|
||||
Mockito.verify(user, Mockito.never()).sendMessage("commands.island.create.creating-island");
|
||||
verify(user, never()).sendMessage("commands.island.create.creating-island");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.island.IslandCreateCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteUserStringListOfStringUnknownSchem() {
|
||||
public void testExecuteUserStringListOfStringUnknownBundle() {
|
||||
assertFalse(cc.execute(user, "", Collections.singletonList("custom")));
|
||||
Mockito.verify(user).sendMessage(Mockito.eq("commands.island.create.unknown-schem"));
|
||||
Mockito.verify(user, Mockito.never()).sendMessage("commands.island.create.creating-island");
|
||||
verify(user).sendMessage(eq("commands.island.create.unknown-blueprint"));
|
||||
verify(user, never()).sendMessage("commands.island.create.creating-island");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.api.commands.island.IslandCreateCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteUserStringListOfStringNoBundle() {
|
||||
assertTrue(cc.execute(user, "", Collections.emptyList()));
|
||||
//verify(bpm).showPanel(any(), any(), any());
|
||||
//TODO verify it is calling the panel
|
||||
}
|
||||
|
||||
/**
|
||||
@ -267,15 +295,17 @@ public class IslandCreateCommandTest {
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testExecuteUserStringListOfStringKnownSchem() throws IOException {
|
||||
when(sm.validate(Mockito.any(), Mockito.any())).thenReturn("custom");
|
||||
public void testExecuteUserStringListOfStringKnownBundle() throws IOException {
|
||||
// Has permission
|
||||
when(bpm.checkPerm(any(), any(), any())).thenReturn(true);
|
||||
when(bpm.validate(any(), any())).thenReturn("custom");
|
||||
assertTrue(cc.execute(user, "", Collections.singletonList("custom")));
|
||||
Mockito.verify(builder).player(Mockito.eq(user));
|
||||
Mockito.verify(builder).world(Mockito.any());
|
||||
Mockito.verify(builder).reason(Mockito.eq(Reason.CREATE));
|
||||
Mockito.verify(builder).name(Mockito.eq("custom"));
|
||||
Mockito.verify(builder).build();
|
||||
Mockito.verify(user).sendMessage("commands.island.create.creating-island");
|
||||
verify(builder).player(eq(user));
|
||||
verify(builder).addon(any());
|
||||
verify(builder).reason(eq(Reason.CREATE));
|
||||
verify(builder).name(eq("custom"));
|
||||
verify(builder).build();
|
||||
verify(user).sendMessage("commands.island.create.creating-island");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -284,7 +314,7 @@ public class IslandCreateCommandTest {
|
||||
@Test
|
||||
public void testExecuteUserStringListOfStringCooldown() {
|
||||
assertTrue(cc.execute(user, "", Collections.emptyList()));
|
||||
Mockito.verify(ic, Mockito.never()).getSubCommand(Mockito.eq("reset"));
|
||||
verify(ic, never()).getSubCommand(eq("reset"));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -294,6 +324,5 @@ public class IslandCreateCommandTest {
|
||||
public void testExecuteUserStringListOfStringNoCooldown() {
|
||||
when(settings.isResetCooldownOnCreate()).thenReturn(true);
|
||||
assertTrue(cc.execute(user, "", Collections.emptyList()));
|
||||
Mockito.verify(ic).getSubCommand(Mockito.eq("reset"));
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,13 @@ package world.bentobox.bentobox.api.commands.island;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
@ -17,9 +19,10 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.Mock;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
@ -30,11 +33,11 @@ import world.bentobox.bentobox.Settings;
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.managers.BlueprintsManager;
|
||||
import world.bentobox.bentobox.managers.CommandsManager;
|
||||
import world.bentobox.bentobox.managers.IslandWorldManager;
|
||||
import world.bentobox.bentobox.managers.IslandsManager;
|
||||
import world.bentobox.bentobox.managers.PlayersManager;
|
||||
import world.bentobox.bentobox.managers.SchemsManager;
|
||||
import world.bentobox.bentobox.managers.island.NewIsland;
|
||||
|
||||
/**
|
||||
@ -53,6 +56,8 @@ public class IslandResetCommandTest {
|
||||
private PlayersManager pm;
|
||||
private World world;
|
||||
private IslandWorldManager iwm;
|
||||
@Mock
|
||||
private BlueprintsManager bpm;
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
@ -91,20 +96,20 @@ public class IslandResetCommandTest {
|
||||
|
||||
// No island for player to begin with (set it later in the tests)
|
||||
im = mock(IslandsManager.class);
|
||||
when(im.hasIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(false);
|
||||
when(im.isOwner(Mockito.any(), Mockito.eq(uuid))).thenReturn(false);
|
||||
when(im.hasIsland(any(), eq(uuid))).thenReturn(false);
|
||||
when(im.isOwner(any(), eq(uuid))).thenReturn(false);
|
||||
when(plugin.getIslands()).thenReturn(im);
|
||||
|
||||
|
||||
// Has team
|
||||
pm = mock(PlayersManager.class);
|
||||
when(im.inTeam(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
when(im.inTeam(any(), eq(uuid))).thenReturn(true);
|
||||
when(plugin.getPlayers()).thenReturn(pm);
|
||||
|
||||
// Server & Scheduler
|
||||
BukkitScheduler sch = mock(BukkitScheduler.class);
|
||||
BukkitTask task = mock(BukkitTask.class);
|
||||
when(sch.runTaskLater(Mockito.any(), Mockito.any(Runnable.class), Mockito.any(Long.class))).thenReturn(task);
|
||||
when(sch.runTaskLater(any(), any(Runnable.class), any(Long.class))).thenReturn(task);
|
||||
|
||||
PowerMockito.mockStatic(Bukkit.class);
|
||||
when(Bukkit.getScheduler()).thenReturn(sch);
|
||||
@ -112,13 +117,12 @@ public class IslandResetCommandTest {
|
||||
|
||||
// IWM friendly name
|
||||
iwm = mock(IslandWorldManager.class);
|
||||
when(iwm.getFriendlyName(Mockito.any())).thenReturn("BSkyBlock");
|
||||
when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock");
|
||||
when(plugin.getIWM()).thenReturn(iwm);
|
||||
|
||||
// Schems manager - custom schem
|
||||
SchemsManager sm = mock(SchemsManager.class);
|
||||
when(sm.validate(Mockito.any(), Mockito.any())).thenReturn("custom");
|
||||
when(plugin.getSchemsManager()).thenReturn(sm);
|
||||
// Bundles manager
|
||||
when(plugin.getBlueprintsManager()).thenReturn(bpm);
|
||||
when(bpm.validate(any(), any())).thenReturn("custom");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -129,142 +133,139 @@ public class IslandResetCommandTest {
|
||||
IslandResetCommand irc = new IslandResetCommand(ic);
|
||||
// Test the reset command
|
||||
// Does not have island
|
||||
assertFalse(irc.execute(user, irc.getLabel(), new ArrayList<>()));
|
||||
Mockito.verify(user).sendMessage("general.errors.no-island");
|
||||
assertFalse(irc.canExecute(user, irc.getLabel(), Collections.emptyList()));
|
||||
verify(user).sendMessage("general.errors.no-island");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotOwner() {
|
||||
IslandResetCommand irc = new IslandResetCommand(ic);
|
||||
// Now has island, but is not the owner
|
||||
when(im.hasIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
assertFalse(irc.execute(user, irc.getLabel(), new ArrayList<>()));
|
||||
Mockito.verify(user).sendMessage("general.errors.not-owner");
|
||||
when(im.hasIsland(any(), eq(uuid))).thenReturn(true);
|
||||
assertFalse(irc.canExecute(user, irc.getLabel(), Collections.emptyList()));
|
||||
verify(user).sendMessage("general.errors.not-owner");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasTeam() {
|
||||
IslandResetCommand irc = new IslandResetCommand(ic);
|
||||
// Now has island, but is not the owner
|
||||
when(im.hasIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
when(im.hasIsland(any(), eq(uuid))).thenReturn(true);
|
||||
// Now is owner, but still has team
|
||||
when(im.isOwner(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
assertFalse(irc.execute(user, irc.getLabel(), new ArrayList<>()));
|
||||
Mockito.verify(user).sendMessage("commands.island.reset.must-remove-members");
|
||||
when(im.isOwner(any(), eq(uuid))).thenReturn(true);
|
||||
assertFalse(irc.canExecute(user, irc.getLabel(), Collections.emptyList()));
|
||||
verify(user).sendMessage("commands.island.reset.must-remove-members");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoResetsLeft() {
|
||||
IslandResetCommand irc = new IslandResetCommand(ic);
|
||||
// Now has island, but is not the owner
|
||||
when(im.hasIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
when(im.hasIsland(any(), eq(uuid))).thenReturn(true);
|
||||
// Now is owner, but still has team
|
||||
when(im.isOwner(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
when(im.isOwner(any(), eq(uuid))).thenReturn(true);
|
||||
// Now has no team
|
||||
when(im.inTeam(Mockito.any(), Mockito.eq(uuid))).thenReturn(false);
|
||||
when(im.inTeam(any(), eq(uuid))).thenReturn(false);
|
||||
|
||||
// Block based on no resets left
|
||||
when(pm.getResets(Mockito.eq(world),Mockito.eq(uuid))).thenReturn(3);
|
||||
when(pm.getResets(eq(world),eq(uuid))).thenReturn(3);
|
||||
|
||||
assertFalse(irc.execute(user, irc.getLabel(), new ArrayList<>()));
|
||||
Mockito.verify(user).sendMessage("commands.island.reset.none-left");
|
||||
assertFalse(irc.canExecute(user, irc.getLabel(), Collections.emptyList()));
|
||||
verify(user).sendMessage("commands.island.reset.none-left");
|
||||
}
|
||||
|
||||
@Ignore("NPE with ChatColor")
|
||||
@Test
|
||||
public void testNoConfirmationRequired() throws IOException {
|
||||
IslandResetCommand irc = new IslandResetCommand(ic);
|
||||
// Now has island, but is not the owner
|
||||
when(im.hasIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
when(im.hasIsland(any(), eq(uuid))).thenReturn(true);
|
||||
// Now is owner, but still has team
|
||||
when(im.isOwner(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
when(im.isOwner(any(), eq(uuid))).thenReturn(true);
|
||||
// Now has no team
|
||||
when(im.inTeam(Mockito.any(), Mockito.eq(uuid))).thenReturn(false);
|
||||
when(im.inTeam(any(), eq(uuid))).thenReturn(false);
|
||||
// Give the user some resets
|
||||
when(pm.getResetsLeft(Mockito.eq(world), Mockito.eq(uuid))).thenReturn(2);
|
||||
when(pm.getResetsLeft(eq(world), eq(uuid))).thenReturn(2);
|
||||
// Set so no confirmation required
|
||||
when(s.isResetConfirmation()).thenReturn(false);
|
||||
|
||||
// Old island mock
|
||||
Island oldIsland = mock(Island.class);
|
||||
when(im.getIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(oldIsland);
|
||||
when(im.getIsland(any(), eq(uuid))).thenReturn(oldIsland);
|
||||
|
||||
// Mock up NewIsland builder
|
||||
NewIsland.Builder builder = mock(NewIsland.Builder.class);
|
||||
when(builder.player(Mockito.any())).thenReturn(builder);
|
||||
when(builder.oldIsland(Mockito.any())).thenReturn(builder);
|
||||
when(builder.reason(Mockito.any())).thenReturn(builder);
|
||||
when(builder.name(Mockito.any())).thenReturn(builder);
|
||||
when(builder.player(any())).thenReturn(builder);
|
||||
when(builder.oldIsland(any())).thenReturn(builder);
|
||||
when(builder.reason(any())).thenReturn(builder);
|
||||
when(builder.name(any())).thenReturn(builder);
|
||||
when(builder.addon(any())).thenReturn(builder);
|
||||
when(builder.build()).thenReturn(mock(Island.class));
|
||||
PowerMockito.mockStatic(NewIsland.class);
|
||||
when(NewIsland.builder()).thenReturn(builder);
|
||||
|
||||
// Reset command, no confirmation required
|
||||
assertTrue(irc.execute(user, irc.getLabel(), new ArrayList<>()));
|
||||
// Verify that build new island was called and the number of resets left shown
|
||||
Mockito.verify(builder).build();
|
||||
Mockito.verify(user).sendMessage("commands.island.reset.resets-left", "[number]", "2");
|
||||
assertTrue(irc.execute(user, irc.getLabel(), Collections.emptyList()));
|
||||
// TODO Verify that panel was shown
|
||||
// verify(bpm).showPanel(any(), eq(user), eq(irc.getLabel()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnlimitedResets() throws IOException {
|
||||
IslandResetCommand irc = new IslandResetCommand(ic);
|
||||
// Now has island, but is not the owner
|
||||
when(im.hasIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
when(im.hasIsland(any(), eq(uuid))).thenReturn(true);
|
||||
// Now is owner, but still has team
|
||||
when(im.isOwner(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
when(im.isOwner(any(), eq(uuid))).thenReturn(true);
|
||||
// Now has no team
|
||||
when(im.inTeam(Mockito.any(), Mockito.eq(uuid))).thenReturn(false);
|
||||
when(im.inTeam(any(), eq(uuid))).thenReturn(false);
|
||||
// Set so no confirmation required
|
||||
when(s.isResetConfirmation()).thenReturn(false);
|
||||
|
||||
// Old island mock
|
||||
Island oldIsland = mock(Island.class);
|
||||
when(im.getIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(oldIsland);
|
||||
when(im.getIsland(any(), eq(uuid))).thenReturn(oldIsland);
|
||||
|
||||
// Mock up NewIsland builder
|
||||
NewIsland.Builder builder = mock(NewIsland.Builder.class);
|
||||
when(builder.player(Mockito.any())).thenReturn(builder);
|
||||
when(builder.oldIsland(Mockito.any())).thenReturn(builder);
|
||||
when(builder.reason(Mockito.any())).thenReturn(builder);
|
||||
when(builder.name(Mockito.any())).thenReturn(builder);
|
||||
when(builder.player(any())).thenReturn(builder);
|
||||
when(builder.oldIsland(any())).thenReturn(builder);
|
||||
when(builder.reason(any())).thenReturn(builder);
|
||||
when(builder.name(any())).thenReturn(builder);
|
||||
when(builder.addon(any())).thenReturn(builder);
|
||||
when(builder.build()).thenReturn(mock(Island.class));
|
||||
PowerMockito.mockStatic(NewIsland.class);
|
||||
when(NewIsland.builder()).thenReturn(builder);
|
||||
// Test with unlimited resets
|
||||
when(pm.getResetsLeft(Mockito.eq(world), Mockito.eq(uuid))).thenReturn(-1);
|
||||
when(pm.getResetsLeft(eq(world), eq(uuid))).thenReturn(-1);
|
||||
|
||||
// Reset
|
||||
assertTrue(irc.execute(user, irc.getLabel(), new ArrayList<>()));
|
||||
// Verify that build new island was called and the number of resets left shown
|
||||
Mockito.verify(builder).build();
|
||||
// This should not be shown
|
||||
Mockito.verify(user, Mockito.never()).sendMessage("commands.island.reset.resets-left", "[number]", "1");
|
||||
assertTrue(irc.canExecute(user, irc.getLabel(), Collections.emptyList()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfirmationRequired() throws IOException {
|
||||
IslandResetCommand irc = new IslandResetCommand(ic);
|
||||
// Now has island, but is not the owner
|
||||
when(im.hasIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
when(im.hasIsland(any(), eq(uuid))).thenReturn(true);
|
||||
// Now is owner, but still has team
|
||||
when(im.isOwner(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
when(im.isOwner(any(), eq(uuid))).thenReturn(true);
|
||||
// Now has no team
|
||||
when(im.inTeam(Mockito.any(), Mockito.eq(uuid))).thenReturn(false);
|
||||
when(im.inTeam(any(), eq(uuid))).thenReturn(false);
|
||||
// Give the user some resets
|
||||
when(pm.getResetsLeft(Mockito.eq(world), Mockito.eq(uuid))).thenReturn(1);
|
||||
// Set so no confirmation required
|
||||
when(s.isResetConfirmation()).thenReturn(false);
|
||||
when(pm.getResetsLeft(eq(world), eq(uuid))).thenReturn(1);
|
||||
|
||||
// Old island mock
|
||||
Island oldIsland = mock(Island.class);
|
||||
when(im.getIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(oldIsland);
|
||||
when(im.getIsland(any(), eq(uuid))).thenReturn(oldIsland);
|
||||
|
||||
// Mock up NewIsland builder
|
||||
NewIsland.Builder builder = mock(NewIsland.Builder.class);
|
||||
when(builder.player(Mockito.any())).thenReturn(builder);
|
||||
when(builder.oldIsland(Mockito.any())).thenReturn(builder);
|
||||
when(builder.reason(Mockito.any())).thenReturn(builder);
|
||||
when(builder.name(Mockito.any())).thenReturn(builder);
|
||||
when(builder.player(any())).thenReturn(builder);
|
||||
when(builder.oldIsland(any())).thenReturn(builder);
|
||||
when(builder.reason(any())).thenReturn(builder);
|
||||
when(builder.name(any())).thenReturn(builder);
|
||||
when(builder.addon(any())).thenReturn(builder);
|
||||
when(builder.build()).thenReturn(mock(Island.class));
|
||||
PowerMockito.mockStatic(NewIsland.class);
|
||||
when(NewIsland.builder()).thenReturn(builder);
|
||||
@ -274,118 +275,72 @@ public class IslandResetCommandTest {
|
||||
when(s.getConfirmationTime()).thenReturn(20);
|
||||
|
||||
// Reset
|
||||
assertTrue(irc.execute(user, irc.getLabel(), new ArrayList<>()));
|
||||
assertTrue(irc.execute(user, irc.getLabel(), Collections.emptyList()));
|
||||
// Check for message
|
||||
Mockito.verify(user).sendMessage("commands.confirmation.confirm", "[seconds]", String.valueOf(s.getConfirmationTime()));
|
||||
verify(user).sendMessage("commands.confirmation.confirm", "[seconds]", String.valueOf(s.getConfirmationTime()));
|
||||
|
||||
// Send command again to confirm
|
||||
assertTrue(irc.execute(user, irc.getLabel(), new ArrayList<>()));
|
||||
assertTrue(irc.execute(user, irc.getLabel(), Collections.emptyList()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewIslandError() throws IOException {
|
||||
public void testNoConfirmationRequiredUnknownBlueprint() throws IOException {
|
||||
IslandResetCommand irc = new IslandResetCommand(ic);
|
||||
// Now has island, but is not the owner
|
||||
when(im.hasIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
// Now is owner, but still has team
|
||||
when(im.isOwner(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
// Now has no team
|
||||
when(im.inTeam(Mockito.any(), Mockito.eq(uuid))).thenReturn(false);
|
||||
// Give the user some resets
|
||||
when(pm.getResetsLeft(Mockito.eq(world), Mockito.eq(uuid))).thenReturn(1);
|
||||
// Set so no confirmation required
|
||||
when(s.isResetConfirmation()).thenReturn(false);
|
||||
|
||||
// Old island mock
|
||||
Island oldIsland = mock(Island.class);
|
||||
when(im.getIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(oldIsland);
|
||||
|
||||
// Mock up NewIsland builder
|
||||
NewIsland.Builder builder = mock(NewIsland.Builder.class);
|
||||
when(builder.player(Mockito.any())).thenReturn(builder);
|
||||
when(builder.oldIsland(Mockito.any())).thenReturn(builder);
|
||||
when(builder.reason(Mockito.any())).thenReturn(builder);
|
||||
when(builder.name(Mockito.any())).thenReturn(builder);
|
||||
when(builder.build()).thenThrow(new IOException());
|
||||
PowerMockito.mockStatic(NewIsland.class);
|
||||
when(NewIsland.builder()).thenReturn(builder);
|
||||
|
||||
// Require no confirmation
|
||||
when(s.isResetConfirmation()).thenReturn(false);
|
||||
|
||||
// Reset
|
||||
assertFalse(irc.execute(user, irc.getLabel(), new ArrayList<>()));
|
||||
Mockito.verify(user).sendMessage("commands.island.create.unable-create-island");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoConfirmationRequiredCustomSchemNoPermission() throws IOException {
|
||||
IslandResetCommand irc = new IslandResetCommand(ic);
|
||||
// Now has island, but is not the owner
|
||||
when(im.hasIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
// Now is owner, but still has team
|
||||
when(im.isOwner(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
// Now has no team
|
||||
when(im.inTeam(Mockito.any(), Mockito.eq(uuid))).thenReturn(false);
|
||||
// Give the user some resets
|
||||
when(pm.getResetsLeft(Mockito.eq(world), Mockito.eq(uuid))).thenReturn(1);
|
||||
// Set so no confirmation required
|
||||
when(s.isResetConfirmation()).thenReturn(false);
|
||||
|
||||
// Old island mock
|
||||
Island oldIsland = mock(Island.class);
|
||||
when(im.getIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(oldIsland);
|
||||
|
||||
// Mock up NewIsland builder
|
||||
NewIsland.Builder builder = mock(NewIsland.Builder.class);
|
||||
when(builder.player(Mockito.any())).thenReturn(builder);
|
||||
when(builder.oldIsland(Mockito.any())).thenReturn(builder);
|
||||
when(builder.reason(Mockito.any())).thenReturn(builder);
|
||||
when(builder.name(Mockito.any())).thenReturn(builder);
|
||||
when(builder.build()).thenReturn(mock(Island.class));
|
||||
PowerMockito.mockStatic(NewIsland.class);
|
||||
when(NewIsland.builder()).thenReturn(builder);
|
||||
|
||||
|
||||
// No such bundle
|
||||
when(bpm.validate(any(), any())).thenReturn(null);
|
||||
// Reset command, no confirmation required
|
||||
assertFalse(irc.execute(user, irc.getLabel(), Collections.singletonList("custom")));
|
||||
verify(user).sendMessage(
|
||||
"commands.island.create.unknown-blueprint"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoConfirmationRequiredBlueprintNoPerm() throws IOException {
|
||||
IslandResetCommand irc = new IslandResetCommand(ic);
|
||||
// Bundle exists
|
||||
when(bpm.validate(any(), any())).thenReturn("custom");
|
||||
// No permission
|
||||
when(bpm.checkPerm(any(), any(), any())).thenReturn(false);
|
||||
// Reset command, no confirmation required
|
||||
assertFalse(irc.execute(user, irc.getLabel(), Collections.singletonList("custom")));
|
||||
Mockito.verify(user).sendMessage("general.errors.no-permission","[permission]","nullisland.create.custom");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoConfirmationRequiredCustomSchemHasPermission() throws IOException {
|
||||
IslandResetCommand irc = new IslandResetCommand(ic);
|
||||
// Now has island, but is not the owner
|
||||
when(im.hasIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
when(im.hasIsland(any(), eq(uuid))).thenReturn(true);
|
||||
// Now is owner, but still has team
|
||||
when(im.isOwner(Mockito.any(), Mockito.eq(uuid))).thenReturn(true);
|
||||
when(im.isOwner(any(), eq(uuid))).thenReturn(true);
|
||||
// Now has no team
|
||||
when(im.inTeam(Mockito.any(), Mockito.eq(uuid))).thenReturn(false);
|
||||
when(im.inTeam(any(), eq(uuid))).thenReturn(false);
|
||||
// Give the user some resets
|
||||
when(pm.getResetsLeft(Mockito.eq(world), Mockito.eq(uuid))).thenReturn(1);
|
||||
when(pm.getResetsLeft(eq(world), eq(uuid))).thenReturn(1);
|
||||
// Set so no confirmation required
|
||||
when(s.isResetConfirmation()).thenReturn(false);
|
||||
|
||||
// Old island mock
|
||||
Island oldIsland = mock(Island.class);
|
||||
when(im.getIsland(Mockito.any(), Mockito.eq(uuid))).thenReturn(oldIsland);
|
||||
when(im.getIsland(any(), eq(uuid))).thenReturn(oldIsland);
|
||||
|
||||
// Mock up NewIsland builder
|
||||
NewIsland.Builder builder = mock(NewIsland.Builder.class);
|
||||
when(builder.player(Mockito.any())).thenReturn(builder);
|
||||
when(builder.oldIsland(Mockito.any())).thenReturn(builder);
|
||||
when(builder.reason(Mockito.any())).thenReturn(builder);
|
||||
when(builder.name(Mockito.any())).thenReturn(builder);
|
||||
when(builder.player(any())).thenReturn(builder);
|
||||
when(builder.oldIsland(any())).thenReturn(builder);
|
||||
when(builder.reason(any())).thenReturn(builder);
|
||||
when(builder.name(any())).thenReturn(builder);
|
||||
when(builder.addon(any())).thenReturn(builder);
|
||||
when(builder.build()).thenReturn(mock(Island.class));
|
||||
PowerMockito.mockStatic(NewIsland.class);
|
||||
when(NewIsland.builder()).thenReturn(builder);
|
||||
|
||||
// Permission
|
||||
when(user.hasPermission(Mockito.anyString())).thenReturn(true);
|
||||
// Bundle exists
|
||||
when(bpm.validate(any(), any())).thenReturn("custom");
|
||||
// Has permission
|
||||
when(bpm.checkPerm(any(), any(), any())).thenReturn(true);
|
||||
// Reset command, no confirmation required
|
||||
assertTrue(irc.execute(user, irc.getLabel(), Collections.singletonList("custom")));
|
||||
// Verify that build new island was called and the number of resets left shown
|
||||
Mockito.verify(builder).build();
|
||||
Mockito.verify(user).sendMessage("commands.island.reset.resets-left", "[number]", "1");
|
||||
verify(user).sendMessage("commands.island.create.creating-island");
|
||||
}
|
||||
}
|
||||
|
@ -1,301 +0,0 @@
|
||||
package world.bentobox.bentobox.schems;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Chest;
|
||||
import org.bukkit.block.CreatureSpawner;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Cow;
|
||||
import org.bukkit.entity.Creeper;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Horse;
|
||||
import org.bukkit.entity.Horse.Color;
|
||||
import org.bukkit.entity.Horse.Style;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Pig;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Sheep;
|
||||
import org.bukkit.inventory.HorseInventory;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.MaterialData;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.Settings;
|
||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.Clipboard;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({Bukkit.class})
|
||||
public class ClipboardTest {
|
||||
|
||||
private BentoBox plugin;
|
||||
private File schemFolder;
|
||||
private Location loc;
|
||||
private User user;
|
||||
private Location loc2;
|
||||
private Sheep sheep;
|
||||
private Horse horse;
|
||||
private Block block;
|
||||
private World world;
|
||||
private BukkitScheduler sched;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
plugin = mock(BentoBox.class);
|
||||
schemFolder = mock(File.class);
|
||||
when(schemFolder.exists()).thenReturn(true);
|
||||
loc = mock(Location.class);
|
||||
world = mock(World.class);
|
||||
block = mock(Block.class);
|
||||
when(block.getType()).thenReturn(Material.GRASS);
|
||||
when(block.getLocation()).thenReturn(loc);
|
||||
|
||||
BlockData bd = mock(BlockData.class);
|
||||
when(bd.getAsString()).thenReturn("Block_data");
|
||||
when(block.getBlockData()).thenReturn(bd);
|
||||
when(world.getBlockAt(Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt())).thenReturn(block);
|
||||
when(loc.getWorld()).thenReturn(world);
|
||||
when(loc.getBlockX()).thenReturn(1);
|
||||
when(loc.getBlockY()).thenReturn(2);
|
||||
when(loc.getBlockZ()).thenReturn(3);
|
||||
when(loc.getBlock()).thenReturn(block);
|
||||
when(loc.toVector()).thenReturn(new Vector(1,2,3));
|
||||
when(loc.getX()).thenReturn(1D);
|
||||
when(loc.getY()).thenReturn(2D);
|
||||
when(loc.getZ()).thenReturn(3D);
|
||||
|
||||
loc2 = mock(Location.class);
|
||||
when(loc2.getWorld()).thenReturn(world);
|
||||
when(loc2.getBlockX()).thenReturn(2);
|
||||
when(loc2.getBlockY()).thenReturn(3);
|
||||
when(loc2.getBlockZ()).thenReturn(4);
|
||||
when(loc2.getBlock()).thenReturn(block);
|
||||
when(loc2.toVector()).thenReturn(new Vector(2,3,4));
|
||||
when(loc2.getX()).thenReturn(2D);
|
||||
when(loc2.getY()).thenReturn(3D);
|
||||
when(loc2.getZ()).thenReturn(4D);
|
||||
// Living entities
|
||||
|
||||
List<LivingEntity> ents = new ArrayList<>();
|
||||
Pig pig = mock(Pig.class);
|
||||
Player player = mock(Player.class);
|
||||
Cow cow = mock(Cow.class);
|
||||
Creeper creeper = mock(Creeper.class);
|
||||
sheep = mock(Sheep.class);
|
||||
horse = mock(Horse.class);
|
||||
when(pig.getLocation()).thenReturn(loc);
|
||||
when(cow.getLocation()).thenReturn(loc);
|
||||
when(creeper.getLocation()).thenReturn(loc);
|
||||
when(player.getLocation()).thenReturn(loc);
|
||||
when(sheep.getLocation()).thenReturn(loc);
|
||||
when(horse.getLocation()).thenReturn(loc);
|
||||
|
||||
when(pig.getType()).thenReturn(EntityType.PIG);
|
||||
when(player.getType()).thenReturn(EntityType.PLAYER);
|
||||
when(cow.getType()).thenReturn(EntityType.COW);
|
||||
when(creeper.getType()).thenReturn(EntityType.CREEPER);
|
||||
when(sheep.getType()).thenReturn(EntityType.SHEEP);
|
||||
when(sheep.getColor()).thenReturn(DyeColor.LIGHT_BLUE);
|
||||
when(horse.getType()).thenReturn(EntityType.HORSE);
|
||||
when(horse.getColor()).thenReturn(Color.CREAMY);
|
||||
when(horse.getStyle()).thenReturn(Style.BLACK_DOTS);
|
||||
|
||||
HorseInventory inv = mock(HorseInventory.class);
|
||||
when(horse.getInventory()).thenReturn(inv);
|
||||
|
||||
// UUIDs (I'm going to assume these will all be unique (prays to god of randomness)
|
||||
when(creeper.getUniqueId()).thenReturn(UUID.randomUUID());
|
||||
when(player.getUniqueId()).thenReturn(UUID.randomUUID());
|
||||
when(cow.getUniqueId()).thenReturn(UUID.randomUUID());
|
||||
when(pig.getUniqueId()).thenReturn(UUID.randomUUID());
|
||||
when(sheep.getUniqueId()).thenReturn(UUID.randomUUID());
|
||||
when(horse.getUniqueId()).thenReturn(UUID.randomUUID());
|
||||
|
||||
ents.add(creeper);
|
||||
ents.add(player);
|
||||
ents.add(cow);
|
||||
ents.add(pig);
|
||||
ents.add(sheep);
|
||||
ents.add(horse);
|
||||
when(world.getLivingEntities()).thenReturn(ents);
|
||||
|
||||
user = mock(User.class);
|
||||
User.setPlugin(plugin);
|
||||
when(user.getLocation()).thenReturn(loc);
|
||||
|
||||
// Scheduler
|
||||
PowerMockito.mockStatic(Bukkit.class);
|
||||
sched = mock(BukkitScheduler.class);
|
||||
when(Bukkit.getScheduler()).thenReturn(sched);
|
||||
|
||||
// Settings
|
||||
Settings settings = mock(Settings.class);
|
||||
when(settings.getPasteSpeed()).thenReturn(200);
|
||||
when(plugin.getSettings()).thenReturn(settings);
|
||||
|
||||
// Default block state
|
||||
BlockState bs = mock(BlockState.class);
|
||||
when(block.getState()).thenReturn(bs);
|
||||
MaterialData md = mock(MaterialData.class);
|
||||
when(bs.getData()).thenReturn(md);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClipboard() {
|
||||
new Clipboard();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetGetPos1() {
|
||||
Clipboard cb = new Clipboard();
|
||||
assertNull(cb.getPos1());
|
||||
cb.setPos1(loc);
|
||||
assertEquals(loc, cb.getPos1());
|
||||
assertNull(cb.getOrigin());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetGetPos2() {
|
||||
Clipboard cb = new Clipboard();
|
||||
assertNull(cb.getPos2());
|
||||
cb.setPos2(loc);
|
||||
assertEquals(loc, cb.getPos2());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetGetOrigin() {
|
||||
Clipboard cb = new Clipboard();
|
||||
assertNull(cb.getOrigin());
|
||||
cb.setOrigin(loc);
|
||||
assertEquals(loc, cb.getOrigin());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyNoPos1Pos2() {
|
||||
Clipboard cb = new Clipboard();
|
||||
cb.copy(user, false);
|
||||
Mockito.verify(user).sendMessage(Mockito.eq("commands.admin.schem.need-pos1-pos2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyNoPos2() {
|
||||
Clipboard cb = new Clipboard();
|
||||
cb.setPos1(loc);
|
||||
cb.copy(user, false);
|
||||
Mockito.verify(user).sendMessage(Mockito.eq("commands.admin.schem.need-pos1-pos2"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy is now done async so these copy tests are invalid
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
public void testCopy() {
|
||||
Clipboard cb = new Clipboard();
|
||||
cb.setPos1(loc);
|
||||
cb.setPos2(loc2);
|
||||
cb.copy(user, false);
|
||||
Mockito.verify(user).sendMessage("commands.admin.schem.copied-blocks", TextVariables.NUMBER, "8");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testCopySigns() {
|
||||
when(block.getType()).thenReturn(Material.SIGN);
|
||||
Sign bs = mock(Sign.class);
|
||||
String[] lines = {"line1", "line2", "line3", "line4"};
|
||||
when(bs.getLines()).thenReturn(lines);
|
||||
when(block.getState()).thenReturn(bs);
|
||||
Clipboard cb = new Clipboard();
|
||||
cb.setPos1(loc);
|
||||
cb.setPos2(loc2);
|
||||
cb.copy(user, false);
|
||||
Mockito.verify(user).sendMessage("commands.admin.schem.copied-blocks", TextVariables.NUMBER, "8");
|
||||
// Every block is a sign, so this should be called 8 times
|
||||
Mockito.verify(bs, Mockito.times(8)).getLines();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testCopyChests() {
|
||||
when(block.getType()).thenReturn(Material.CHEST);
|
||||
Chest bs = mock(Chest.class);
|
||||
Inventory inv = mock(Inventory.class);
|
||||
ItemStack[] contents = { new ItemStack(Material.ACACIA_BOAT, 1), new ItemStack(Material.GLASS, 23)};
|
||||
when(inv.getContents()).thenReturn(contents);
|
||||
when(bs.getInventory()).thenReturn(inv);
|
||||
when(block.getState()).thenReturn(bs);
|
||||
Clipboard cb = new Clipboard();
|
||||
cb.setPos1(loc);
|
||||
cb.setPos2(loc2);
|
||||
cb.copy(user, false);
|
||||
Mockito.verify(user).sendMessage("commands.admin.schem.copied-blocks", TextVariables.NUMBER, "8");
|
||||
// Every block is a sign, so this should be called 8 times
|
||||
Mockito.verify(bs, Mockito.times(8)).getInventory();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testCopyCreatureSpawners() {
|
||||
when(block.getType()).thenReturn(Material.SPAWNER);
|
||||
CreatureSpawner bs = mock(CreatureSpawner.class);
|
||||
when(bs.getSpawnedType()).thenReturn(EntityType.CAVE_SPIDER);
|
||||
when(block.getState()).thenReturn(bs);
|
||||
Clipboard cb = new Clipboard();
|
||||
cb.setPos1(loc);
|
||||
cb.setPos2(loc2);
|
||||
cb.copy(user, false);
|
||||
Mockito.verify(user).sendMessage("commands.admin.schem.copied-blocks", TextVariables.NUMBER, "8");
|
||||
// Every block is a sign, so this should be called 8 times
|
||||
Mockito.verify(bs, Mockito.times(8)).getMaxNearbyEntities();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testCopyAir() {
|
||||
// No entities
|
||||
when(world.getLivingEntities()).thenReturn(new ArrayList<>());
|
||||
when(block.getType()).thenReturn(Material.AIR);
|
||||
BlockState bs = mock(BlockState.class);
|
||||
when(block.getState()).thenReturn(bs);
|
||||
Clipboard cb = new Clipboard();
|
||||
cb.setPos1(loc);
|
||||
cb.setPos2(loc2);
|
||||
// Do not copy air
|
||||
cb.copy(user, false);
|
||||
Mockito.verify(user).sendMessage("commands.admin.schem.copied-blocks", TextVariables.NUMBER, "0");
|
||||
cb.copy(user, true);
|
||||
Mockito.verify(user).sendMessage("commands.admin.schem.copied-blocks", TextVariables.NUMBER, "8");
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user