mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2025-03-26 05:29:39 +01:00
Better blueprint bedrock handling
Prevents blueprints from being saved unless they have a bedrock block in them. If a blueprint is loaded and does not have a bedrock block, one is added and a warning given in the console. Added test class for BlueprintClipboardManager https://github.com/BentoBoxWorld/BentoBox/issues/777
This commit is contained in:
parent
5dcec3ee1b
commit
99d34d06ba
src
main
java/world/bentobox/bentobox
resources/locales
test/java/world/bentobox/bentobox/managers
@ -34,6 +34,11 @@ public class AdminBlueprintSaveCommand extends ConfirmableCommand {
|
||||
BlueprintClipboard clipboard = parent.getClipboards().computeIfAbsent(user.getUniqueId(), v -> new BlueprintClipboard());
|
||||
String fileName = args.get(0).toLowerCase(Locale.ENGLISH);
|
||||
if (clipboard.isFull()) {
|
||||
// Check if blueprint had bedrock
|
||||
if (clipboard.getBlueprint().getBedrock() == null) {
|
||||
user.sendMessage("commands.admin.blueprint.bedrock-required");
|
||||
return false;
|
||||
}
|
||||
// Check if file exists
|
||||
File newFile = new File(parent.getBlueprintsFolder(), fileName + BlueprintsManager.BLUEPRINT_SUFFIX);
|
||||
if (newFile.exists()) {
|
||||
|
@ -14,6 +14,9 @@ import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
@ -21,6 +24,7 @@ import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.Blueprint;
|
||||
import world.bentobox.bentobox.blueprints.BlueprintClipboard;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBlock;
|
||||
import world.bentobox.bentobox.database.json.BentoboxTypeAdapterFactory;
|
||||
|
||||
/**
|
||||
@ -101,8 +105,17 @@ public class BlueprintClipboardManager {
|
||||
Blueprint bp;
|
||||
try (FileReader fr = new FileReader(file)) {
|
||||
bp = gson.fromJson(fr, Blueprint.class);
|
||||
} catch (Exception e) {
|
||||
plugin.logError("Blueprint has JSON error: " + zipFile.getName());
|
||||
throw new IOException("Blueprint has JSON error: " + zipFile.getName());
|
||||
}
|
||||
Files.delete(file.toPath());
|
||||
// Bedrock check and set
|
||||
if (bp.getBedrock() == null) {
|
||||
bp.setBedrock(new Vector(bp.getxSize() / 2, bp.getySize() / 2, bp.getzSize() / 2));
|
||||
bp.getBlocks().put(bp.getBedrock(), new BlueprintBlock(Material.BEDROCK.createBlockData().getAsString()));
|
||||
plugin.logWarning("Blueprint " + fileName + " had no bedrock block in it so one was added automatically in the center. You should check it.");
|
||||
}
|
||||
return bp;
|
||||
}
|
||||
|
||||
|
@ -193,6 +193,7 @@ commands:
|
||||
blueprint:
|
||||
parameters: "<load/copy/paste/pos1/pos2/save>"
|
||||
description: "manipulate blueprints"
|
||||
bedrock-required: "&cAt least one bedrock block must be in a blueprint!"
|
||||
copy-first: "&cCopy first!"
|
||||
file-exists: "&cFile already exists, overwrite?"
|
||||
no-such-file: "&cNo such file!"
|
||||
|
@ -0,0 +1,385 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package world.bentobox.bentobox.managers;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.Comparator;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
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.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.Blueprint;
|
||||
import world.bentobox.bentobox.blueprints.BlueprintClipboard;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest( {Bukkit.class, BentoBox.class} )
|
||||
public class BlueprintClipboardManagerTest {
|
||||
|
||||
@Mock
|
||||
private BentoBox plugin;
|
||||
@Mock
|
||||
private BlueprintClipboard clipboard;
|
||||
|
||||
private File blueprintFolder;
|
||||
|
||||
private String json = "{\n" +
|
||||
" \"name\": \"blueprint\",\n" +
|
||||
" \"attached\": {},\n" +
|
||||
" \"entities\": {},\n" +
|
||||
" \"blocks\": [\n" +
|
||||
" [\n" +
|
||||
" [3.0, -5.0, 8.0], {\n" +
|
||||
" \"blockData\": \"minecraft:stone\"\n" +
|
||||
" }\n" +
|
||||
" ],\n" +
|
||||
" [\n" +
|
||||
" [6.0, -13.0, -20.0], {\n" +
|
||||
" \"blockData\": \"minecraft:diorite\"\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
" ],\n" +
|
||||
" \"xSize\": 10,\n" +
|
||||
" \"ySize\": 10,\n" +
|
||||
" \"zSize\": 10,\n" +
|
||||
" \"bedrock\": [-2.0, -16.0, -1.0]\n" +
|
||||
"}";
|
||||
|
||||
private String jsonNoBedrock = "{\n" +
|
||||
" \"name\": \"blueprint\",\n" +
|
||||
" \"attached\": {},\n" +
|
||||
" \"entities\": {},\n" +
|
||||
" \"blocks\": [\n" +
|
||||
" [\n" +
|
||||
" [3.0, -5.0, 8.0], {\n" +
|
||||
" \"blockData\": \"minecraft:stone\"\n" +
|
||||
" }\n" +
|
||||
" ],\n" +
|
||||
" [\n" +
|
||||
" [6.0, -13.0, -20.0], {\n" +
|
||||
" \"blockData\": \"minecraft:diorite\"\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
" ],\n" +
|
||||
" \"xSize\": 10,\n" +
|
||||
" \"ySize\": 10,\n" +
|
||||
" \"zSize\": 10\n" +
|
||||
"}";
|
||||
|
||||
private void zip(File targetFile) throws IOException {
|
||||
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];
|
||||
int length;
|
||||
while((length = inputStream.read(buffer)) >= 0) {
|
||||
zipOutputStream.write(buffer, 0, length);
|
||||
}
|
||||
}
|
||||
try {
|
||||
Files.delete(targetFile.toPath());
|
||||
} catch (Exception e) {
|
||||
plugin.logError(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
blueprintFolder = new File("blueprints");
|
||||
PowerMockito.mockStatic(Bukkit.class);
|
||||
BlockData blockData = mock(BlockData.class);
|
||||
when(Bukkit.createBlockData(Mockito.any(Material.class))).thenReturn(blockData);
|
||||
when(blockData.getAsString()).thenReturn("test123");
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (blueprintFolder.exists()) {
|
||||
// Clean up file system
|
||||
Files.walk(blueprintFolder.toPath())
|
||||
.sorted(Comparator.reverseOrder())
|
||||
.map(Path::toFile)
|
||||
.forEach(File::delete);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#BlueprintClipboardManager(world.bentobox.bentobox.BentoBox, java.io.File)}.
|
||||
*/
|
||||
@Test
|
||||
public void testBlueprintClipboardManagerBentoBoxFile() {
|
||||
new BlueprintClipboardManager(plugin, blueprintFolder);
|
||||
assertTrue(blueprintFolder.exists());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#BlueprintClipboardManager(world.bentobox.bentobox.BentoBox, java.io.File, world.bentobox.bentobox.blueprints.BlueprintClipboard)}.
|
||||
*/
|
||||
@Test
|
||||
public void testBlueprintClipboardManagerBentoBoxFileBlueprintClipboard() {
|
||||
new BlueprintClipboardManager(plugin, blueprintFolder, clipboard);
|
||||
assertTrue(blueprintFolder.exists());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#getClipboard()}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetClipboard() {
|
||||
BlueprintClipboardManager bcm = new BlueprintClipboardManager(plugin, blueprintFolder, clipboard);
|
||||
assertEquals(clipboard, bcm.getClipboard());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#loadBlueprint(java.lang.String)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testLoadBlueprintNoSuchFile() {
|
||||
BlueprintClipboardManager bcm = new BlueprintClipboardManager(plugin, blueprintFolder);
|
||||
try {
|
||||
bcm.loadBlueprint("test");
|
||||
} catch (Exception e) {
|
||||
assertTrue(e instanceof IOException);
|
||||
} finally {
|
||||
verify(plugin).logError("Could not load blueprint file - does not exist : test.blu");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#loadBlueprint(java.lang.String)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testLoadBlueprintNoFileInZip() throws IOException {
|
||||
blueprintFolder.mkdirs();
|
||||
// Make a blueprint file
|
||||
YamlConfiguration config = new YamlConfiguration();
|
||||
config.set("hello", "this is a test");
|
||||
File configFile = new File(blueprintFolder, "blueprint.blu");
|
||||
config.save(configFile);
|
||||
assertTrue(configFile.exists());
|
||||
BlueprintClipboardManager bcm = new BlueprintClipboardManager(plugin, blueprintFolder);
|
||||
try {
|
||||
bcm.loadBlueprint("blueprint");
|
||||
} catch (Exception e) {
|
||||
assertTrue(e instanceof IOException);
|
||||
} finally {
|
||||
verify(plugin).logError("Could not load blueprint file - does not exist : blueprint");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#loadBlueprint(java.lang.String)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testLoadBlueprintFileInZipJSONError() throws IOException {
|
||||
blueprintFolder.mkdirs();
|
||||
// Make a blueprint file
|
||||
YamlConfiguration config = new YamlConfiguration();
|
||||
config.set("hello", "this is a test");
|
||||
File configFile = new File(blueprintFolder, "blueprint");
|
||||
config.save(configFile);
|
||||
// Zip it
|
||||
zip(configFile);
|
||||
BlueprintClipboardManager bcm = new BlueprintClipboardManager(plugin, blueprintFolder);
|
||||
try {
|
||||
bcm.loadBlueprint("blueprint");
|
||||
} catch (Exception e) {
|
||||
assertTrue(e instanceof IOException);
|
||||
} finally {
|
||||
verify(plugin).logError("Blueprint has JSON error: blueprint.blu");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#loadBlueprint(java.lang.String)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testLoadBlueprintFileInZipNoBedrock() throws IOException {
|
||||
blueprintFolder.mkdirs();
|
||||
// Make a blueprint file
|
||||
File configFile = new File(blueprintFolder, "blueprint");
|
||||
byte[] bytes = jsonNoBedrock.getBytes(StandardCharsets.UTF_8);
|
||||
Files.write(configFile.toPath(), bytes, StandardOpenOption.CREATE);
|
||||
// Zip it
|
||||
zip(configFile);
|
||||
BlueprintClipboardManager bcm = new BlueprintClipboardManager(plugin, blueprintFolder);
|
||||
Blueprint bp = bcm.loadBlueprint("blueprint");
|
||||
verify(plugin).logWarning("Blueprint blueprint had no bedrock block in it so one was added automatically in the center. You should check it.");
|
||||
// Verify bedrock was placed in the center of the blueprint
|
||||
assertEquals(5, bp.getBedrock().getBlockX());
|
||||
assertEquals(5, bp.getBedrock().getBlockY());
|
||||
assertEquals(5, bp.getBedrock().getBlockZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#loadBlueprint(java.lang.String)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testLoadBlueprintFileInZip() throws IOException {
|
||||
blueprintFolder.mkdirs();
|
||||
// Make a blueprint file
|
||||
File configFile = new File(blueprintFolder, "blueprint");
|
||||
byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
|
||||
Files.write(configFile.toPath(), bytes, StandardOpenOption.CREATE);
|
||||
// Zip it
|
||||
zip(configFile);
|
||||
BlueprintClipboardManager bcm = new BlueprintClipboardManager(plugin, blueprintFolder);
|
||||
Blueprint bp = bcm.loadBlueprint("blueprint");
|
||||
assertEquals(-2, bp.getBedrock().getBlockX());
|
||||
assertEquals(-16, bp.getBedrock().getBlockY());
|
||||
assertEquals(-1, bp.getBedrock().getBlockZ());
|
||||
assertTrue(bp.getAttached().isEmpty());
|
||||
assertTrue(bp.getEntities().isEmpty());
|
||||
assertEquals(2, bp.getBlocks().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#load(java.lang.String)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testLoadString() throws IOException {
|
||||
blueprintFolder.mkdirs();
|
||||
// Make a blueprint file
|
||||
File configFile = new File(blueprintFolder, "blueprint");
|
||||
byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
|
||||
Files.write(configFile.toPath(), bytes, StandardOpenOption.CREATE);
|
||||
// Zip it
|
||||
zip(configFile);
|
||||
BlueprintClipboardManager bcm = new BlueprintClipboardManager(plugin, blueprintFolder);
|
||||
bcm.load("blueprint");
|
||||
Blueprint bp = bcm.getClipboard().getBlueprint();
|
||||
assertEquals(-2, bp.getBedrock().getBlockX());
|
||||
assertEquals(-16, bp.getBedrock().getBlockY());
|
||||
assertEquals(-1, bp.getBedrock().getBlockZ());
|
||||
assertTrue(bp.getAttached().isEmpty());
|
||||
assertTrue(bp.getEntities().isEmpty());
|
||||
assertEquals(2, bp.getBlocks().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#load(world.bentobox.bentobox.api.user.User, java.lang.String)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testLoadUserString() throws IOException {
|
||||
blueprintFolder.mkdirs();
|
||||
// Make a blueprint file
|
||||
File configFile = new File(blueprintFolder, "blueprint");
|
||||
byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
|
||||
Files.write(configFile.toPath(), bytes, StandardOpenOption.CREATE);
|
||||
// Zip it
|
||||
zip(configFile);
|
||||
BlueprintClipboardManager bcm = new BlueprintClipboardManager(plugin, blueprintFolder);
|
||||
User user = mock(User.class);
|
||||
assertTrue(bcm.load(user, "blueprint"));
|
||||
verify(user).sendMessage("general.success");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#load(world.bentobox.bentobox.api.user.User, java.lang.String)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testLoadUserStringFail() throws IOException {
|
||||
BlueprintClipboardManager bcm = new BlueprintClipboardManager(plugin, blueprintFolder);
|
||||
User user = mock(User.class);
|
||||
assertFalse(bcm.load(user, "blueprint"));
|
||||
verify(user).sendMessage("commands.admin.blueprint.could-not-load");
|
||||
verify(plugin).logError("Could not load blueprint file - does not exist : blueprint.blu");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#save(world.bentobox.bentobox.api.user.User, java.lang.String)}.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testSave() throws IOException {
|
||||
// Load a blueprint, then save it
|
||||
blueprintFolder.mkdirs();
|
||||
// Make a blueprint file
|
||||
File configFile = new File(blueprintFolder, "blueprint");
|
||||
byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
|
||||
Files.write(configFile.toPath(), bytes, StandardOpenOption.CREATE);
|
||||
// Zip it
|
||||
zip(configFile);
|
||||
BlueprintClipboardManager bcm = new BlueprintClipboardManager(plugin, blueprintFolder);
|
||||
bcm.load("blueprint");
|
||||
User user = mock(User.class);
|
||||
assertTrue(bcm.save(user, "test1234"));
|
||||
File bp = new File(blueprintFolder, "test1234.blu");
|
||||
assertTrue(bp.exists());
|
||||
verify(user).sendMessage("general.success");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#saveBlueprint(world.bentobox.bentobox.blueprints.Blueprint)}.
|
||||
*/
|
||||
@Test
|
||||
public void testSaveBlueprintNoName() {
|
||||
BlueprintClipboardManager bcm = new BlueprintClipboardManager(plugin, blueprintFolder);
|
||||
Blueprint blueprint = mock(Blueprint.class);
|
||||
when(blueprint.getName()).thenReturn("");
|
||||
assertFalse(bcm.saveBlueprint(blueprint));
|
||||
verify(plugin).logError("Blueprint name was empty - could not save it");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.BlueprintClipboardManager#saveBlueprint(world.bentobox.bentobox.blueprints.Blueprint)}.
|
||||
*/
|
||||
@Test
|
||||
public void testSaveBlueprintSuccess() {
|
||||
BlueprintClipboardManager bcm = new BlueprintClipboardManager(plugin, blueprintFolder);
|
||||
Blueprint blueprint = new Blueprint();
|
||||
blueprint.setName("test123");
|
||||
assertTrue(bcm.saveBlueprint(blueprint));
|
||||
File bp = new File(blueprintFolder, "test123.blu");
|
||||
assertTrue(bp.exists());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user