mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-12-29 12:37:37 +01:00
Merge pull request #426 from BentoBoxWorld/async-paste2
Implemented async schem pasting
This commit is contained in:
commit
a7f99e2a65
@ -214,7 +214,7 @@ public class BentoBox extends JavaPlugin {
|
||||
if (islandsManager != null) {
|
||||
islandsManager.shutdown();
|
||||
}
|
||||
// Save settings
|
||||
// Save settings - ensures admins always have the latest config file
|
||||
if (settings != null) {
|
||||
new Config<>(this, Settings.class).saveConfigObject(settings);
|
||||
}
|
||||
|
@ -140,6 +140,11 @@ public class Settings implements DataObject {
|
||||
@ConfigEntry(path = "island.name.max-length")
|
||||
private int nameMaxLength = 20;
|
||||
|
||||
@ConfigComment("Number of blocks to paste per tick when pasting a schem")
|
||||
@ConfigComment("Smaller values will help reduce noticeable lag but will make pasting take longer")
|
||||
@ConfigEntry(path = "island.paste-speed")
|
||||
private int pasteSpeed = 1000;
|
||||
|
||||
// Ranks
|
||||
@ConfigEntry(path = "island.custom-ranks", experimental = true)
|
||||
private Map<String, Integer> customRanks = new HashMap<>();
|
||||
@ -359,6 +364,20 @@ public class Settings implements DataObject {
|
||||
this.nameMaxLength = nameMaxLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pasteSpeed the pasteSpeed to set
|
||||
*/
|
||||
public void setPasteSpeed(int pasteSpeed) {
|
||||
this.pasteSpeed = pasteSpeed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return paste speed in blocks per tick
|
||||
*/
|
||||
public int getPasteSpeed() {
|
||||
return this.pasteSpeed;
|
||||
}
|
||||
|
||||
public Map<String, Integer> getCustomRanks() {
|
||||
return customRanks;
|
||||
}
|
||||
@ -383,4 +402,6 @@ public class Settings implements DataObject {
|
||||
this.uniqueId = uniqueId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -90,6 +90,7 @@ public class IslandResetCommand extends ConfirmableCommand {
|
||||
// Reset the island
|
||||
Player player = user.getPlayer();
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
user.sendMessage("commands.island.create.creating-island");
|
||||
// Get the player's old island
|
||||
Island oldIsland = getIslands().getIsland(getWorld(), player.getUniqueId());
|
||||
// Remove them from this island (it still exists and will be deleted later)
|
||||
|
@ -10,10 +10,11 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.database.json.AbstractJSONDatabaseHandler;
|
||||
import world.bentobox.bentobox.database.DatabaseConnector;
|
||||
import world.bentobox.bentobox.database.json.AbstractJSONDatabaseHandler;
|
||||
import world.bentobox.bentobox.database.objects.DataObject;
|
||||
|
||||
/**
|
||||
@ -72,7 +73,17 @@ public class MySQLDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
|
||||
// Load all the results
|
||||
Gson gson = getGson();
|
||||
while (resultSet.next()) {
|
||||
list.add(gson.fromJson(resultSet.getString("json"), dataObject));
|
||||
String json = resultSet.getString("json");
|
||||
if (json != null) {
|
||||
try {
|
||||
T gsonResult = gson.fromJson(json, dataObject);
|
||||
if (gsonResult != null) {
|
||||
list.add(gsonResult);
|
||||
}
|
||||
} catch (JsonSyntaxException ex) {
|
||||
plugin.logError("Could not load object " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
|
@ -564,6 +564,7 @@ public class IslandsManager {
|
||||
user.sendMessage("commands.island.go.teleported", TextVariables.NUMBER, String.valueOf(number));
|
||||
}
|
||||
// Exit spectator mode if in it
|
||||
|
||||
if (player.getGameMode().equals(GameMode.SPECTATOR)) {
|
||||
player.setGameMode(plugin.getIWM().getDefaultGameMode(world));
|
||||
}
|
||||
@ -679,25 +680,25 @@ public class IslandsManager {
|
||||
* @param island to remove players from
|
||||
*/
|
||||
public void removePlayersFromIsland(Island island) {
|
||||
// Teleport players away
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (island.inIslandSpace(player.getLocation().getBlockX(), player.getLocation().getBlockZ())) {
|
||||
// Teleport island players to their island home
|
||||
if (hasIsland(island.getWorld(), player.getUniqueId()) || plugin.getIslands().inTeam(island.getWorld(), player.getUniqueId())) {
|
||||
homeTeleport(island.getWorld(), player);
|
||||
World w = island.getWorld();
|
||||
Bukkit.getOnlinePlayers().stream()
|
||||
.filter(p -> p.getGameMode().equals(plugin.getIWM().getDefaultGameMode(island.getWorld())))
|
||||
.filter(p -> island.onIsland(p.getLocation())).forEach(p -> {
|
||||
// Teleport island players to their island home
|
||||
if (!island.getMemberSet().contains(p.getUniqueId()) && (hasIsland(w, p.getUniqueId()) || inTeam(w, p.getUniqueId()))) {
|
||||
homeTeleport(w, p);
|
||||
} else {
|
||||
// Move player to spawn
|
||||
if (spawn.containsKey(w)) {
|
||||
// go to island spawn
|
||||
p.teleport(spawn.get(w).getSpawnPoint(w.getEnvironment()));
|
||||
} else {
|
||||
// Move player to spawn
|
||||
if (spawn.containsKey(island.getWorld())) {
|
||||
// go to island spawn
|
||||
player.teleport(spawn.get(island.getWorld()).getSpawnPoint(island.getWorld().getEnvironment()));
|
||||
} else {
|
||||
plugin.logWarning("During island deletion player " + player.getName() + " could not be sent home so was placed into spectator mode.");
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
player.getPlayer().setFlying(true);
|
||||
}
|
||||
plugin.logWarning("During island deletion player " + p.getName() + " could not be sent home so was placed into spectator mode.");
|
||||
p.setGameMode(GameMode.SPECTATOR);
|
||||
p.setFlying(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -797,13 +798,13 @@ public class IslandsManager {
|
||||
*/
|
||||
public void setOwner(User user, UUID targetUUID, Island island) {
|
||||
islandCache.setOwner(island, targetUUID);
|
||||
user.sendMessage("commands.island.team.setowner.name-is-the-owner", "[name]", plugin.getPlayers().getName(targetUUID));
|
||||
user.sendMessage("commands.island.team.setowner.name-is-the-owner", "[name]", plugin.getPlayers().getName(targetUUID));
|
||||
plugin.getIWM().getAddon(island.getWorld()).ifPresent(addon -> {
|
||||
User target = User.getInstance(targetUUID);
|
||||
// Tell target. If they are offline, then they may receive a message when they login
|
||||
target.sendMessage("commands.island.team.setowner.you-are-the-owner");
|
||||
// Permission checks for range changes only work when the target is online
|
||||
if (target.isOnline()) {
|
||||
if (target.isOnline()) {
|
||||
// Check if new owner has a different range permission than the island size
|
||||
int range = target.getPermissionValue(
|
||||
addon.getPermissionPrefix() + "island.range",
|
||||
|
@ -46,11 +46,7 @@ public class NewIsland {
|
||||
this.reason = reason;
|
||||
this.world = world;
|
||||
this.name = name;
|
||||
newIsland();
|
||||
if (oldIsland != null) {
|
||||
// Delete the old island
|
||||
plugin.getIslands().deleteIsland(oldIsland, true);
|
||||
}
|
||||
newIsland(oldIsland);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,8 +117,9 @@ public class NewIsland {
|
||||
|
||||
/**
|
||||
* Makes an island.
|
||||
* @param oldIsland
|
||||
*/
|
||||
public void newIsland() {
|
||||
public void newIsland(Island oldIsland) {
|
||||
Location next = getNextIsland();
|
||||
if (next == null) {
|
||||
plugin.logError("Failed to make island - no unoccupied spot found");
|
||||
@ -160,11 +157,21 @@ public class NewIsland {
|
||||
plugin.getPlayers().setHomeLocation(user, island.getSpawnPoint(Environment.NORMAL), 1);
|
||||
}
|
||||
// Stop the player from falling or moving if they are
|
||||
user.getPlayer().setVelocity(new Vector(0,0,0));
|
||||
user.getPlayer().setFallDistance(0F);
|
||||
if (user.isOnline()) {
|
||||
user.getPlayer().setVelocity(new Vector(0,0,0));
|
||||
user.getPlayer().setFallDistance(0F);
|
||||
|
||||
// Teleport player after this island is built
|
||||
plugin.getIslands().homeTeleport(world, user.getPlayer(), true);
|
||||
// Teleport player after this island is built
|
||||
plugin.getIslands().homeTeleport(world, user.getPlayer(), true);
|
||||
} else {
|
||||
// Remove the player again to completely clear the data
|
||||
User.removePlayer(user.getPlayer());
|
||||
}
|
||||
// Delete old island
|
||||
if (oldIsland != null) {
|
||||
// Delete the old island
|
||||
plugin.getIslands().deleteIsland(oldIsland, true);
|
||||
}
|
||||
});
|
||||
// Make nether island
|
||||
if (plugin.getIWM().isNetherGenerate(world) && plugin.getIWM().isNetherIslands(world) && plugin.getIWM().getNetherWorld(world) != null) {
|
||||
|
@ -10,6 +10,7 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
@ -41,7 +42,9 @@ import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.Attachable;
|
||||
import org.bukkit.material.Colorable;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
@ -55,9 +58,21 @@ import world.bentobox.bentobox.util.Util;
|
||||
*/
|
||||
public class Clipboard {
|
||||
|
||||
enum PasteState {
|
||||
BLOCKS,
|
||||
ATTACHMENTS,
|
||||
ENTITIES,
|
||||
DONE
|
||||
}
|
||||
|
||||
// Speed of pasting
|
||||
private int pasteSpeed;
|
||||
private PasteState pasteState;
|
||||
|
||||
// Commonly used texts along this class.
|
||||
private static final String ATTACHED = "attached";
|
||||
private static final String BLOCK = "blocks";
|
||||
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 INVENTORY = "inventory";
|
||||
private static final String ENTITY = "entity";
|
||||
@ -73,6 +88,8 @@ public class Clipboard {
|
||||
|
||||
private File schemFolder;
|
||||
|
||||
private BukkitTask pastingTask;
|
||||
|
||||
public Clipboard(BentoBox plugin, File schemFolder) {
|
||||
super();
|
||||
this.plugin = plugin;
|
||||
@ -80,6 +97,8 @@ public class Clipboard {
|
||||
schemFolder.mkdirs();
|
||||
}
|
||||
this.schemFolder = schemFolder;
|
||||
pasteSpeed = plugin.getSettings().getPasteSpeed();
|
||||
pasteState = PasteState.BLOCKS;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -187,15 +206,66 @@ public class Clipboard {
|
||||
// Calculate location for pasting
|
||||
Location loc = island.getCenter().toVector().subtract(off).toLocation(world);
|
||||
// Paste
|
||||
if (blockConfig.contains(BLOCK)) {
|
||||
blockConfig.getConfigurationSection(BLOCK).getKeys(false).forEach(b -> pasteBlock(world, island, loc, blockConfig.getConfigurationSection(BLOCK + "." + b)));
|
||||
} else {
|
||||
paste(world, island, loc, task);
|
||||
}
|
||||
|
||||
private void paste(World world, Island island, Location loc, Runnable task) {
|
||||
if (!blockConfig.contains(BLOCKS_YAML_PREFIX)) {
|
||||
plugin.logError("Clipboard has no block data in it to paste!");
|
||||
return;
|
||||
}
|
||||
// Run follow on task if it exists
|
||||
if (task != null) {
|
||||
Bukkit.getScheduler().runTaskLater(plugin, task, 2L);
|
||||
}
|
||||
// Iterators for the various schem sections
|
||||
Iterator<String> it = blockConfig.getConfigurationSection(BLOCKS_YAML_PREFIX).getKeys(false).iterator();
|
||||
Iterator<String> it2 = blockConfig.contains(ATTACHED_YAML_PREFIX) ? blockConfig.getConfigurationSection(ATTACHED_YAML_PREFIX).getKeys(false).iterator() : null;
|
||||
Iterator<String> it3 = blockConfig.contains(ENTITIES_YAML_PREFIX) ? blockConfig.getConfigurationSection(ENTITIES_YAML_PREFIX).getKeys(false).iterator() : null;
|
||||
|
||||
// Initial state & speed
|
||||
pasteState = PasteState.BLOCKS;
|
||||
pasteSpeed = plugin.getSettings().getPasteSpeed();
|
||||
|
||||
pastingTask = Bukkit.getScheduler().runTaskTimer(plugin, () -> {
|
||||
int count = 0;
|
||||
while (pasteState.equals(PasteState.BLOCKS) && count < pasteSpeed && it.hasNext()) {
|
||||
pasteBlock(world, island, loc, blockConfig.getConfigurationSection(BLOCKS_YAML_PREFIX + it.next()));
|
||||
count++;
|
||||
}
|
||||
while (it2 != null && pasteState.equals(PasteState.ATTACHMENTS) && count < pasteSpeed && it2.hasNext()) {
|
||||
pasteBlock(world, island, loc, blockConfig.getConfigurationSection(ATTACHED_YAML_PREFIX + it2.next()));
|
||||
count++;
|
||||
}
|
||||
while (it3 != null && pasteState.equals(PasteState.ENTITIES) && count < pasteSpeed && it3.hasNext()) {
|
||||
pasteEntity(world, island, loc, blockConfig.getConfigurationSection(ENTITIES_YAML_PREFIX + it3.next()));
|
||||
count++;
|
||||
}
|
||||
// STATE SHIFT
|
||||
if (pasteState.equals(PasteState.BLOCKS) && !it.hasNext()) {
|
||||
// Blocks done.
|
||||
if (it2 == null && it3 == null) {
|
||||
// No attachments or entities
|
||||
pasteState = PasteState.DONE;
|
||||
} else {
|
||||
// Next paste attachments, otherwise skip to entities
|
||||
pasteState = it2 != null ? PasteState.ATTACHMENTS : PasteState.ENTITIES;
|
||||
}
|
||||
}
|
||||
if (pasteState.equals(PasteState.ATTACHMENTS) && !it2.hasNext()) {
|
||||
// Attachments done. Next paste entities, otherwise done
|
||||
pasteState = it3 != null ? PasteState.ENTITIES : PasteState.DONE;
|
||||
}
|
||||
if (pasteState.equals(PasteState.ENTITIES) && !it3.hasNext()) {
|
||||
pasteState = PasteState.DONE;
|
||||
}
|
||||
if (pasteState.equals(PasteState.DONE)) {
|
||||
// All done. Cancel task
|
||||
pastingTask.cancel();
|
||||
if (task != null) {
|
||||
// Run follow on task if it exists
|
||||
Bukkit.getScheduler().runTaskLater(plugin, task, 2L);
|
||||
}
|
||||
}
|
||||
}, 0L, 1L);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -203,8 +273,9 @@ public class Clipboard {
|
||||
* @param location - location
|
||||
*/
|
||||
public void pasteClipboard(Location location) {
|
||||
if (blockConfig.contains(BLOCK)) {
|
||||
blockConfig.getConfigurationSection(BLOCK).getKeys(false).forEach(b -> pasteBlock(location.getWorld(), null, location, blockConfig.getConfigurationSection(BLOCK + "." + b)));
|
||||
if (blockConfig.contains(BLOCKS_YAML_PREFIX)) {
|
||||
paste(location.getWorld(), null, location, null);
|
||||
//blockConfig.getConfigurationSection(BLOCKS_YAML_PREFIX).getKeys(false).forEach(b -> pasteBlock(location.getWorld(), null, location, blockConfig.getConfigurationSection(BLOCKS_YAML_PREFIX + "." + b)));
|
||||
} else {
|
||||
plugin.logError("Clipboard has no block data in it to paste!");
|
||||
}
|
||||
@ -229,7 +300,7 @@ public class Clipboard {
|
||||
plugin.getIWM().getAddon(island.getWorld()).ifPresent(addon -> {
|
||||
lines.clear();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
lines.add(ChatColor.translateAlternateColorCodes('&', plugin.getLocalesManager().getOrDefault(User.getInstance(island.getOwner()),
|
||||
lines.add(ChatColor.translateAlternateColorCodes('&', plugin.getLocalesManager().getOrDefault(User.getInstance(island.getOwner()),
|
||||
addon.getDescription().getName().toLowerCase() + ".sign.line" + i,"")));
|
||||
}
|
||||
});
|
||||
@ -257,18 +328,22 @@ public class Clipboard {
|
||||
Block block = world.getBlockAt(x, y, z);
|
||||
String blockData = config.getString("bd");
|
||||
if (blockData != null) {
|
||||
if (config.getBoolean(ATTACHED)) {
|
||||
plugin.getServer().getScheduler().runTask(plugin, () -> setBlock(island, block, config, blockData));
|
||||
} else {
|
||||
setBlock(island, block, config, blockData);
|
||||
}
|
||||
setBlock(island, block, config, blockData);
|
||||
}
|
||||
// Entities
|
||||
// Entities (legacy)
|
||||
if (config.isConfigurationSection(ENTITY)) {
|
||||
setEntity(block.getLocation(), config);
|
||||
setEntity(block.getLocation(), config.getConfigurationSection(ENTITY));
|
||||
}
|
||||
}
|
||||
|
||||
private void pasteEntity(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]);
|
||||
setEntity(new Location(world, x, y, z), config);
|
||||
}
|
||||
|
||||
private void setBlock(Island island, Block block, ConfigurationSection config, String blockData) {
|
||||
// Set the block data
|
||||
block.setBlockData(Bukkit.createBlockData(blockData));
|
||||
@ -281,11 +356,11 @@ public class Clipboard {
|
||||
* @param location - locaton
|
||||
* @param config - config section
|
||||
*/
|
||||
private void setEntity(Location location, ConfigurationSection config) {
|
||||
ConfigurationSection en = config.getConfigurationSection(ENTITY);
|
||||
private void setEntity(Location location, ConfigurationSection en) {
|
||||
en.getKeys(false).forEach(k -> {
|
||||
ConfigurationSection ent = en.getConfigurationSection(k);
|
||||
Location center = location.add(new Vector(0.5, 0.0, 0.5));
|
||||
// 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"));
|
||||
@ -369,11 +444,11 @@ public class Clipboard {
|
||||
String pos = x + "," + y + "," + z;
|
||||
|
||||
// Position defines the section
|
||||
ConfigurationSection s = blockConfig.createSection(BLOCK + "." + pos);
|
||||
ConfigurationSection s = blockConfig.createSection(BLOCKS_YAML_PREFIX + "." + pos);
|
||||
|
||||
// Set entities
|
||||
for (LivingEntity e: entities) {
|
||||
ConfigurationSection en = s.createSection("entity." + e.getUniqueId());
|
||||
ConfigurationSection en = blockConfig.createSection(ENTITIES_YAML_PREFIX + pos + "." + e.getUniqueId());
|
||||
en.set("type", e.getType().name());
|
||||
en.set("name", e.getCustomName());
|
||||
if (e instanceof Colorable) {
|
||||
@ -413,15 +488,34 @@ public class Clipboard {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Block state
|
||||
BlockState bs = block.getState();
|
||||
|
||||
// Set block data
|
||||
s.set("bd", block.getBlockData().getAsString());
|
||||
if (bs.getData() instanceof Attachable) {
|
||||
ConfigurationSection a = blockConfig.createSection(ATTACHED_YAML_PREFIX + pos);
|
||||
a.set("bd", block.getBlockData().getAsString());
|
||||
// Placeholder for attachment
|
||||
s.set("bd", "minecraft:air");
|
||||
// Signs
|
||||
if (bs instanceof Sign) {
|
||||
Sign sign = (Sign)bs;
|
||||
a.set("lines", Arrays.asList(sign.getLines()));
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
s.set("bd", block.getBlockData().getAsString());
|
||||
// Signs
|
||||
if (bs instanceof Sign) {
|
||||
Sign sign = (Sign)bs;
|
||||
s.set("lines", Arrays.asList(sign.getLines()));
|
||||
}
|
||||
}
|
||||
|
||||
if (block.getType().equals(Material.BEDROCK)) {
|
||||
blockConfig.set(BEDROCK, x + "," + y + "," + z);
|
||||
}
|
||||
|
||||
// Block state
|
||||
BlockState bs = block.getState();
|
||||
// Chests
|
||||
if (bs instanceof InventoryHolder) {
|
||||
InventoryHolder ih = (InventoryHolder)bs;
|
||||
@ -432,11 +526,7 @@ public class Clipboard {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Signs
|
||||
if (bs instanceof Sign) {
|
||||
Sign sign = (Sign)bs;
|
||||
s.set("lines", Arrays.asList(sign.getLines()));
|
||||
}
|
||||
|
||||
if (bs instanceof CreatureSpawner) {
|
||||
CreatureSpawner spawner = (CreatureSpawner)bs;
|
||||
s.set("spawnedType",spawner.getSpawnedType().name());
|
||||
|
@ -72,6 +72,9 @@ 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
|
||||
# Smaller values will help reduce noticeable lag but will make pasting take longer
|
||||
paste-speed: 1000
|
||||
# /!\ This feature is experimental and might not work as expected or might not work at all.
|
||||
custom-ranks: {}
|
||||
# These settings should not be edited
|
||||
|
@ -247,7 +247,7 @@ commands:
|
||||
parameters: "<schem>"
|
||||
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..."
|
||||
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."
|
||||
info:
|
||||
|
@ -108,6 +108,7 @@ public class AdminClearresetsallCommandTest {
|
||||
/**
|
||||
* Test method for .
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void testExecuteCheckConfirm() {
|
||||
AdminClearresetsallCommand itl = new AdminClearresetsallCommand(ac);
|
||||
|
@ -36,6 +36,7 @@ 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;
|
||||
@ -47,10 +48,12 @@ 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.database.objects.Island;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({Bukkit.class})
|
||||
public class ClipboardTest {
|
||||
@ -76,7 +79,7 @@ public class ClipboardTest {
|
||||
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);
|
||||
@ -87,7 +90,7 @@ public class ClipboardTest {
|
||||
when(loc.getBlockZ()).thenReturn(3);
|
||||
when(loc.getBlock()).thenReturn(block);
|
||||
when(loc.toVector()).thenReturn(new Vector(1,2,3));
|
||||
|
||||
|
||||
loc2 = mock(Location.class);
|
||||
when(loc2.getWorld()).thenReturn(world);
|
||||
when(loc2.getBlockX()).thenReturn(2);
|
||||
@ -95,7 +98,7 @@ public class ClipboardTest {
|
||||
when(loc2.getBlockZ()).thenReturn(4);
|
||||
when(loc2.getBlock()).thenReturn(block);
|
||||
// Living entities
|
||||
|
||||
|
||||
List<LivingEntity> ents = new ArrayList<>();
|
||||
Pig pig = mock(Pig.class);
|
||||
Player player = mock(Player.class);
|
||||
@ -109,7 +112,7 @@ public class ClipboardTest {
|
||||
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);
|
||||
@ -122,7 +125,7 @@ public class ClipboardTest {
|
||||
|
||||
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());
|
||||
@ -138,29 +141,40 @@ public class ClipboardTest {
|
||||
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() {
|
||||
when(schemFolder.exists()).thenReturn(false);
|
||||
new Clipboard(plugin, schemFolder);
|
||||
new Clipboard(plugin, schemFolder);
|
||||
Mockito.verify(schemFolder).mkdirs();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetGetPos1() {
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
assertNull(cb.getPos1());
|
||||
cb.setPos1(loc);
|
||||
assertEquals(loc, cb.getPos1());
|
||||
@ -169,7 +183,7 @@ public class ClipboardTest {
|
||||
|
||||
@Test
|
||||
public void testSetGetPos2() {
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
assertNull(cb.getPos2());
|
||||
cb.setPos2(loc);
|
||||
assertEquals(loc, cb.getPos2());
|
||||
@ -177,7 +191,7 @@ public class ClipboardTest {
|
||||
|
||||
@Test
|
||||
public void testSetGetOrigin() {
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
assertNull(cb.getOrigin());
|
||||
cb.setOrigin(loc);
|
||||
assertEquals(loc, cb.getOrigin());
|
||||
@ -185,28 +199,28 @@ public class ClipboardTest {
|
||||
|
||||
@Test
|
||||
public void testCopyNoPos1Pos2() {
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
cb.copy(user, false);
|
||||
Mockito.verify(user).sendMessage(Mockito.eq("commands.admin.schem.need-pos1-pos2"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCopyNoPos2() {
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
cb.setPos1(loc);
|
||||
cb.copy(user, false);
|
||||
Mockito.verify(user).sendMessage(Mockito.eq("commands.admin.schem.need-pos1-pos2"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCopy() {
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
cb.setPos1(loc);
|
||||
cb.setPos2(loc2);
|
||||
cb.copy(user, false);
|
||||
Mockito.verify(user).sendMessage("commands.admin.schem.copied-blocks", TextVariables.NUMBER, "8");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCopySigns() {
|
||||
when(block.getType()).thenReturn(Material.SIGN);
|
||||
@ -214,7 +228,7 @@ public class ClipboardTest {
|
||||
String[] lines = {"line1", "line2", "line3", "line4"};
|
||||
when(bs.getLines()).thenReturn(lines);
|
||||
when(block.getState()).thenReturn(bs);
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
cb.setPos1(loc);
|
||||
cb.setPos2(loc2);
|
||||
cb.copy(user, false);
|
||||
@ -232,7 +246,7 @@ public class ClipboardTest {
|
||||
when(inv.getContents()).thenReturn(contents);
|
||||
when(bs.getInventory()).thenReturn(inv);
|
||||
when(block.getState()).thenReturn(bs);
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
cb.setPos1(loc);
|
||||
cb.setPos2(loc2);
|
||||
cb.copy(user, false);
|
||||
@ -240,14 +254,14 @@ public class ClipboardTest {
|
||||
// Every block is a sign, so this should be called 8 times
|
||||
Mockito.verify(bs, Mockito.times(8)).getInventory();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
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(plugin, schemFolder);
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
cb.setPos1(loc);
|
||||
cb.setPos2(loc2);
|
||||
cb.copy(user, false);
|
||||
@ -255,7 +269,7 @@ public class ClipboardTest {
|
||||
// Every block is a sign, so this should be called 8 times
|
||||
Mockito.verify(bs, Mockito.times(8)).getMaxNearbyEntities();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCopyAir() {
|
||||
// No entities
|
||||
@ -263,7 +277,7 @@ public class ClipboardTest {
|
||||
when(block.getType()).thenReturn(Material.AIR);
|
||||
BlockState bs = mock(BlockState.class);
|
||||
when(block.getState()).thenReturn(bs);
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
cb.setPos1(loc);
|
||||
cb.setPos2(loc2);
|
||||
// Do not copy air
|
||||
@ -273,7 +287,7 @@ public class ClipboardTest {
|
||||
Mockito.verify(user).sendMessage("commands.admin.schem.copied-blocks", TextVariables.NUMBER, "8");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testPasteIslandNoData() {
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
@ -281,10 +295,10 @@ public class ClipboardTest {
|
||||
when(island.getCenter()).thenReturn(loc);
|
||||
cb.pasteIsland(world, island, () -> {});
|
||||
Mockito.verify(plugin).logError(Mockito.eq("Clipboard has no block data in it to paste!"));
|
||||
// Verify the task is run
|
||||
Mockito.verify(sched).runTaskLater(Mockito.eq(plugin), Mockito.any(Runnable.class), Mockito.eq(2L));
|
||||
// Verify the task is run
|
||||
Mockito.verify(sched, Mockito.never()).runTaskTimer(Mockito.any(), Mockito.any(Runnable.class), Mockito.eq(0L), Mockito.eq(1L));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPasteIslandWithData() {
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
@ -294,19 +308,8 @@ public class ClipboardTest {
|
||||
cb.setPos2(loc2);
|
||||
cb.copy(user, false);
|
||||
cb.pasteIsland(world, island, () -> {});
|
||||
// This is set just once because the coords of the block are always the same
|
||||
Mockito.verify(block).setBlockData(Mockito.any());
|
||||
// Verify the entities are spawned
|
||||
Mockito.verify(world).spawnEntity(Mockito.eq(null), Mockito.eq(EntityType.PIG));
|
||||
Mockito.verify(world).spawnEntity(Mockito.eq(null), Mockito.eq(EntityType.CREEPER));
|
||||
Mockito.verify(world).spawnEntity(Mockito.eq(null), Mockito.eq(EntityType.HORSE));
|
||||
Mockito.verify(world).spawnEntity(Mockito.eq(null), Mockito.eq(EntityType.SHEEP));
|
||||
Mockito.verify(world).spawnEntity(Mockito.eq(null), Mockito.eq(EntityType.COW));
|
||||
// Player should NOT spawn!!
|
||||
Mockito.verify(world, Mockito.never()).spawnEntity(Mockito.eq(null), Mockito.eq(EntityType.PLAYER));
|
||||
|
||||
// Verify the task is run
|
||||
Mockito.verify(sched).runTaskLater(Mockito.eq(plugin), Mockito.any(Runnable.class), Mockito.eq(2L));
|
||||
Mockito.verify(sched).runTaskTimer(Mockito.any(), Mockito.any(Runnable.class), Mockito.eq(0L), Mockito.eq(1L));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -315,7 +318,7 @@ public class ClipboardTest {
|
||||
cb.pasteClipboard(loc);
|
||||
Mockito.verify(plugin).logError(Mockito.eq("Clipboard has no block data in it to paste!"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPasteClipboard() {
|
||||
Clipboard cb = new Clipboard(plugin, schemFolder);
|
||||
@ -323,14 +326,8 @@ public class ClipboardTest {
|
||||
cb.setPos2(loc2);
|
||||
cb.copy(user, false);
|
||||
cb.pasteClipboard(loc);
|
||||
// This is set just once because the coords of the block are always the same
|
||||
Mockito.verify(block).setBlockData(Mockito.any());
|
||||
// Verify the entities are spawned
|
||||
Mockito.verify(world).spawnEntity(Mockito.eq(null), Mockito.eq(EntityType.PIG));
|
||||
Mockito.verify(world).spawnEntity(Mockito.eq(null), Mockito.eq(EntityType.CREEPER));
|
||||
Mockito.verify(world).spawnEntity(Mockito.eq(null), Mockito.eq(EntityType.HORSE));
|
||||
Mockito.verify(world).spawnEntity(Mockito.eq(null), Mockito.eq(EntityType.SHEEP));
|
||||
Mockito.verify(world).spawnEntity(Mockito.eq(null), Mockito.eq(EntityType.COW));
|
||||
// Verify the task is run
|
||||
Mockito.verify(sched).runTaskTimer(Mockito.any(), Mockito.any(Runnable.class), Mockito.eq(0L), Mockito.eq(1L));
|
||||
// Player should NOT spawn!!
|
||||
Mockito.verify(world, Mockito.never()).spawnEntity(Mockito.eq(null), Mockito.eq(EntityType.PLAYER));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user