From f77c48218a58161568097fd3ea4ce381b91fa1dc Mon Sep 17 00:00:00 2001 From: wea_ondara Date: Sat, 11 Apr 2020 13:53:28 +0200 Subject: [PATCH] added entity group limits via permissions to islands --- .../java/world/bentobox/limits/Settings.java | 9 +++- .../limits/listeners/EntityLimitListener.java | 26 ++++++++---- .../limits/listeners/JoinListener.java | 8 +++- .../limits/objects/IslandBlockCount.java | 41 +++++++++++++++++++ 4 files changed, 73 insertions(+), 11 deletions(-) diff --git a/src/main/java/world/bentobox/limits/Settings.java b/src/main/java/world/bentobox/limits/Settings.java index 82ea0ff..aa4b194 100644 --- a/src/main/java/world/bentobox/limits/Settings.java +++ b/src/main/java/world/bentobox/limits/Settings.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.EnumMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -84,7 +85,7 @@ public class Settings { addon.logError("Unknown entity type: " + s + " - skipping..."); } return null; - }).filter(e -> e != null).collect(Collectors.toSet()); + }).filter(e -> e != null).collect(Collectors.toCollection(LinkedHashSet::new)); if (entities.isEmpty()) continue; EntityGroup group = new EntityGroup(name, entities, limit); @@ -95,6 +96,9 @@ public class Settings { }); } } + + addon.log("Entity group limits:"); + getGroupLimitDefinitions().stream().map(e -> "Limit " + e.getName() + " to " + e.getLimit()).forEach(addon::log); } private EntityType getType(String key) { @@ -115,6 +119,9 @@ public class Settings { return groupLimits; } + /** + * @return the group limit definitions + */ public List getGroupLimitDefinitions() { return groupLimits.values().stream().flatMap(e -> e.stream()).distinct().collect(Collectors.toList()); } diff --git a/src/main/java/world/bentobox/limits/listeners/EntityLimitListener.java b/src/main/java/world/bentobox/limits/listeners/EntityLimitListener.java index 04168da..15df9af 100644 --- a/src/main/java/world/bentobox/limits/listeners/EntityLimitListener.java +++ b/src/main/java/world/bentobox/limits/listeners/EntityLimitListener.java @@ -1,8 +1,11 @@ package world.bentobox.limits.listeners; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; import org.bukkit.Location; import org.bukkit.World; @@ -169,18 +172,26 @@ public class EntityLimitListener implements Listener { private boolean atLimit(Island island, Entity ent) { // Check island settings first int limitAmount = -1; - List groups = new ArrayList(); + Map groupsLimits = new HashMap<>(); if (addon.getBlockLimitListener().getIsland(island.getUniqueId()) != null) { limitAmount = addon.getBlockLimitListener().getIsland(island.getUniqueId()).getEntityLimit(ent.getType()); + List groupdefs = addon.getSettings().getGroupLimits().getOrDefault(ent.getType(), new ArrayList()); + groupdefs.forEach(def -> { + int limit = addon.getBlockLimitListener().getIsland(island.getUniqueId()).getEntityGroupLimit(def.getName()); + if (limit >= 0) + groupsLimits.put(def, limit); + }); } // If no island settings then try global settings if (limitAmount < 0 && addon.getSettings().getLimits().containsKey(ent.getType())) { limitAmount = addon.getSettings().getLimits().get(ent.getType()); } - if (groups.isEmpty() && addon.getSettings().getGroupLimits().containsKey(ent.getType())) { - groups = addon.getSettings().getGroupLimits().get(ent.getType()); + if (addon.getSettings().getGroupLimits().containsKey(ent.getType())) { + addon.getSettings().getGroupLimits().getOrDefault(ent.getType(), new ArrayList<>()).stream() + .filter(group -> !groupsLimits.containsKey(group) || groupsLimits.get(group) > group.getLimit()) + .forEach(group -> groupsLimits.put(group, group.getLimit())); } - if (limitAmount < 0 && groups.isEmpty()) return false; + if (limitAmount < 0 && groupsLimits.isEmpty()) return false; // We have to count the entities int count = (int) ent.getWorld().getEntities().stream() @@ -190,12 +201,11 @@ public class EntityLimitListener implements Listener { return true; // Now do the group limits - for (Settings.EntityGroup group : groups) //do not use lambda - { + for (Map.Entry group : groupsLimits.entrySet()) { //do not use lambda count = (int) ent.getWorld().getEntities().stream() - .filter(e -> group.contains(e.getType())) + .filter(e -> group.getKey().contains(e.getType())) .filter(e -> island.inIslandSpace(e.getLocation())).count(); - if (count >= group.getLimit()) + if (count >= group.getValue()) return true; } return false; diff --git a/src/main/java/world/bentobox/limits/listeners/JoinListener.java b/src/main/java/world/bentobox/limits/listeners/JoinListener.java index 612a5de..724b3e8 100644 --- a/src/main/java/world/bentobox/limits/listeners/JoinListener.java +++ b/src/main/java/world/bentobox/limits/listeners/JoinListener.java @@ -23,6 +23,7 @@ import world.bentobox.bentobox.api.events.island.IslandEvent.Reason; import world.bentobox.bentobox.api.events.team.TeamEvent.TeamSetownerEvent; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.limits.Limits; +import world.bentobox.limits.Settings.EntityGroup; import world.bentobox.limits.objects.IslandBlockCount; /** @@ -55,7 +56,7 @@ public class JoinListener implements Listener { // Check formatting String[] split = perms.getPermission().split("\\."); if (split.length != 5) { - logError(player.getName(), perms.getPermission(), "format must be '" + permissionPrefix + "MATERIAL.NUMBER' or '" + permissionPrefix + "ENTITY-TYPE.NUMBER'"); + logError(player.getName(), perms.getPermission(), "format must be '" + permissionPrefix + "MATERIAL.NUMBER', '" + permissionPrefix + "ENTITY-TYPE.NUMBER', or '" + permissionPrefix + "ENTITY-GROUP.NUMBER'"); return; } // Check value @@ -66,6 +67,7 @@ public class JoinListener implements Listener { // Entities & materials EntityType et = Arrays.stream(EntityType.values()).filter(t -> t.name().equalsIgnoreCase(split[3])).findFirst().orElse(null); Material m = Arrays.stream(Material.values()).filter(t -> t.name().equalsIgnoreCase(split[3])).findFirst().orElse(null); + EntityGroup entgroup = addon.getSettings().getGroupLimitDefinitions().stream().filter(e -> e.getName().equalsIgnoreCase(split[3])).findFirst().orElse(null); if (et == null && m == null) { logError(player.getName(), perms.getPermission(), split[3].toUpperCase(Locale.ENGLISH) + " is not a valid material or entity type."); @@ -75,7 +77,9 @@ public class JoinListener implements Listener { if (ibc == null) { ibc = new IslandBlockCount(islandId, gameMode); } - if (et != null && m == null) { + if (entgroup != null) { + ibc.setEntityGroupLimit(entgroup.getName(), Math.max(ibc.getEntityGroupLimit(entgroup.getName()), Integer.valueOf(split[4]))); + } else 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) { diff --git a/src/main/java/world/bentobox/limits/objects/IslandBlockCount.java b/src/main/java/world/bentobox/limits/objects/IslandBlockCount.java index b94b265..f9ac2db 100644 --- a/src/main/java/world/bentobox/limits/objects/IslandBlockCount.java +++ b/src/main/java/world/bentobox/limits/objects/IslandBlockCount.java @@ -1,6 +1,7 @@ package world.bentobox.limits.objects; import java.util.EnumMap; +import java.util.HashMap; import java.util.Map; import org.bukkit.Material; @@ -32,6 +33,8 @@ public class IslandBlockCount implements DataObject { private Map blockLimits = new EnumMap<>(Material.class); @Expose private Map entityLimits = new EnumMap<>(EntityType.class); + @Expose + private Map entityGroupLimits = new HashMap<>(); // Required for YAML database public IslandBlockCount() {} @@ -201,4 +204,42 @@ public class IslandBlockCount implements DataObject { entityLimits.clear(); } + /** + * @return the entityGroupLimits + */ + public Map getEntityGroupLimits() { + return entityGroupLimits; + } + + /** + * @param entityGroupLimits the entityGroupLimits to set + */ + public void setEntityGroupLimits(Map entityGroupLimits) { + this.entityGroupLimits = entityGroupLimits; + } + + /** + * Set an island-specific entity group limit + * @param name - entity group + * @param limit - limit + */ + public void setEntityGroupLimit(String name, int limit) { + entityGroupLimits.put(name, limit); + } + + /** + * Get the limit for an entity group + * @param name - entity group + * @return limit or -1 for unlimited + */ + public int getEntityGroupLimit(String name) { + return entityGroupLimits.getOrDefault(name, -1); + } + + /** + * Clear all island-specific entity group limits + */ + public void clearEntityGroupLimits() { + entityGroupLimits.clear(); + } }