mirror of
https://github.com/BentoBoxWorld/Boxed.git
synced 2024-11-30 12:54:33 +01:00
Merge pull request #79 from BentoBoxWorld/on_demand_structures
This commit is contained in:
commit
25b06eca51
1
.github/.gitignore
vendored
Normal file
1
.github/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/.DS_Store
|
4
pom.xml
4
pom.xml
@ -58,8 +58,8 @@
|
||||
<!-- Non-minecraft related dependencies -->
|
||||
<powermock.version>2.0.9</powermock.version>
|
||||
<!-- More visible way how to change dependency versions -->
|
||||
<spigot.version>1.20.4-R0.1-SNAPSHOT</spigot.version>
|
||||
<bentobox.version>2.0.0-SNAPSHOT</bentobox.version>
|
||||
<spigot.version>1.21-R0.1-SNAPSHOT</spigot.version>
|
||||
<bentobox.version>2.4.0-SNAPSHOT</bentobox.version>
|
||||
<!-- Revision variable removes warning about dynamic version -->
|
||||
<revision>${build.version}-SNAPSHOT</revision>
|
||||
<!-- Do not change unless you want different name for local builds. -->
|
||||
|
@ -11,6 +11,7 @@ import org.bukkit.Difficulty;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.configuration.ConfigComment;
|
||||
import world.bentobox.bentobox.api.configuration.ConfigEntry;
|
||||
import world.bentobox.bentobox.api.configuration.StoreAt;
|
||||
@ -106,6 +107,7 @@ public class Settings implements WorldSettings {
|
||||
private int ticksPerMonsterSpawns = -1;
|
||||
|
||||
@ConfigComment("Radius of player area. (So distance between player starting spots is twice this)")
|
||||
@ConfigComment("MUST BE A FACTOR OF 16. If not, it will be rounded to be one.")
|
||||
@ConfigComment("It is the same for every dimension : Overworld, Nether and End.")
|
||||
@ConfigEntry(path = "world.area-radius", needsReset = true)
|
||||
private int islandDistance = 320;
|
||||
@ -494,6 +496,11 @@ public class Settings implements WorldSettings {
|
||||
*/
|
||||
@Override
|
||||
public int getIslandDistance() {
|
||||
if (islandDistance % 16 != 0) {
|
||||
islandDistance = islandDistance - (islandDistance % 16);
|
||||
BentoBox.getInstance()
|
||||
.logWarning("Boxed: Area radius is not a factor of 16. Rounding to " + islandDistance);
|
||||
}
|
||||
return islandDistance;
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,10 @@ package world.bentobox.boxed.listeners;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@ -12,6 +14,7 @@ import java.util.Queue;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
@ -33,6 +36,7 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.loot.LootTables;
|
||||
import org.bukkit.structure.Structure;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
@ -93,19 +97,23 @@ public class NewAreaListener implements Listener {
|
||||
private final File structureFile;
|
||||
private final Queue<StructureRecord> itemsToBuild = new LinkedList<>();
|
||||
private static final Random rand = new Random();
|
||||
private boolean pasting;
|
||||
private boolean pasting = true;
|
||||
private static final Gson gson = new Gson();
|
||||
Pair<Integer, Integer> min = new Pair<>(0, 0);
|
||||
Pair<Integer, Integer> max = new Pair<>(0, 0);
|
||||
// Database handler for structure data
|
||||
private final Database<IslandStructures> handler;
|
||||
private final Map<String, IslandStructures> islandStructureCache = new HashMap<>();
|
||||
private Map<Pair<Integer, Integer>, List<StructureRecord>> readyToBuild = new HashMap<>();
|
||||
private static String bukkitVersion = "v" + Bukkit.getBukkitVersion().replace('.', '_').replace('-', '_');
|
||||
private static String pluginPackageName;
|
||||
|
||||
/**
|
||||
* @param addon addon
|
||||
*/
|
||||
public NewAreaListener(Boxed addon) {
|
||||
this.addon = addon;
|
||||
pluginPackageName = addon.getClass().getPackage().getName();
|
||||
// Save the default structures file from the jar
|
||||
addon.saveResource("structures.yml", false);
|
||||
// Load the config
|
||||
@ -113,11 +121,11 @@ public class NewAreaListener implements Listener {
|
||||
// Get database ready
|
||||
handler = new Database<>(addon, IslandStructures.class);
|
||||
// Try to build something every second
|
||||
runStructurePrinter(addon);
|
||||
runStructurePrinter();
|
||||
}
|
||||
|
||||
private void runStructurePrinter(Boxed addon2) {
|
||||
Bukkit.getScheduler().runTaskTimer(addon.getPlugin(), this::buildStructure, 20, 20);
|
||||
private void runStructurePrinter() {
|
||||
Bukkit.getScheduler().runTaskTimer(addon.getPlugin(), this::buildStructure, 100, 60);
|
||||
for (String js : JAR_STRUCTURES) {
|
||||
addon.saveResource("structures/" + js + ".nbt", false);
|
||||
File structureFile = new File(addon.getDataFolder(), "structures/" + js + ".nbt");
|
||||
@ -146,6 +154,29 @@ public class NewAreaListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
private void placeStructure(StructureRecord item) {
|
||||
// Set the semaphore - only paste one at a time
|
||||
pasting = true;
|
||||
// Place the structure - this cannot be done async
|
||||
item.structure().place(item.location(), true, item.rot(), item.mirror(), -1, 1, rand);
|
||||
addon.log(item.name() + " placed at " + item.location().getWorld().getName() + " "
|
||||
+ Util.xyz(item.location().toVector()));
|
||||
// Remove any jigsaw artifacts
|
||||
BoundingBox bb = removeJigsaw(item);
|
||||
// Store it for future reference
|
||||
addon.getIslands().getIslandAt(item.location()).map(Island::getUniqueId).ifPresent(id -> {
|
||||
//.log("Saved " + item.name());
|
||||
if (item.location().getWorld().getEnvironment().equals(Environment.NETHER)) {
|
||||
getIslandStructData(id).addNetherStructure(bb, item.name());
|
||||
} else {
|
||||
getIslandStructData(id).addStructure(bb, item.name());
|
||||
}
|
||||
handler.saveObjectAsync(getIslandStructData(id));
|
||||
});
|
||||
// Clear the semaphore
|
||||
pasting = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load known structures from the templates file. This makes them available for
|
||||
* admins to use in the boxed place file. If this is not done, then no
|
||||
@ -155,22 +186,49 @@ public class NewAreaListener implements Listener {
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onBentoBoxReady(BentoBoxReadyEvent event) {
|
||||
addon.saveResource("templates.yml", false);
|
||||
File templateFile = new File(addon.getDataFolder(), "templates.yml");
|
||||
if (templateFile.exists()) {
|
||||
YamlConfiguration loader = YamlConfiguration.loadConfiguration(templateFile);
|
||||
List<String> list = loader.getStringList("templates");
|
||||
for (String struct : list) {
|
||||
if (!struct.endsWith("/")) {
|
||||
Bukkit.getStructureManager().loadStructure(NamespacedKey.fromString(struct));
|
||||
Bukkit.getScheduler().runTaskAsynchronously(addon.getPlugin(), () -> {
|
||||
addon.saveResource("templates.yml", false);
|
||||
File templateFile = new File(addon.getDataFolder(), "templates.yml");
|
||||
if (templateFile.exists()) {
|
||||
YamlConfiguration loader = YamlConfiguration.loadConfiguration(templateFile);
|
||||
List<String> list = loader.getStringList("templates");
|
||||
for (String struct : list) {
|
||||
if (!struct.endsWith("/")) {
|
||||
Bukkit.getStructureManager().loadStructure(NamespacedKey.fromString(struct));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pasting = false; // Allow pasting
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Track if a place has entered a structure.
|
||||
* Add items to the queue when they are needed due to chunk loading
|
||||
* @param e ChunkLoadEvent
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onChunkLoad(ChunkLoadEvent e) {
|
||||
Chunk chunk = e.getChunk();
|
||||
// Check if this island is in this game
|
||||
if (!(addon.inWorld(chunk.getWorld()))) {
|
||||
return;
|
||||
}
|
||||
Pair<Integer, Integer> chunkCoords = new Pair<Integer, Integer>(chunk.getX(), chunk.getZ());
|
||||
if (this.readyToBuild.containsKey(chunkCoords)) {
|
||||
Iterator<StructureRecord> it = this.readyToBuild.get(chunkCoords).iterator();
|
||||
while (it.hasNext()) {
|
||||
StructureRecord item = it.next();
|
||||
if (item.location().getWorld().equals(e.getWorld())) {
|
||||
this.itemsToBuild.add(item);
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Track if a player has entered a structure.
|
||||
*
|
||||
* @param e PlayerMoveEvent
|
||||
*/
|
||||
@ -312,36 +370,14 @@ public class NewAreaListener implements Listener {
|
||||
int y = Integer.parseInt(value[1].strip());
|
||||
int z = Integer.parseInt(value[2].strip()) + center.getBlockZ();
|
||||
Location l = new Location(world, x, y, z);
|
||||
itemsToBuild.add(new StructureRecord(name, s, l, rot, mirror, noMobs));
|
||||
readyToBuild.computeIfAbsent(new Pair<Integer, Integer>(x >> 4, z >> 4), k -> new ArrayList<>())
|
||||
.add(new StructureRecord(name, s, l, rot, mirror, noMobs));
|
||||
} else {
|
||||
addon.logError("Structure file syntax error: " + vector + ": " + Arrays.toString(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void placeStructure(StructureRecord item) {
|
||||
// Set the semaphore - only paste one at a time
|
||||
pasting = true;
|
||||
// Place the structure
|
||||
item.structure().place(item.location(), true, item.rot(), item.mirror(), -1, 1, rand);
|
||||
addon.log(item.name() + " placed at " + item.location().getWorld().getName() + " "
|
||||
+ Util.xyz(item.location().toVector()));
|
||||
// Remove any jigsaw artifacts
|
||||
BoundingBox bb = removeJigsaw(item);
|
||||
// Store it for future reference
|
||||
addon.getIslands().getIslandAt(item.location()).map(Island::getUniqueId).ifPresent(id -> {
|
||||
addon.log("Saved " + item.name());
|
||||
if (item.location().getWorld().getEnvironment().equals(Environment.NETHER)) {
|
||||
getIslandStructData(id).addNetherStructure(bb, item.name());
|
||||
} else {
|
||||
getIslandStructData(id).addStructure(bb, item.name());
|
||||
}
|
||||
handler.saveObjectAsync(getIslandStructData(id));
|
||||
});
|
||||
// Clear the semaphore
|
||||
pasting = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes Jigsaw blocks from a placed structure. Fills underwater ruins with
|
||||
* water.
|
||||
@ -403,6 +439,9 @@ public class NewAreaListener implements Listener {
|
||||
private static void processStructureBlock(Block b) {
|
||||
// I would like to read the data from the block and do something with it!
|
||||
String data = nmsData(b);
|
||||
if (data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
BoxedStructureBlock bsb = gson.fromJson(data, BoxedStructureBlock.class);
|
||||
b.setType(Material.STRUCTURE_VOID);
|
||||
Enums.getIfPresent(EntityType.class, bsb.getMetadata().toUpperCase(Locale.ENGLISH)).toJavaUtil()
|
||||
@ -425,6 +464,9 @@ public class NewAreaListener implements Listener {
|
||||
|
||||
private static void processJigsaw(Block b, StructureRotation structureRotation, boolean pasteMobs) {
|
||||
String data = nmsData(b);
|
||||
if (data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
BoxedJigsawBlock bjb = gson.fromJson(data, BoxedJigsawBlock.class);
|
||||
String finalState = correctDirection(bjb.getFinal_state(), structureRotation);
|
||||
BlockData bd = Bukkit.createBlockData(finalState);
|
||||
@ -542,10 +584,6 @@ public class NewAreaListener implements Listener {
|
||||
}
|
||||
|
||||
private static String nmsData(Block block) {
|
||||
// Bukkit method that was added in 2011
|
||||
// Example value: 1.20.4-R0.1-SNAPSHOT
|
||||
String bukkitVersion = "v" + Bukkit.getBukkitVersion().replace('.', '_').replace('-', '_');
|
||||
String pluginPackageName = BentoBox.getInstance().getClass().getPackage().getName();
|
||||
AbstractMetaData handler;
|
||||
try {
|
||||
Class<?> clazz = Class.forName(pluginPackageName + ".nms." + bukkitVersion + ".GetMetaData");
|
||||
@ -555,6 +593,7 @@ public class NewAreaListener implements Listener {
|
||||
throw new IllegalStateException("Class " + clazz.getName() + " does not implement AbstractGetMetaData");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
BentoBox.getInstance().logWarning("No metadata handler found for " + bukkitVersion + " in Boxed.");
|
||||
handler = new world.bentobox.boxed.nms.fallback.GetMetaData();
|
||||
}
|
||||
|
@ -1,7 +1,14 @@
|
||||
package world.bentobox.boxed.nms;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.protocol.game.PacketPlayOutTileEntityData;
|
||||
import net.minecraft.world.level.block.entity.TileEntity;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -9,4 +16,28 @@ public abstract class AbstractMetaData {
|
||||
|
||||
public abstract String nmsData(Block block);
|
||||
|
||||
protected String getData(TileEntity te, String method, String field) {
|
||||
try {
|
||||
// Check if the method 'j' exists
|
||||
Method updatePacketMethod = te.getClass().getDeclaredMethod(method);
|
||||
if (updatePacketMethod != null) {
|
||||
// Invoke the method to get the PacketPlayOutTileEntityData object
|
||||
updatePacketMethod.setAccessible(true);
|
||||
PacketPlayOutTileEntityData packet = (PacketPlayOutTileEntityData) updatePacketMethod.invoke(te);
|
||||
|
||||
// Access the private field for the NBTTagCompound getter in PacketPlayOutTileEntityData
|
||||
Field fieldC = packet.getClass().getDeclaredField(field);
|
||||
fieldC.setAccessible(true);
|
||||
NBTTagCompound nbtTag = (NBTTagCompound) fieldC.get(packet);
|
||||
|
||||
return nbtTag.toString(); // This will show what you want
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
System.out.println("The method '" + method + "' does not exist in the TileEntity class.");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ public class GetMetaData extends AbstractMetaData {
|
||||
|
||||
@Override
|
||||
public String nmsData(Block block) {
|
||||
return "Nothing"; // We cannot read it if we have no NMS
|
||||
return ""; // We cannot read it if we have no NMS
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,14 +1,10 @@
|
||||
package world.bentobox.boxed.nms.v1_20_4_R0_1_SNAPSHOT;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_20_R3.CraftWorld;
|
||||
|
||||
import net.minecraft.core.BlockPosition;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.protocol.game.PacketPlayOutTileEntityData;
|
||||
import net.minecraft.world.level.block.entity.TileEntity;
|
||||
import world.bentobox.boxed.nms.AbstractMetaData;
|
||||
|
||||
@ -18,20 +14,8 @@ public class GetMetaData extends AbstractMetaData {
|
||||
public String nmsData(Block block) {
|
||||
Location w = block.getLocation();
|
||||
CraftWorld cw = (CraftWorld) w.getWorld(); // CraftWorld is NMS one
|
||||
// for 1.13+ (we have use WorldServer)
|
||||
TileEntity te = cw.getHandle().c_(new BlockPosition(w.getBlockX(), w.getBlockY(), w.getBlockZ()));
|
||||
try {
|
||||
PacketPlayOutTileEntityData packet = ((PacketPlayOutTileEntityData) te.j()); // get update packet from NMS
|
||||
// object
|
||||
// here we should use reflection because "c" field isn't accessible
|
||||
Field f = packet.getClass().getDeclaredField("c"); // get field
|
||||
f.setAccessible(true); // make it available
|
||||
NBTTagCompound nbtTag = (NBTTagCompound) f.get(packet);
|
||||
return nbtTag.toString(); // this will show what you want
|
||||
} catch (Exception exc) {
|
||||
exc.printStackTrace();
|
||||
}
|
||||
return "Nothing";
|
||||
}
|
||||
|
||||
return getData(te, "j", "c");
|
||||
}
|
||||
}
|
@ -1,14 +1,10 @@
|
||||
package world.bentobox.boxed.nms.v1_20_6_R0_1_SNAPSHOT;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_20_R4.CraftWorld;
|
||||
|
||||
import net.minecraft.core.BlockPosition;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.protocol.game.PacketPlayOutTileEntityData;
|
||||
import net.minecraft.world.level.block.entity.TileEntity;
|
||||
import world.bentobox.boxed.nms.AbstractMetaData;
|
||||
|
||||
@ -18,20 +14,8 @@ public class GetMetaData extends AbstractMetaData {
|
||||
public String nmsData(Block block) {
|
||||
Location w = block.getLocation();
|
||||
CraftWorld cw = (CraftWorld) w.getWorld(); // CraftWorld is NMS one
|
||||
// for 1.13+ (we have use WorldServer)
|
||||
TileEntity te = cw.getHandle().c_(new BlockPosition(w.getBlockX(), w.getBlockY(), w.getBlockZ()));
|
||||
try {
|
||||
PacketPlayOutTileEntityData packet = ((PacketPlayOutTileEntityData) te.j()); // get update packet from NMS
|
||||
// object
|
||||
// here we should use reflection because "c" field isn't accessible
|
||||
Field f = packet.getClass().getDeclaredField("c"); // get field
|
||||
f.setAccessible(true); // make it available
|
||||
NBTTagCompound nbtTag = (NBTTagCompound) f.get(packet);
|
||||
return nbtTag.toString(); // this will show what you want
|
||||
} catch (Exception exc) {
|
||||
exc.printStackTrace();
|
||||
}
|
||||
return "Nothing";
|
||||
}
|
||||
|
||||
return getData(te, "j", "c");
|
||||
}
|
||||
}
|
@ -1,14 +1,10 @@
|
||||
package world.bentobox.boxed.nms.v1_21_R0_1_SNAPSHOT;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_21_R1.CraftWorld;
|
||||
|
||||
import net.minecraft.core.BlockPosition;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.protocol.game.PacketPlayOutTileEntityData;
|
||||
import net.minecraft.world.level.block.entity.TileEntity;
|
||||
import world.bentobox.boxed.nms.AbstractMetaData;
|
||||
|
||||
@ -20,18 +16,8 @@ public class GetMetaData extends AbstractMetaData {
|
||||
CraftWorld cw = (CraftWorld) w.getWorld(); // CraftWorld is NMS one
|
||||
// for 1.13+ (we have use WorldServer)
|
||||
TileEntity te = cw.getHandle().c_(new BlockPosition(w.getBlockX(), w.getBlockY(), w.getBlockZ()));
|
||||
try {
|
||||
PacketPlayOutTileEntityData packet = ((PacketPlayOutTileEntityData) te.j()); // get update packet from NMS
|
||||
// object
|
||||
// here we should use reflection because "c" field isn't accessible
|
||||
Field f = packet.getClass().getDeclaredField("c"); // get field
|
||||
f.setAccessible(true); // make it available
|
||||
NBTTagCompound nbtTag = (NBTTagCompound) f.get(packet);
|
||||
return nbtTag.toString(); // this will show what you want
|
||||
} catch (Exception exc) {
|
||||
exc.printStackTrace();
|
||||
}
|
||||
return "Nothing";
|
||||
|
||||
return getData(te, "az_", "tag");
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ package world.bentobox.boxed;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -13,17 +14,30 @@ import org.bukkit.Difficulty;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.reflect.Whitebox;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({ BentoBox.class })
|
||||
public class SettingsTest {
|
||||
|
||||
@Mock
|
||||
private BentoBox plugin;
|
||||
Settings s;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
// Set up plugin
|
||||
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
|
||||
s = new Settings();
|
||||
}
|
||||
/**
|
||||
@ -59,7 +73,8 @@ public class SettingsTest {
|
||||
@Test
|
||||
public void testSetIslandDistance() {
|
||||
s.setIslandDistance(123);
|
||||
assertEquals(123, s.getIslandDistance());
|
||||
assertEquals(112, s.getIslandDistance());
|
||||
verify(plugin).logWarning("Boxed: Area radius is not a factor of 16. Rounding to 112");
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user