diff --git a/src/main/java/world/bentobox/limits/Settings.java b/src/main/java/world/bentobox/limits/Settings.java index c781c33..230be6e 100644 --- a/src/main/java/world/bentobox/limits/Settings.java +++ b/src/main/java/world/bentobox/limits/Settings.java @@ -1,9 +1,13 @@ package world.bentobox.limits; +import java.util.ArrayList; import java.util.Arrays; import java.util.EnumMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.EntityType; @@ -11,6 +15,7 @@ import org.bukkit.entity.EntityType; public class Settings { private final Map limits = new EnumMap<>(EntityType.class); + private final Map> groupLimits = new EnumMap<>(EntityType.class); private final List gameModes; private static final List DISALLOWED = Arrays.asList( EntityType.PRIMED_TNT, @@ -60,6 +65,33 @@ public class Settings { } addon.log("Entity limits:"); limits.entrySet().stream().map(e -> "Limit " + e.getKey().toString() + " to " + e.getValue()).forEach(addon::log); + + //group limits + el = addon.getConfig().getConfigurationSection("entitygrouplimits"); + if (el != null) { + for (String name : el.getKeys(false)) { + int limit = el.getInt(name + ".limit"); + Set entities = el.getStringList(name + ".entities").stream().map(s -> { + EntityType type = getType(s); + if (type != null) { + if (DISALLOWED.contains(type)) { + addon.logError("Entity type: " + s + " is not supported - skipping..."); + } else { + return type; + } + } else { + addon.logError("Unknown entity type: " + s + " - skipping..."); + } + return null; + }).filter(e -> e != null).collect(Collectors.toSet()); + EntityGroup group = new EntityGroup(name, entities, limit); + entities.forEach(e -> { + List groups = groupLimits.getOrDefault(e, new ArrayList()); + groups.add(group); + groupLimits.put(e, groups); + }); + } + } } private EntityType getType(String key) { @@ -73,6 +105,13 @@ public class Settings { return limits; } + /** + * @return the group limits + */ + public Map> getGroupLimits() { + return groupLimits; + } + /** * @return the gameModes */ @@ -80,4 +119,31 @@ public class Settings { return gameModes; } + public static class EntityGroup { + private final String name; + private final Set types; + private final int limit; + + public EntityGroup(String name, Set types, int limit) { + this.name = name; + this.types = types; + this.limit = limit; + } + + public boolean contains(EntityType type) { + return types.contains(type); + } + + public String getName() { + return name; + } + + public Set getTypes() { + return types; + } + + public int getLimit() { + return limit; + } + } } diff --git a/src/main/java/world/bentobox/limits/listeners/EntityLimitListener.java b/src/main/java/world/bentobox/limits/listeners/EntityLimitListener.java index 5d5cf5a..04168da 100644 --- a/src/main/java/world/bentobox/limits/listeners/EntityLimitListener.java +++ b/src/main/java/world/bentobox/limits/listeners/EntityLimitListener.java @@ -1,5 +1,7 @@ package world.bentobox.limits.listeners; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import org.bukkit.Location; @@ -19,6 +21,7 @@ import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.util.Util; import world.bentobox.limits.Limits; +import world.bentobox.limits.Settings; public class EntityLimitListener implements Listener { private static final String MOD_BYPASS = "mod.bypass"; @@ -166,6 +169,7 @@ public class EntityLimitListener implements Listener { private boolean atLimit(Island island, Entity ent) { // Check island settings first int limitAmount = -1; + List groups = new ArrayList(); if (addon.getBlockLimitListener().getIsland(island.getUniqueId()) != null) { limitAmount = addon.getBlockLimitListener().getIsland(island.getUniqueId()).getEntityLimit(ent.getType()); } @@ -173,11 +177,28 @@ public class EntityLimitListener implements Listener { if (limitAmount < 0 && addon.getSettings().getLimits().containsKey(ent.getType())) { limitAmount = addon.getSettings().getLimits().get(ent.getType()); } - if (limitAmount < 0) return false; + if (groups.isEmpty() && addon.getSettings().getGroupLimits().containsKey(ent.getType())) { + groups = addon.getSettings().getGroupLimits().get(ent.getType()); + } + if (limitAmount < 0 && groups.isEmpty()) return false; + // We have to count the entities - return ent.getWorld().getEntities().stream() + int count = (int) ent.getWorld().getEntities().stream() .filter(e -> e.getType().equals(ent.getType())) - .filter(e -> island.inIslandSpace(e.getLocation())).count() >= limitAmount; + .filter(e -> island.inIslandSpace(e.getLocation())).count(); + if (count >= limitAmount) + return true; + + // Now do the group limits + for (Settings.EntityGroup group : groups) //do not use lambda + { + count = (int) ent.getWorld().getEntities().stream() + .filter(e -> group.contains(e.getType())) + .filter(e -> island.inIslandSpace(e.getLocation())).count(); + if (count >= group.getLimit()) + return true; + } + return false; } }