mirror of
https://github.com/BentoBoxWorld/Limits.git
synced 2024-09-27 14:12:57 +02:00
Compare commits
73 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
eb5ceba4c7 | ||
|
902b597b11 | ||
|
50347bb922 | ||
|
f08c45822d | ||
|
6b9262efc7 | ||
|
e2670a49e0 | ||
|
40fdf283b1 | ||
|
6dedd50db5 | ||
|
19373fa9b3 | ||
|
674614eb22 | ||
|
c0d965daa6 | ||
|
2ea2c4526e | ||
|
0db1cfc2b8 | ||
|
397e6d281e | ||
|
89af2ae996 | ||
|
3a42692909 | ||
|
894fc1347c | ||
|
e53f11ea19 | ||
|
f408d9c00b | ||
|
f9ce3ede64 | ||
|
2f01344068 | ||
|
7da342bec5 | ||
|
65c7e6e8d0 | ||
|
ee577e210a | ||
|
9ffe0c740a | ||
|
843aa89f6c | ||
|
39c630b92a | ||
|
4323a1a53a | ||
|
2b9b3dacf8 | ||
|
2d92663cd4 | ||
|
a35816cc80 | ||
|
9763dc1227 | ||
|
f6b3e3b8db | ||
|
5137c24c91 | ||
|
e16d1f1893 | ||
|
6b770d083e | ||
|
eeafa239c4 | ||
|
68f696a46c | ||
|
995ac6191f | ||
|
d87d194c65 | ||
|
8dd35fabcf | ||
|
e17245b86f | ||
|
f0727586a3 | ||
|
69ded8fc3e | ||
|
9e7a52c4d9 | ||
|
3b6e912bae | ||
|
97006d28c1 | ||
|
989ebcba7b | ||
|
a1c75e1192 | ||
|
fdd827a297 | ||
|
bc905adccb | ||
|
ed2af07f07 | ||
|
f726492eae | ||
|
26d357fd42 | ||
|
cf5be3ef30 | ||
|
be3554bf8c | ||
|
782150f0f4 | ||
|
388f973aee | ||
|
5fd461ddea | ||
|
b459f8bdb5 | ||
|
baa73b76a5 | ||
|
d7bff1df7d | ||
|
1a7d2b8f3e | ||
|
e8dffc76f5 | ||
|
fe0e935e14 | ||
|
360ba0b2de | ||
|
d038269f8c | ||
|
78e02b6196 | ||
|
7582aa93d7 | ||
|
886c6c5fa5 | ||
|
8d56a4078a | ||
|
6e9d83c348 | ||
|
f635c07ead |
13
.github/workflows/build.yml
vendored
13
.github/workflows/build.yml
vendored
@ -11,21 +11,22 @@ jobs:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
- name: Set up JDK 16
|
||||
uses: actions/setup-java@v1
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 16
|
||||
distribution: 'adopt'
|
||||
java-version: 17
|
||||
- name: Cache SonarCloud packages
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.sonar/cache
|
||||
key: ${{ runner.os }}-sonar
|
||||
restore-keys: ${{ runner.os }}-sonar
|
||||
- name: Cache Maven packages
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.m2
|
||||
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
|
||||
|
62
pom.xml
62
pom.xml
@ -53,18 +53,18 @@
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>16</java.version>
|
||||
<java.version>17</java.version>
|
||||
<!-- Non-minecraft related dependencies -->
|
||||
<powermock.version>2.0.9</powermock.version>
|
||||
<!-- More visible way how to change dependency versions -->
|
||||
<spigot.version>1.16.5-R0.1-SNAPSHOT</spigot.version>
|
||||
<bentobox.version>1.18.0-SNAPSHOT</bentobox.version>
|
||||
<spigot.version>1.20.5-R0.1-SNAPSHOT</spigot.version>
|
||||
<bentobox.version>2.4.1-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.19.0</build.version>
|
||||
<build.version>1.24.0</build.version>
|
||||
<sonar.projectKey>BentoBoxWorld_Limits</sonar.projectKey>
|
||||
<sonar.organization>bentobox-world</sonar.organization>
|
||||
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
|
||||
@ -196,37 +196,40 @@
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<configuration>
|
||||
<release>${java.version}</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M5</version>
|
||||
<configuration>
|
||||
<argLine>
|
||||
${argLine}
|
||||
--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.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/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/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
|
||||
--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
|
||||
--add-opens java.base/java.lang.ref=ALL-UNNAMED
|
||||
--add-opens java.base/java.util.jar=ALL-UNNAMED
|
||||
--add-opens java.base/java.util.zip=ALL-UNNAMED
|
||||
</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
@ -248,30 +251,45 @@
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.3</version>
|
||||
<version>0.8.10</version>
|
||||
<configuration>
|
||||
<append>true</append>
|
||||
<excludes>
|
||||
<!-- This is required to prevent Jacoco from adding
|
||||
synthetic fields to a JavaBean class (causes errors in testing) -->
|
||||
<exclude>**/*Names*</exclude>
|
||||
<!-- Prevents the Material is too large to mock error -->
|
||||
<exclude>org/bukkit/Material*</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>pre-unit-test</id>
|
||||
<id>prepare-agent</id>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>post-unit-test</id>
|
||||
<id>report</id>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<formats>
|
||||
<format>XML</format>
|
||||
</formats>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<configuration>
|
||||
<release>${java.version}</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
72
src/main/java/world/bentobox/limits/EntityGroup.java
Normal file
72
src/main/java/world/bentobox/limits/EntityGroup.java
Normal file
@ -0,0 +1,72 @@
|
||||
package world.bentobox.limits;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
/**
|
||||
* A named class representing a group of entities and their limits
|
||||
*
|
||||
*/
|
||||
public class EntityGroup {
|
||||
private final String name;
|
||||
private final Set<EntityType> types;
|
||||
private final int limit;
|
||||
private final Material icon;
|
||||
|
||||
public EntityGroup(String name, Set<EntityType> types, int limit, Material icon) {
|
||||
this.name = name;
|
||||
this.types = types;
|
||||
this.limit = limit;
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public boolean contains(EntityType type) {
|
||||
return types.contains(type);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Set<EntityType> getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 83 * hash + Objects.hashCode(this.name);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final EntityGroup other = (EntityGroup) obj;
|
||||
return Objects.equals(this.name, other.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the icon
|
||||
*/
|
||||
public Material getIcon() {
|
||||
return Objects.requireNonNullElse(icon, Material.BARRIER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EntityGroup [name=" + name + ", types=" + types + ", limit=" + limit + ", icon=" + icon + "]";
|
||||
}
|
||||
}
|
@ -1,19 +1,21 @@
|
||||
package world.bentobox.limits;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import world.bentobox.bentobox.api.addons.Addon;
|
||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.limits.commands.AdminCommand;
|
||||
import world.bentobox.limits.commands.PlayerCommand;
|
||||
import world.bentobox.limits.commands.admin.AdminCommand;
|
||||
import world.bentobox.limits.commands.player.PlayerCommand;
|
||||
import world.bentobox.limits.listeners.BlockLimitsListener;
|
||||
import world.bentobox.limits.listeners.EntityLimitListener;
|
||||
import world.bentobox.limits.listeners.JoinListener;
|
||||
@ -29,7 +31,7 @@ public class Limits extends Addon {
|
||||
|
||||
private static final String LIMIT_NOT_SET = "Limit not set";
|
||||
private Settings settings;
|
||||
private List<GameModeAddon> gameModes;
|
||||
private List<GameModeAddon> gameModes = new ArrayList<>();
|
||||
private BlockLimitsListener blockLimitListener;
|
||||
private JoinListener joinListener;
|
||||
|
||||
@ -108,9 +110,9 @@ public class Limits extends Addon {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the game mode for this world
|
||||
* Get the permission prefix for this world
|
||||
* @param world - world
|
||||
* @return game mode name or empty string if none
|
||||
* @return permisdsion prefix or empty string if none
|
||||
*/
|
||||
public String getGameModePermPrefix(World world) {
|
||||
return gameModes.stream().filter(gm -> gm.inWorld(world)).findFirst().map(GameModeAddon::getPermissionPrefix).orElse("");
|
||||
@ -138,6 +140,9 @@ public class Limits extends Addon {
|
||||
Arrays.stream(Material.values())
|
||||
.filter(Material::isBlock)
|
||||
.forEach(m -> registerCountAndLimitPlaceholders(m, gm));
|
||||
|
||||
Arrays.stream(EntityType.values())
|
||||
.forEach(e -> registerCountAndLimitPlaceholders(e, gm));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,6 +154,8 @@ public class Limits extends Addon {
|
||||
* Placeholders:
|
||||
* "Limits_bskyblock_island_hopper_count"
|
||||
* "Limits_bskyblock_island_hopper_limit"
|
||||
* "Limits_bskyblock_island_hopper_base_limit"
|
||||
* "Limits_bskyblock_island_zombie_limit"
|
||||
*
|
||||
* @param m material
|
||||
* @param gm game mode
|
||||
@ -160,6 +167,18 @@ public class Limits extends Addon {
|
||||
getPlugin().getPlaceholdersManager().registerPlaceholder(this,
|
||||
gm.getDescription().getName().toLowerCase() + "_island_" + m.toString().toLowerCase() + "_limit",
|
||||
user -> getLimit(user, m, gm));
|
||||
getPlugin().getPlaceholdersManager().registerPlaceholder(this,
|
||||
gm.getDescription().getName().toLowerCase() + "_island_" + m.toString().toLowerCase() + "_base_limit",
|
||||
user -> getBaseLimit(user, m, gm));
|
||||
}
|
||||
|
||||
private void registerCountAndLimitPlaceholders(EntityType e, GameModeAddon gm) {
|
||||
getPlugin().getPlaceholdersManager().registerPlaceholder(this,
|
||||
gm.getDescription().getName().toLowerCase() + "_island_" + e.toString().toLowerCase() + "_limit",
|
||||
user -> getLimit(user, e, gm));
|
||||
getPlugin().getPlaceholdersManager().registerPlaceholder(this,
|
||||
gm.getDescription().getName().toLowerCase() + "_island_" + e.toString().toLowerCase() + "_base_limit",
|
||||
user -> getBaseLimit(user, e, gm));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -191,11 +210,56 @@ public class Limits extends Addon {
|
||||
if (is == null) {
|
||||
return LIMIT_NOT_SET;
|
||||
}
|
||||
@Nullable IslandBlockCount ibc = getBlockLimitListener().getIsland(is.getUniqueId());
|
||||
if (ibc == null) {
|
||||
if (user != null) {
|
||||
// Check the permissions of the user and update
|
||||
this.getJoinListener().checkPerms(user.getPlayer(), gm.getPermissionPrefix() + "island.limit.",
|
||||
is.getUniqueId(), gm.getDescription().getName());
|
||||
}
|
||||
int limit = this.getBlockLimitListener().
|
||||
getMaterialLimits(is.getWorld(), is.getUniqueId()).getOrDefault(m, -1);
|
||||
|
||||
return limit == -1 ? LIMIT_NOT_SET : String.valueOf(limit);
|
||||
}
|
||||
|
||||
private String getBaseLimit(@Nullable User user, Material m, GameModeAddon gm) {
|
||||
Island is = gm.getIslands().getIsland(gm.getOverWorld(), user);
|
||||
if (is == null) {
|
||||
return LIMIT_NOT_SET;
|
||||
}
|
||||
int limit = ibc.getBlockLimit(m);
|
||||
|
||||
int limit = this.getBlockLimitListener().
|
||||
getMaterialLimits(is.getWorld(), is.getUniqueId()).
|
||||
getOrDefault(m, -1);
|
||||
|
||||
if (limit > 0) {
|
||||
limit -= this.getBlockLimitListener().getIsland(is).getBlockLimitOffset(m);
|
||||
}
|
||||
|
||||
return limit == -1 ? LIMIT_NOT_SET : String.valueOf(limit);
|
||||
}
|
||||
|
||||
private String getLimit(@Nullable User user, EntityType e, GameModeAddon gm) {
|
||||
Island is = gm.getIslands().getIsland(gm.getOverWorld(), user);
|
||||
if (is == null) {
|
||||
return LIMIT_NOT_SET;
|
||||
}
|
||||
|
||||
int limit = this.getBlockLimitListener().getIsland(is).getEntityLimit(e);
|
||||
if (limit < 0 && this.getSettings().getLimits().containsKey(e)) {
|
||||
limit = this.getSettings().getLimits().get(e);
|
||||
}
|
||||
|
||||
return limit == -1 ? LIMIT_NOT_SET : String.valueOf(limit);
|
||||
}
|
||||
|
||||
private String getBaseLimit(@Nullable User user, EntityType e, GameModeAddon gm) {
|
||||
Island is = gm.getIslands().getIsland(gm.getOverWorld(), user);
|
||||
if (is == null || !this.getSettings().getLimits().containsKey(e)) {
|
||||
return LIMIT_NOT_SET;
|
||||
}
|
||||
|
||||
int limit = this.getSettings().getLimits().get(e);
|
||||
|
||||
return limit == -1 ? LIMIT_NOT_SET : String.valueOf(limit);
|
||||
}
|
||||
|
||||
|
19
src/main/java/world/bentobox/limits/LimitsPladdon.java
Normal file
19
src/main/java/world/bentobox/limits/LimitsPladdon.java
Normal file
@ -0,0 +1,19 @@
|
||||
package world.bentobox.limits;
|
||||
|
||||
|
||||
import world.bentobox.bentobox.api.addons.Addon;
|
||||
import world.bentobox.bentobox.api.addons.Pladdon;
|
||||
|
||||
|
||||
public class LimitsPladdon extends Pladdon {
|
||||
|
||||
private Addon addon;
|
||||
|
||||
@Override
|
||||
public Addon getAddon() {
|
||||
if (addon == null) {
|
||||
addon = new Limits();
|
||||
}
|
||||
return addon;
|
||||
}
|
||||
}
|
@ -1,8 +1,19 @@
|
||||
package world.bentobox.limits;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
@ -13,15 +24,15 @@ public class Settings {
|
||||
private final List<String> gameModes;
|
||||
private final boolean asyncGolums;
|
||||
private static final List<EntityType> DISALLOWED = Arrays.asList(
|
||||
EntityType.PRIMED_TNT,
|
||||
EntityType.TNT,
|
||||
EntityType.EVOKER_FANGS,
|
||||
EntityType.LLAMA_SPIT,
|
||||
EntityType.DRAGON_FIREBALL,
|
||||
EntityType.AREA_EFFECT_CLOUD,
|
||||
EntityType.ENDER_SIGNAL,
|
||||
EntityType.END_CRYSTAL,
|
||||
EntityType.SMALL_FIREBALL,
|
||||
EntityType.FIREBALL,
|
||||
EntityType.THROWN_EXP_BOTTLE,
|
||||
EntityType.EXPERIENCE_BOTTLE,
|
||||
EntityType.EXPERIENCE_ORB,
|
||||
EntityType.SHULKER_BULLET,
|
||||
EntityType.WITHER_SKULL,
|
||||
@ -30,9 +41,8 @@ public class Settings {
|
||||
EntityType.SPECTRAL_ARROW,
|
||||
EntityType.SNOWBALL,
|
||||
EntityType.EGG,
|
||||
EntityType.LEASH_HITCH,
|
||||
EntityType.LEASH_KNOT,
|
||||
EntityType.GIANT,
|
||||
EntityType.ENDER_CRYSTAL,
|
||||
EntityType.ENDER_PEARL,
|
||||
EntityType.ENDER_DRAGON,
|
||||
EntityType.ITEM_FRAME,
|
||||
@ -69,6 +79,14 @@ public class Settings {
|
||||
if (el != null) {
|
||||
for (String name : el.getKeys(false)) {
|
||||
int limit = el.getInt(name + ".limit");
|
||||
String iconName = el.getString(name + ".icon", "BARRIER");
|
||||
Material icon = Material.BARRIER;
|
||||
try {
|
||||
icon = Material.valueOf(iconName.toUpperCase(Locale.ENGLISH));
|
||||
} catch (Exception e) {
|
||||
addon.logError("Invalid group icon name: " + iconName + ". Use a Bukkit Material.");
|
||||
icon = Material.BARRIER;
|
||||
}
|
||||
Set<EntityType> entities = el.getStringList(name + ".entities").stream().map(s -> {
|
||||
EntityType type = getType(s);
|
||||
if (type != null) {
|
||||
@ -84,7 +102,7 @@ public class Settings {
|
||||
}).filter(Objects::nonNull).collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
if (entities.isEmpty())
|
||||
continue;
|
||||
EntityGroup group = new EntityGroup(name, entities, limit);
|
||||
EntityGroup group = new EntityGroup(name, entities, limit, icon);
|
||||
entities.forEach(e -> {
|
||||
List<EntityGroup> groups = groupLimits.getOrDefault(e, new ArrayList<>());
|
||||
groups.add(group);
|
||||
@ -129,65 +147,6 @@ public class Settings {
|
||||
return gameModes;
|
||||
}
|
||||
|
||||
/**
|
||||
* A named class representing a group of entities and their limits
|
||||
*
|
||||
*/
|
||||
public static class EntityGroup {
|
||||
private final String name;
|
||||
private final Set<EntityType> types;
|
||||
private final int limit;
|
||||
|
||||
public EntityGroup(String name, Set<EntityType> 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<EntityType> getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int hash = 7;
|
||||
hash = 83 * hash + Objects.hashCode(this.name);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final EntityGroup other = (EntityGroup) obj;
|
||||
return Objects.equals(this.name, other.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "EntityGroup{" + "name=" + name + ", types=" + types + ", limit=" + limit + '}';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the asyncGolums
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
package world.bentobox.limits.commands;
|
||||
package world.bentobox.limits.commands.admin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -10,6 +10,8 @@ import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
import world.bentobox.limits.Limits;
|
||||
import world.bentobox.limits.commands.player.LimitPanel;
|
||||
|
||||
|
||||
/**
|
||||
* Admin command for limits
|
||||
@ -27,7 +29,9 @@ public class AdminCommand extends CompositeCommand {
|
||||
public AdminCommand(Limits addon, CompositeCommand parent) {
|
||||
super(parent, "limits");
|
||||
this.addon = addon;
|
||||
new CalcCommand(addon, this);
|
||||
|
||||
new CalcCommand(this.addon, this);
|
||||
new OffsetCommand(this.addon, this);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
@ -1,4 +1,4 @@
|
||||
package world.bentobox.limits.commands;
|
||||
package world.bentobox.limits.commands.admin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
@ -0,0 +1,695 @@
|
||||
//
|
||||
// Created by BONNe
|
||||
// Copyright - 2022
|
||||
//
|
||||
|
||||
|
||||
package world.bentobox.limits.commands.admin;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Enums;
|
||||
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
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.objects.IslandBlockCount;
|
||||
|
||||
|
||||
/**
|
||||
* This command manages offsets to the player island limits.
|
||||
*/
|
||||
public class OffsetCommand extends CompositeCommand
|
||||
{
|
||||
/**
|
||||
* Instantiates a new Offset command.
|
||||
*
|
||||
* @param addon the addon
|
||||
* @param parent the parent
|
||||
*/
|
||||
public OffsetCommand(Limits addon, CompositeCommand parent)
|
||||
{
|
||||
super(parent, "offset");
|
||||
|
||||
new OffsetSetCommand(addon, this);
|
||||
new OffsetAddCommand(addon, this);
|
||||
new OffsetRemoveCommand(addon, this);
|
||||
new OffsetResetCommand(addon, this);
|
||||
new OffsetDisplayCommand(addon, this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setup()
|
||||
{
|
||||
this.setOnlyPlayer(false);
|
||||
|
||||
this.setPermission("admin.limits.offset");
|
||||
this.setParametersHelp("admin.limits.offset.parameters");
|
||||
this.setDescription("admin.limits.offset.description");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String s, List<String> list)
|
||||
{
|
||||
this.showHelp(this, user);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This command allows setting limit offset for material or entity.
|
||||
*/
|
||||
private static class OffsetSetCommand extends CompositeCommand
|
||||
{
|
||||
/**
|
||||
* Instantiates a new Offset set command.
|
||||
*
|
||||
* @param addon the addon
|
||||
* @param parent the parent
|
||||
*/
|
||||
public OffsetSetCommand(Limits addon, CompositeCommand parent)
|
||||
{
|
||||
super(parent, "set");
|
||||
this.addon = addon;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setup()
|
||||
{
|
||||
this.setOnlyPlayer(false);
|
||||
|
||||
this.setPermission("admin.limits.offset.set");
|
||||
this.setParametersHelp("admin.limits.offset.set.parameters");
|
||||
this.setDescription("admin.limits.offset.set.description");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args)
|
||||
{
|
||||
if (args.size() != 3)
|
||||
{
|
||||
// Show help
|
||||
this.showHelp(this, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get target player
|
||||
UUID targetUUID = Util.getUUID(args.get(0));
|
||||
|
||||
if (targetUUID == null)
|
||||
{
|
||||
user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
|
||||
return false;
|
||||
}
|
||||
|
||||
Island island = this.getIslands().getIsland(this.getWorld(), targetUUID);
|
||||
|
||||
if (island == null)
|
||||
{
|
||||
user.sendMessage("general.errors.player-has-no-island");
|
||||
return false;
|
||||
}
|
||||
|
||||
IslandBlockCount islandData = this.addon.getBlockLimitListener().getIsland(island);
|
||||
|
||||
// Get new offset
|
||||
if (!Util.isInteger(args.get(2), true))
|
||||
{
|
||||
user.sendMessage("general.errors.must-be-a-number", TextVariables.NUMBER, args.get(2));
|
||||
return false;
|
||||
}
|
||||
|
||||
Material material = Material.matchMaterial(args.get(1));
|
||||
EntityType entityType = matchEntity(args.get(1));
|
||||
|
||||
if (material == null && entityType == null)
|
||||
{
|
||||
user.sendMessage("admin.limits.offset.unknown", TextVariables.NAME, args.get(1));
|
||||
return false;
|
||||
}
|
||||
|
||||
int offset = Integer.parseInt(args.get(2));
|
||||
|
||||
if (material != null && offset == islandData.getBlockLimitOffset(material) ||
|
||||
entityType != null && offset == islandData.getEntityLimitOffset(entityType))
|
||||
{
|
||||
user.sendMessage("admin.limits.offset.set.same",
|
||||
TextVariables.NAME,
|
||||
args.get(1),
|
||||
TextVariables.NUMBER,
|
||||
args.get(2));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (material != null)
|
||||
{
|
||||
islandData.setBlockLimitsOffset(material, offset);
|
||||
islandData.setChanged();
|
||||
|
||||
user.sendMessage("admin.limits.offset.set.success",
|
||||
TextVariables.NUMBER, String.valueOf(offset),
|
||||
TextVariables.NAME, material.name());
|
||||
}
|
||||
else
|
||||
{
|
||||
islandData.setEntityLimitsOffset(entityType, offset);
|
||||
islandData.setChanged();
|
||||
|
||||
user.sendMessage("admin.limits.offset.set.success",
|
||||
TextVariables.NUMBER, String.valueOf(offset),
|
||||
TextVariables.NAME, entityType.name());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Optional<List<String>> tabComplete(User user, String alias, List<String> args)
|
||||
{
|
||||
return OffsetCommand.craftTabComplete(user, alias, args);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Instance of limits addon.
|
||||
*/
|
||||
private final Limits addon;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This command allows increasing limit offset for material or entity.
|
||||
*/
|
||||
private static class OffsetAddCommand extends CompositeCommand
|
||||
{
|
||||
/**
|
||||
* Instantiates a new Offset add command.
|
||||
*
|
||||
* @param addon the addon
|
||||
* @param parent the parent
|
||||
*/
|
||||
public OffsetAddCommand(Limits addon, CompositeCommand parent)
|
||||
{
|
||||
super(parent, "add");
|
||||
this.addon = addon;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setup()
|
||||
{
|
||||
this.setOnlyPlayer(false);
|
||||
|
||||
this.setPermission("admin.limits.offset.add");
|
||||
this.setParametersHelp("admin.limits.offset.add.parameters");
|
||||
this.setDescription("admin.limits.offset.add.description");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args)
|
||||
{
|
||||
if (args.size() != 3)
|
||||
{
|
||||
// Show help
|
||||
this.showHelp(this, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get target player
|
||||
UUID targetUUID = Util.getUUID(args.get(0));
|
||||
|
||||
if (targetUUID == null)
|
||||
{
|
||||
user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
|
||||
return false;
|
||||
}
|
||||
|
||||
Island island = this.getIslands().getIsland(this.getWorld(), targetUUID);
|
||||
|
||||
if (island == null)
|
||||
{
|
||||
user.sendMessage("general.errors.player-has-no-island");
|
||||
return false;
|
||||
}
|
||||
|
||||
IslandBlockCount islandData = this.addon.getBlockLimitListener().getIsland(island);
|
||||
|
||||
// Get new offset
|
||||
if (!Util.isInteger(args.get(2), true) || Integer.parseInt(args.get(2)) < 0)
|
||||
{
|
||||
user.sendMessage("general.errors.must-be-positive-number", TextVariables.NUMBER, args.get(2));
|
||||
return false;
|
||||
}
|
||||
|
||||
Material material = Material.matchMaterial(args.get(1));
|
||||
EntityType entityType = matchEntity(args.get(1));
|
||||
|
||||
if (material == null && entityType == null)
|
||||
{
|
||||
user.sendMessage("admin.limits.offset.unknown", TextVariables.NAME, args.get(1));
|
||||
return false;
|
||||
}
|
||||
|
||||
int offset = Integer.parseInt(args.get(2));
|
||||
|
||||
if (material != null)
|
||||
{
|
||||
offset += islandData.getBlockLimitOffset(material);
|
||||
|
||||
islandData.setBlockLimitsOffset(material, offset);
|
||||
islandData.setChanged();
|
||||
|
||||
user.sendMessage("admin.limits.offset.add.success",
|
||||
TextVariables.NUMBER, String.valueOf(offset),
|
||||
TextVariables.NAME, material.name());
|
||||
}
|
||||
else
|
||||
{
|
||||
offset += islandData.getEntityLimitOffset(entityType);
|
||||
|
||||
islandData.setEntityLimitsOffset(entityType, offset);
|
||||
islandData.setChanged();
|
||||
|
||||
user.sendMessage("admin.limits.offset.add.success",
|
||||
TextVariables.NUMBER, String.valueOf(offset),
|
||||
TextVariables.NAME, entityType.name());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Optional<List<String>> tabComplete(User user, String alias, List<String> args)
|
||||
{
|
||||
return OffsetCommand.craftTabComplete(user, alias, args);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Instance of limits addon.
|
||||
*/
|
||||
private final Limits addon;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This command allows reducing limit offset for material or entity.
|
||||
*/
|
||||
private static class OffsetRemoveCommand extends CompositeCommand
|
||||
{
|
||||
/**
|
||||
* Instantiates a new Offset remove command.
|
||||
*
|
||||
* @param addon the addon
|
||||
* @param parent the parent
|
||||
*/
|
||||
public OffsetRemoveCommand(Limits addon, CompositeCommand parent)
|
||||
{
|
||||
super(parent, "remove");
|
||||
this.addon = addon;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setup()
|
||||
{
|
||||
this.setOnlyPlayer(false);
|
||||
|
||||
this.setPermission("admin.limits.offset.remove");
|
||||
this.setParametersHelp("admin.limits.offset.remove.parameters");
|
||||
this.setDescription("admin.limits.offset.remove.description");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args)
|
||||
{
|
||||
if (args.size() != 3)
|
||||
{
|
||||
// Show help
|
||||
this.showHelp(this, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get target player
|
||||
UUID targetUUID = Util.getUUID(args.get(0));
|
||||
|
||||
if (targetUUID == null)
|
||||
{
|
||||
user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
|
||||
return false;
|
||||
}
|
||||
|
||||
Island island = this.getIslands().getIsland(this.getWorld(), targetUUID);
|
||||
|
||||
if (island == null)
|
||||
{
|
||||
user.sendMessage("general.errors.player-has-no-island");
|
||||
return false;
|
||||
}
|
||||
|
||||
IslandBlockCount islandData = this.addon.getBlockLimitListener().getIsland(island);
|
||||
|
||||
// Get new offset
|
||||
if (!Util.isInteger(args.get(2), true) || Integer.parseInt(args.get(2)) < 0)
|
||||
{
|
||||
user.sendMessage("general.errors.must-be-positive-number", TextVariables.NUMBER, args.get(2));
|
||||
return false;
|
||||
}
|
||||
|
||||
Material material = Material.matchMaterial(args.get(1));
|
||||
EntityType entityType = matchEntity(args.get(1));
|
||||
|
||||
if (material == null && entityType == null)
|
||||
{
|
||||
user.sendMessage("admin.limits.offset.unknown", TextVariables.NAME, args.get(1));
|
||||
return false;
|
||||
}
|
||||
|
||||
int offset = Integer.parseInt(args.get(2));
|
||||
|
||||
if (material != null)
|
||||
{
|
||||
offset = islandData.getBlockLimitOffset(material) - offset;
|
||||
|
||||
islandData.setBlockLimitsOffset(material, offset);
|
||||
islandData.setChanged();
|
||||
|
||||
user.sendMessage("admin.limits.offset.remove.success",
|
||||
TextVariables.NUMBER, String.valueOf(offset),
|
||||
TextVariables.NAME, material.name());
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = islandData.getEntityLimitOffset(entityType) - offset;
|
||||
|
||||
islandData.setEntityLimitsOffset(entityType, offset);
|
||||
islandData.setChanged();
|
||||
|
||||
user.sendMessage("admin.limits.offset.remove.success",
|
||||
TextVariables.NUMBER, String.valueOf(offset),
|
||||
TextVariables.NAME, entityType.name());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Optional<List<String>> tabComplete(User user, String alias, List<String> args)
|
||||
{
|
||||
return OffsetCommand.craftTabComplete(user, alias, args);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Instance of limits addon.
|
||||
*/
|
||||
private final Limits addon;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This command allows resetting limit offset for material or entity.
|
||||
*/
|
||||
private static class OffsetResetCommand extends CompositeCommand
|
||||
{
|
||||
/**
|
||||
* Instantiates a new Offset reset command.
|
||||
*
|
||||
* @param addon the addon
|
||||
* @param parent the parent
|
||||
*/
|
||||
public OffsetResetCommand(Limits addon, CompositeCommand parent)
|
||||
{
|
||||
super(parent, "reset");
|
||||
this.addon = addon;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setup()
|
||||
{
|
||||
this.setOnlyPlayer(false);
|
||||
|
||||
this.setPermission("admin.limits.offset.reset");
|
||||
this.setParametersHelp("admin.limits.offset.reset.parameters");
|
||||
this.setDescription("admin.limits.offset.reset.description");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args)
|
||||
{
|
||||
if (args.size() != 2)
|
||||
{
|
||||
// Show help
|
||||
this.showHelp(this, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get target player
|
||||
UUID targetUUID = Util.getUUID(args.get(0));
|
||||
|
||||
if (targetUUID == null)
|
||||
{
|
||||
user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
|
||||
return false;
|
||||
}
|
||||
|
||||
Island island = this.getIslands().getIsland(this.getWorld(), targetUUID);
|
||||
|
||||
if (island == null)
|
||||
{
|
||||
user.sendMessage("general.errors.player-has-no-island");
|
||||
return false;
|
||||
}
|
||||
|
||||
IslandBlockCount islandData = this.addon.getBlockLimitListener().getIsland(island);
|
||||
|
||||
Material material = Material.matchMaterial(args.get(1));
|
||||
EntityType entityType = matchEntity(args.get(1));
|
||||
|
||||
if (material == null && entityType == null)
|
||||
{
|
||||
user.sendMessage("admin.limits.offset.unknown", TextVariables.NAME, args.get(1));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (material != null)
|
||||
{
|
||||
islandData.setBlockLimitsOffset(material, 0);
|
||||
islandData.setChanged();
|
||||
|
||||
user.sendMessage("admin.limits.offset.reset.success",
|
||||
TextVariables.NAME, material.name());
|
||||
}
|
||||
else
|
||||
{
|
||||
islandData.setEntityLimitsOffset(entityType, 0);
|
||||
islandData.setChanged();
|
||||
|
||||
user.sendMessage("admin.limits.offset.reset.success",
|
||||
TextVariables.NAME, entityType.name());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Optional<List<String>> tabComplete(User user, String alias, List<String> args)
|
||||
{
|
||||
return OffsetCommand.craftTabComplete(user, alias, args);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Instance of limits addon.
|
||||
*/
|
||||
private final Limits addon;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This command allows viewing limit offset for material or entity.
|
||||
*/
|
||||
private static class OffsetDisplayCommand extends CompositeCommand
|
||||
{
|
||||
/**
|
||||
* Instantiates a new Offset display command.
|
||||
*
|
||||
* @param addon the addon
|
||||
* @param parent the parent
|
||||
*/
|
||||
public OffsetDisplayCommand(Limits addon, CompositeCommand parent)
|
||||
{
|
||||
super(parent, "view", "display");
|
||||
this.addon = addon;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setup()
|
||||
{
|
||||
this.setOnlyPlayer(false);
|
||||
|
||||
this.setPermission("admin.limits.offset.view");
|
||||
this.setParametersHelp("admin.limits.offset.view.parameters");
|
||||
this.setDescription("admin.limits.offset.view.description");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean execute(User user, String label, List<String> args)
|
||||
{
|
||||
if (args.size() != 2)
|
||||
{
|
||||
// Show help
|
||||
this.showHelp(this, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get target player
|
||||
UUID targetUUID = Util.getUUID(args.get(0));
|
||||
|
||||
if (targetUUID == null)
|
||||
{
|
||||
user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
|
||||
return false;
|
||||
}
|
||||
|
||||
Island island = this.getIslands().getIsland(this.getWorld(), targetUUID);
|
||||
|
||||
if (island == null)
|
||||
{
|
||||
user.sendMessage("general.errors.player-has-no-island");
|
||||
return false;
|
||||
}
|
||||
|
||||
IslandBlockCount islandData = this.addon.getBlockLimitListener().getIsland(island);
|
||||
|
||||
Material material = Material.matchMaterial(args.get(1));
|
||||
EntityType entityType = matchEntity(args.get(1));
|
||||
|
||||
if (material == null && entityType == null)
|
||||
{
|
||||
user.sendMessage("admin.limits.offset.unknown", TextVariables.NAME, args.get(1));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (material != null)
|
||||
{
|
||||
int offset = islandData.getBlockLimitOffset(material);
|
||||
user.sendMessage("admin.limits.offset.view.message",
|
||||
TextVariables.NAME, material.name(),
|
||||
TextVariables.NUMBER, String.valueOf(offset));
|
||||
}
|
||||
else
|
||||
{
|
||||
int offset = islandData.getEntityLimitOffset(entityType);
|
||||
user.sendMessage("admin.limits.offset.view.message",
|
||||
TextVariables.NAME, entityType.name(),
|
||||
TextVariables.NUMBER, String.valueOf(offset));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Optional<List<String>> tabComplete(User user, String alias, List<String> args)
|
||||
{
|
||||
return OffsetCommand.craftTabComplete(user, alias, args);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Instance of limits addon.
|
||||
*/
|
||||
private final Limits addon;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This material matches name to an entity type.
|
||||
* @param name Name that must be matched.
|
||||
* @return EntityType or null.
|
||||
*/
|
||||
@Nullable
|
||||
private static EntityType matchEntity(String name)
|
||||
{
|
||||
String filtered = name;
|
||||
|
||||
if (filtered.startsWith(NamespacedKey.MINECRAFT + ":"))
|
||||
{
|
||||
filtered = filtered.substring((NamespacedKey.MINECRAFT + ":").length());
|
||||
}
|
||||
|
||||
filtered = filtered.toUpperCase(java.util.Locale.ENGLISH);
|
||||
filtered = filtered.replaceAll("\\s+", "_").replaceAll("\\W", "");
|
||||
|
||||
return Enums.getIfPresent(EntityType.class, filtered).orNull();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method crafts tab complete for all subcommands
|
||||
* @param user User who runs command.
|
||||
* @param alias Command alias.
|
||||
* @param args List of args.
|
||||
* @return Optional list of strings.
|
||||
*/
|
||||
private static Optional<List<String>> craftTabComplete(User user, String alias, List<String> args)
|
||||
{
|
||||
String lastArg = !args.isEmpty() ? args.get(args.size() - 1) : "";
|
||||
|
||||
if (args.isEmpty())
|
||||
{
|
||||
// Don't show every player on the server. Require at least the first letter
|
||||
return Optional.empty();
|
||||
}
|
||||
else if (args.size() == 4)
|
||||
{
|
||||
List<String> options = new ArrayList<>(Util.getOnlinePlayerList(user));
|
||||
return Optional.of(Util.tabLimit(options, lastArg));
|
||||
}
|
||||
else if (args.size() == 5)
|
||||
{
|
||||
List<String> options = Arrays.stream(Material.values()).
|
||||
map(Enum::name).
|
||||
collect(Collectors.toList());
|
||||
|
||||
options.addAll(Arrays.stream(EntityType.values()).
|
||||
map(Enum::name).
|
||||
collect(Collectors.toList()));
|
||||
|
||||
return Optional.of(Util.tabLimit(options, lastArg));
|
||||
}
|
||||
else
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package world.bentobox.limits.commands;
|
||||
package world.bentobox.limits.commands.player;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
@ -1,7 +1,13 @@
|
||||
package world.bentobox.limits.commands;
|
||||
package world.bentobox.limits.commands.player;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Material;
|
||||
@ -18,8 +24,8 @@ import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
import world.bentobox.limits.EntityGroup;
|
||||
import world.bentobox.limits.Limits;
|
||||
import world.bentobox.limits.Settings.EntityGroup;
|
||||
import world.bentobox.limits.objects.IslandBlockCount;
|
||||
|
||||
/**
|
||||
@ -32,11 +38,13 @@ public class LimitTab implements Tab {
|
||||
A2Z,
|
||||
Z2A
|
||||
}
|
||||
// This maps the entity types to the icon that should be shown in the panel
|
||||
// If the icon is null, then the entity type is not covered by the addon
|
||||
|
||||
/**
|
||||
* This maps the entity types to the icon that should be shown in the panel
|
||||
* If the icon is null, then the entity type is not covered by the addon
|
||||
*/
|
||||
private static final Map<EntityType, Material> E2M = ImmutableMap.<EntityType, Material>builder()
|
||||
.put(EntityType.MUSHROOM_COW, Material.MOOSHROOM_SPAWN_EGG)
|
||||
.put(EntityType.SNOWMAN, Material.SNOW_BLOCK)
|
||||
.put(EntityType.MOOSHROOM, Material.MOOSHROOM_SPAWN_EGG).put(EntityType.SNOW_GOLEM, Material.SNOW_BLOCK)
|
||||
.put(EntityType.IRON_GOLEM, Material.IRON_BLOCK)
|
||||
.put(EntityType.ILLUSIONER, Material.VILLAGER_SPAWN_EGG)
|
||||
.put(EntityType.WITHER, Material.WITHER_SKELETON_SKULL)
|
||||
@ -45,21 +53,22 @@ public class LimitTab implements Tab {
|
||||
.put(EntityType.ITEM_FRAME, Material.ITEM_FRAME)
|
||||
.put(EntityType.PAINTING, Material.PAINTING)
|
||||
// Minecarts
|
||||
.put(EntityType.MINECART_TNT, Material.TNT_MINECART)
|
||||
.put(EntityType.MINECART_CHEST, Material.CHEST_MINECART)
|
||||
.put(EntityType.MINECART_COMMAND, Material.COMMAND_BLOCK_MINECART)
|
||||
.put(EntityType.MINECART_FURNACE, Material.FURNACE_MINECART)
|
||||
.put(EntityType.MINECART_HOPPER, Material.HOPPER_MINECART)
|
||||
.put(EntityType.MINECART_MOB_SPAWNER, Material.MINECART)
|
||||
.put(EntityType.TNT_MINECART, Material.TNT_MINECART).put(EntityType.CHEST_MINECART, Material.CHEST_MINECART)
|
||||
.put(EntityType.COMMAND_BLOCK_MINECART, Material.COMMAND_BLOCK_MINECART)
|
||||
.put(EntityType.FURNACE_MINECART, Material.FURNACE_MINECART)
|
||||
.put(EntityType.HOPPER_MINECART, Material.HOPPER_MINECART)
|
||||
.put(EntityType.SPAWNER_MINECART, Material.MINECART)
|
||||
.put(EntityType.CHEST_BOAT, Material.OAK_CHEST_BOAT)
|
||||
.build();
|
||||
// This is a map of blocks to Material
|
||||
// This is a map of blocks to Items
|
||||
private static final Map<Material, Material> B2M;
|
||||
static {
|
||||
ImmutableMap.Builder<Material, Material> builder = ImmutableMap.<Material, Material>builder()
|
||||
.put(Material.POTATOES, Material.POTATO)
|
||||
.put(Material.CARROTS, Material.CARROT)
|
||||
.put(Material.BEETROOTS, Material.BEETROOT)
|
||||
.put(Material.REDSTONE_WIRE, Material.REDSTONE);
|
||||
.put(Material.REDSTONE_WIRE, Material.REDSTONE).put(Material.MELON_STEM, Material.MELON)
|
||||
.put(Material.PUMPKIN_STEM, Material.PUMPKIN);
|
||||
// Block to Material icons
|
||||
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"))));
|
||||
@ -103,28 +112,17 @@ public class LimitTab implements Tab {
|
||||
.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)));
|
||||
ibc.getEntityGroupLimitsOffset().forEach((key, value) -> {
|
||||
if (groupByName.get(key) != null) {
|
||||
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());
|
||||
String description = "";
|
||||
description += "(" + prettyNames(v) + ")\n";
|
||||
Material m;
|
||||
try {
|
||||
if (E2M.containsKey(k)) {
|
||||
m = E2M.get(k);
|
||||
} else if (k.isAlive()) {
|
||||
m = Material.valueOf(k + "_SPAWN_EGG");
|
||||
} else {
|
||||
// Regular material
|
||||
m = Material.valueOf(k.toString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
m = Material.BARRIER;
|
||||
}
|
||||
pib.icon(m);
|
||||
pib.icon(v.getIcon());
|
||||
long count = getCount(island, v);
|
||||
String color = count >= limit ? user.getTranslation("island.limits.max-color") : user.getTranslation("island.limits.regular-color");
|
||||
description += color
|
||||
@ -182,7 +180,7 @@ public class LimitTab implements Tab {
|
||||
pib.icon(B2M.getOrDefault(en.getKey(), en.getKey()));
|
||||
|
||||
int count = ibc == null ? 0 : ibc.getBlockCounts().getOrDefault(en.getKey(), 0);
|
||||
int value = en.getValue() + (ibc == null ? 0 : ibc.getBlockLimitsOffset().getOrDefault(en.getKey(), 0));
|
||||
int value = en.getValue();
|
||||
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",
|
@ -1,4 +1,4 @@
|
||||
package world.bentobox.limits.commands;
|
||||
package world.bentobox.limits.commands.player;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package world.bentobox.limits.commands;
|
||||
package world.bentobox.limits.commands.player;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -6,7 +6,7 @@ import org.bukkit.entity.Player;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import world.bentobox.limits.Settings.EntityGroup;
|
||||
import world.bentobox.limits.EntityGroup;
|
||||
import world.bentobox.limits.objects.IslandBlockCount;
|
||||
|
||||
/**
|
||||
|
@ -30,6 +30,7 @@ import org.bukkit.event.block.BlockExplodeEvent;
|
||||
import org.bukkit.event.block.BlockFadeEvent;
|
||||
import org.bukkit.event.block.BlockFormEvent;
|
||||
import org.bukkit.event.block.BlockFromToEvent;
|
||||
import org.bukkit.event.block.BlockGrowEvent;
|
||||
import org.bukkit.event.block.BlockMultiPlaceEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.block.BlockSpreadEvent;
|
||||
@ -38,12 +39,14 @@ import org.bukkit.event.block.LeavesDecayEvent;
|
||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import world.bentobox.bentobox.api.events.island.IslandDeleteEvent;
|
||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.database.Database;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
import world.bentobox.limits.Limits;
|
||||
import world.bentobox.limits.objects.IslandBlockCount;
|
||||
@ -207,6 +210,13 @@ public class BlockLimitsListener implements Listener {
|
||||
notify(e, User.getInstance(e.getPlayer()), process(e.getBlock(), true), e.getBlock().getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the event and notify the user of failure
|
||||
* @param e event
|
||||
* @param user user
|
||||
* @param limit maximum limit allowed
|
||||
* @param m material
|
||||
*/
|
||||
private void notify(Cancellable e, User user, int limit, Material m) {
|
||||
if (limit > -1) {
|
||||
user.notify("block-limits.hit-limit",
|
||||
@ -247,6 +257,16 @@ public class BlockLimitsListener implements Listener {
|
||||
process(e.getBlock(), true);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onBlock(BlockGrowEvent e) {
|
||||
if (process(e.getNewState().getBlock(), true) > -1) {
|
||||
e.setCancelled(true);
|
||||
e.getBlock().getWorld().getBlockAt(e.getBlock().getLocation()).setBlockData(e.getBlock().getBlockData());
|
||||
} else {
|
||||
process(e.getBlock(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onBlock(LeavesDecayEvent e) {
|
||||
process(e.getBlock(), false);
|
||||
@ -387,18 +407,18 @@ public class BlockLimitsListener implements Listener {
|
||||
*/
|
||||
private int checkLimit(World w, Material m, String id) {
|
||||
// Check island limits
|
||||
IslandBlockCount island = islandCountMap.get(id);
|
||||
if (island.isBlockLimited(m)) {
|
||||
return island.isAtLimit(m) ? island.getBlockLimit(m) : -1;
|
||||
IslandBlockCount ibc = islandCountMap.get(id);
|
||||
if (ibc.isBlockLimited(m)) {
|
||||
return ibc.isAtLimit(m) ? ibc.getBlockLimit(m) + ibc.getBlockLimitOffset(m) : -1;
|
||||
}
|
||||
// Check specific world limits
|
||||
if (worldLimitMap.containsKey(w) && worldLimitMap.get(w).containsKey(m)) {
|
||||
// Material is overridden in world
|
||||
return island.isAtLimit(m, worldLimitMap.get(w).get(m)) ? worldLimitMap.get(w).get(m) : -1;
|
||||
return ibc.isAtLimit(m, worldLimitMap.get(w).get(m)) ? worldLimitMap.get(w).get(m) + ibc.getBlockLimitOffset(m) : -1;
|
||||
}
|
||||
// Check default limit map
|
||||
if (defaultLimitMap.containsKey(m) && island.isAtLimit(m, defaultLimitMap.get(m))) {
|
||||
return defaultLimitMap.get(m);
|
||||
if (defaultLimitMap.containsKey(m) && ibc.isAtLimit(m, defaultLimitMap.get(m))) {
|
||||
return defaultLimitMap.get(m) + ibc.getBlockLimitOffset(m);
|
||||
}
|
||||
// No limit
|
||||
return -1;
|
||||
@ -422,7 +442,12 @@ public class BlockLimitsListener implements Listener {
|
||||
}
|
||||
// Island
|
||||
if (islandCountMap.containsKey(id)) {
|
||||
result.putAll(islandCountMap.get(id).getBlockLimits());
|
||||
IslandBlockCount islandBlockCount = islandCountMap.get(id);
|
||||
result.putAll(islandBlockCount.getBlockLimits());
|
||||
|
||||
// Add offsets to the every limit.
|
||||
islandBlockCount.getBlockLimitsOffset().forEach((material, offset) ->
|
||||
result.put(material, result.getOrDefault(material, 0) + offset));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -463,4 +488,14 @@ public class BlockLimitsListener implements Listener {
|
||||
return islandCountMap.get(islandId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the island block count for island and make one if it does not exist
|
||||
* @param island island
|
||||
* @return island block count
|
||||
*/
|
||||
@NonNull
|
||||
public IslandBlockCount getIsland(Island island) {
|
||||
return islandCountMap.computeIfAbsent(island.getUniqueId(), k -> new IslandBlockCount(k, island.getGameMode()));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,11 +16,12 @@ 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.Breedable;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Villager;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@ -30,15 +31,17 @@ 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;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
import world.bentobox.limits.EntityGroup;
|
||||
import world.bentobox.limits.Limits;
|
||||
import world.bentobox.limits.Settings;
|
||||
import world.bentobox.limits.Settings.EntityGroup;
|
||||
import world.bentobox.limits.objects.IslandBlockCount;
|
||||
|
||||
public class EntityLimitListener implements Listener {
|
||||
private static final String MOD_BYPASS = "mod.bypass";
|
||||
@ -88,12 +91,12 @@ public class EntityLimitListener implements Listener {
|
||||
public void onBreed(final EntityBreedEvent e) {
|
||||
if (addon.inGameModeWorld(e.getEntity().getWorld())
|
||||
&& e.getBreeder() != null
|
||||
&& e.getBreeder() instanceof Player p
|
||||
&& (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);
|
||||
&& e.getFather() instanceof Breedable f && e.getMother() instanceof Breedable m) {
|
||||
f.setBreed(false);
|
||||
m.setBreed(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,7 +110,7 @@ public class EntityLimitListener implements Listener {
|
||||
justSpawned.remove(e.getEntity().getUniqueId());
|
||||
return;
|
||||
}
|
||||
if (e.getSpawnReason().equals(SpawnReason.SHOULDER_ENTITY) || e.getSpawnReason().equals(SpawnReason.BREEDING)) {
|
||||
if (e.getSpawnReason().equals(SpawnReason.SHOULDER_ENTITY) || (!(e.getEntity() instanceof Villager ) && 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;
|
||||
@ -169,6 +172,7 @@ public class EntityLimitListener implements Listener {
|
||||
|
||||
private boolean processIsland(Cancellable c, LivingEntity e, Location l, SpawnReason reason, boolean async) {
|
||||
if (addon.getIslands().getIslandAt(e.getLocation()).isEmpty()) {
|
||||
c.setCancelled(false);
|
||||
return true;
|
||||
}
|
||||
Island island = addon.getIslands().getIslandAt(e.getLocation()).get();
|
||||
@ -177,7 +181,7 @@ public class EntityLimitListener implements Listener {
|
||||
if (island.isSpawn() || !res.hit()) {
|
||||
// Allowed
|
||||
if (async) {
|
||||
Bukkit.getScheduler().runTask(BentoBox.getInstance(), () -> l.getWorld().spawn(l, e.getClass(), entity -> preSpawn(entity, reason, l)));
|
||||
Bukkit.getScheduler().runTask(BentoBox.getInstance(), () -> preSpawn(e.getType(), reason, l));
|
||||
} // else do nothing
|
||||
} else {
|
||||
if (async) {
|
||||
@ -192,21 +196,23 @@ public class EntityLimitListener implements Listener {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void preSpawn(Entity entity, SpawnReason reason, Location l) {
|
||||
justSpawned.add(entity.getUniqueId());
|
||||
private void preSpawn(EntityType entityType, SpawnReason reason, Location l) {
|
||||
|
||||
// Check for entities that need cleanup
|
||||
switch (reason) {
|
||||
case BUILD_IRONGOLEM -> detectIronGolem(l);
|
||||
case BUILD_SNOWMAN -> detectSnowman(l);
|
||||
case BUILD_WITHER -> {
|
||||
detectWither(l);
|
||||
}
|
||||
default -> throw new IllegalArgumentException("Unexpected value: " + reason);
|
||||
}
|
||||
Entity entity = l.getWorld().spawnEntity(l, entityType);
|
||||
justSpawned.add(entity.getUniqueId());
|
||||
if (reason == SpawnReason.BUILD_WITHER) {
|
||||
// Create explosion
|
||||
l.getWorld().createExplosion(l, 7F, true, true, entity);
|
||||
}
|
||||
default -> {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void detectIronGolem(Location l) {
|
||||
@ -220,7 +226,7 @@ public class EntityLimitListener implements Listener {
|
||||
if (body.getType().equals(Material.IRON_BLOCK)) {
|
||||
// Check for head
|
||||
Block head = body.getRelative(bf);
|
||||
if (head.getType().equals(Material.CARVED_PUMPKIN)) {
|
||||
if (head.getType() == Material.CARVED_PUMPKIN || head.getType() == Material.JACK_O_LANTERN) {
|
||||
// Check for arms the rule is that they must be opposite and have nothing "beneath" them
|
||||
for (BlockFace bf2 : CARDINALS) {
|
||||
Block arm1 = body.getRelative(bf2);
|
||||
@ -243,7 +249,6 @@ public class EntityLimitListener implements Listener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void detectSnowman(Location l) {
|
||||
@ -257,7 +262,7 @@ public class EntityLimitListener implements Listener {
|
||||
if (body.getType().equals(Material.SNOW_BLOCK)) {
|
||||
// Check for head
|
||||
Block head = body.getRelative(bf);
|
||||
if (head.getType().equals(Material.CARVED_PUMPKIN)) {
|
||||
if (head.getType() == Material.CARVED_PUMPKIN || head.getType() == Material.JACK_O_LANTERN) {
|
||||
// Erase
|
||||
addon.getBlockLimitListener().removeBlock(body);
|
||||
addon.getBlockLimitListener().removeBlock(head);
|
||||
@ -368,12 +373,18 @@ public class EntityLimitListener implements Listener {
|
||||
AtLimitResult atLimit(Island island, Entity ent) {
|
||||
// Check island settings first
|
||||
int limitAmount = -1;
|
||||
Map<Settings.EntityGroup, Integer> groupsLimits = new HashMap<>();
|
||||
if (addon.getBlockLimitListener().getIsland(island.getUniqueId()) != null) {
|
||||
limitAmount = addon.getBlockLimitListener().getIsland(island.getUniqueId()).getEntityLimit(ent.getType());
|
||||
List<Settings.EntityGroup> groupdefs = addon.getSettings().getGroupLimits().getOrDefault(ent.getType(), new ArrayList<>());
|
||||
Map<EntityGroup, Integer> groupsLimits = new HashMap<>();
|
||||
|
||||
@Nullable
|
||||
IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(island.getUniqueId());
|
||||
if (ibc != null) {
|
||||
// Get the limit amount for this type
|
||||
limitAmount = ibc.getEntityLimit(ent.getType());
|
||||
// Handle entity groups
|
||||
List<EntityGroup> groupdefs = addon.getSettings().getGroupLimits().getOrDefault(ent.getType(),
|
||||
new ArrayList<>());
|
||||
groupdefs.forEach(def -> {
|
||||
int limit = addon.getBlockLimitListener().getIsland(island.getUniqueId()).getEntityGroupLimit(def.getName());
|
||||
int limit = ibc.getEntityGroupLimit(def.getName());
|
||||
if (limit >= 0)
|
||||
groupsLimits.put(def, limit);
|
||||
});
|
||||
@ -382,40 +393,49 @@ public class EntityLimitListener implements Listener {
|
||||
if (limitAmount < 0 && addon.getSettings().getLimits().containsKey(ent.getType())) {
|
||||
limitAmount = addon.getSettings().getLimits().get(ent.getType());
|
||||
}
|
||||
// Group limits
|
||||
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 && groupsLimits.isEmpty()) return new AtLimitResult();
|
||||
if (limitAmount < 0 && groupsLimits.isEmpty()) {
|
||||
return new AtLimitResult();
|
||||
}
|
||||
|
||||
// We have to count the entities
|
||||
if (limitAmount >= 0)
|
||||
{
|
||||
int count = (int) ent.getWorld().getEntities().stream()
|
||||
int count = (int) ent.getWorld().getNearbyEntities(island.getBoundingBox()).stream()
|
||||
.filter(e -> e.getType().equals(ent.getType()))
|
||||
.filter(e -> island.inIslandSpace(e.getLocation()))
|
||||
.count();
|
||||
if (count >= limitAmount) {
|
||||
return new AtLimitResult(ent.getType(), limitAmount);
|
||||
int max = limitAmount + (ibc == null ? 0 : ibc.getEntityLimitOffset(ent.getType()));
|
||||
if (count >= max) {
|
||||
return new AtLimitResult(ent.getType(), max);
|
||||
}
|
||||
}
|
||||
// Merge in any permission-based limits
|
||||
if (addon.getBlockLimitListener().getIsland(island.getUniqueId()) != null) {
|
||||
Map<String, EntityGroup> groupbyname = groupsLimits.keySet().stream().collect(Collectors.toMap(EntityGroup::getName, e -> e));
|
||||
addon.getBlockLimitListener().getIsland(island.getUniqueId()).getEntityGroupLimits().entrySet().stream()
|
||||
// Group limits
|
||||
if (ibc != null) {
|
||||
Map<String, EntityGroup> groupbyname = groupsLimits.keySet().stream()
|
||||
.collect(Collectors.toMap(EntityGroup::getName, e -> e));
|
||||
ibc.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
|
||||
for (Map.Entry<EntityGroup, Integer> group : groupsLimits.entrySet()) { //do not use lambda
|
||||
if (group.getValue() < 0)
|
||||
continue;
|
||||
int count = (int) ent.getWorld().getEntities().stream()
|
||||
// int count = (int) ent.getWorld().getEntities().stream()
|
||||
// .filter(e -> group.getKey().contains(e.getType()))
|
||||
// .filter(e -> island.inIslandSpace(e.getLocation())).count();
|
||||
int count = (int) ent.getWorld().getNearbyEntities(island.getBoundingBox()).stream()
|
||||
.filter(e -> group.getKey().contains(e.getType()))
|
||||
.filter(e -> island.inIslandSpace(e.getLocation())).count();
|
||||
if (count >= group.getValue())
|
||||
return new AtLimitResult(group.getKey(), group.getValue());
|
||||
.count();
|
||||
int max = group.getValue() + + (ibc == null ? 0 : ibc.getEntityGroupLimitOffset(group.getKey().getName()));
|
||||
if (count >= max) {
|
||||
return new AtLimitResult(group.getKey(), max);
|
||||
}
|
||||
}
|
||||
return new AtLimitResult();
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
@ -18,21 +17,20 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
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;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.limits.EntityGroup;
|
||||
import world.bentobox.limits.Limits;
|
||||
import world.bentobox.limits.Settings.EntityGroup;
|
||||
import world.bentobox.limits.events.LimitsJoinPermCheckEvent;
|
||||
import world.bentobox.limits.events.LimitsPermCheckEvent;
|
||||
import world.bentobox.limits.objects.IslandBlockCount;
|
||||
|
||||
/**
|
||||
* Sets block limits based on player permission
|
||||
*
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
@ -45,7 +43,9 @@ public class JoinListener implements Listener {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and set the permissions of the player and how they affect the island limits
|
||||
* Check and set the permissions of the player and how they affect the island
|
||||
* limits
|
||||
*
|
||||
* @param player - player
|
||||
* @param permissionPrefix - permission prefix for this game mode
|
||||
* @param islandId - island string id
|
||||
@ -61,21 +61,23 @@ public class JoinListener implements Listener {
|
||||
ibc.getBlockLimits().clear();
|
||||
}
|
||||
for (PermissionAttachmentInfo perms : player.getEffectivePermissions()) {
|
||||
if (!perms.getValue()
|
||||
|| !perms.getPermission().startsWith(permissionPrefix)
|
||||
if (!perms.getValue() || !perms.getPermission().startsWith(permissionPrefix)
|
||||
|| badSyntaxCheck(perms, player.getName(), permissionPrefix)) {
|
||||
continue;
|
||||
}
|
||||
// Check formatting
|
||||
String[] split = perms.getPermission().split("\\.");
|
||||
// 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);
|
||||
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(t -> t.getName().equalsIgnoreCase(split[3])).findFirst().orElse(null);
|
||||
|
||||
if (entgroup == null && et == null && m == null) {
|
||||
logError(player.getName(), perms.getPermission(), split[3].toUpperCase(Locale.ENGLISH) + " is not a valid material or entity type/group.");
|
||||
logError(player.getName(), perms.getPermission(),
|
||||
split[3].toUpperCase(Locale.ENGLISH) + " is not a valid material or entity type/group.");
|
||||
break;
|
||||
}
|
||||
// Make an ibc if required
|
||||
@ -84,21 +86,29 @@ public class JoinListener implements Listener {
|
||||
}
|
||||
// Get the value
|
||||
int value = Integer.parseInt(split[4]);
|
||||
addon.log("Setting login limit via perm for " + player.getName() + "...");
|
||||
|
||||
// Fire perm check event
|
||||
LimitsPermCheckEvent l = new LimitsPermCheckEvent(player, islandId, ibc, entgroup, et, m, value);
|
||||
Bukkit.getPluginManager().callEvent(l);
|
||||
if (l.isCancelled()) continue;
|
||||
if (l.isCancelled()) {
|
||||
addon.log("Permissions not set because another addon/plugin canceled setting.");
|
||||
continue;
|
||||
}
|
||||
// Use event values
|
||||
ibc = l.getIbc();
|
||||
// Make an ibc if required
|
||||
if (ibc == null) {
|
||||
ibc = new IslandBlockCount(islandId, gameMode);
|
||||
}
|
||||
// Run null checks and set ibc
|
||||
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);
|
||||
// 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);
|
||||
}
|
||||
|
||||
private boolean badSyntaxCheck(PermissionAttachmentInfo perms, String name, String permissionPrefix) {
|
||||
@ -110,42 +120,51 @@ public class JoinListener implements Listener {
|
||||
// Check formatting
|
||||
String[] split = perms.getPermission().split("\\.");
|
||||
if (split.length != 5) {
|
||||
logError(name, perms.getPermission(), "format must be '" + permissionPrefix + "MATERIAL.NUMBER', '" + permissionPrefix + "ENTITY-TYPE.NUMBER', or '" + permissionPrefix + "ENTITY-GROUP.NUMBER'");
|
||||
logError(name, perms.getPermission(), "format must be '" + permissionPrefix + "MATERIAL.NUMBER', '"
|
||||
+ permissionPrefix + "ENTITY-TYPE.NUMBER', or '" + permissionPrefix + "ENTITY-GROUP.NUMBER'");
|
||||
return true;
|
||||
}
|
||||
// Check value
|
||||
if (!NumberUtils.isDigits(split[4])) {
|
||||
logError(name, perms.getPermission(), "the last part MUST be a number!");
|
||||
try {
|
||||
Integer.parseInt(split[4]);
|
||||
} catch (Exception e) {
|
||||
logError(name, perms.getPermission(), "the last part MUST be an integer!");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void runNullCheckAndSet(@Nullable IslandBlockCount ibc, @NonNull LimitsPermCheckEvent l) {
|
||||
if (ibc == null) {
|
||||
return;
|
||||
}
|
||||
private void runNullCheckAndSet(@NonNull IslandBlockCount ibc, @NonNull LimitsPermCheckEvent l) {
|
||||
EntityGroup entgroup = l.getEntityGroup();
|
||||
EntityType et = l.getEntityType();
|
||||
Material m = l.getMaterial();
|
||||
int value = l.getValue();
|
||||
if (entgroup != null) {
|
||||
// Entity group limit
|
||||
ibc.setEntityGroupLimit(entgroup.getName(), Math.max(ibc.getEntityGroupLimit(entgroup.getName()), value));
|
||||
int v = Math.max(ibc.getEntityGroupLimit(entgroup.getName()), value);
|
||||
ibc.setEntityGroupLimit(entgroup.getName(), v);
|
||||
addon.log("Setting group limit " + entgroup.getName() + " " + v);
|
||||
} else if (et != null && m == null) {
|
||||
// Entity limit
|
||||
ibc.setEntityLimit(et, Math.max(ibc.getEntityLimit(et), value));
|
||||
int v = Math.max(ibc.getEntityLimit(et), value);
|
||||
ibc.setEntityLimit(et, v);
|
||||
addon.log("Setting entity limit " + et + " " + v);
|
||||
} else if (m != null && et == null) {
|
||||
// Material limit
|
||||
ibc.setBlockLimit(m, Math.max(ibc.getBlockLimit(m), value));
|
||||
// Block limit
|
||||
int v = Math.max(ibc.getBlockLimit(m), value);
|
||||
addon.log("Setting block limit " + m + " " + v);
|
||||
ibc.setBlockLimit(m, v);
|
||||
} else {
|
||||
if (m != null && m.isBlock()) {
|
||||
int v = Math.max(ibc.getBlockLimit(m), value);
|
||||
addon.log("Setting block limit " + m + " " + v);
|
||||
// Material limit
|
||||
ibc.setBlockLimit(m, Math.max(ibc.getBlockLimit(m), value));
|
||||
} else if (et != null){
|
||||
ibc.setBlockLimit(m, v);
|
||||
} else if (et != null) {
|
||||
int v = Math.max(ibc.getEntityLimit(et), value);
|
||||
addon.log("Setting entity limit " + et + " " + v);
|
||||
// This is an entity setting
|
||||
ibc.setEntityLimit(et, Math.max(ibc.getEntityLimit(et), value));
|
||||
ibc.setEntityLimit(et, v);
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,8 +180,7 @@ public class JoinListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onNewIsland(IslandEvent e) {
|
||||
if (!e.getReason().equals(Reason.CREATED)
|
||||
&& !e.getReason().equals(Reason.RESETTED)
|
||||
if (!e.getReason().equals(Reason.CREATED) && !e.getReason().equals(Reason.RESETTED)
|
||||
&& !e.getReason().equals(Reason.REGISTERED)) {
|
||||
return;
|
||||
}
|
||||
@ -175,22 +193,29 @@ public class JoinListener implements Listener {
|
||||
setOwnerPerms(e.getIsland(), e.getNewOwner());
|
||||
}
|
||||
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onPlayerJoin(PlayerJoinEvent e) {
|
||||
// Check if player has any islands in the game modes
|
||||
addon.getGameModes().forEach(gm -> {
|
||||
if (addon.getIslands().hasIsland(gm.getOverWorld(), e.getPlayer().getUniqueId())) {
|
||||
String islandId = Objects.requireNonNull(addon.getIslands().getIsland(gm.getOverWorld(), e.getPlayer().getUniqueId())).getUniqueId();
|
||||
addon.getIslands().getIslands(gm.getOverWorld(), e.getPlayer().getUniqueId()).stream()
|
||||
.map(Island::getUniqueId).forEach(islandId -> {
|
||||
IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(islandId);
|
||||
if (joinEventCheck(e.getPlayer(), islandId, ibc)) {
|
||||
return;
|
||||
}
|
||||
checkPerms(e.getPlayer(), gm.getPermissionPrefix() + "island.limit.", islandId, gm.getDescription().getName());
|
||||
if (!joinEventCheck(e.getPlayer(), islandId, ibc)) {
|
||||
checkPerms(e.getPlayer(), gm.getPermissionPrefix() + "island.limit.", islandId,
|
||||
gm.getDescription().getName());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire event so other addons can cancel this permissions change
|
||||
*
|
||||
* @param player player
|
||||
* @param islandId island id
|
||||
* @param ibc island block count
|
||||
* @return true if canceled
|
||||
*/
|
||||
private boolean joinEventCheck(Player player, String islandId, IslandBlockCount ibc) {
|
||||
// Fire event, so other addons can cancel this permissions change
|
||||
LimitsJoinPermCheckEvent e = new LimitsJoinPermCheckEvent(player, islandId, ibc);
|
||||
@ -200,7 +225,8 @@ public class JoinListener implements Listener {
|
||||
}
|
||||
// Get ibc from event if it has changed
|
||||
ibc = e.getIbc();
|
||||
// If perms should be ignored, but the IBC given in the event used, then set it and return
|
||||
// If perms should be ignored, but the IBC given in the event used, then set it
|
||||
// and return
|
||||
if (e.isIgnorePerms() && ibc != null) {
|
||||
addon.getBlockLimitListener().setIsland(islandId, ibc);
|
||||
return true;
|
||||
@ -240,7 +266,8 @@ public class JoinListener implements Listener {
|
||||
String prefix = addon.getGameModePermPrefix(world);
|
||||
String name = addon.getGameModeName(world);
|
||||
if (!prefix.isEmpty() && !name.isEmpty() && owner.getPlayer() != null) {
|
||||
checkPerms(Objects.requireNonNull(owner.getPlayer()), prefix + "island.limit.", island.getUniqueId(), name);
|
||||
checkPerms(Objects.requireNonNull(owner.getPlayer()), prefix + "island.limit.",
|
||||
island.getUniqueId(), name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package world.bentobox.limits.objects;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.EntityType;
|
||||
@ -19,35 +20,36 @@ import world.bentobox.bentobox.database.objects.Table;
|
||||
@Table(name = "IslandBlockCount")
|
||||
public class IslandBlockCount implements DataObject {
|
||||
|
||||
@Expose
|
||||
private String uniqueId;
|
||||
|
||||
@Expose
|
||||
private String gameMode;
|
||||
|
||||
@Expose
|
||||
private Map<Material, Integer> blockCounts = new EnumMap<>(Material.class);
|
||||
|
||||
private boolean changed;
|
||||
|
||||
/**
|
||||
* Permission based limits
|
||||
*/
|
||||
@Expose
|
||||
private Map<Material, Integer> blockLimits = new EnumMap<>(Material.class);
|
||||
|
||||
@Expose
|
||||
private Map<EntityType, Integer> entityLimits = new EnumMap<>(EntityType.class);
|
||||
private Map<Material, Integer> blockLimitsOffset = new EnumMap<>(Material.class);
|
||||
|
||||
private boolean changed;
|
||||
|
||||
@Expose
|
||||
private Map<String, Integer> entityGroupLimits = new HashMap<>();
|
||||
@Expose
|
||||
private Map<Material, Integer> blockLimitsOffset = new EnumMap<>(Material.class);
|
||||
private Map<String, Integer> entityGroupLimitsOffset = new HashMap<>();
|
||||
@Expose
|
||||
private Map<EntityType, Integer> entityLimits = new EnumMap<>(EntityType.class);
|
||||
@Expose
|
||||
private Map<EntityType, Integer> entityLimitsOffset = new EnumMap<>(EntityType.class);
|
||||
@Expose
|
||||
private Map<String, Integer> entityGroupLimitsOffset = new HashMap<>();
|
||||
private String gameMode;
|
||||
@Expose
|
||||
private String uniqueId;
|
||||
|
||||
/**
|
||||
* Create an island block count object
|
||||
*
|
||||
* @param islandId - unique Island ID string
|
||||
* @param gameMode - Game mode name from gm.getDescription().getName()
|
||||
*/
|
||||
@ -57,23 +59,42 @@ public class IslandBlockCount implements DataObject {
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see world.bentobox.bentobox.database.objects.DataObject#getUniqueId()
|
||||
/**
|
||||
* Add a material to the count
|
||||
*
|
||||
* @param material - material
|
||||
*/
|
||||
@Override
|
||||
public String getUniqueId() {
|
||||
return uniqueId;
|
||||
public void add(Material material) {
|
||||
getBlockCounts().merge(material, 1, Integer::sum);
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see world.bentobox.bentobox.database.objects.DataObject#setUniqueId(java.lang.String)
|
||||
/**
|
||||
* Clear all island-specific entity group limits
|
||||
*/
|
||||
@Override
|
||||
public void setUniqueId(String uniqueId) {
|
||||
this.uniqueId = uniqueId;
|
||||
public void clearEntityGroupLimits() {
|
||||
entityGroupLimits.clear();
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all island-specific entity type limits
|
||||
*/
|
||||
public void clearEntityLimits() {
|
||||
entityLimits.clear();
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block count for this material for this island
|
||||
*
|
||||
* @param m - material
|
||||
* @return count
|
||||
*/
|
||||
public Integer getBlockCount(Material m) {
|
||||
return getBlockCounts().getOrDefault(m, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the blockCount
|
||||
*/
|
||||
@ -85,221 +106,30 @@ public class IslandBlockCount implements DataObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param blockCounts the blockCount to set
|
||||
*/
|
||||
public void setBlockCounts(Map<Material, Integer> blockCounts) {
|
||||
this.blockCounts = blockCounts;
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block count for this material for this island
|
||||
* Get the block limit for this material for this island
|
||||
*
|
||||
* @param m - material
|
||||
* @return count
|
||||
* @return limit or -1 for unlimited
|
||||
*/
|
||||
public Integer getBlockCount(Material m) {
|
||||
return blockCounts.getOrDefault(m, 0);
|
||||
public int getBlockLimit(Material m) {
|
||||
return getBlockLimits().getOrDefault(m, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a material to the count
|
||||
* @param material - material
|
||||
*/
|
||||
public void add(Material material) {
|
||||
blockCounts.merge(material, 1, Integer::sum);
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a material from the count
|
||||
* @param material - material
|
||||
*/
|
||||
public void remove(Material material) {
|
||||
blockCounts.put(material, blockCounts.getOrDefault(material, 0) - 1);
|
||||
blockCounts.values().removeIf(v -> v <= 0);
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this material is at or over a limit
|
||||
* @param material - block material
|
||||
* @param limit - limit to check
|
||||
* @return true if count is >= limit
|
||||
*/
|
||||
public boolean isAtLimit(Material material, int limit) {
|
||||
return blockCounts.getOrDefault(material, 0) >= limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if no more of this material can be added to this island
|
||||
* Get the block offset for this material for this island
|
||||
*
|
||||
* @param m - material
|
||||
* @return true if no more material can be added
|
||||
* @return offset
|
||||
*/
|
||||
public boolean isAtLimit(Material m) {
|
||||
// Check island limits first
|
||||
return blockLimits.containsKey(m) && blockCounts.getOrDefault(m, 0) >= getBlockLimit(m);
|
||||
}
|
||||
|
||||
public boolean isBlockLimited(Material m) {
|
||||
return blockLimits.containsKey(m);
|
||||
public int getBlockLimitOffset(Material m) {
|
||||
return getBlockLimitsOffset().getOrDefault(m, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the blockLimits
|
||||
*/
|
||||
public Map<Material, Integer> getBlockLimits() {
|
||||
return blockLimits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param blockLimits the blockLimits to set
|
||||
*/
|
||||
public void setBlockLimits(Map<Material, Integer> blockLimits) {
|
||||
this.blockLimits = blockLimits;
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block limit for this material for this island
|
||||
* @param m - material
|
||||
* @return limit or -1 for unlimited
|
||||
*/
|
||||
public Integer getBlockLimit(Material m) {
|
||||
return blockLimits.getOrDefault(m, -1) + getBlockLimitsOffset().getOrDefault(m, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the block limit for this material for this island
|
||||
* @param m - material
|
||||
* @param limit - maximum number allowed
|
||||
*/
|
||||
public void setBlockLimit(Material m, int limit) {
|
||||
blockLimits.put(m, limit);
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the gameMode
|
||||
*/
|
||||
public String getGameMode() {
|
||||
return gameMode;
|
||||
}
|
||||
|
||||
public boolean isGameMode(String gameMode) {
|
||||
return this.gameMode.equals(gameMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param gameMode the gameMode to set
|
||||
*/
|
||||
public void setGameMode(String gameMode) {
|
||||
this.gameMode = gameMode;
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) + getEntityLimitsOffset().getOrDefault(t, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all island-specific entity type limits
|
||||
*/
|
||||
public void clearEntityLimits() {
|
||||
entityLimits.clear();
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entityGroupLimits
|
||||
*/
|
||||
public Map<String, Integer> getEntityGroupLimits() {
|
||||
return entityGroupLimits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entityGroupLimits the entityGroupLimits to set
|
||||
*/
|
||||
public void setEntityGroupLimits(Map<String, Integer> entityGroupLimits) {
|
||||
this.entityGroupLimits = entityGroupLimits;
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
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) + getEntityGroupLimitsOffset().getOrDefault(name, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all island-specific entity group limits
|
||||
*/
|
||||
public void clearEntityGroupLimits() {
|
||||
entityGroupLimits.clear();
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the changed
|
||||
*/
|
||||
public boolean isChanged() {
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param changed the changed to set
|
||||
*/
|
||||
public void setChanged(boolean changed) {
|
||||
this.changed = changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark changed
|
||||
*/
|
||||
public void setChanged() {
|
||||
this.changed = true;
|
||||
return Objects.requireNonNullElse(blockLimits, new EnumMap<>(Material.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -313,31 +143,30 @@ public class IslandBlockCount implements DataObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Get the limit for an entity group
|
||||
*
|
||||
* @param name - entity group
|
||||
* @return limit or -1 for unlimited
|
||||
*/
|
||||
public void setBlockLimitsOffset(Material m, Integer blockLimitsOffset) {
|
||||
getBlockLimitsOffset().put(m, blockLimitsOffset);
|
||||
public int getEntityGroupLimit(String name) {
|
||||
return getEntityGroupLimits().getOrDefault(name, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entityLimitsOffset
|
||||
* Get the offset for an entity group
|
||||
*
|
||||
* @param name - entity group
|
||||
* @return offset
|
||||
*/
|
||||
public Map<EntityType, Integer> getEntityLimitsOffset() {
|
||||
if (entityLimitsOffset == null) {
|
||||
entityLimitsOffset = new EnumMap<>(EntityType.class);
|
||||
}
|
||||
return entityLimitsOffset;
|
||||
public int getEntityGroupLimitOffset(String name) {
|
||||
return getEntityGroupLimitsOffset().getOrDefault(name, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return the entityGroupLimits
|
||||
*/
|
||||
public void setEntityLimitsOffset(EntityType t, Integer entityLimitsOffset) {
|
||||
this.getEntityLimitsOffset().put(t, entityLimitsOffset);
|
||||
public Map<String, Integer> getEntityGroupLimits() {
|
||||
return Objects.requireNonNullElse(entityGroupLimits, new HashMap<>());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -351,11 +180,238 @@ public class IslandBlockCount implements DataObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an offset to an entity group limit. This will increase/decrease the value of the limit.
|
||||
* Get the limit for an entity type
|
||||
*
|
||||
* @param t - entity type
|
||||
* @return limit or -1 for unlimited
|
||||
*/
|
||||
public int getEntityLimit(EntityType t) {
|
||||
return getEntityLimits().getOrDefault(t, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the limit offset for an entity type
|
||||
*
|
||||
* @param t - entity type
|
||||
* @return offset
|
||||
*/
|
||||
public int getEntityLimitOffset(EntityType t) {
|
||||
return getEntityLimitsOffset().getOrDefault(t, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entityLimits
|
||||
*/
|
||||
public Map<EntityType, Integer> getEntityLimits() {
|
||||
return Objects.requireNonNullElse(entityLimits, new EnumMap<>(EntityType.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entityLimitsOffset
|
||||
*/
|
||||
public Map<EntityType, Integer> getEntityLimitsOffset() {
|
||||
if (entityLimitsOffset == null) {
|
||||
entityLimitsOffset = new EnumMap<>(EntityType.class);
|
||||
}
|
||||
return entityLimitsOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the gameMode
|
||||
*/
|
||||
public String getGameMode() {
|
||||
return gameMode;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see world.bentobox.bentobox.database.objects.DataObject#getUniqueId()
|
||||
*/
|
||||
@Override
|
||||
public String getUniqueId() {
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if no more of this material can be added to this island
|
||||
*
|
||||
* @param m - material
|
||||
* @return true if no more material can be added
|
||||
*/
|
||||
public boolean isAtLimit(Material m) {
|
||||
// Check island limits first
|
||||
return getBlockLimits().containsKey(m)
|
||||
&& getBlockCounts().getOrDefault(m, 0) >= getBlockLimit(m) + this.getBlockLimitOffset(m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this material is at or over a limit
|
||||
*
|
||||
* @param material - block material
|
||||
* @param limit - limit to check
|
||||
* @return true if count is >= limit
|
||||
*/
|
||||
public boolean isAtLimit(Material material, int limit) {
|
||||
return getBlockCounts().getOrDefault(material, 0) >= limit + this.getBlockLimitOffset(material);
|
||||
}
|
||||
|
||||
public boolean isBlockLimited(Material m) {
|
||||
return getBlockLimits().containsKey(m);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the changed
|
||||
*/
|
||||
public boolean isChanged() {
|
||||
return changed;
|
||||
}
|
||||
|
||||
public boolean isGameMode(String gameMode) {
|
||||
return getGameMode().equals(gameMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a material from the count
|
||||
*
|
||||
* @param material - material
|
||||
*/
|
||||
public void remove(Material material) {
|
||||
getBlockCounts().put(material, getBlockCounts().getOrDefault(material, 0) - 1);
|
||||
getBlockCounts().values().removeIf(v -> v <= 0);
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param blockCounts the blockCount to set
|
||||
*/
|
||||
public void setBlockCounts(Map<Material, Integer> blockCounts) {
|
||||
this.blockCounts = blockCounts;
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the block limit for this material for this island
|
||||
*
|
||||
* @param m - material
|
||||
* @param limit - maximum number allowed
|
||||
*/
|
||||
public void setBlockLimit(Material m, int limit) {
|
||||
getBlockLimits().put(m, limit);
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param blockLimits the blockLimits to set
|
||||
*/
|
||||
public void setBlockLimits(Map<Material, Integer> blockLimits) {
|
||||
this.blockLimits = blockLimits;
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark changed
|
||||
*/
|
||||
public void setChanged() {
|
||||
this.changed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param changed the changed to set
|
||||
*/
|
||||
public void setChanged(boolean changed) {
|
||||
this.changed = changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an island-specific entity group limit
|
||||
*
|
||||
* @param name - entity group
|
||||
* @param limit - limit
|
||||
*/
|
||||
public void setEntityGroupLimit(String name, int limit) {
|
||||
getEntityGroupLimits().put(name, limit);
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entityGroupLimits the entityGroupLimits to set
|
||||
*/
|
||||
public void setEntityGroupLimits(Map<String, Integer> entityGroupLimits) {
|
||||
this.entityGroupLimits = entityGroupLimits;
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an island-specific entity type limit
|
||||
*
|
||||
* @param t - entity type
|
||||
* @param limit - limit
|
||||
*/
|
||||
public void setEntityLimit(EntityType t, int limit) {
|
||||
getEntityLimits().put(t, limit);
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entityLimits the entityLimits to set
|
||||
*/
|
||||
public void setEntityLimits(Map<EntityType, Integer> entityLimits) {
|
||||
this.entityLimits = entityLimits;
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an offset to an entity limit. This will increase/decrease the value of
|
||||
* the limit.
|
||||
*
|
||||
* @param type Entity Type
|
||||
* @param entityLimitsOffset the entityLimitsOffset to set
|
||||
*/
|
||||
public void setEntityLimitsOffset(EntityType type, Integer entityLimitsOffset) {
|
||||
this.getEntityLimitsOffset().put(type, entityLimitsOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param gameMode the gameMode to set
|
||||
*/
|
||||
public void setGameMode(String gameMode) {
|
||||
this.gameMode = gameMode;
|
||||
setChanged();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* world.bentobox.bentobox.database.objects.DataObject#setUniqueId(java.lang.
|
||||
* String)
|
||||
*/
|
||||
@Override
|
||||
public void setUniqueId(String uniqueId) {
|
||||
this.uniqueId = uniqueId;
|
||||
setChanged();
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
name: Limits
|
||||
main: world.bentobox.limits.Limits
|
||||
version: ${version}${build.number}
|
||||
api-version: 1.16.5
|
||||
api-version: 2.3.0
|
||||
|
||||
authors: tastybento
|
||||
|
||||
softdepend: AcidIsland, BSkyBlock, CaveBlock
|
||||
softdepend: AcidIsland, BSkyBlock, CaveBlock, AOneBlock, SkyGrid
|
||||
|
||||
permissions:
|
||||
'[gamemode].limits.player.limits':
|
||||
@ -17,3 +17,6 @@ permissions:
|
||||
'[gamemode].limits.admin.limits':
|
||||
description: Player can use admin limits command
|
||||
default: op
|
||||
'[gamemode].mod.bypass':
|
||||
description: Player can bypass limits
|
||||
default: op
|
||||
|
@ -41,3 +41,90 @@ entitylimits:
|
||||
ENDERMAN: 5
|
||||
CHICKEN: 10
|
||||
|
||||
# Entity Groups
|
||||
# Name the group anything you like
|
||||
# Select an icon, which is a Bukkit Material
|
||||
# Select the limit for the total group
|
||||
# List the entities in the group using Bukkit EntityTypes
|
||||
entitygrouplimits:
|
||||
Monsters:
|
||||
icon: ROTTEN_FLESH
|
||||
limit: 250
|
||||
entities:
|
||||
- SKELETON
|
||||
- SILVERFISH
|
||||
- STRAY
|
||||
- ZOMBIE_VILLAGER
|
||||
- WITHER
|
||||
- WARDEN
|
||||
- BLAZE
|
||||
- DROWNED
|
||||
- BREEZE
|
||||
- ZOMBIFIED_PIGLIN
|
||||
- EVOKER
|
||||
- PILLAGER
|
||||
- HUSK
|
||||
- CREEPER
|
||||
- VINDICATOR
|
||||
- ZOMBIE
|
||||
- ENDERMAN
|
||||
- ELDER_GUARDIAN
|
||||
- WITHER_SKELETON
|
||||
- CAVE_SPIDER
|
||||
- GUARDIAN
|
||||
- RAVAGER
|
||||
- PIGLIN
|
||||
- BOGGED
|
||||
- WITCH
|
||||
- ENDERMITE
|
||||
- ZOGLIN
|
||||
- PIGLIN_BRUTE
|
||||
- ILLUSIONER
|
||||
- SPIDER
|
||||
- VEX
|
||||
Animals:
|
||||
icon: SADDLE
|
||||
limit: 200
|
||||
entities:
|
||||
- SHEEP
|
||||
- AXOLOTL
|
||||
- DONKEY
|
||||
- MOOSHROOM
|
||||
- TRADER_LLAMA
|
||||
- BEE
|
||||
- HORSE
|
||||
- ZOMBIE_HORSE
|
||||
- PIG
|
||||
- PARROT
|
||||
- CHICKEN
|
||||
- RABBIT
|
||||
- SNIFFER
|
||||
- FROG
|
||||
- GOAT
|
||||
- PANDA
|
||||
- CAMEL
|
||||
- STRIDER
|
||||
- TURTLE
|
||||
- CAT
|
||||
- SKELETON_HORSE
|
||||
- COW
|
||||
- LLAMA
|
||||
- ARMADILLO
|
||||
- HOGLIN
|
||||
- POLAR_BEAR
|
||||
- WOLF
|
||||
- MULE
|
||||
- OCELOT
|
||||
- FOX
|
||||
- DOLPHIN
|
||||
- COD
|
||||
- PUFFERFISH
|
||||
- TADPOLE
|
||||
- SQUID
|
||||
- SALMON
|
||||
- TROPICAL_FISH
|
||||
- GLOW_SQUID
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -20,7 +20,32 @@ admin:
|
||||
parameters: "<player>"
|
||||
description: "recalculate the island limits for player"
|
||||
finished: "&a Island recalc finished successfully!"
|
||||
|
||||
offset:
|
||||
unknown: "&c Unknown material or entity [name]."
|
||||
main:
|
||||
parameters: ""
|
||||
description: "allows to manage limits offsets for materials and entities"
|
||||
set:
|
||||
parameters: "<player> <material|entity> <number>"
|
||||
description: "sets new offset for material or entity limit"
|
||||
success: "&a Limit offset for [name] is set to [number]."
|
||||
same: "&c Limit offset for [name] is already [number]."
|
||||
add:
|
||||
parameters: "<player> <material|entity> <number>"
|
||||
description: "adds offset for material or entity limit"
|
||||
success: "&a Limit offset for [name] is increased till [number]."
|
||||
remove:
|
||||
parameters: "<player> <material|entity> <number>"
|
||||
description: "reduces offset for material or entity limit"
|
||||
success: "&a Limit offset for [name] is reduced till [number]."
|
||||
reset:
|
||||
parameters: "<player> <material|entity>"
|
||||
description: "removes offset for material or entity"
|
||||
success: "&a Limit offset for [name] is set to 0."
|
||||
view:
|
||||
parameters: "<player> <material|entity>"
|
||||
description: "displays offset for material or entity"
|
||||
message: "&a [name] offset is set to [number]."
|
||||
island:
|
||||
limits:
|
||||
description: "show your island limits"
|
||||
|
55
src/main/resources/locales/es.yml
Normal file
55
src/main/resources/locales/es.yml
Normal file
@ -0,0 +1,55 @@
|
||||
---
|
||||
block-limits:
|
||||
hit-limit: "&c[material] limitado a [number]!"
|
||||
entity-limits:
|
||||
hit-limit: "¡Aparición de &c[entity] limitada a [number]!"
|
||||
limits:
|
||||
panel-title: Límites de la isla
|
||||
admin:
|
||||
limits:
|
||||
main:
|
||||
parameters: "<jugador>"
|
||||
description: mostrar los límites de la isla para el jugador
|
||||
calc:
|
||||
parameters: "<jugador>"
|
||||
description: recalcular los límites de la isla para el jugador
|
||||
finished: "&a ¡El recálculo de la Isla terminó con éxito!"
|
||||
offset:
|
||||
unknown: "&c Material o entidad desconocida [name]."
|
||||
main:
|
||||
description: permite gestionar compensaciones de límites para materiales y
|
||||
entidades
|
||||
set:
|
||||
parameters: "<jugador> <material|entidad> <número>"
|
||||
description: establece una nueva compensación para el límite de material o
|
||||
entidad
|
||||
success: "&a El desplazamiento límite para [name] está establecido en [number]."
|
||||
same: "&c El límite de compensación para [name] ya es [number]."
|
||||
add:
|
||||
parameters: "<jugador> <material|entidad> <número>"
|
||||
description: agrega compensación por límite de material o entidad
|
||||
success: "&a El límite de compensación para [name] aumenta hasta [number]."
|
||||
remove:
|
||||
parameters: "<jugador> <material|entidad> <número>"
|
||||
description: reduce la compensación por límite de material o entidad
|
||||
success: "&a La compensación límite para [name] se reduce hasta [number]."
|
||||
reset:
|
||||
parameters: "<jugador> <material|entidad>"
|
||||
description: elimina la compensación para material o entidad
|
||||
success: "&a El desplazamiento límite para [number] está establecido en 0."
|
||||
view:
|
||||
parameters: "<jugador> <material|entidad>"
|
||||
description: muestra el desplazamiento para material o entidad
|
||||
message: "& desplazamiento de [name] se establece en [number]."
|
||||
island:
|
||||
limits:
|
||||
description: muestra los límites de tu isla
|
||||
max-color: "&c"
|
||||
regular-color: "&a"
|
||||
block-limit-syntax: "[number]/[limit]"
|
||||
no-limits: "&cNo hay limites establecidos en este mundo"
|
||||
recount:
|
||||
description: cuenta los límites para tu isla
|
||||
now-recounting: "&b Ahora contando. Esto podría tomar un tiempo, por favor espere..."
|
||||
in-progress: "&c El recuento de la isla está en progreso. Espere por favor..."
|
||||
time-out: "&c Ha pasado demasiado tiempo contando. ¿La isla es realmente grande?"
|
30
src/main/resources/locales/fr.yml
Normal file
30
src/main/resources/locales/fr.yml
Normal file
@ -0,0 +1,30 @@
|
||||
block-limits:
|
||||
hit-limit: "&c[material] limité à [number]!"
|
||||
entity-limits:
|
||||
hit-limit: "&c[entity] spawning limited to [number]!"
|
||||
limits:
|
||||
panel-title: "Limites de l'île"
|
||||
|
||||
|
||||
admin:
|
||||
limits:
|
||||
main:
|
||||
parameters: "<player>"
|
||||
description: "affiche les limites de l'île pour le joueur"
|
||||
calc:
|
||||
parameters: "<player>"
|
||||
description: "recalcule les limites de l'île pour le joueur"
|
||||
finished: "&a Recomptage terminé avec succès!"
|
||||
|
||||
island:
|
||||
limits:
|
||||
description: "affichez les limites de votre île"
|
||||
max-color: "&c"
|
||||
regular-color: "&a"
|
||||
block-limit-syntax: "[number]/[limit]"
|
||||
no-limits: "&cas de limites définies dans ce monde"
|
||||
recount:
|
||||
description: "recompte les limites de votre île"
|
||||
now-recounting: "&b Recomptage en cours. Cela peut prendre un certain temps, veuillez patienter..."
|
||||
in-progress: "&c Le recomptage de l'île est en cours. Veuillez patienter s'il vous plaît..."
|
||||
time-out: "&c Time out lors du recomptage. L'île est-elle vraiment grande?"
|
@ -1,27 +1,54 @@
|
||||
#
|
||||
# This is a YML file. Be careful when editing. Check your edits in a YAML checker like #
|
||||
# the one at http://yaml-online-parser.appspot.com #
|
||||
---
|
||||
block-limits:
|
||||
hit-limit: '&c[material] limitowany do [number]!'
|
||||
hit-limit: "&c[material] limitowany do [number]!"
|
||||
entity-limits:
|
||||
hit-limit: '&cSpawnowanie [entity] limitowane do [number]!'
|
||||
hit-limit: "&cSpawnowanie [entity] limitowane do [number]!"
|
||||
limits:
|
||||
panel-title: Limity wysp
|
||||
admin:
|
||||
limits:
|
||||
main:
|
||||
parameters: <gracz>
|
||||
parameters: "<gracz>"
|
||||
description: pokazuje limity wysp gracza
|
||||
calc:
|
||||
parameters: <gracz>
|
||||
parameters: "<gracz>"
|
||||
description: ponownie oblicza limity wyspy dla gracza
|
||||
finished: '&aPrzeliczanie zakończone!'
|
||||
finished: "&aPrzeliczanie zakończone!"
|
||||
offset:
|
||||
unknown: "&c Nieznany materiał lub podmiot [name]."
|
||||
main:
|
||||
description: pozwala zarządzać limitów dla materiałów i podmiotów,
|
||||
set:
|
||||
parameters: "<gracz> <materiał|istota> <liczba>"
|
||||
description: ustawia nową wartość dla limitu materiału lub encji
|
||||
success: "&a Przesunięcie limitu dla [name] jest ustawione na [number]."
|
||||
same: "&c Limit dla [name] jest aktualnie [number]."
|
||||
add:
|
||||
parameters: "<gracz> <materiał|istota> <liczba>"
|
||||
description: dodaje przesunięcie dla limitu materiału lub potworów
|
||||
success: "&a Przesunięcie limitu dla [name] jest zwiększone do [number]."
|
||||
remove:
|
||||
parameters: "<gracz> <materiał|istota> <liczba>"
|
||||
description: zmniejsza offset dla limitu materiału lub podmiotu
|
||||
success: "&a Limit dla bloku [name] \nzostał zmniejszony do [number]."
|
||||
reset:
|
||||
parameters: "<gracz> <materiał|istota>"
|
||||
description: usuwa wartość dla materiału lub istoty
|
||||
success: "&a Limit dla [name] jest ustawione na 0."
|
||||
view:
|
||||
parameters: "<gracz> <materiał|istota>"
|
||||
description: displays offset for material or entity
|
||||
message: "&a [name] wartość jest ustawiona na [number]."
|
||||
island:
|
||||
limits:
|
||||
description: pokazuje limity twojej wyspy
|
||||
max-color: '&c'
|
||||
regular-color: '&a'
|
||||
block-limit-syntax: '[number]/[limit]'
|
||||
no-limits: '&cBrak ustawionych limitów.'
|
||||
max-color: "&c"
|
||||
regular-color: "&a"
|
||||
block-limit-syntax: "[number]/[limit]"
|
||||
no-limits: "&cBrak ustawionych limitów."
|
||||
recount:
|
||||
description: określa limity dla twojej wyspy
|
||||
now-recounting: "&b Teraz przeliczam. To może chwilę potrwać, proszę czekać..."
|
||||
in-progress: "&c Trwa odzyskiwanie wyspy. Proszę czekać..."
|
||||
time-out: "&c Przekroczono limit czasu podczas przeliczania. Czy wyspa jest
|
||||
naprawdę duża?"
|
||||
|
@ -30,3 +30,6 @@ island:
|
||||
no-limits: "&c此世界中无限制"
|
||||
recount:
|
||||
description: "重新计数岛屿限制"
|
||||
now-recounting: "&b 开始重新计算. 可能需要一定的时间, 请稍等......"
|
||||
in-progress: "&c 重新计算岛屿限制中. 请稍等......"
|
||||
time-out: "&c 重新计算超时. 岛屿太大了吗?"
|
||||
|
9
src/main/resources/plugin.yml
Normal file
9
src/main/resources/plugin.yml
Normal file
@ -0,0 +1,9 @@
|
||||
name: BentoBox-Limits
|
||||
main: world.bentobox.limits.LimitsPladdon
|
||||
version: ${project.version}${build.number}
|
||||
api-version: "1.19"
|
||||
|
||||
authors: [tastybento]
|
||||
contributors: ["The BentoBoxWorld Community"]
|
||||
website: https://bentobox.world
|
||||
description: ${project.description}
|
@ -1,7 +1,5 @@
|
||||
package bentobox.addon.limits.listeners;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
@ -11,6 +9,14 @@ import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
@ -34,6 +40,7 @@ import world.bentobox.bentobox.api.events.island.IslandEvent;
|
||||
import world.bentobox.bentobox.api.events.team.TeamSetownerEvent;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.managers.IslandsManager;
|
||||
import world.bentobox.limits.EntityGroup;
|
||||
import world.bentobox.limits.Limits;
|
||||
import world.bentobox.limits.Settings;
|
||||
import world.bentobox.limits.listeners.BlockLimitsListener;
|
||||
@ -45,7 +52,7 @@ import world.bentobox.limits.objects.IslandBlockCount;
|
||||
*
|
||||
*/
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest( {Bukkit.class} )
|
||||
@PrepareForTest({ Bukkit.class })
|
||||
public class JoinListenerTest {
|
||||
|
||||
@Mock
|
||||
@ -80,11 +87,12 @@ public class JoinListenerTest {
|
||||
when(addon.getGameModePermPrefix(any())).thenReturn("bskyblock.");
|
||||
when(addon.getSettings()).thenReturn(settings);
|
||||
// Settings
|
||||
when(settings.getGroupLimitDefinitions()).thenReturn(new ArrayList<>(List.of(new Settings.EntityGroup("friendly", new HashSet<>(), -1))));
|
||||
when(settings.getGroupLimitDefinitions())
|
||||
.thenReturn(new ArrayList<>(List.of(new EntityGroup("friendly", new HashSet<>(), -1, null))));
|
||||
// Island Manager
|
||||
when(im.hasIsland(any(), any(UUID.class))).thenReturn(true);
|
||||
when(island.getUniqueId()).thenReturn("unique_id");
|
||||
when(im.getIsland(any(), any(UUID.class))).thenReturn(island);
|
||||
when(im.getIslands(any(), any(UUID.class))).thenReturn(List.of(island));
|
||||
// Default is that player has island
|
||||
when(addon.getIslands()).thenReturn(im);
|
||||
// Player
|
||||
@ -114,7 +122,8 @@ public class JoinListenerTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.limits.listeners.JoinListener#onNewIsland(world.bentobox.bentobox.api.events.island.IslandEvent)}.
|
||||
* Test method for
|
||||
* {@link world.bentobox.limits.listeners.JoinListener#onNewIsland(world.bentobox.bentobox.api.events.island.IslandEvent)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnNewIslandWrongReason() {
|
||||
@ -124,7 +133,8 @@ public class JoinListenerTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.limits.listeners.JoinListener#onNewIsland(world.bentobox.bentobox.api.events.island.IslandEvent)}.
|
||||
* Test method for
|
||||
* {@link world.bentobox.limits.listeners.JoinListener#onNewIsland(world.bentobox.bentobox.api.events.island.IslandEvent)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnNewIslandRegistered() {
|
||||
@ -134,7 +144,8 @@ public class JoinListenerTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.limits.listeners.JoinListener#onNewIsland(world.bentobox.bentobox.api.events.island.IslandEvent)}.
|
||||
* Test method for
|
||||
* {@link world.bentobox.limits.listeners.JoinListener#onNewIsland(world.bentobox.bentobox.api.events.island.IslandEvent)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnNewIslandResetted() {
|
||||
@ -185,7 +196,8 @@ public class JoinListenerTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.limits.listeners.JoinListener#onOwnerChange(world.bentobox.bentobox.api.events.team.TeamEvent.TeamSetownerEvent)}.
|
||||
* Test method for
|
||||
* {@link world.bentobox.limits.listeners.JoinListener#onOwnerChange(world.bentobox.bentobox.api.events.team.TeamEvent.TeamSetownerEvent)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnOwnerChange() {
|
||||
@ -198,7 +210,8 @@ public class JoinListenerTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnPlayerJoin() {
|
||||
@ -209,7 +222,8 @@ public class JoinListenerTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnPlayerJoinIBCNull() {
|
||||
@ -220,9 +234,9 @@ public class JoinListenerTest {
|
||||
verify(bll, never()).setIsland("unique_id", ibc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnPlayerJoinWithPermNotLimits() {
|
||||
@ -238,7 +252,8 @@ public class JoinListenerTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnPlayerJoinWithPermLimitsWrongSize() {
|
||||
@ -250,11 +265,13 @@ public class JoinListenerTest {
|
||||
when(player.getEffectivePermissions()).thenReturn(perms);
|
||||
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
|
||||
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', 'bskyblock.island.limit.ENTITY-TYPE.NUMBER', or 'bskyblock.island.limit.ENTITY-GROUP.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', 'bskyblock.island.limit.ENTITY-TYPE.NUMBER', or 'bskyblock.island.limit.ENTITY-GROUP.NUMBER' Ignoring...");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnPlayerJoinWithPermLimitsInvalidMaterial() {
|
||||
@ -266,11 +283,13 @@ public class JoinListenerTest {
|
||||
when(player.getEffectivePermissions()).thenReturn(perms);
|
||||
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
|
||||
jl.onPlayerJoin(e);
|
||||
verify(addon).logError("Player tastybento has permission: 'bskyblock.island.limit.mumbo.34' but MUMBO is not a valid material or entity type/group. Ignoring...");
|
||||
verify(addon).logError(
|
||||
"Player tastybento has permission: 'bskyblock.island.limit.mumbo.34' but MUMBO is not a valid material or entity type/group. Ignoring...");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnPlayerJoinWithPermLimitsWildcard() {
|
||||
@ -282,11 +301,13 @@ public class JoinListenerTest {
|
||||
when(player.getEffectivePermissions()).thenReturn(perms);
|
||||
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
|
||||
jl.onPlayerJoin(e);
|
||||
verify(addon).logError("Player tastybento has permission: 'bskyblock.island.limit.*' but wildcards are not allowed. Ignoring...");
|
||||
verify(addon).logError(
|
||||
"Player tastybento has permission: 'bskyblock.island.limit.*' but wildcards are not allowed. Ignoring...");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnPlayerJoinWithPermLimitsNotNumber() {
|
||||
@ -298,11 +319,13 @@ public class JoinListenerTest {
|
||||
when(player.getEffectivePermissions()).thenReturn(perms);
|
||||
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
|
||||
jl.onPlayerJoin(e);
|
||||
verify(addon).logError("Player tastybento has permission: 'bskyblock.island.limit.STONE.abc' but the last part MUST be a number! Ignoring...");
|
||||
verify(addon).logError(
|
||||
"Player tastybento has permission: 'bskyblock.island.limit.STONE.abc' but the last part MUST be an integer! Ignoring...");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnPlayerJoinWithPermLimitsSuccess() {
|
||||
@ -319,7 +342,8 @@ public class JoinListenerTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnPlayerJoinWithPermLimitsSuccessEntity() {
|
||||
@ -336,7 +360,8 @@ public class JoinListenerTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnPlayerJoinWithPermLimitsSuccessEntityGroup() {
|
||||
@ -353,7 +378,8 @@ public class JoinListenerTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnPlayerJoinWithPermLimitsMultiPerms() {
|
||||
@ -363,7 +389,7 @@ public class JoinListenerTest {
|
||||
when(permAtt.getValue()).thenReturn(true);
|
||||
perms.add(permAtt);
|
||||
PermissionAttachmentInfo permAtt2 = mock(PermissionAttachmentInfo.class);
|
||||
when(permAtt2.getPermission()).thenReturn("bskyblock.island.limit.grass.14");
|
||||
when(permAtt2.getPermission()).thenReturn("bskyblock.island.limit.short_grass.14");
|
||||
when(permAtt2.getValue()).thenReturn(true);
|
||||
perms.add(permAtt2);
|
||||
PermissionAttachmentInfo permAtt3 = mock(PermissionAttachmentInfo.class);
|
||||
@ -388,7 +414,7 @@ public class JoinListenerTest {
|
||||
jl.onPlayerJoin(e);
|
||||
verify(addon, never()).logError(anyString());
|
||||
verify(ibc).setBlockLimit(eq(Material.STONE), eq(24));
|
||||
verify(ibc).setBlockLimit(eq(Material.GRASS), eq(14));
|
||||
verify(ibc).setBlockLimit(eq(Material.SHORT_GRASS), eq(14));
|
||||
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));
|
||||
@ -455,7 +481,8 @@ public class JoinListenerTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnUnregisterIslandNotUnregistered() {
|
||||
@ -465,7 +492,8 @@ public class JoinListenerTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnUnregisterIslandNotInWorld() {
|
||||
@ -476,7 +504,8 @@ public class JoinListenerTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnUnregisterIslandInWorld() {
|
||||
@ -510,6 +539,4 @@ public class JoinListenerTest {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
363
src/test/java/world/bentobox/limits/LimitsTest.java
Normal file
363
src/test/java/world/bentobox/limits/LimitsTest.java
Normal file
@ -0,0 +1,363 @@
|
||||
package world.bentobox.limits;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.UnsafeValues;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemFactory;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.reflect.Whitebox;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.Settings;
|
||||
import world.bentobox.bentobox.api.addons.AddonDescription;
|
||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.database.DatabaseSetup.DatabaseType;
|
||||
import world.bentobox.bentobox.database.objects.Island;
|
||||
import world.bentobox.bentobox.managers.AddonsManager;
|
||||
import world.bentobox.bentobox.managers.CommandsManager;
|
||||
import world.bentobox.bentobox.managers.FlagsManager;
|
||||
import world.bentobox.bentobox.managers.IslandWorldManager;
|
||||
import world.bentobox.bentobox.managers.IslandsManager;
|
||||
import world.bentobox.bentobox.managers.PlaceholdersManager;
|
||||
|
||||
/**
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({Bukkit.class, BentoBox.class, User.class})
|
||||
public class LimitsTest {
|
||||
private static File jFile;
|
||||
@Mock
|
||||
private User user;
|
||||
@Mock
|
||||
private IslandsManager im;
|
||||
@Mock
|
||||
private Island island;
|
||||
@Mock
|
||||
private BentoBox plugin;
|
||||
@Mock
|
||||
private FlagsManager fm;
|
||||
@Mock
|
||||
private GameModeAddon gameMode;
|
||||
@Mock
|
||||
private AddonsManager am;
|
||||
@Mock
|
||||
private BukkitScheduler scheduler;
|
||||
|
||||
@Mock
|
||||
private Settings pluginSettings;
|
||||
@Mock
|
||||
private PlaceholdersManager phm;
|
||||
@Mock
|
||||
private CompositeCommand cmd;
|
||||
@Mock
|
||||
private CompositeCommand adminCmd;
|
||||
@Mock
|
||||
private World world;
|
||||
private UUID uuid;
|
||||
|
||||
@Mock
|
||||
private PluginManager pim;
|
||||
|
||||
|
||||
private Limits addon;
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
cleanUp();
|
||||
// Make the addon jar
|
||||
jFile = new File("addon.jar");
|
||||
// Copy over config file from src folder
|
||||
Path fromPath = Paths.get("src/main/resources/config.yml");
|
||||
Path path = Paths.get("config.yml");
|
||||
Files.copy(fromPath, path);
|
||||
try (JarOutputStream tempJarOutputStream = new JarOutputStream(new FileOutputStream(jFile))) {
|
||||
//Added the new files to the jar.
|
||||
try (FileInputStream fis = new FileInputStream(path.toFile())) {
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead = 0;
|
||||
JarEntry entry = new JarEntry(path.toString());
|
||||
tempJarOutputStream.putNextEntry(entry);
|
||||
while((bytesRead = fis.read(buffer)) != -1) {
|
||||
tempJarOutputStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// Set up plugin
|
||||
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
|
||||
when(plugin.getLogger()).thenReturn(Logger.getAnonymousLogger());
|
||||
|
||||
// The database type has to be created one line before the thenReturn() to work!
|
||||
DatabaseType value = DatabaseType.JSON;
|
||||
when(plugin.getSettings()).thenReturn(pluginSettings);
|
||||
when(pluginSettings.getDatabaseType()).thenReturn(value);
|
||||
|
||||
//when(plugin.isEnabled()).thenReturn(true);
|
||||
// Command manager
|
||||
CommandsManager cm = mock(CommandsManager.class);
|
||||
when(plugin.getCommandsManager()).thenReturn(cm);
|
||||
|
||||
// Player
|
||||
Player p = mock(Player.class);
|
||||
// Sometimes use Mockito.withSettings().verboseLogging()
|
||||
when(user.isOp()).thenReturn(false);
|
||||
uuid = UUID.randomUUID();
|
||||
when(user.getUniqueId()).thenReturn(uuid);
|
||||
when(user.getPlayer()).thenReturn(p);
|
||||
when(user.getName()).thenReturn("tastybento");
|
||||
User.setPlugin(plugin);
|
||||
|
||||
// Island World Manager
|
||||
IslandWorldManager iwm = mock(IslandWorldManager.class);
|
||||
when(plugin.getIWM()).thenReturn(iwm);
|
||||
|
||||
|
||||
|
||||
// Player has island to begin with
|
||||
when(im.getIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(island);
|
||||
when(plugin.getIslands()).thenReturn(im);
|
||||
|
||||
// Locales
|
||||
// Return the reference (USE THIS IN THE FUTURE)
|
||||
when(user.getTranslation(Mockito.anyString())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
|
||||
|
||||
// Server
|
||||
PowerMockito.mockStatic(Bukkit.class);
|
||||
Server server = mock(Server.class);
|
||||
when(Bukkit.getServer()).thenReturn(server);
|
||||
when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger());
|
||||
when(Bukkit.getPluginManager()).thenReturn(mock(PluginManager.class));
|
||||
|
||||
// Addon
|
||||
addon = new Limits();
|
||||
File dataFolder = new File("addons/Level");
|
||||
addon.setDataFolder(dataFolder);
|
||||
addon.setFile(jFile);
|
||||
AddonDescription desc = new AddonDescription.Builder("bentobox", "Level", "1.3").description("test").authors("tastybento").build();
|
||||
addon.setDescription(desc);
|
||||
|
||||
// Addons manager
|
||||
when(plugin.getAddonsManager()).thenReturn(am);
|
||||
// One game mode
|
||||
when(am.getGameModeAddons()).thenReturn(Collections.singletonList(gameMode));
|
||||
AddonDescription desc2 = new AddonDescription.Builder("bentobox", "BSkyBlock", "1.3").description("test").authors("tasty").build();
|
||||
when(gameMode.getDescription()).thenReturn(desc2);
|
||||
when(gameMode.getOverWorld()).thenReturn(world);
|
||||
|
||||
// Player command
|
||||
@NonNull
|
||||
Optional<CompositeCommand> opCmd = Optional.of(cmd);
|
||||
when(gameMode.getPlayerCommand()).thenReturn(opCmd);
|
||||
// Admin command
|
||||
Optional<CompositeCommand> opAdminCmd = Optional.of(adminCmd);
|
||||
when(gameMode.getAdminCommand()).thenReturn(opAdminCmd);
|
||||
|
||||
// Perm prefix
|
||||
when(gameMode.getPermissionPrefix()).thenReturn("bskyblock.");
|
||||
|
||||
// Flags manager
|
||||
when(plugin.getFlagsManager()).thenReturn(fm);
|
||||
when(fm.getFlags()).thenReturn(Collections.emptyList());
|
||||
|
||||
|
||||
// Bukkit
|
||||
PowerMockito.mockStatic(Bukkit.class);
|
||||
when(Bukkit.getScheduler()).thenReturn(scheduler);
|
||||
ItemMeta meta = mock(ItemMeta.class);
|
||||
ItemFactory itemFactory = mock(ItemFactory.class);
|
||||
when(itemFactory.getItemMeta(any())).thenReturn(meta);
|
||||
when(Bukkit.getItemFactory()).thenReturn(itemFactory);
|
||||
UnsafeValues unsafe = mock(UnsafeValues.class);
|
||||
when(unsafe.getDataVersion()).thenReturn(777);
|
||||
when(Bukkit.getUnsafe()).thenReturn(unsafe);
|
||||
when(Bukkit.getPluginManager()).thenReturn(pim);
|
||||
|
||||
// placeholders
|
||||
when(plugin.getPlaceholdersManager()).thenReturn(phm);
|
||||
|
||||
// World
|
||||
when(world.getName()).thenReturn("bskyblock-world");
|
||||
// Island
|
||||
when(island.getWorld()).thenReturn(world);
|
||||
when(island.getOwner()).thenReturn(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
deleteAll(new File("database"));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void cleanUp() throws Exception {
|
||||
new File("addon.jar").delete();
|
||||
new File("config.yml").delete();
|
||||
deleteAll(new File("addons"));
|
||||
}
|
||||
|
||||
private static void deleteAll(File file) throws IOException {
|
||||
if (file.exists()) {
|
||||
Files.walk(file.toPath())
|
||||
.sorted(Comparator.reverseOrder())
|
||||
.map(Path::toFile)
|
||||
.forEach(File::delete);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.limits.Limits#onEnable()}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnEnable() {
|
||||
addon.onEnable();
|
||||
File f = new File("config.yml");
|
||||
assertTrue(f.exists());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.limits.Limits#onDisable()}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnDisable() {
|
||||
addon.onDisable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.limits.Limits#getSettings()}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetSettings() {
|
||||
assertNull(addon.getSettings());
|
||||
addon.onEnable();
|
||||
world.bentobox.limits.Settings set = addon.getSettings();
|
||||
assertFalse(set.getLimits().isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.limits.Limits#getGameModes()}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetGameModes() {
|
||||
assertTrue(addon.getGameModes().isEmpty());
|
||||
addon.onEnable();
|
||||
assertFalse(addon.getGameModes().isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.limits.Limits#getBlockLimitListener()}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetBlockLimitListener() {
|
||||
assertNull(addon.getBlockLimitListener());
|
||||
addon.onEnable();
|
||||
assertNotNull(addon.getBlockLimitListener());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.limits.Limits#inGameModeWorld(org.bukkit.World)}.
|
||||
*/
|
||||
@Test
|
||||
public void testInGameModeWorld() {
|
||||
addon.onEnable();
|
||||
assertFalse(addon.inGameModeWorld(world));
|
||||
when(gameMode.inWorld(world)).thenReturn(true);
|
||||
assertTrue(addon.inGameModeWorld(world));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.limits.Limits#getGameModeName(org.bukkit.World)}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetGameModeName() {
|
||||
when(gameMode.inWorld(world)).thenReturn(true);
|
||||
assertTrue(addon.getGameModeName(world).isEmpty());
|
||||
addon.onEnable();
|
||||
assertEquals("BSkyBlock", addon.getGameModeName(world));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.limits.Limits#getGameModePermPrefix(org.bukkit.World)}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetGameModePermPrefix() {
|
||||
when(gameMode.inWorld(world)).thenReturn(true);
|
||||
addon.onEnable();
|
||||
assertEquals("bskyblock.", addon.getGameModePermPrefix(world));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.limits.Limits#isCoveredGameMode(java.lang.String)}.
|
||||
*/
|
||||
@Test
|
||||
public void testIsCoveredGameMode() {
|
||||
assertFalse(addon.isCoveredGameMode("BSkyBlock"));
|
||||
addon.onEnable();
|
||||
assertTrue(addon.isCoveredGameMode("BSkyBlock"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.limits.Limits#getJoinListener()}.
|
||||
*/
|
||||
@Test
|
||||
public void testGetJoinListener() {
|
||||
assertNull(addon.getJoinListener());
|
||||
addon.onEnable();
|
||||
assertNotNull(addon.getJoinListener());
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package world.bentobox.limits.commands;
|
||||
package world.bentobox.limits.commands.player;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
@ -19,7 +19,6 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@ -80,15 +79,11 @@ public class EntityLimitListenerTest {
|
||||
collection.add(ent);
|
||||
collection.add(ent);
|
||||
collection.add(ent);
|
||||
when(world.getEntities()).thenReturn(collection);
|
||||
when(world.getNearbyEntities(any())).thenReturn(collection);
|
||||
|
||||
ell = new EntityLimitListener(addon);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for {@link EntityLimitListener#atLimit(Island, Entity)}
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user