Added permission limits for entities
https://github.com/BentoBoxWorld/Limits/issues/47
This commit is contained in:
parent
f907784bd7
commit
fb6f6757d5
|
@ -173,7 +173,13 @@ public class EntityLimitListener implements Listener {
|
||||||
long count = ent.getWorld().getEntities().stream()
|
long count = ent.getWorld().getEntities().stream()
|
||||||
.filter(e -> e.getType().equals(ent.getType()))
|
.filter(e -> e.getType().equals(ent.getType()))
|
||||||
.filter(e -> island.inIslandSpace(e.getLocation())).count();
|
.filter(e -> island.inIslandSpace(e.getLocation())).count();
|
||||||
return addon.getSettings().getLimits().containsKey(ent.getType()) && count >= addon.getSettings().getLimits().get(ent.getType());
|
// Check island settings first
|
||||||
|
int limitAmount = addon.getBlockLimitListener().getIsland(island.getUniqueId()).getEntityLimit(ent.getType());
|
||||||
|
// If no island settings then try global settings
|
||||||
|
if (limitAmount < 0 && addon.getSettings().getLimits().containsKey(ent.getType())) {
|
||||||
|
limitAmount = addon.getSettings().getLimits().get(ent.getType());
|
||||||
|
}
|
||||||
|
return count >= limitAmount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package world.bentobox.limits.listeners;
|
package world.bentobox.limits.listeners;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -9,6 +10,7 @@ import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
|
@ -38,41 +40,55 @@ public class JoinListener implements Listener {
|
||||||
|
|
||||||
private void checkPerms(Player player, String permissionPrefix, String islandId, String gameMode) {
|
private void checkPerms(Player player, String permissionPrefix, String islandId, String gameMode) {
|
||||||
IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(islandId);
|
IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(islandId);
|
||||||
|
|
||||||
for (PermissionAttachmentInfo perms : player.getEffectivePermissions()) {
|
for (PermissionAttachmentInfo perms : player.getEffectivePermissions()) {
|
||||||
if (perms.getPermission().startsWith(permissionPrefix)) {
|
if (!perms.getPermission().startsWith(permissionPrefix)) continue;
|
||||||
// No wildcards
|
// No wildcards
|
||||||
if (perms.getPermission().contains(permissionPrefix + "*")) {
|
if (perms.getPermission().contains(permissionPrefix + "*")) {
|
||||||
logError(player.getName(), perms.getPermission(), "wildcards are not allowed.");
|
logError(player.getName(), perms.getPermission(), "wildcards are not allowed.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Get the Material
|
// Check formatting
|
||||||
String[] split = perms.getPermission().split("\\.");
|
String[] split = perms.getPermission().split("\\.");
|
||||||
if (split.length != 5) {
|
if (split.length != 5) {
|
||||||
logError(player.getName(), perms.getPermission(), "format must be '" + permissionPrefix + "MATERIAL.NUMBER'");
|
logError(player.getName(), perms.getPermission(), "format must be '" + permissionPrefix + "MATERIAL.NUMBER' or '" + permissionPrefix + "ENTITY-TYPE.NUMBER'");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Material m = Material.getMaterial(split[3].toUpperCase(Locale.ENGLISH));
|
// Check value
|
||||||
if (m == null) {
|
if (!NumberUtils.isDigits(split[4])) {
|
||||||
logError(player.getName(), perms.getPermission(), split[3].toUpperCase(Locale.ENGLISH) + " is not a valid material.");
|
logError(player.getName(), perms.getPermission(), "the last part MUST be a number!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Get the max value should there be more than one
|
// Entities & materials
|
||||||
if (!NumberUtils.isDigits(split[4])) {
|
EntityType et = Arrays.stream(EntityType.values()).filter(t -> t.name().equalsIgnoreCase(split[3])).findFirst().orElse(null);
|
||||||
logError(player.getName(), perms.getPermission(), "the last part MUST be a number!");
|
Material m = Arrays.stream(Material.values()).filter(t -> t.name().equalsIgnoreCase(split[3])).findFirst().orElse(null);
|
||||||
} else {
|
|
||||||
// Set the limit
|
if (et == null && m == null) {
|
||||||
if (ibc == null) {
|
logError(player.getName(), perms.getPermission(), split[3].toUpperCase(Locale.ENGLISH) + " is not a valid material or entity type.");
|
||||||
ibc = new IslandBlockCount(islandId, gameMode);
|
break;
|
||||||
}
|
}
|
||||||
|
// Make an ibc if required
|
||||||
|
if (ibc == null) {
|
||||||
|
ibc = new IslandBlockCount(islandId, gameMode);
|
||||||
|
}
|
||||||
|
if (et != null && m == null) {
|
||||||
|
// Entity limit
|
||||||
|
ibc.setEntityLimit(et, Math.max(ibc.getEntityLimit(et), Integer.valueOf(split[4])));
|
||||||
|
} else if (m != null && et == null) {
|
||||||
|
// Material limit
|
||||||
|
ibc.setBlockLimit(m, Math.max(ibc.getBlockLimit(m), Integer.valueOf(split[4])));
|
||||||
|
} else {
|
||||||
|
if (m.isBlock()) {
|
||||||
|
// Material limit
|
||||||
ibc.setBlockLimit(m, Math.max(ibc.getBlockLimit(m), Integer.valueOf(split[4])));
|
ibc.setBlockLimit(m, Math.max(ibc.getBlockLimit(m), Integer.valueOf(split[4])));
|
||||||
|
} else {
|
||||||
|
// This is an entity setting
|
||||||
|
ibc.setEntityLimit(et, Math.max(ibc.getEntityLimit(et), Integer.valueOf(split[4])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If any changes have been made then store it
|
// If any changes have been made then store it - don't make files unless they are needed
|
||||||
if (ibc != null) {
|
if (ibc != null) addon.getBlockLimitListener().setIsland(islandId, ibc);
|
||||||
addon.getBlockLimitListener().setIsland(islandId, ibc);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logError(String name, String perm, String error) {
|
private void logError(String name, String perm, String error) {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
||||||
|
@ -29,6 +30,8 @@ public class IslandBlockCount implements DataObject {
|
||||||
*/
|
*/
|
||||||
@Expose
|
@Expose
|
||||||
private Map<Material, Integer> blockLimits = new EnumMap<>(Material.class);
|
private Map<Material, Integer> blockLimits = new EnumMap<>(Material.class);
|
||||||
|
@Expose
|
||||||
|
private Map<EntityType, Integer> entityLimits = new EnumMap<>(EntityType.class);
|
||||||
|
|
||||||
// Required for YAML database
|
// Required for YAML database
|
||||||
public IslandBlockCount() {}
|
public IslandBlockCount() {}
|
||||||
|
@ -158,4 +161,44 @@ public class IslandBlockCount implements DataObject {
|
||||||
public void setGameMode(String gameMode) {
|
public void setGameMode(String gameMode) {
|
||||||
this.gameMode = gameMode;
|
this.gameMode = gameMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the entityLimits
|
||||||
|
*/
|
||||||
|
public Map<EntityType, Integer> getEntityLimits() {
|
||||||
|
return entityLimits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param entityLimits the entityLimits to set
|
||||||
|
*/
|
||||||
|
public void setEntityLimits(Map<EntityType, Integer> entityLimits) {
|
||||||
|
this.entityLimits = entityLimits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an island-specific entity type limit
|
||||||
|
* @param t - entity type
|
||||||
|
* @param limit - limit
|
||||||
|
*/
|
||||||
|
public void setEntityLimit(EntityType t, int limit) {
|
||||||
|
entityLimits.put(t, limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the limit for an entity type
|
||||||
|
* @param t - entity type
|
||||||
|
* @return limit or -1 for unlimited
|
||||||
|
*/
|
||||||
|
public int getEntityLimit(EntityType t) {
|
||||||
|
return entityLimits.getOrDefault(t, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all island-specific entity type limits
|
||||||
|
*/
|
||||||
|
public void clearEntityLimits() {
|
||||||
|
entityLimits.clear();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
package bentobox.addon.limits.listeners;
|
package bentobox.addon.limits.listeners;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
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;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -19,6 +18,7 @@ import java.util.UUID;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||||
|
@ -243,7 +243,7 @@ public class JoinListenerTest {
|
||||||
when(player.getEffectivePermissions()).thenReturn(perms);
|
when(player.getEffectivePermissions()).thenReturn(perms);
|
||||||
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
|
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
|
||||||
jl.onPlayerJoin(e);
|
jl.onPlayerJoin(e);
|
||||||
verify(addon).logError("Player tastybento has permission: 'bskyblock.island.limit.my.perm.for.game' but format must be 'bskyblock.island.limit.MATERIAL.NUMBER' Ignoring...");
|
verify(addon).logError("Player tastybento has permission: 'bskyblock.island.limit.my.perm.for.game' but format must be 'bskyblock.island.limit.MATERIAL.NUMBER' or 'bskyblock.island.limit.ENTITY-TYPE.NUMBER' Ignoring...");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -258,7 +258,7 @@ public class JoinListenerTest {
|
||||||
when(player.getEffectivePermissions()).thenReturn(perms);
|
when(player.getEffectivePermissions()).thenReturn(perms);
|
||||||
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
|
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
|
||||||
jl.onPlayerJoin(e);
|
jl.onPlayerJoin(e);
|
||||||
verify(addon).logError("Player tastybento has permission: 'bskyblock.island.limit.mumbo.34' but MUMBO is not a valid material. Ignoring...");
|
verify(addon).logError("Player tastybento has permission: 'bskyblock.island.limit.mumbo.34' but MUMBO is not a valid material or entity type. Ignoring...");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -306,6 +306,22 @@ public class JoinListenerTest {
|
||||||
verify(addon, never()).logError(anyString());
|
verify(addon, never()).logError(anyString());
|
||||||
verify(ibc).setBlockLimit(eq(Material.STONE), eq(24));
|
verify(ibc).setBlockLimit(eq(Material.STONE), eq(24));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.limits.listeners.JoinListener#onPlayerJoin(org.bukkit.event.player.PlayerJoinEvent)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testOnPlayerJoinWithPermLimitsSuccessEntity() {
|
||||||
|
Set<PermissionAttachmentInfo> perms = new HashSet<>();
|
||||||
|
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
|
||||||
|
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.BAT.24");
|
||||||
|
perms.add(permAtt);
|
||||||
|
when(player.getEffectivePermissions()).thenReturn(perms);
|
||||||
|
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
|
||||||
|
jl.onPlayerJoin(e);
|
||||||
|
verify(addon, never()).logError(anyString());
|
||||||
|
verify(ibc).setEntityLimit(eq(EntityType.BAT), eq(24));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.limits.listeners.JoinListener#onPlayerJoin(org.bukkit.event.player.PlayerJoinEvent)}.
|
* Test method for {@link world.bentobox.limits.listeners.JoinListener#onPlayerJoin(org.bukkit.event.player.PlayerJoinEvent)}.
|
||||||
|
@ -322,6 +338,12 @@ public class JoinListenerTest {
|
||||||
PermissionAttachmentInfo permAtt3 = mock(PermissionAttachmentInfo.class);
|
PermissionAttachmentInfo permAtt3 = mock(PermissionAttachmentInfo.class);
|
||||||
when(permAtt3.getPermission()).thenReturn("bskyblock.island.limit.dirt.34");
|
when(permAtt3.getPermission()).thenReturn("bskyblock.island.limit.dirt.34");
|
||||||
perms.add(permAtt3);
|
perms.add(permAtt3);
|
||||||
|
PermissionAttachmentInfo permAtt4 = mock(PermissionAttachmentInfo.class);
|
||||||
|
when(permAtt4.getPermission()).thenReturn("bskyblock.island.limit.chicken.34");
|
||||||
|
perms.add(permAtt4);
|
||||||
|
PermissionAttachmentInfo permAtt5 = mock(PermissionAttachmentInfo.class);
|
||||||
|
when(permAtt5.getPermission()).thenReturn("bskyblock.island.limit.cave_spider.4");
|
||||||
|
perms.add(permAtt5);
|
||||||
when(player.getEffectivePermissions()).thenReturn(perms);
|
when(player.getEffectivePermissions()).thenReturn(perms);
|
||||||
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
|
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
|
||||||
jl.onPlayerJoin(e);
|
jl.onPlayerJoin(e);
|
||||||
|
@ -329,6 +351,8 @@ public class JoinListenerTest {
|
||||||
verify(ibc).setBlockLimit(eq(Material.STONE), eq(24));
|
verify(ibc).setBlockLimit(eq(Material.STONE), eq(24));
|
||||||
verify(ibc).setBlockLimit(eq(Material.GRASS), eq(14));
|
verify(ibc).setBlockLimit(eq(Material.GRASS), eq(14));
|
||||||
verify(ibc).setBlockLimit(eq(Material.DIRT), eq(34));
|
verify(ibc).setBlockLimit(eq(Material.DIRT), eq(34));
|
||||||
|
verify(ibc).setEntityLimit(eq(EntityType.CHICKEN), eq(34));
|
||||||
|
verify(ibc).setEntityLimit(eq(EntityType.CAVE_SPIDER), eq(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -357,8 +381,33 @@ public class JoinListenerTest {
|
||||||
verify(ibc, never()).setBlockLimit(eq(Material.STONE), eq(14));
|
verify(ibc, never()).setBlockLimit(eq(Material.STONE), eq(14));
|
||||||
verify(ibc).setBlockLimit(eq(Material.STONE), eq(34));
|
verify(ibc).setBlockLimit(eq(Material.STONE), eq(34));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test method for {@link world.bentobox.limits.listeners.JoinListener#onPlayerJoin(org.bukkit.event.player.PlayerJoinEvent)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testOnPlayerJoinWithPermLimitsMultiPermsSameEntity() {
|
||||||
|
// IBC - set the entity limit for BAT to be 25 already
|
||||||
|
when(ibc.getEntityLimit(any())).thenReturn(25);
|
||||||
|
Set<PermissionAttachmentInfo> perms = new HashSet<>();
|
||||||
|
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
|
||||||
|
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.BAT.24");
|
||||||
|
perms.add(permAtt);
|
||||||
|
PermissionAttachmentInfo permAtt2 = mock(PermissionAttachmentInfo.class);
|
||||||
|
when(permAtt2.getPermission()).thenReturn("bskyblock.island.limit.BAT.14");
|
||||||
|
perms.add(permAtt2);
|
||||||
|
PermissionAttachmentInfo permAtt3 = mock(PermissionAttachmentInfo.class);
|
||||||
|
when(permAtt3.getPermission()).thenReturn("bskyblock.island.limit.BAT.34");
|
||||||
|
perms.add(permAtt3);
|
||||||
|
when(player.getEffectivePermissions()).thenReturn(perms);
|
||||||
|
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
|
||||||
|
jl.onPlayerJoin(e);
|
||||||
|
verify(addon, never()).logError(anyString());
|
||||||
|
// Only the limit over 25 should be set
|
||||||
|
verify(ibc, never()).setEntityLimit(eq(EntityType.BAT), eq(24));
|
||||||
|
verify(ibc, never()).setEntityLimit(eq(EntityType.BAT), eq(14));
|
||||||
|
verify(ibc).setEntityLimit(eq(EntityType.BAT), eq(34));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test method for {@link world.bentobox.limits.listeners.JoinListener#onUnregisterIsland(world.bentobox.bentobox.api.events.island.IslandEvent)}.
|
* Test method for {@link world.bentobox.limits.listeners.JoinListener#onUnregisterIsland(world.bentobox.bentobox.api.events.island.IslandEvent)}.
|
||||||
|
|
Loading…
Reference in New Issue