diff --git a/pom.xml b/pom.xml
index 937765d..312b6c4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,13 +46,13 @@
2.0.2
1.13.2-R0.1-SNAPSHOT
- 1.6.0
+ 1.9.0-SNAPSHOT
${build.version}-SNAPSHOT
-LOCAL
- 1.7.0
+ 1.9.0
diff --git a/src/main/java/bentobox/addon/limits/commands/CalcCommand.java b/src/main/java/bentobox/addon/limits/commands/CalcCommand.java
index 5e2b07e..1e6f9c5 100644
--- a/src/main/java/bentobox/addon/limits/commands/CalcCommand.java
+++ b/src/main/java/bentobox/addon/limits/commands/CalcCommand.java
@@ -24,7 +24,7 @@ public class CalcCommand extends CompositeCommand {
* @param addon - addon
*/
public CalcCommand(Limits addon, CompositeCommand parent) {
- super(parent, "calc");
+ super(parent, "calc", "recount");
this.addon = addon;
}
@@ -60,7 +60,7 @@ public class CalcCommand extends CompositeCommand {
}
}
- public void calcLimits(UUID targetPlayer, User sender) {
+ private void calcLimits(UUID targetPlayer, User sender) {
if (addon.getIslands().getIsland(getWorld(), targetPlayer) != null) {
new LimitsCalc(getWorld(), getPlugin(), targetPlayer, addon, sender);
} else {
diff --git a/src/main/java/bentobox/addon/limits/commands/LimitPanel.java b/src/main/java/bentobox/addon/limits/commands/LimitPanel.java
index 15e39d0..ee85594 100644
--- a/src/main/java/bentobox/addon/limits/commands/LimitPanel.java
+++ b/src/main/java/bentobox/addon/limits/commands/LimitPanel.java
@@ -2,6 +2,7 @@ package bentobox.addon.limits.commands;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
@@ -58,8 +59,8 @@ public class LimitPanel {
.put(Material.BEETROOTS, Material.BEETROOT)
.put(Material.REDSTONE_WIRE, Material.REDSTONE);
// Block to Material icons
- Optional.ofNullable(Material.getMaterial("SWEET_BERRY_BUSH")).ifPresent(material -> builder.put(material, Material.getMaterial("SWEET_BERRIES")));
- Optional.ofNullable(Material.getMaterial("BAMBOO_SAPLING")).ifPresent(material -> builder.put(material, Material.getMaterial("BAMBOO")));
+ Optional.ofNullable(Material.getMaterial("SWEET_BERRY_BUSH")).ifPresent(material -> builder.put(material, Objects.requireNonNull(Material.getMaterial("SWEET_BERRIES"))));
+ Optional.ofNullable(Material.getMaterial("BAMBOO_SAPLING")).ifPresent(material -> builder.put(material, Objects.requireNonNull(Material.getMaterial("BAMBOO"))));
B2M = builder.build();
}
@@ -105,7 +106,7 @@ public class LimitPanel {
addon.getSettings().getLimits().forEach((k,v) -> {
PanelItemBuilder pib = new PanelItemBuilder();
pib.name(Util.prettifyText(k.toString()));
- Material m = Material.BARRIER;
+ Material m;
try {
if (E2M.containsKey(k)) {
m = E2M.get(k);
diff --git a/src/main/java/bentobox/addon/limits/commands/LimitsCalc.java b/src/main/java/bentobox/addon/limits/commands/LimitsCalc.java
index 1a0d105..a652e28 100644
--- a/src/main/java/bentobox/addon/limits/commands/LimitsCalc.java
+++ b/src/main/java/bentobox/addon/limits/commands/LimitsCalc.java
@@ -1,16 +1,13 @@
package bentobox.addon.limits.commands;
-import java.util.EnumMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+import org.bukkit.Bukkit;
import org.bukkit.ChunkSnapshot;
import org.bukkit.Material;
import org.bukkit.World;
-import org.bukkit.scheduler.BukkitTask;
import bentobox.addon.limits.Limits;
import bentobox.addon.limits.listeners.BlockLimitsListener;
@@ -19,71 +16,47 @@ import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.util.Pair;
+import world.bentobox.bentobox.util.Util;
/**
*
- * @author YellowZaki
+ * @author YellowZaki, tastybento
*/
public class LimitsCalc {
- private boolean checking;
- private Limits addon;
- private World world;
- private Island island;
- private BlockLimitsListener bll;
+ private final Limits addon;
+ private final World world;
+ private final Island island;
+ private final BlockLimitsListener bll;
private IslandBlockCount ibc;
- private Map blockCount;
- private BukkitTask task;
- private User sender;
+ private final Map blockCount;
+ private final User sender;
+ private final Set> chunksToScan;
+ private int count;
LimitsCalc(World world, BentoBox instance, UUID targetPlayer, Limits addon, User sender) {
- this.checking = true;
this.addon = addon;
- this.world = world;
this.island = instance.getIslands().getIsland(world, targetPlayer);
this.bll = addon.getBlockLimitListener();
this.ibc = bll.getIsland(island.getUniqueId());
blockCount = new EnumMap<>(Material.class);
this.sender = sender;
- Set> chunksToScan = getChunksToScan(island);
- this.task = addon.getServer().getScheduler().runTaskTimer(addon.getPlugin(), () -> {
- Set chunkSnapshot = new HashSet<>();
- if (checking) {
- Iterator> it = chunksToScan.iterator();
- if (!it.hasNext()) {
- // Nothing left
- tidyUp();
- return;
- }
- // Add chunk snapshots to the list
- while (it.hasNext() && chunkSnapshot.size() < 200) {
- Pair pair = it.next();
- if (!world.isChunkLoaded(pair.x, pair.z)) {
- world.loadChunk(pair.x, pair.z);
- chunkSnapshot.add(world.getChunkAt(pair.x, pair.z).getChunkSnapshot());
- world.unloadChunk(pair.x, pair.z);
- } else {
- chunkSnapshot.add(world.getChunkAt(pair.x, pair.z).getChunkSnapshot());
- }
- it.remove();
- }
- // Move to next step
- checking = false;
- checkChunksAsync(chunkSnapshot);
- }
- }, 0L, 1);
- }
+ this.world = world;
- private void checkChunksAsync(final Set chunkSnapshot) {
- // Run async task to scan chunks
- addon.getServer().getScheduler().runTaskAsynchronously(addon.getPlugin(), () -> {
- for (ChunkSnapshot chunk : chunkSnapshot) {
- scanChunk(chunk);
- }
- // Nothing happened, change state
- checking = true;
- });
+ // Get chunks to scan
+ chunksToScan = getChunksToScan(island);
+ count = 0;
+ chunksToScan.forEach(c -> Util.getChunkAtAsync(world, c.x, c.z).thenAccept(ch -> {
+ ChunkSnapshot snapShot = ch.getChunkSnapshot();
+ Bukkit.getScheduler().runTaskAsynchronously(addon.getPlugin(), () -> {
+ this.scanChunk(snapShot);
+ count++;
+ if (count == chunksToScan.size()) {
+ this.tidyUp();
+ }
+ });
+ }));
}
@@ -98,7 +71,7 @@ public class LimitsCalc {
if (chunk.getZ() * 16 + z < island.getMinProtectedZ() || chunk.getZ() * 16 + z >= island.getMinProtectedZ() + island.getProtectionRange() * 2) {
continue;
}
- for (int y = 0; y < island.getCenter().getWorld().getMaxHeight(); y++) {
+ for (int y = 0; y < Objects.requireNonNull(island.getCenter().getWorld()).getMaxHeight(); y++) {
Material blockData = chunk.getBlockType(x, y, z);
// Air is free
if (!blockData.equals(Material.AIR)) {
@@ -114,9 +87,9 @@ public class LimitsCalc {
// md is limited
if (bll.getMaterialLimits(world, island.getUniqueId()).containsKey(md)) {
if (!blockCount.containsKey(md)) {
- blockCount.put(md, 1);
+ blockCount.put(md, new AtomicInteger(1));
} else {
- blockCount.put(md, blockCount.get(md) + 1);
+ blockCount.get(md).getAndIncrement();
}
}
}
@@ -133,14 +106,15 @@ public class LimitsCalc {
}
private void tidyUp() {
- // Cancel
- task.cancel();
if (ibc == null) {
ibc = new IslandBlockCount();
}
- ibc.setBlockCount(blockCount);
+ ibc.setBlockCount(blockCount.entrySet().stream()
+ .collect(Collectors.toMap(
+ Map.Entry::getKey,
+ entry -> entry.getValue().get())));
bll.setIsland(island.getUniqueId(), ibc);
- sender.sendMessage("admin.limits.calc.finished");
+ Bukkit.getScheduler().runTask(addon.getPlugin(), () -> sender.sendMessage("admin.limits.calc.finished"));
}
}
diff --git a/src/main/java/bentobox/addon/limits/listeners/BlockLimitsListener.java b/src/main/java/bentobox/addon/limits/listeners/BlockLimitsListener.java
index 4bd1070..c0efac9 100644
--- a/src/main/java/bentobox/addon/limits/listeners/BlockLimitsListener.java
+++ b/src/main/java/bentobox/addon/limits/listeners/BlockLimitsListener.java
@@ -1,13 +1,6 @@
package bentobox.addon.limits.listeners;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import java.util.*;
import org.bukkit.Bukkit;
import org.bukkit.Material;
@@ -98,19 +91,19 @@ public class BlockLimitsListener implements Listener {
addon.log("Loading default limits");
if (addon.getConfig().isConfigurationSection("blocklimits")) {
ConfigurationSection limitConfig = addon.getConfig().getConfigurationSection("blocklimits");
- defaultLimitMap = loadLimits(limitConfig);
+ defaultLimitMap = loadLimits(Objects.requireNonNull(limitConfig));
}
// Load specific worlds
if (addon.getConfig().isConfigurationSection("worlds")) {
ConfigurationSection worlds = addon.getConfig().getConfigurationSection("worlds");
- for (String worldName : worlds.getKeys(false)) {
+ for (String worldName : Objects.requireNonNull(worlds).getKeys(false)) {
World world = Bukkit.getWorld(worldName);
if (world != null && addon.inGameModeWorld(world)) {
addon.log("Loading limits for " + world.getName());
worldLimitMap.putIfAbsent(world, new HashMap<>());
ConfigurationSection matsConfig = worlds.getConfigurationSection(worldName);
- worldLimitMap.put(world, loadLimits(matsConfig));
+ worldLimitMap.put(world, loadLimits(Objects.requireNonNull(matsConfig)));
}
}
}
@@ -156,7 +149,7 @@ public class BlockLimitsListener implements Listener {
handleBreak(e, e.getPlayer(), e.getBlock());
}
- void handleBreak(Cancellable e, Player player, Block b) {
+ private void handleBreak(Cancellable e, Player player, Block b) {
Material mat = b.getType();
// Special handling for crops that can break in different ways
if (mat.equals(Material.WHEAT_SEEDS)) {
diff --git a/src/main/java/bentobox/addon/limits/listeners/EntityLimitListener.java b/src/main/java/bentobox/addon/limits/listeners/EntityLimitListener.java
index 5d30557..23f872b 100644
--- a/src/main/java/bentobox/addon/limits/listeners/EntityLimitListener.java
+++ b/src/main/java/bentobox/addon/limits/listeners/EntityLimitListener.java
@@ -1,6 +1,9 @@
package bentobox.addon.limits.listeners;
+import java.util.Objects;
+
import org.bukkit.Location;
+import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -41,7 +44,7 @@ public class EntityLimitListener implements Listener {
}
if (addon.getSettings().getLimits().containsKey(e.getVehicle().getType())) {
// If someone in that area has the bypass permission, allow the spawning
- for (Entity entity : e.getVehicle().getLocation().getWorld().getNearbyEntities(e.getVehicle().getLocation(), 5, 5, 5)) {
+ for (Entity entity : Objects.requireNonNull(e.getVehicle().getLocation().getWorld()).getNearbyEntities(e.getVehicle().getLocation(), 5, 5, 5)) {
if (entity instanceof Player) {
Player player = (Player)entity;
boolean bypass = (player.isOp() || player.hasPermission(addon.getPlugin().getIWM().getPermissionPrefix(e.getVehicle().getWorld()) + MOD_BYPASS));
@@ -103,7 +106,7 @@ public class EntityLimitListener implements Listener {
private boolean checkByPass(Location l) {
// If someone in that area has the bypass permission, allow the spawning
- for (Entity entity : l.getWorld().getNearbyEntities(l, 5, 5, 5)) {
+ for (Entity entity : Objects.requireNonNull(l.getWorld()).getNearbyEntities(l, 5, 5, 5)) {
if (entity instanceof Player) {
Player player = (Player)entity;
if (player.isOp() || player.hasPermission(addon.getPlugin().getIWM().getPermissionPrefix(l.getWorld()) + MOD_BYPASS)) {
@@ -121,8 +124,9 @@ public class EntityLimitListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlock(HangingPlaceEvent e) {
Player player = e.getPlayer();
+ if (player == null) return;
addon.getIslands().getIslandAt(e.getEntity().getLocation()).ifPresent(island -> {
- boolean bypass = player.isOp() || player.hasPermission(addon.getPlugin().getIWM().getPermissionPrefix(e.getEntity().getWorld()) + MOD_BYPASS);
+ boolean bypass = Objects.requireNonNull(player).isOp() || player.hasPermission(addon.getPlugin().getIWM().getPermissionPrefix(e.getEntity().getWorld()) + MOD_BYPASS);
// Check if entity can be hung
if (!bypass && !island.isSpawn() && atLimit(island, e.getEntity())) {
// Not allowed
@@ -143,7 +147,9 @@ public class EntityLimitListener implements Listener {
e.setCancelled(true);
// If the reason is anything but because of a spawner then tell players within range
if (!e.getSpawnReason().equals(SpawnReason.SPAWNER) && !e.getSpawnReason().equals(SpawnReason.NATURAL) && !e.getSpawnReason().equals(SpawnReason.INFECTION) && !e.getSpawnReason().equals(SpawnReason.NETHER_PORTAL) && !e.getSpawnReason().equals(SpawnReason.REINFORCEMENTS) && !e.getSpawnReason().equals(SpawnReason.SLIME_SPLIT)) {
- for (Entity ent : e.getLocation().getWorld().getNearbyEntities(e.getLocation(), 5, 5, 5)) {
+ World w = e.getLocation().getWorld();
+ if (w == null) return;
+ for (Entity ent : w.getNearbyEntities(e.getLocation(), 5, 5, 5)) {
if (ent instanceof Player) {
User.getInstance(ent).sendMessage("entity-limits.hit-limit", "[entity]",
Util.prettifyText(e.getEntityType().toString()),
diff --git a/src/main/java/bentobox/addon/limits/listeners/JoinListener.java b/src/main/java/bentobox/addon/limits/listeners/JoinListener.java
index c6ca053..d2bea4b 100644
--- a/src/main/java/bentobox/addon/limits/listeners/JoinListener.java
+++ b/src/main/java/bentobox/addon/limits/listeners/JoinListener.java
@@ -1,6 +1,7 @@
package bentobox.addon.limits.listeners;
import java.util.Locale;
+import java.util.Objects;
import java.util.UUID;
import org.apache.commons.lang.math.NumberUtils;
@@ -141,8 +142,8 @@ public class JoinListener implements Listener {
// Set perm-based limits
String prefix = addon.getGameModePermPrefix(world);
String name = addon.getGameModeName(world);
- if (!prefix.isEmpty() && !name.isEmpty()) {
- checkPerms(owner.getPlayer(), prefix + "island.limit.", island.getUniqueId(), name);
+ if (!prefix.isEmpty() && !name.isEmpty() && owner.getPlayer() != null) {
+ checkPerms(Objects.requireNonNull(owner.getPlayer()), prefix + "island.limit.", island.getUniqueId(), name);
}
}
}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index b7d8d72..41cd928 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -27,7 +27,7 @@ worlds:
HOPPER: 11
# Default entity limits within a player's island space (protected area and to island limit).
-# A limit of 5 will allow up to 5 entites in over world, 5 in nether and 5 in the end.
+# A limit of 5 will allow up to 5 entities in over world, 5 in nether and 5 in the end.
# Affects all types of creature spawning. Also includes entities like MINECARTS.
# Note: Only the first 49 limited blocks and entities are shown in the limits GUI.
entitylimits:
diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml
index d8eaf98..211b49a 100755
--- a/src/main/resources/locales/en-US.yml
+++ b/src/main/resources/locales/en-US.yml
@@ -19,7 +19,7 @@ admin:
calc:
parameters: ""
description: "recalculate the island limits for player"
- finished: "&aIsland recalc finished sucessfully!"
+ finished: "&aIsland recalc finished successfully!"
island:
limits:
diff --git a/src/test/java/bentobox/addon/limits/listeners/JoinListenerTest.java b/src/test/java/bentobox/addon/limits/listeners/JoinListenerTest.java
index 1d1f45b..a52701b 100644
--- a/src/test/java/bentobox/addon/limits/listeners/JoinListenerTest.java
+++ b/src/test/java/bentobox/addon/limits/listeners/JoinListenerTest.java
@@ -1,6 +1,3 @@
-/**
- *
- */
package bentobox.addon.limits.listeners;
import static org.mockito.Mockito.mock;
@@ -10,6 +7,7 @@ import static org.mockito.Mockito.when;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.times;
import java.util.Collections;
@@ -24,7 +22,6 @@ import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.permissions.PermissionAttachmentInfo;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -70,11 +67,8 @@ public class JoinListenerTest {
@Mock
private Island island;
- /**
- * @throws java.lang.Exception
- */
@Before
- public void setUp() throws Exception {
+ public void setUp() {
jl = new JoinListener(addon);
// Setup addon
when(addon.getGameModes()).thenReturn(Collections.singletonList(bskyblock));
@@ -111,13 +105,6 @@ public class JoinListenerTest {
when(island.getOwner()).thenReturn(UUID.randomUUID());
}
- /**
- * @throws java.lang.Exception
- */
- @After
- public void tearDown() throws Exception {
- }
-
/**
* Test method for {@link bentobox.addon.limits.listeners.JoinListener#onNewIsland(world.bentobox.bentobox.api.events.island.IslandEvent)}.
*/
@@ -157,7 +144,7 @@ public class JoinListenerTest {
IslandEvent e = new IslandEvent(island, null, false, null, IslandEvent.Reason.CREATED);
jl.onNewIsland(e);
verify(island).getWorld();
- verify(owner).getPlayer();
+ verify(owner, times(2)).getPlayer();
}
/**