Merge pull request #177 from BentoBoxWorld/develop

Version 1.19.1
This commit is contained in:
tastybento 2023-04-15 15:48:01 -07:00 committed by GitHub
commit 3e60b7b2eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 1094 additions and 137 deletions

View File

@ -14,10 +14,10 @@ jobs:
- uses: actions/checkout@v2
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 16
- name: Set up JDK 17
uses: actions/setup-java@v1
with:
java-version: 16
java-version: 17
- name: Cache SonarCloud packages
uses: actions/cache@v1
with:

62
pom.xml
View File

@ -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.19.4-R0.1-SNAPSHOT</spigot.version>
<bentobox.version>1.23.0</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.19.1</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>
<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,7 +251,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.3</version>
<version>0.8.7</version>
<configuration>
<append>true</append>
<excludes>
@ -259,19 +262,32 @@
</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>

View File

@ -7,13 +7,14 @@ 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;
@ -138,6 +139,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 +153,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 +166,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 +209,53 @@ public class Limits extends Addon {
if (is == null) {
return LIMIT_NOT_SET;
}
@Nullable IslandBlockCount ibc = getBlockLimitListener().getIsland(is.getUniqueId());
if (ibc == null) {
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);
}

View File

@ -0,0 +1,14 @@
package world.bentobox.limits;
import world.bentobox.bentobox.api.addons.Addon;
import world.bentobox.bentobox.api.addons.Pladdon;
public class LimitsPladdon extends Pladdon {
@Override
public Addon getAddon() {
return new Limits();
}
}

View File

@ -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)

View File

@ -1,4 +1,4 @@
package world.bentobox.limits.commands;
package world.bentobox.limits.commands.admin;
import java.util.ArrayList;
import java.util.List;

View File

@ -0,0 +1,689 @@
//
// Created by BONNe
// Copyright - 2022
//
package world.bentobox.limits.commands.admin;
import com.google.common.base.Enums;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.EntityType;
import org.eclipse.jdt.annotation.Nullable;
import java.util.*;
import java.util.stream.Collectors;
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();
}
}
}

View File

@ -1,4 +1,4 @@
package world.bentobox.limits.commands;
package world.bentobox.limits.commands.player;
import java.util.Map;
import java.util.UUID;

View File

@ -1,4 +1,4 @@
package world.bentobox.limits.commands;
package world.bentobox.limits.commands.player;
import java.util.*;
import java.util.Map.Entry;
@ -103,8 +103,11 @@ 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();
@ -182,7 +185,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",

View File

@ -1,4 +1,4 @@
package world.bentobox.limits.commands;
package world.bentobox.limits.commands.player;
import java.util.List;

View File

@ -1,4 +1,4 @@
package world.bentobox.limits.commands;
package world.bentobox.limits.commands.player;
import java.util.List;

View File

@ -1,14 +1,6 @@
package world.bentobox.limits.listeners;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.*;
import org.bukkit.Bukkit;
import org.bukkit.Material;
@ -23,27 +15,18 @@ import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockBurnEvent;
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.BlockMultiPlaceEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.BlockSpreadEvent;
import org.bukkit.event.block.EntityBlockFormEvent;
import org.bukkit.event.block.LeavesDecayEvent;
import org.bukkit.event.block.*;
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 +190,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 +237,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 +387,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 +422,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 +468,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()));
}
}

View File

@ -16,7 +16,8 @@ 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.Villager;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
@ -30,6 +31,7 @@ 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;
@ -39,6 +41,7 @@ import world.bentobox.bentobox.util.Util;
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;
@ -369,11 +372,16 @@ public class EntityLimitListener implements Listener {
// 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());
@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<Settings.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,28 +390,32 @@ 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()));
}
@ -411,11 +423,16 @@ public class EntityLimitListener implements Listener {
for (Map.Entry<Settings.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();
}

View File

@ -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,9 +17,7 @@ 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;
@ -84,19 +81,25 @@ 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);
}
@ -114,38 +117,46 @@ public class JoinListener implements Listener {
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));
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);
}
}
@ -191,6 +202,13 @@ public class JoinListener implements Listener {
});
}
/**
* 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);

View File

@ -127,7 +127,7 @@ public class IslandBlockCount implements DataObject {
* @return true if count is >= limit
*/
public boolean isAtLimit(Material material, int limit) {
return blockCounts.getOrDefault(material, 0) >= limit;
return blockCounts.getOrDefault(material, 0) >= limit + this.getBlockLimitOffset(material);
}
/**
@ -137,7 +137,7 @@ public class IslandBlockCount implements DataObject {
*/
public boolean isAtLimit(Material m) {
// Check island limits first
return blockLimits.containsKey(m) && blockCounts.getOrDefault(m, 0) >= getBlockLimit(m);
return blockLimits.containsKey(m) && blockCounts.getOrDefault(m, 0) >= getBlockLimit(m) + this.getBlockLimitOffset(m);
}
public boolean isBlockLimited(Material m) {
@ -164,8 +164,17 @@ public class IslandBlockCount implements DataObject {
* @param m - material
* @return limit or -1 for unlimited
*/
public Integer getBlockLimit(Material m) {
return blockLimits.getOrDefault(m, -1) + getBlockLimitsOffset().getOrDefault(m, 0);
public int getBlockLimit(Material m) {
return blockLimits.getOrDefault(m, -1);
}
/**
* Get the block offset for this material for this island
* @param m - material
* @return offset
*/
public int getBlockLimitOffset(Material m) {
return getBlockLimitsOffset().getOrDefault(m, 0);
}
/**
@ -228,7 +237,16 @@ public class IslandBlockCount implements DataObject {
* @return limit or -1 for unlimited
*/
public int getEntityLimit(EntityType t) {
return entityLimits.getOrDefault(t, -1) + getEntityLimitsOffset().getOrDefault(t, 0);
return entityLimits.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);
}
/**
@ -270,7 +288,16 @@ public class IslandBlockCount implements DataObject {
* @return limit or -1 for unlimited
*/
public int getEntityGroupLimit(String name) {
return entityGroupLimits.getOrDefault(name, -1) + getEntityGroupLimitsOffset().getOrDefault(name, 0);
return entityGroupLimits.getOrDefault(name, -1);
}
/**
* Get the offset for an entity group
* @param name - entity group
* @return offset
*/
public int getEntityGroupLimitOffset(String name) {
return getEntityGroupLimitsOffset().getOrDefault(name, 0);
}
/**

View File

@ -5,7 +5,7 @@ api-version: 1.16.5
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

View File

@ -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"

View 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?"

View File

@ -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?"

View File

@ -30,3 +30,6 @@ island:
no-limits: "&c此世界中无限制"
recount:
description: "重新计数岛屿限制"
now-recounting: "&b 开始重新计算. 可能需要一定的时间, 请稍等......"
in-progress: "&c 重新计算岛屿限制中. 请稍等......"
time-out: "&c 重新计算超时. 岛屿太大了吗?"

View 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}

View File

@ -298,7 +298,7 @@ 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...");
}
/**

View File

@ -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;

View File

@ -19,6 +19,7 @@ import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.util.BoundingBox;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@ -80,15 +81,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)}
*/