mirror of
https://github.com/BentoBoxWorld/Limits.git
synced 2024-11-15 23:25:53 +01:00
commit
a5980b2386
24
pom.xml
24
pom.xml
@ -57,14 +57,14 @@
|
||||
<!-- Non-minecraft related dependencies -->
|
||||
<powermock.version>2.0.9</powermock.version>
|
||||
<!-- More visible way how to change dependency versions -->
|
||||
<spigot.version>1.17.1-R0.1-SNAPSHOT</spigot.version>
|
||||
<bentobox.version>1.17.1</bentobox.version>
|
||||
<spigot.version>1.16.1-R0.1-SNAPSHOT</spigot.version>
|
||||
<bentobox.version>1.18.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. -->
|
||||
<build.number>-LOCAL</build.number>
|
||||
<!-- This allows to change between versions. -->
|
||||
<build.version>1.17.2</build.version>
|
||||
<build.version>1.18.1</build.version>
|
||||
<sonar.projectKey>BentoBoxWorld_Limits</sonar.projectKey>
|
||||
<sonar.organization>bentobox-world</sonar.organization>
|
||||
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
|
||||
@ -210,7 +210,23 @@
|
||||
<version>3.0.0-M5</version>
|
||||
<configuration>
|
||||
<argLine>
|
||||
--illegal-access=permit
|
||||
--add-opens java.base/java.lang=ALL-UNNAMED
|
||||
--add-opens java.base/java.math=ALL-UNNAMED
|
||||
--add-opens java.base/java.io=ALL-UNNAMED
|
||||
--add-opens java.base/java.util=ALL-UNNAMED
|
||||
--add-opens java.base/java.util.stream=ALL-UNNAMED
|
||||
--add-opens java.base/java.text=ALL-UNNAMED
|
||||
--add-opens java.base/java.util.regex=ALL-UNNAMED
|
||||
--add-opens java.base/java.nio.channels.spi=ALL-UNNAMED
|
||||
--add-opens java.base/sun.nio.ch=ALL-UNNAMED
|
||||
--add-opens java.base/java.net=ALL-UNNAMED
|
||||
--add-opens java.base/java.util.concurrent=ALL-UNNAMED
|
||||
--add-opens java.base/sun.nio.fs=ALL-UNNAMED
|
||||
--add-opens java.base/sun.nio.cs=ALL-UNNAMED
|
||||
--add-opens java.base/java.nio.file=ALL-UNNAMED
|
||||
--add-opens java.base/java.nio.charset=ALL-UNNAMED
|
||||
--add-opens java.base/java.lang.reflect=ALL-UNNAMED
|
||||
--add-opens java.logging/java.util.logging=ALL-UNNAMED
|
||||
</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
@ -17,6 +17,7 @@ import world.bentobox.limits.commands.PlayerCommand;
|
||||
import world.bentobox.limits.listeners.BlockLimitsListener;
|
||||
import world.bentobox.limits.listeners.EntityLimitListener;
|
||||
import world.bentobox.limits.listeners.JoinListener;
|
||||
import world.bentobox.limits.objects.IslandBlockCount;
|
||||
|
||||
|
||||
/**
|
||||
@ -26,6 +27,7 @@ import world.bentobox.limits.listeners.JoinListener;
|
||||
*/
|
||||
public class Limits extends Addon {
|
||||
|
||||
private static final String LIMIT_NOT_SET = "Limit not set";
|
||||
private Settings settings;
|
||||
private List<GameModeAddon> gameModes;
|
||||
private BlockLimitsListener blockLimitListener;
|
||||
@ -134,8 +136,8 @@ public class Limits extends Addon {
|
||||
private void registerPlaceholders(GameModeAddon gm) {
|
||||
if (getPlugin().getPlaceholdersManager() == null) return;
|
||||
Arrays.stream(Material.values())
|
||||
.filter(m -> m.isBlock())
|
||||
.forEach(m -> registerCountAndLimitPlaceholders(m, gm));
|
||||
.filter(Material::isBlock)
|
||||
.forEach(m -> registerCountAndLimitPlaceholders(m, gm));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,8 +150,8 @@ public class Limits extends Addon {
|
||||
* "Limits_bskyblock_island_hopper_count"
|
||||
* "Limits_bskyblock_island_hopper_limit"
|
||||
*
|
||||
* @param m
|
||||
* @param gm
|
||||
* @param m material
|
||||
* @param gm game mode
|
||||
*/
|
||||
private void registerCountAndLimitPlaceholders(Material m, GameModeAddon gm) {
|
||||
getPlugin().getPlaceholdersManager().registerPlaceholder(this,
|
||||
@ -163,7 +165,7 @@ public class Limits extends Addon {
|
||||
/**
|
||||
* @param user - Used to identify the island the user belongs to
|
||||
* @param m - The material we are trying to count on the island
|
||||
* @param gm
|
||||
* @param gm Game Mode Addon
|
||||
* @return Number of blocks of the specified material on the given user's island
|
||||
*/
|
||||
private int getCount(@Nullable User user, Material m, GameModeAddon gm) {
|
||||
@ -171,24 +173,30 @@ public class Limits extends Addon {
|
||||
if (is == null) {
|
||||
return 0;
|
||||
}
|
||||
return getBlockLimitListener().getIsland(gm.getIslands().getIsland(gm.getOverWorld(), user).getUniqueId()).
|
||||
getBlockCount(m);
|
||||
@Nullable IslandBlockCount ibc = getBlockLimitListener().getIsland(is.getUniqueId());
|
||||
if (ibc == null) {
|
||||
return 0;
|
||||
}
|
||||
return ibc.getBlockCount(m);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param user - Used to identify the island the user belongs to
|
||||
* @param m - The material whose limit we are querying
|
||||
* @param gm
|
||||
* @param gm Game Mode Addon
|
||||
* @return The limit of the specified material on the given user's island
|
||||
*/
|
||||
private String getLimit(@Nullable User user, Material m, GameModeAddon gm) {
|
||||
Island is = gm.getIslands().getIsland(gm.getOverWorld(), user);
|
||||
if (is == null) {
|
||||
return "Limit not set";
|
||||
return LIMIT_NOT_SET;
|
||||
}
|
||||
int limit = getBlockLimitListener().getIsland(gm.getIslands().getIsland(gm.getOverWorld(), user).getUniqueId()).
|
||||
getBlockLimit(m);
|
||||
return limit == -1 ? "Limit not set" : String.valueOf(limit);
|
||||
@Nullable IslandBlockCount ibc = getBlockLimitListener().getIsland(is.getUniqueId());
|
||||
if (ibc == null) {
|
||||
return LIMIT_NOT_SET;
|
||||
}
|
||||
int limit = ibc.getBlockLimit(m);
|
||||
return limit == -1 ? LIMIT_NOT_SET : String.valueOf(limit);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,14 +1,6 @@
|
||||
package world.bentobox.limits;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@ -89,7 +81,7 @@ public class Settings {
|
||||
addon.logError("Unknown entity type: " + s + " - skipping...");
|
||||
}
|
||||
return null;
|
||||
}).filter(e -> e != null).collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
}).filter(Objects::nonNull).collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
if (entities.isEmpty())
|
||||
continue;
|
||||
EntityGroup group = new EntityGroup(name, entities, limit);
|
||||
@ -102,7 +94,7 @@ public class Settings {
|
||||
}
|
||||
|
||||
addon.log("Entity group limits:");
|
||||
getGroupLimitDefinitions().stream().map(e -> "Limit " + e.getName() + " (" + e.getTypes().stream().map(x -> x.name()).collect(Collectors.joining(", ")) + ") to " + e.getLimit()).forEach(addon::log);
|
||||
getGroupLimitDefinitions().stream().map(e -> "Limit " + e.getName() + " (" + e.getTypes().stream().map(Enum::name).collect(Collectors.joining(", ")) + ") to " + e.getLimit()).forEach(addon::log);
|
||||
}
|
||||
|
||||
private EntityType getType(String key) {
|
||||
@ -110,7 +102,7 @@ public class Settings {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the limits
|
||||
* @return the entity limits
|
||||
*/
|
||||
public Map<EntityType, Integer> getLimits() {
|
||||
return Collections.unmodifiableMap(limits);
|
||||
@ -127,7 +119,7 @@ public class Settings {
|
||||
* @return the group limit definitions
|
||||
*/
|
||||
public List<EntityGroup> getGroupLimitDefinitions() {
|
||||
return groupLimits.values().stream().flatMap(e -> e.stream()).distinct().collect(Collectors.toList());
|
||||
return groupLimits.values().stream().flatMap(Collection::stream).distinct().toList();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,9 +178,7 @@ public class Settings {
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final EntityGroup other = (EntityGroup) obj;
|
||||
if (!Objects.equals(this.name, other.name))
|
||||
return false;
|
||||
return true;
|
||||
return Objects.equals(this.name, other.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,13 +1,7 @@
|
||||
package world.bentobox.limits.commands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Material;
|
||||
@ -88,26 +82,30 @@ public class LimitTab implements Tab {
|
||||
addEntityLimits(ibc, island);
|
||||
addEntityGroupLimits(ibc, island);
|
||||
// Sort
|
||||
switch (sortBy) {
|
||||
default:
|
||||
Collections.sort(result, (o1, o2) -> o1.getName().compareTo(o2.getName()));
|
||||
break;
|
||||
case Z2A:
|
||||
Collections.sort(result, (o1, o2) -> o2.getName().compareTo(o1.getName()));
|
||||
break;
|
||||
if (sortBy == SORT_BY.Z2A) {
|
||||
result.sort((o1, o2) -> o2.getName().compareTo(o1.getName()));
|
||||
} else {
|
||||
result.sort(Comparator.comparing(PanelItem::getName));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addEntityGroupLimits(IslandBlockCount ibc, Island island) {
|
||||
// Entity group limits
|
||||
Map<EntityGroup, Integer> groupmap = addon.getSettings().getGroupLimitDefinitions().stream().collect(Collectors.toMap(e -> e, e -> e.getLimit()));
|
||||
Map<String, EntityGroup> groupbyname = groupmap.keySet().stream().collect(Collectors.toMap(e -> e.getName(), e -> e));
|
||||
Map<EntityGroup, Integer> groupMap = addon.getSettings().getGroupLimitDefinitions().stream().collect(Collectors.toMap(e -> e, EntityGroup::getLimit));
|
||||
// Group by same loop up map
|
||||
Map<String, EntityGroup> groupByName = groupMap.keySet().stream().collect(Collectors.toMap(EntityGroup::getName, e -> e));
|
||||
// Merge in any permission-based limits
|
||||
if (ibc != null) ibc.getEntityGroupLimits().entrySet().stream()
|
||||
.filter(e -> groupbyname.containsKey(e.getKey()))
|
||||
.forEach(e -> groupmap.put(groupbyname.get(e.getKey()), e.getValue()));
|
||||
groupmap.forEach((v, limit) -> {
|
||||
if (ibc == null) {
|
||||
return;
|
||||
}
|
||||
ibc.getEntityGroupLimits().entrySet().stream()
|
||||
.filter(e -> groupByName.containsKey(e.getKey()))
|
||||
.forEach(e -> groupMap.put(groupByName.get(e.getKey()), e.getValue()));
|
||||
// Update the group map for each group limit offset. If the value already exists add it
|
||||
ibc.getEntityGroupLimitsOffset().forEach((key, value) ->
|
||||
groupMap.put(groupByName.get(key), (groupMap.getOrDefault(groupByName.get(key), 0) + value)));
|
||||
groupMap.forEach((v, limit) -> {
|
||||
PanelItemBuilder pib = new PanelItemBuilder();
|
||||
EntityType k = v.getTypes().iterator().next();
|
||||
pib.name(v.getName());
|
||||
@ -118,7 +116,7 @@ public class LimitTab implements Tab {
|
||||
if (E2M.containsKey(k)) {
|
||||
m = E2M.get(k);
|
||||
} else if (k.isAlive()) {
|
||||
m = Material.valueOf(k.toString() + "_SPAWN_EGG");
|
||||
m = Material.valueOf(k + "_SPAWN_EGG");
|
||||
} else {
|
||||
// Regular material
|
||||
m = Material.valueOf(k.toString());
|
||||
@ -142,7 +140,11 @@ public class LimitTab implements Tab {
|
||||
// Entity limits
|
||||
Map<EntityType, Integer> map = new HashMap<>(addon.getSettings().getLimits());
|
||||
// Merge in any permission-based limits
|
||||
if (ibc != null) ibc.getEntityLimits().forEach(map::put);
|
||||
if (ibc != null) {
|
||||
map.putAll(ibc.getEntityLimits());
|
||||
ibc.getEntityLimitsOffset().forEach((k,v) -> map.put(k, map.getOrDefault(k, 0) + v));
|
||||
}
|
||||
|
||||
map.forEach((k,v) -> {
|
||||
PanelItemBuilder pib = new PanelItemBuilder();
|
||||
pib.name(Util.prettifyText(k.toString()));
|
||||
@ -151,7 +153,7 @@ public class LimitTab implements Tab {
|
||||
if (E2M.containsKey(k)) {
|
||||
m = E2M.get(k);
|
||||
} else if (k.isAlive()) {
|
||||
m = Material.valueOf(k.toString() + "_SPAWN_EGG");
|
||||
m = Material.valueOf(k + "_SPAWN_EGG");
|
||||
} else {
|
||||
// Regular material
|
||||
m = Material.valueOf(k.toString());
|
||||
@ -180,11 +182,12 @@ public class LimitTab implements Tab {
|
||||
pib.icon(B2M.getOrDefault(en.getKey(), en.getKey()));
|
||||
|
||||
int count = ibc == null ? 0 : ibc.getBlockCounts().getOrDefault(en.getKey(), 0);
|
||||
String color = count >= en.getValue() ? user.getTranslation("island.limits.max-color") : user.getTranslation("island.limits.regular-color");
|
||||
int value = en.getValue() + (ibc == null ? 0 : ibc.getBlockLimitsOffset().getOrDefault(en.getKey(), 0));
|
||||
String color = count >= value ? user.getTranslation("island.limits.max-color") : user.getTranslation("island.limits.regular-color");
|
||||
pib.description(color
|
||||
+ user.getTranslation("island.limits.block-limit-syntax",
|
||||
TextVariables.NUMBER, String.valueOf(count),
|
||||
"[limit]", String.valueOf(en.getValue())));
|
||||
"[limit]", String.valueOf(value)));
|
||||
result.add(pib.build());
|
||||
}
|
||||
}
|
||||
|
@ -37,10 +37,9 @@ public class LimitsCalc {
|
||||
private IslandBlockCount ibc;
|
||||
private final Map<Material, AtomicInteger> blockCount;
|
||||
private final User sender;
|
||||
private final Set<Pair<Integer, Integer>> chunksToScan;
|
||||
private int count;
|
||||
private int chunksToScanCount;
|
||||
private BentoBox plugin;
|
||||
private final int chunksToScanCount;
|
||||
private final BentoBox plugin;
|
||||
|
||||
|
||||
/**
|
||||
@ -56,13 +55,13 @@ public class LimitsCalc {
|
||||
this.addon = addon;
|
||||
this.island = instance.getIslands().getIsland(world, targetPlayer);
|
||||
this.bll = addon.getBlockLimitListener();
|
||||
this.ibc = bll.getIsland(island.getUniqueId());
|
||||
this.ibc = bll.getIsland(Objects.requireNonNull(island).getUniqueId());
|
||||
blockCount = new EnumMap<>(Material.class);
|
||||
this.sender = sender;
|
||||
this.world = world;
|
||||
|
||||
// Get chunks to scan
|
||||
chunksToScan = getChunksToScan(island);
|
||||
Set<Pair<Integer, Integer>> chunksToScan = getChunksToScan(island);
|
||||
count = 0;
|
||||
|
||||
boolean isNether = plugin.getIWM().isNetherGenerate(world) && plugin.getIWM().isNetherIslands(world);
|
||||
@ -76,7 +75,7 @@ public class LimitsCalc {
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void asyncScan(World world2, Pair<Integer, Integer> c) {
|
||||
@ -141,7 +140,7 @@ public class LimitsCalc {
|
||||
|
||||
private void tidyUp() {
|
||||
if (ibc == null) {
|
||||
ibc = new IslandBlockCount();
|
||||
ibc = new IslandBlockCount(island.getUniqueId(), plugin.getIWM().getAddon(world).map(a -> a.getDescription().getName()).orElse("default"));
|
||||
}
|
||||
ibc.setBlockCounts(blockCount.entrySet().stream()
|
||||
.collect(Collectors.toMap(
|
||||
|
@ -2,6 +2,7 @@ package world.bentobox.limits.events;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
@ -21,6 +22,16 @@ public class LimitsJoinPermCheckEvent extends BentoBoxEvent implements Cancellab
|
||||
private IslandBlockCount ibc;
|
||||
private boolean cancel;
|
||||
private boolean ignorePerms;
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
@Override
|
||||
public @NonNull HandlerList getHandlers() {
|
||||
return getHandlerList();
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when a player joins the server and before limit settings for their island are changed based
|
||||
@ -99,7 +110,7 @@ public class LimitsJoinPermCheckEvent extends BentoBoxEvent implements Cancellab
|
||||
|
||||
/**
|
||||
* Ignore player's perms. This differs to canceling the event in that the IslandBlockCount will be used if given via
|
||||
* {@link setIbc(IslandBlockCount ibc)}
|
||||
* {@link #setIbc(IslandBlockCount ibc)}
|
||||
* @param ignorePerms the ignorePerms to set
|
||||
*/
|
||||
public void setIgnorePerms(boolean ignorePerms) {
|
||||
|
@ -52,7 +52,7 @@ public class LimitsPermCheckEvent extends LimitsJoinPermCheckEvent {
|
||||
/**
|
||||
* @return the entityGroup
|
||||
*/
|
||||
public EntityGroup getEntityGroup() {
|
||||
public @Nullable EntityGroup getEntityGroup() {
|
||||
return entityGroup;
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ public class LimitsPermCheckEvent extends LimitsJoinPermCheckEvent {
|
||||
/**
|
||||
* @param entityGroup the entityGroup to set
|
||||
*/
|
||||
public void setEntityGroup(EntityGroup entityGroup) {
|
||||
public void setEntityGroup(@Nullable EntityGroup entityGroup) {
|
||||
this.entityGroup = entityGroup;
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ public class LimitsPermCheckEvent extends LimitsJoinPermCheckEvent {
|
||||
/**
|
||||
* @return the entityType
|
||||
*/
|
||||
public EntityType getEntityType() {
|
||||
public @Nullable EntityType getEntityType() {
|
||||
return entityType;
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ public class LimitsPermCheckEvent extends LimitsJoinPermCheckEvent {
|
||||
/**
|
||||
* @param entityType the entityType to set
|
||||
*/
|
||||
public void setEntityType(EntityType entityType) {
|
||||
public void setEntityType(@Nullable EntityType entityType) {
|
||||
this.entityType = entityType;
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ public class LimitsPermCheckEvent extends LimitsJoinPermCheckEvent {
|
||||
/**
|
||||
* @return the material
|
||||
*/
|
||||
public Material getMaterial() {
|
||||
public @Nullable Material getMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ public class LimitsPermCheckEvent extends LimitsJoinPermCheckEvent {
|
||||
/**
|
||||
* @param material the material to set
|
||||
*/
|
||||
public void setMaterial(Material material) {
|
||||
public void setMaterial(@Nullable Material material) {
|
||||
this.material = material;
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,7 @@ public class BlockLimitsListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onTurtleEggBreak(PlayerInteractEvent e) {
|
||||
if (e.getAction().equals(Action.PHYSICAL) && e.getClickedBlock().getType().equals(Material.TURTLE_EGG)) {
|
||||
if (e.getAction().equals(Action.PHYSICAL) && e.getClickedBlock() != null && e.getClickedBlock().getType().equals(Material.TURTLE_EGG)) {
|
||||
handleBreak(e, e.getClickedBlock());
|
||||
}
|
||||
}
|
||||
@ -296,8 +296,8 @@ public class BlockLimitsListener implements Listener {
|
||||
return Material.PLAYER_HEAD;
|
||||
} else if (mat == Material.DRAGON_WALL_HEAD) {
|
||||
return Material.DRAGON_HEAD;
|
||||
} else if (mat != null && mat == Material.getMaterial("BAMBOO_SAPLING")) {
|
||||
return Material.getMaterial("BAMBOO");
|
||||
} else if (mat == Material.BAMBOO_SAPLING) {
|
||||
return Material.BAMBOO;
|
||||
} else if (mat == Material.PISTON_HEAD || mat == Material.MOVING_PISTON) {
|
||||
TechnicalPiston tp = (TechnicalPiston) b;
|
||||
if (tp.getType() == TechnicalPiston.Type.NORMAL) {
|
||||
@ -314,7 +314,6 @@ public class BlockLimitsListener implements Listener {
|
||||
*
|
||||
* @param b - block
|
||||
* @param add - true to add a block, false to remove
|
||||
* @param changeTo - material this block will become
|
||||
* @return limit amount if over limit, or -1 if no limitation
|
||||
*/
|
||||
private int process(Block b, boolean add) {
|
||||
@ -329,6 +328,10 @@ public class BlockLimitsListener implements Listener {
|
||||
// Invalid world
|
||||
return -1;
|
||||
}
|
||||
// Ignore the center block - usually bedrock, but for AOneBlock it's the magic block
|
||||
if (addon.getConfig().getBoolean("ignore-center-block", true) && i.getCenter().equals(b.getLocation())) {
|
||||
return -1;
|
||||
}
|
||||
islandCountMap.putIfAbsent(id, new IslandBlockCount(id, gameMode));
|
||||
if (add) {
|
||||
// Check limit
|
||||
@ -411,14 +414,14 @@ public class BlockLimitsListener implements Listener {
|
||||
// Merge limits
|
||||
Map<Material, Integer> result = new EnumMap<>(Material.class);
|
||||
// Default
|
||||
defaultLimitMap.forEach(result::put);
|
||||
result.putAll(defaultLimitMap);
|
||||
// World
|
||||
if (worldLimitMap.containsKey(w)) {
|
||||
worldLimitMap.get(w).forEach(result::put);
|
||||
result.putAll(worldLimitMap.get(w));
|
||||
}
|
||||
// Island
|
||||
if (islandCountMap.containsKey(id)) {
|
||||
islandCountMap.get(id).getBlockLimits().forEach(result::put);
|
||||
result.putAll(islandCountMap.get(id).getBlockLimits());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package world.bentobox.limits.listeners;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -17,6 +16,7 @@ import org.bukkit.Tag;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Animals;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
@ -27,6 +27,7 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||
import org.bukkit.event.entity.EntityBreedEvent;
|
||||
import org.bukkit.event.hanging.HangingPlaceEvent;
|
||||
import org.bukkit.event.vehicle.VehicleCreateEvent;
|
||||
|
||||
@ -43,17 +44,7 @@ public class EntityLimitListener implements Listener {
|
||||
private static final String MOD_BYPASS = "mod.bypass";
|
||||
private final Limits addon;
|
||||
private final List<UUID> justSpawned = new ArrayList<>();
|
||||
private static final List<BlockFace> CARDINALS;
|
||||
static {
|
||||
List<BlockFace> cardinals = new ArrayList<>();
|
||||
cardinals.add(BlockFace.UP);
|
||||
cardinals.add(BlockFace.NORTH);
|
||||
cardinals.add(BlockFace.SOUTH);
|
||||
cardinals.add(BlockFace.EAST);
|
||||
cardinals.add(BlockFace.WEST);
|
||||
cardinals.add(BlockFace.DOWN);
|
||||
CARDINALS = Collections.unmodifiableList(cardinals);
|
||||
}
|
||||
private static final List<BlockFace> CARDINALS = List.of(BlockFace.UP, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST, BlockFace.DOWN);
|
||||
|
||||
/**
|
||||
* Handles entity and natural limitations
|
||||
@ -61,7 +52,6 @@ public class EntityLimitListener implements Listener {
|
||||
*/
|
||||
public EntityLimitListener(Limits addon) {
|
||||
this.addon = addon;
|
||||
justSpawned.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,46 +61,39 @@ public class EntityLimitListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onMinecart(VehicleCreateEvent e) {
|
||||
// Return if not in a known world
|
||||
|
||||
if (!addon.inGameModeWorld(e.getVehicle().getWorld())) {
|
||||
return;
|
||||
}
|
||||
// Debounce
|
||||
if (justSpawned.contains(e.getVehicle().getUniqueId())) {
|
||||
justSpawned.remove(e.getVehicle().getUniqueId());
|
||||
return;
|
||||
}
|
||||
// If someone in that area has the bypass permission, allow the spawning
|
||||
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));
|
||||
// Check island
|
||||
addon.getIslands().getProtectedIslandAt(e.getVehicle().getLocation()).ifPresent(island -> {
|
||||
// Ignore spawn
|
||||
if (island.isSpawn()) {
|
||||
return;
|
||||
}
|
||||
// Check if the player is at the limit
|
||||
AtLimitResult res;
|
||||
if (!bypass && (res = atLimit(island, e.getVehicle())).hit()) {
|
||||
e.setCancelled(true);
|
||||
for (Entity ent : e.getVehicle().getLocation().getWorld().getNearbyEntities(e.getVehicle().getLocation(), 5, 5, 5)) {
|
||||
if (ent instanceof Player) {
|
||||
((Player) ent).updateInventory();
|
||||
if (res.getTypelimit() != null) {
|
||||
User.getInstance(ent).notify("entity-limits.hit-limit", "[entity]",
|
||||
Util.prettifyText(e.getVehicle().getType().toString()),
|
||||
TextVariables.NUMBER, String.valueOf(res.getTypelimit().getValue()));
|
||||
} else {
|
||||
User.getInstance(ent).notify("entity-limits.hit-limit", "[entity]",
|
||||
res.getGrouplimit().getKey().getName() + " (" + res.getGrouplimit().getKey().getTypes().stream().map(x -> Util.prettifyText(x.toString())).collect(Collectors.joining(", ")) + ")",
|
||||
TextVariables.NUMBER, String.valueOf(res.getGrouplimit().getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
// Check island
|
||||
addon.getIslands().getProtectedIslandAt(e.getVehicle().getLocation())
|
||||
// Ignore spawn
|
||||
.filter(i -> !i.isSpawn())
|
||||
.ifPresent(island -> {
|
||||
// Check if the player is at the limit
|
||||
AtLimitResult res = atLimit(island, e.getVehicle());
|
||||
if (res.hit()) {
|
||||
e.setCancelled(true);
|
||||
this.tellPlayers(e.getVehicle().getLocation(), e.getVehicle(), SpawnReason.MOUNT, res);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onBreed(final EntityBreedEvent e) {
|
||||
if (addon.inGameModeWorld(e.getEntity().getWorld())
|
||||
&& e.getBreeder() != null
|
||||
&& e.getBreeder() instanceof Player p
|
||||
&& !(p.isOp() || p.hasPermission(addon.getPlugin().getIWM().getPermissionPrefix(e.getEntity().getWorld()) + MOD_BYPASS))
|
||||
&& !checkLimit(e, e.getEntity(), SpawnReason.BREEDING, false)
|
||||
&& e.getFather() instanceof Animals f && e.getMother() instanceof Animals m) {
|
||||
f.setLoveModeTicks(0);
|
||||
m.setLoveModeTicks(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,53 +107,21 @@ public class EntityLimitListener implements Listener {
|
||||
justSpawned.remove(e.getEntity().getUniqueId());
|
||||
return;
|
||||
}
|
||||
boolean bypass = false;
|
||||
// Check why it was spawned
|
||||
switch (e.getSpawnReason()) {
|
||||
// These reasons are due to a player being involved (usually) so there may be a bypass
|
||||
case BREEDING:
|
||||
case BUILD_IRONGOLEM:
|
||||
case BUILD_SNOWMAN:
|
||||
case BUILD_WITHER:
|
||||
case CURED:
|
||||
case EGG:
|
||||
case SPAWNER_EGG:
|
||||
bypass = checkByPass(e.getLocation());
|
||||
break;
|
||||
case SHOULDER_ENTITY:
|
||||
if (e.getSpawnReason().equals(SpawnReason.SHOULDER_ENTITY) || e.getSpawnReason().equals(SpawnReason.BREEDING)) {
|
||||
// Special case - do nothing - jumping around spawns parrots as they drop off player's shoulder
|
||||
// Ignore breeding because it's handled in the EntityBreedEvent listener
|
||||
return;
|
||||
default:
|
||||
// Other natural reasons
|
||||
break;
|
||||
}
|
||||
// Some checks can be done async, some not
|
||||
switch (e.getSpawnReason()) {
|
||||
case BUILD_SNOWMAN:
|
||||
case BUILD_IRONGOLEM:
|
||||
checkLimit(e, e.getEntity(), e.getSpawnReason(), bypass, addon.getSettings().isAsyncGolums());
|
||||
default:
|
||||
if (e.getSpawnReason().equals(SpawnReason.BUILD_SNOWMAN) || e.getSpawnReason().equals(SpawnReason.BUILD_IRONGOLEM)) {
|
||||
checkLimit(e, e.getEntity(), e.getSpawnReason(), addon.getSettings().isAsyncGolums());
|
||||
} else {
|
||||
// Check limit sync
|
||||
checkLimit(e, e.getEntity(), e.getSpawnReason(), bypass, false);
|
||||
break;
|
||||
|
||||
checkLimit(e, e.getEntity(), e.getSpawnReason(), false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean checkByPass(Location l) {
|
||||
// If someone in that area has the bypass permission, allow the spawning
|
||||
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)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* handles paintings and item frames
|
||||
* @param e - event
|
||||
@ -205,61 +156,56 @@ public class EntityLimitListener implements Listener {
|
||||
/**
|
||||
* Check if a creature is allowed to spawn or not
|
||||
* @param e - CreatureSpawnEvent
|
||||
* @param bypass - true if the player involved can bypass the checks
|
||||
* @param async - true if check can be done async, false if not
|
||||
* @return true if allowed or asycn, false if not.
|
||||
*/
|
||||
private void checkLimit(Cancellable c, LivingEntity e, SpawnReason reason, boolean bypass, boolean async) {
|
||||
private boolean checkLimit(Cancellable c, LivingEntity e, SpawnReason reason, boolean async) {
|
||||
Location l = e.getLocation();
|
||||
if (async) {
|
||||
c.setCancelled(true);
|
||||
}
|
||||
processIsland(c, e, l, reason, bypass, async);
|
||||
return processIsland(c, e, l, reason, async);
|
||||
}
|
||||
|
||||
private void processIsland(Cancellable c, LivingEntity e, Location l, SpawnReason reason, boolean bypass, boolean async) {
|
||||
addon.getIslands().getIslandAt(e.getLocation()).ifPresent(island -> {
|
||||
// Check if creature is allowed to spawn or not
|
||||
AtLimitResult res = atLimit(island, e);
|
||||
|
||||
if (bypass || island.isSpawn() || !res.hit()) {
|
||||
// Allowed
|
||||
if (async) {
|
||||
Bukkit.getScheduler().runTask(BentoBox.getInstance(), () -> {
|
||||
l.getWorld().spawn(l, e.getClass(), entity -> preSpawn(entity, reason, l));
|
||||
});
|
||||
} // else do nothing
|
||||
private boolean processIsland(Cancellable c, LivingEntity e, Location l, SpawnReason reason, boolean async) {
|
||||
if (addon.getIslands().getIslandAt(e.getLocation()).isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
Island island = addon.getIslands().getIslandAt(e.getLocation()).get();
|
||||
// Check if creature is allowed to spawn or not
|
||||
AtLimitResult res = atLimit(island, e);
|
||||
if (island.isSpawn() || !res.hit()) {
|
||||
// Allowed
|
||||
if (async) {
|
||||
Bukkit.getScheduler().runTask(BentoBox.getInstance(), () -> l.getWorld().spawn(l, e.getClass(), entity -> preSpawn(entity, reason, l)));
|
||||
} // else do nothing
|
||||
} else {
|
||||
if (async) {
|
||||
e.remove();
|
||||
} else {
|
||||
if (async) {
|
||||
e.remove();
|
||||
} else {
|
||||
c.setCancelled(true);
|
||||
}
|
||||
// If the reason is anything but because of a spawner then tell players within range
|
||||
tellPlayers(c, l, e, reason, res);
|
||||
c.setCancelled(true);
|
||||
}
|
||||
|
||||
});
|
||||
// If the reason is anything but because of a spawner then tell players within range
|
||||
tellPlayers(l, e, reason, res);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void preSpawn(Entity entity, SpawnReason reason, Location l) {
|
||||
justSpawned.add(entity.getUniqueId());
|
||||
// Check for entities that need cleanup
|
||||
switch (reason) {
|
||||
case BUILD_IRONGOLEM:
|
||||
detectIronGolem(l);
|
||||
break;
|
||||
case BUILD_SNOWMAN:
|
||||
detectSnowman(l);
|
||||
break;
|
||||
case BUILD_WITHER:
|
||||
case BUILD_IRONGOLEM -> detectIronGolem(l);
|
||||
case BUILD_SNOWMAN -> detectSnowman(l);
|
||||
case BUILD_WITHER -> {
|
||||
detectWither(l);
|
||||
// Create explosion
|
||||
l.getWorld().createExplosion(l, 7F, true, true, entity);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
default -> {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -379,28 +325,37 @@ public class EntityLimitListener implements Listener {
|
||||
return Tag.WITHER_SUMMON_BASE_BLOCKS.isTagged(body.getType());
|
||||
}
|
||||
|
||||
private void tellPlayers(Cancellable e, Location l, LivingEntity entity, SpawnReason reason, AtLimitResult res) {
|
||||
if (!reason.equals(SpawnReason.SPAWNER) && !reason.equals(SpawnReason.NATURAL)
|
||||
&& !reason.equals(SpawnReason.INFECTION) && !reason.equals(SpawnReason.NETHER_PORTAL)
|
||||
&& !reason.equals(SpawnReason.REINFORCEMENTS) && !reason.equals(SpawnReason.SLIME_SPLIT)) {
|
||||
World w = l.getWorld();
|
||||
if (w == null) return;
|
||||
Bukkit.getScheduler().runTask(addon.getPlugin(), () -> {
|
||||
for (Entity ent : w.getNearbyEntities(l, 5, 5, 5)) {
|
||||
if (ent instanceof Player) {
|
||||
if (res.getTypelimit() != null) {
|
||||
User.getInstance(ent).notify("entity-limits.hit-limit", "[entity]",
|
||||
Util.prettifyText(entity.getType().toString()),
|
||||
TextVariables.NUMBER, String.valueOf(res.getTypelimit().getValue()));
|
||||
} else {
|
||||
User.getInstance(ent).notify("entity-limits.hit-limit", "[entity]",
|
||||
res.getGrouplimit().getKey().getName() + " (" + res.getGrouplimit().getKey().getTypes().stream().map(x -> Util.prettifyText(x.toString())).collect(Collectors.joining(", ")) + ")",
|
||||
TextVariables.NUMBER, String.valueOf(res.getGrouplimit().getValue()));
|
||||
}
|
||||
/**
|
||||
* Tell players within a 5 x 5 x 5 radius that the spawning was denied. Informing happens 1 tick after event
|
||||
* @param l location
|
||||
* @param entity entity spawned
|
||||
* @param reason reason - some reasons are not reported
|
||||
* @param res at limit result
|
||||
*/
|
||||
private void tellPlayers(Location l, Entity entity, SpawnReason reason, AtLimitResult res) {
|
||||
if (reason.equals(SpawnReason.SPAWNER) || reason.equals(SpawnReason.NATURAL)
|
||||
|| reason.equals(SpawnReason.INFECTION) || reason.equals(SpawnReason.NETHER_PORTAL)
|
||||
|| reason.equals(SpawnReason.REINFORCEMENTS) || reason.equals(SpawnReason.SLIME_SPLIT)) {
|
||||
return;
|
||||
}
|
||||
World w = l.getWorld();
|
||||
if (w == null) return;
|
||||
Bukkit.getScheduler().runTask(addon.getPlugin(), () -> {
|
||||
for (Entity ent : w.getNearbyEntities(l, 5, 5, 5)) {
|
||||
if (ent instanceof Player p) {
|
||||
p.updateInventory();
|
||||
if (res.getTypelimit() != null) {
|
||||
User.getInstance(p).notify("entity-limits.hit-limit", "[entity]",
|
||||
Util.prettifyText(entity.getType().toString()),
|
||||
TextVariables.NUMBER, String.valueOf(res.getTypelimit().getValue()));
|
||||
} else {
|
||||
User.getInstance(p).notify("entity-limits.hit-limit", "[entity]",
|
||||
res.getGrouplimit().getKey().getName() + " (" + res.getGrouplimit().getKey().getTypes().stream().map(x -> Util.prettifyText(x.toString())).collect(Collectors.joining(", ")) + ")",
|
||||
TextVariables.NUMBER, String.valueOf(res.getGrouplimit().getValue()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@ -433,6 +388,7 @@ public class EntityLimitListener implements Listener {
|
||||
.forEach(group -> groupsLimits.put(group, group.getLimit()));
|
||||
}
|
||||
if (limitAmount < 0 && groupsLimits.isEmpty()) return new AtLimitResult();
|
||||
|
||||
// We have to count the entities
|
||||
if (limitAmount >= 0)
|
||||
{
|
||||
@ -440,18 +396,17 @@ public class EntityLimitListener implements Listener {
|
||||
.filter(e -> e.getType().equals(ent.getType()))
|
||||
.filter(e -> island.inIslandSpace(e.getLocation()))
|
||||
.count();
|
||||
if (count >= limitAmount)
|
||||
if (count >= limitAmount) {
|
||||
return new AtLimitResult(ent.getType(), limitAmount);
|
||||
}
|
||||
}
|
||||
|
||||
// Merge in any permission-based limits
|
||||
if (addon.getBlockLimitListener().getIsland(island.getUniqueId()) != null) {
|
||||
Map<String, EntityGroup> groupbyname = groupsLimits.keySet().stream().collect(Collectors.toMap(e -> e.getName(), e -> e));
|
||||
Map<String, EntityGroup> groupbyname = groupsLimits.keySet().stream().collect(Collectors.toMap(EntityGroup::getName, e -> e));
|
||||
addon.getBlockLimitListener().getIsland(island.getUniqueId()).getEntityGroupLimits().entrySet().stream()
|
||||
.filter(e -> groupbyname.containsKey(e.getKey()))
|
||||
.forEach(e -> groupsLimits.put(groupbyname.get(e.getKey()), e.getValue()));
|
||||
}
|
||||
|
||||
// Now do the group limits
|
||||
for (Map.Entry<Settings.EntityGroup, Integer> group : groupsLimits.entrySet()) { //do not use lambda
|
||||
if (group.getValue() < 0)
|
||||
@ -465,7 +420,7 @@ public class EntityLimitListener implements Listener {
|
||||
return new AtLimitResult();
|
||||
}
|
||||
|
||||
class AtLimitResult {
|
||||
static class AtLimitResult {
|
||||
private Map.Entry<EntityType, Integer> typelimit;
|
||||
private Map.Entry<EntityGroup, Integer> grouplimit;
|
||||
|
||||
|
@ -20,6 +20,7 @@ import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.events.island.IslandEvent;
|
||||
import world.bentobox.bentobox.api.events.island.IslandEvent.Reason;
|
||||
import world.bentobox.bentobox.api.events.team.TeamSetownerEvent;
|
||||
@ -60,7 +61,7 @@ public class JoinListener implements Listener {
|
||||
ibc.getBlockLimits().clear();
|
||||
}
|
||||
for (PermissionAttachmentInfo perms : player.getEffectivePermissions()) {
|
||||
if (!perms.getValue()
|
||||
if (!perms.getValue()
|
||||
|| !perms.getPermission().startsWith(permissionPrefix)
|
||||
|| badSyntaxCheck(perms, player.getName(), permissionPrefix)) {
|
||||
continue;
|
||||
@ -93,7 +94,9 @@ public class JoinListener implements Listener {
|
||||
runNullCheckAndSet(ibc, l);
|
||||
}
|
||||
// Check removed permissions
|
||||
|
||||
if (ibc == null) {
|
||||
BentoBox.getInstance().logDebug("IBC is still null");
|
||||
}
|
||||
// If any changes have been made then store it - don't make files unless they are needed
|
||||
if (ibc != null) addon.getBlockLimitListener().setIsland(islandId, ibc);
|
||||
}
|
||||
@ -145,7 +148,7 @@ public class JoinListener implements Listener {
|
||||
ibc.setEntityLimit(et, Math.max(ibc.getEntityLimit(et), value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void logError(String name, String perm, String error) {
|
||||
|
@ -80,10 +80,9 @@ public class EntityLimitsDO implements DataObject {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof EntityLimitsDO)) {
|
||||
if (!(obj instanceof EntityLimitsDO other)) {
|
||||
return false;
|
||||
}
|
||||
EntityLimitsDO other = (EntityLimitsDO) obj;
|
||||
if (uniqueId == null) {
|
||||
return other.uniqueId == null;
|
||||
} else return uniqueId.equals(other.uniqueId);
|
||||
|
@ -20,16 +20,16 @@ import world.bentobox.bentobox.database.objects.Table;
|
||||
public class IslandBlockCount implements DataObject {
|
||||
|
||||
@Expose
|
||||
private String uniqueId = "";
|
||||
private String uniqueId;
|
||||
|
||||
@Expose
|
||||
private String gameMode = "";
|
||||
private String gameMode;
|
||||
|
||||
@Expose
|
||||
private Map<Material, Integer> blockCounts = new EnumMap<>(Material.class);
|
||||
|
||||
private boolean changed;
|
||||
|
||||
|
||||
/**
|
||||
* Permission based limits
|
||||
*/
|
||||
@ -39,9 +39,12 @@ public class IslandBlockCount implements DataObject {
|
||||
private Map<EntityType, Integer> entityLimits = new EnumMap<>(EntityType.class);
|
||||
@Expose
|
||||
private Map<String, Integer> entityGroupLimits = new HashMap<>();
|
||||
|
||||
// Required for YAML database
|
||||
public IslandBlockCount() {}
|
||||
@Expose
|
||||
private Map<Material, Integer> blockLimitsOffset = new EnumMap<>(Material.class);
|
||||
@Expose
|
||||
private Map<EntityType, Integer> entityLimitsOffset = new EnumMap<>(EntityType.class);
|
||||
@Expose
|
||||
private Map<String, Integer> entityGroupLimitsOffset = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Create an island block count object
|
||||
@ -75,6 +78,9 @@ public class IslandBlockCount implements DataObject {
|
||||
* @return the blockCount
|
||||
*/
|
||||
public Map<Material, Integer> getBlockCounts() {
|
||||
if (blockCounts == null) {
|
||||
blockCounts = new EnumMap<>(Material.class);
|
||||
}
|
||||
return blockCounts;
|
||||
}
|
||||
|
||||
@ -131,7 +137,7 @@ public class IslandBlockCount implements DataObject {
|
||||
*/
|
||||
public boolean isAtLimit(Material m) {
|
||||
// Check island limits first
|
||||
return blockLimits.containsKey(m) && blockCounts.getOrDefault(m, 0) >= blockLimits.get(m);
|
||||
return blockLimits.containsKey(m) && blockCounts.getOrDefault(m, 0) >= getBlockLimit(m);
|
||||
}
|
||||
|
||||
public boolean isBlockLimited(Material m) {
|
||||
@ -159,7 +165,7 @@ public class IslandBlockCount implements DataObject {
|
||||
* @return limit or -1 for unlimited
|
||||
*/
|
||||
public Integer getBlockLimit(Material m) {
|
||||
return blockLimits.getOrDefault(m, -1);
|
||||
return blockLimits.getOrDefault(m, -1) + getBlockLimitsOffset().getOrDefault(m, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -222,7 +228,7 @@ public class IslandBlockCount implements DataObject {
|
||||
* @return limit or -1 for unlimited
|
||||
*/
|
||||
public int getEntityLimit(EntityType t) {
|
||||
return entityLimits.getOrDefault(t, -1);
|
||||
return entityLimits.getOrDefault(t, -1) + getEntityLimitsOffset().getOrDefault(t, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -232,7 +238,7 @@ public class IslandBlockCount implements DataObject {
|
||||
entityLimits.clear();
|
||||
setChanged();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the entityGroupLimits
|
||||
*/
|
||||
@ -247,7 +253,7 @@ public class IslandBlockCount implements DataObject {
|
||||
this.entityGroupLimits = entityGroupLimits;
|
||||
setChanged();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set an island-specific entity group limit
|
||||
* @param name - entity group
|
||||
@ -257,16 +263,16 @@ public class IslandBlockCount implements DataObject {
|
||||
entityGroupLimits.put(name, limit);
|
||||
setChanged();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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);
|
||||
return entityGroupLimits.getOrDefault(name, -1) + getEntityGroupLimitsOffset().getOrDefault(name, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clear all island-specific entity group limits
|
||||
*/
|
||||
@ -288,11 +294,68 @@ public class IslandBlockCount implements DataObject {
|
||||
public void setChanged(boolean changed) {
|
||||
this.changed = changed;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mark changed
|
||||
*/
|
||||
public void setChanged() {
|
||||
this.changed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the blockLimitsOffset
|
||||
*/
|
||||
public Map<Material, Integer> getBlockLimitsOffset() {
|
||||
if (blockLimitsOffset == null) {
|
||||
blockLimitsOffset = new EnumMap<>(Material.class);
|
||||
}
|
||||
return blockLimitsOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an offset to a block limit. This will increase/decrease the value of the limit.
|
||||
* @param m material
|
||||
* @param blockLimitsOffset the blockLimitsOffset to set
|
||||
*/
|
||||
public void setBlockLimitsOffset(Material m, Integer blockLimitsOffset) {
|
||||
getBlockLimitsOffset().put(m, blockLimitsOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entityLimitsOffset
|
||||
*/
|
||||
public Map<EntityType, Integer> getEntityLimitsOffset() {
|
||||
if (entityLimitsOffset == null) {
|
||||
entityLimitsOffset = new EnumMap<>(EntityType.class);
|
||||
}
|
||||
return entityLimitsOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an offset to an entity limit. This will increase/decrease the value of the limit.
|
||||
* @param t Entity Type
|
||||
* @param entityLimitsOffset the entityLimitsOffset to set
|
||||
*/
|
||||
public void setEntityLimitsOffset(EntityType t, Integer entityLimitsOffset) {
|
||||
this.getEntityLimitsOffset().put(t, entityLimitsOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entityGroupLimitsOffset
|
||||
*/
|
||||
public Map<String, Integer> getEntityGroupLimitsOffset() {
|
||||
if (entityGroupLimitsOffset == null) {
|
||||
entityGroupLimitsOffset = new HashMap<>();
|
||||
}
|
||||
return entityGroupLimitsOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an offset to an entity group limit. This will increase/decrease the value of the limit.
|
||||
* @param name group name
|
||||
* @param entityGroupLimitsOffset the entityGroupLimitsOffset to set
|
||||
*/
|
||||
public void setEntityGroupLimitsOffset(String name, Integer entityGroupLimitsOffset) {
|
||||
getEntityGroupLimitsOffset().put(name, entityGroupLimitsOffset);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
name: Limits
|
||||
main: world.bentobox.limits.Limits
|
||||
version: ${version}${build.number}
|
||||
api-version: 1.17
|
||||
api-version: 1.16.5
|
||||
|
||||
authors: tastybento
|
||||
|
||||
|
@ -4,6 +4,10 @@ gamemodes:
|
||||
- BSkyBlock
|
||||
- CaveBlock
|
||||
|
||||
# Ignore this island's center block. For most worlds, this is bedrock, but for AOneBlock it is
|
||||
# the magic block, so ignoring it from limits makes sense.
|
||||
ignore-center-block: true
|
||||
|
||||
# Permissions
|
||||
# Island owners can be given permissions that override all general settings
|
||||
# Format is GAME-MODE-NAME.island.limit.MATERIAL.LIMIT
|
||||
|
@ -1,7 +1,7 @@
|
||||
package bentobox.addon.limits.listeners;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.*;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
@ -11,12 +11,6 @@ import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
@ -86,7 +80,7 @@ public class JoinListenerTest {
|
||||
when(addon.getGameModePermPrefix(any())).thenReturn("bskyblock.");
|
||||
when(addon.getSettings()).thenReturn(settings);
|
||||
// Settings
|
||||
when(settings.getGroupLimitDefinitions()).thenReturn(new ArrayList<>(Arrays.asList(new Settings.EntityGroup("friendly", new HashSet<>(), -1))));
|
||||
when(settings.getGroupLimitDefinitions()).thenReturn(new ArrayList<>(List.of(new Settings.EntityGroup("friendly", new HashSet<>(), -1))));
|
||||
// Island Manager
|
||||
when(im.hasIsland(any(), any(UUID.class))).thenReturn(true);
|
||||
when(island.getUniqueId()).thenReturn("unique_id");
|
||||
|
@ -55,7 +55,7 @@ public class LimitTabTest {
|
||||
private Settings settings;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
public void setUp() {
|
||||
// Island
|
||||
when(island.getWorld()).thenReturn(world);
|
||||
// Addon
|
||||
@ -74,11 +74,11 @@ public class LimitTabTest {
|
||||
when(world.getEntities()).thenReturn(Collections.singletonList(entity));
|
||||
when(nether.getEntities()).thenReturn(Collections.singletonList(entity));
|
||||
when(end.getEntities()).thenReturn(Collections.singletonList(entity));
|
||||
lp = new LimitTab(addon, new IslandBlockCount(), Collections.emptyMap(), island, world, null, LimitTab.SORT_BY.A2Z);
|
||||
lp = new LimitTab(addon, new IslandBlockCount("", ""), Collections.emptyMap(), island, world, null, LimitTab.SORT_BY.A2Z);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -45,7 +45,6 @@ public class EntityLimitListenerTest {
|
||||
private LivingEntity ent;
|
||||
@Mock
|
||||
private BlockLimitsListener bll;
|
||||
private Settings settings;
|
||||
@Mock
|
||||
private World world;
|
||||
private List<Entity> collection;
|
||||
@ -63,7 +62,7 @@ public class EntityLimitListenerTest {
|
||||
when(island.getUniqueId()).thenReturn(UUID.randomUUID().toString());
|
||||
when(island.inIslandSpace(any(Location.class))).thenReturn(true);
|
||||
|
||||
ibc = new IslandBlockCount();
|
||||
ibc = new IslandBlockCount("","");
|
||||
when(bll.getIsland(anyString())).thenReturn(ibc);
|
||||
when(addon.getBlockLimitListener()).thenReturn(bll);
|
||||
|
||||
@ -71,7 +70,7 @@ public class EntityLimitListenerTest {
|
||||
config.load("src/main/resources/config.yml");
|
||||
// Settings
|
||||
when(addon.getConfig()).thenReturn(config);
|
||||
settings = new Settings(addon);
|
||||
Settings settings = new Settings(addon);
|
||||
when(addon.getSettings()).thenReturn(settings);
|
||||
|
||||
// World
|
||||
@ -87,7 +86,7 @@ public class EntityLimitListenerTest {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user