Compare commits

..

34 Commits

Author SHA1 Message Date
tastybento
eb5ceba4c7 Version 1.24.0 2024-09-22 15:17:30 -07:00
tastybento
902b597b11
Merge pull request #200 from BentoBoxWorld/195_animal_monster_limit
Add default Animal and Monster entity groups to config.yml #195
2024-09-20 21:29:46 -07:00
tastybento
50347bb922 Add default Animal and Monster entity groups to config.yml #195
These were already supported but I also added an icon option.
2024-09-20 19:48:43 -07:00
tastybento
f08c45822d Add NPE protection 2024-09-19 21:54:05 -07:00
tastybento
6b9262efc7 Check user perms not just on login for limits 2024-09-19 21:50:40 -07:00
tastybento
e2670a49e0 Version 1.23.0 2024-09-19 21:50:18 -07:00
tastybento
40fdf283b1 Fix for snowmen 2024-07-17 16:47:34 -07:00
tastybento
6dedd50db5 Fix for Jack O'lantern iron exploit #190 2024-07-17 16:42:27 -07:00
tastybento
19373fa9b3 Added Limits test class 2024-07-17 13:59:45 -07:00
tastybento
674614eb22 Fix tests. Build against 1.20.5 to avoid test issues 2024-07-16 21:57:27 -07:00
tastybento
c0d965daa6 Update to 1.21 2024-07-16 21:52:52 -07:00
tastybento
2ea2c4526e Shift to Minecraft 1.21 2024-07-16 21:51:06 -07:00
tastybento
0db1cfc2b8 Version 1.22.0 2024-07-16 21:50:53 -07:00
tastybento
397e6d281e Version 1.21.1 2024-07-05 17:07:51 -07:00
tastybento
89af2ae996 Return the pladdon that was made. 2024-07-02 09:33:48 -07:00
tastybento
3a42692909 Merge branch 'develop' of https://github.com/BentoBoxWorld/Limits.git into develop 2024-04-04 09:02:53 -07:00
tastybento
894fc1347c Fix test 2024-04-04 09:02:45 -07:00
tastybento
e53f11ea19
Merge pull request #182 from BentoBoxWorld/gitlocalize-28605
Update Spanish locale
2024-04-04 08:55:39 -07:00
tastybento
f408d9c00b Update to use BentoBox 2.3.0 2024-04-04 08:55:12 -07:00
Santos
f9ce3ede64 Translate es.yml via GitLocalize 2024-03-06 08:43:37 +00:00
mt-gitlocalize
2f01344068 Translate es.yml via GitLocalize 2024-03-06 08:43:37 +00:00
BONNe
7da342bec5 Translate es.yml via GitLocalize 2024-03-06 08:43:36 +00:00
Jaimexo
65c7e6e8d0 Translate es.yml via GitLocalize 2024-03-06 08:43:35 +00:00
tastybento
ee577e210a Update to 1.20.4 2024-01-13 08:54:29 -08:00
tastybento
9ffe0c740a Refactor code to enable golem spawning. #180 2024-01-09 17:47:24 +09:00
tastybento
843aa89f6c Version 1.20.1 2024-01-09 12:01:00 +09:00
tastybento
39c630b92a Version 1.20.0
This requires BentoBox 2.0.0 to run.
2023-11-28 16:04:07 -08:00
tastybento
4323a1a53a Update to BentoBox 2.0.0 API
Check for multiple islands when the player joins.
2023-11-28 16:03:11 -08:00
tastybento
2b9b3dacf8 Add NPE protection #178 2023-11-26 08:32:30 -08:00
tastybento
2d92663cd4 BentoBox API 2.0.0 2023-11-12 13:24:15 -08:00
tastybento
a35816cc80
Update pom.xml 2023-07-10 21:40:28 -07:00
tastybento
9763dc1227 Update Jacoco 2023-07-10 21:24:10 -07:00
tastybento
f6b3e3b8db Added distribution required for Github Action 2023-06-24 13:56:29 -07:00
tastybento
5137c24c91 Update Github Build script 2023-06-24 13:46:08 -07:00
19 changed files with 1436 additions and 801 deletions

View File

@ -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 17
uses: actions/setup-java@v1
uses: actions/setup-java@v3
with:
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') }}

10
pom.xml
View File

@ -57,14 +57,14 @@
<!-- Non-minecraft related dependencies -->
<powermock.version>2.0.9</powermock.version>
<!-- More visible way how to change dependency versions -->
<spigot.version>1.19.4-R0.1-SNAPSHOT</spigot.version>
<bentobox.version>1.23.0</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.1</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>
@ -251,13 +251,15 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</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>

View 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 + "]";
}
}

View File

@ -1,14 +1,15 @@
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;
@ -30,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;
@ -109,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("");
@ -209,10 +210,13 @@ public class Limits extends Addon {
if (is == null) {
return LIMIT_NOT_SET;
}
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);
getMaterialLimits(is.getWorld(), is.getUniqueId()).getOrDefault(m, -1);
return limit == -1 ? LIMIT_NOT_SET : String.valueOf(limit);
}

View File

@ -7,8 +7,13 @@ import world.bentobox.bentobox.api.addons.Pladdon;
public class LimitsPladdon extends Pladdon {
private Addon addon;
@Override
public Addon getAddon() {
return new Limits();
if (addon == null) {
addon = new Limits();
}
return addon;
}
}

View File

@ -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
*/

View File

@ -7,13 +7,19 @@
package world.bentobox.limits.commands.admin;
import com.google.common.base.Enums;
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 java.util.*;
import java.util.stream.Collectors;
import com.google.common.base.Enums;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.localization.TextVariables;

View File

@ -1,7 +1,13 @@
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"))));
@ -110,24 +119,10 @@ public class LimitTab implements Tab {
});
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

View File

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

View File

@ -1,6 +1,14 @@
package world.bentobox.limits.listeners;
import java.util.*;
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 org.bukkit.Bukkit;
import org.bukkit.Material;
@ -15,7 +23,19 @@ 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.*;
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.BlockGrowEvent;
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.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.player.PlayerInteractEvent;

View File

@ -17,11 +17,11 @@ import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
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;
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;
@ -38,9 +38,9 @@ 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 {
@ -172,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();
@ -180,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) {
@ -195,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) {
@ -223,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);
@ -246,7 +249,6 @@ public class EntityLimitListener implements Listener {
}
}
}
}
private void detectSnowman(Location l) {
@ -260,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);
@ -371,7 +373,7 @@ 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<>();
Map<EntityGroup, Integer> groupsLimits = new HashMap<>();
@Nullable
IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(island.getUniqueId());
@ -379,7 +381,8 @@ public class EntityLimitListener implements Listener {
// 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<>());
List<EntityGroup> groupdefs = addon.getSettings().getGroupLimits().getOrDefault(ent.getType(),
new ArrayList<>());
groupdefs.forEach(def -> {
int limit = ibc.getEntityGroupLimit(def.getName());
if (limit >= 0)
@ -420,7 +423,7 @@ public class EntityLimitListener implements Listener {
.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()

View File

@ -22,14 +22,15 @@ 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
*
*/
@ -38,132 +39,139 @@ public class JoinListener implements Listener {
private final Limits addon;
public JoinListener(Limits addon) {
this.addon = addon;
this.addon = addon;
}
/**
* Check and set the permissions of the player and how they affect the island limits
* @param player - player
* 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
* @param gameMode - game mode string doing the checking
* @param islandId - island string id
* @param gameMode - game mode string doing the checking
*/
public void checkPerms(Player player, String permissionPrefix, String islandId, String gameMode) {
IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(islandId);
// Check permissions
if (ibc != null) {
// Clear permission limits
ibc.getEntityLimits().clear();
ibc.getEntityGroupLimits().clear();
ibc.getBlockLimits().clear();
}
for (PermissionAttachmentInfo perms : player.getEffectivePermissions()) {
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);
EntityGroup entgroup = addon.getSettings().getGroupLimitDefinitions().stream()
.filter(t -> t.getName().equalsIgnoreCase(split[3])).findFirst().orElse(null);
IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(islandId);
// Check permissions
if (ibc != null) {
// Clear permission limits
ibc.getEntityLimits().clear();
ibc.getEntityGroupLimits().clear();
ibc.getBlockLimits().clear();
}
for (PermissionAttachmentInfo perms : player.getEffectivePermissions()) {
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);
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.");
break;
}
// Make an ibc if required
if (ibc == null) {
ibc = new IslandBlockCount(islandId, gameMode);
}
// Get the value
int value = Integer.parseInt(split[4]);
addon.log("Setting login limit via perm for " + player.getName() + "...");
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.");
break;
}
// Make an ibc if required
if (ibc == null) {
ibc = new IslandBlockCount(islandId, gameMode);
}
// 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()) {
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 any changes have been made then store it - don't make files unless they are needed
if (ibc != null) addon.getBlockLimitListener().setIsland(islandId, ibc);
// Fire perm check event
LimitsPermCheckEvent l = new LimitsPermCheckEvent(player, islandId, ibc, entgroup, et, m, value);
Bukkit.getPluginManager().callEvent(l);
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 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) {
// No wildcards
if (perms.getPermission().contains(permissionPrefix + "*")) {
logError(name, perms.getPermission(), "wildcards are not allowed.");
return true;
}
// 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'");
return true;
}
// Check value
try {
Integer.parseInt(split[4]);
} catch(Exception e) {
logError(name, perms.getPermission(), "the last part MUST be an integer!");
return true;
}
return false;
// No wildcards
if (perms.getPermission().contains(permissionPrefix + "*")) {
logError(name, perms.getPermission(), "wildcards are not allowed.");
return true;
}
// 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'");
return true;
}
// Check value
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(@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
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
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) {
// 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, 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, v);
}
}
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
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
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) {
// 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, 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, v);
}
}
}
private void logError(String name, String perm, String error) {
addon.logError("Player " + name + " has permission: '" + perm + "' but " + error + " Ignoring...");
addon.logError("Player " + name + " has permission: '" + perm + "' but " + error + " Ignoring...");
}
/*
@ -172,66 +180,66 @@ 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)
&& !e.getReason().equals(Reason.REGISTERED)) {
return;
}
setOwnerPerms(e.getIsland(), e.getOwner());
if (!e.getReason().equals(Reason.CREATED) && !e.getReason().equals(Reason.RESETTED)
&& !e.getReason().equals(Reason.REGISTERED)) {
return;
}
setOwnerPerms(e.getIsland(), e.getOwner());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onOwnerChange(TeamSetownerEvent e) {
removeOwnerPerms(e.getIsland());
setOwnerPerms(e.getIsland(), e.getNewOwner());
removeOwnerPerms(e.getIsland());
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();
IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(islandId);
if (joinEventCheck(e.getPlayer(), islandId, ibc)) {
return;
}
checkPerms(e.getPlayer(), gm.getPermissionPrefix() + "island.limit.", islandId, gm.getDescription().getName());
}
});
// Check if player has any islands in the game modes
addon.getGameModes().forEach(gm -> {
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)) {
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 player player
* @param islandId island id
* @param ibc island block count
* @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);
Bukkit.getPluginManager().callEvent(e);
if (e.isCancelled()) {
return true;
}
// 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 (e.isIgnorePerms() && ibc != null) {
addon.getBlockLimitListener().setIsland(islandId, ibc);
return true;
}
return false;
// Fire event, so other addons can cancel this permissions change
LimitsJoinPermCheckEvent e = new LimitsJoinPermCheckEvent(player, islandId, ibc);
Bukkit.getPluginManager().callEvent(e);
if (e.isCancelled()) {
return true;
}
// 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 (e.isIgnorePerms() && ibc != null) {
addon.getBlockLimitListener().setIsland(islandId, ibc);
return true;
}
return false;
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onUnregisterIsland(IslandEvent e) {
if (!e.getReason().equals(Reason.UNREGISTERED)) {
return;
}
removeOwnerPerms(e.getIsland());
if (!e.getReason().equals(Reason.UNREGISTERED)) {
return;
}
removeOwnerPerms(e.getIsland());
}
/*
@ -239,29 +247,30 @@ public class JoinListener implements Listener {
*/
private void removeOwnerPerms(Island island) {
World world = island.getWorld();
if (addon.inGameModeWorld(world)) {
IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(island.getUniqueId());
if (ibc != null) {
ibc.getBlockLimits().clear();
}
}
World world = island.getWorld();
if (addon.inGameModeWorld(world)) {
IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(island.getUniqueId());
if (ibc != null) {
ibc.getBlockLimits().clear();
}
}
}
private void setOwnerPerms(Island island, UUID ownerUUID) {
World world = island.getWorld();
if (addon.inGameModeWorld(world)) {
// Check if owner is online
OfflinePlayer owner = Bukkit.getOfflinePlayer(ownerUUID);
if (owner.isOnline()) {
// Set perm-based limits
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);
}
}
}
World world = island.getWorld();
if (addon.inGameModeWorld(world)) {
// Check if owner is online
OfflinePlayer owner = Bukkit.getOfflinePlayer(ownerUUID);
if (owner.isOnline()) {
// Set perm-based limits
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);
}
}
}
}
}

View File

@ -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,370 +20,398 @@ 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()
*/
public IslandBlockCount(String islandId, String gameMode) {
this.uniqueId = islandId;
this.gameMode = gameMode;
setChanged();
}
/* (non-Javadoc)
* @see world.bentobox.bentobox.database.objects.DataObject#getUniqueId()
*/
@Override
public String getUniqueId() {
return uniqueId;
}
/* (non-Javadoc)
* @see world.bentobox.bentobox.database.objects.DataObject#setUniqueId(java.lang.String)
*/
@Override
public void setUniqueId(String uniqueId) {
this.uniqueId = uniqueId;
setChanged();
}
/**
* @return the blockCount
*/
public Map<Material, Integer> getBlockCounts() {
if (blockCounts == null) {
blockCounts = new EnumMap<>(Material.class);
}
return blockCounts;
}
/**
* @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
* @param m - material
* @return count
*/
public Integer getBlockCount(Material m) {
return blockCounts.getOrDefault(m, 0);
this.uniqueId = islandId;
this.gameMode = gameMode;
setChanged();
}
/**
* 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 + this.getBlockLimitOffset(material);
}
/**
* 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 blockLimits.containsKey(m) && blockCounts.getOrDefault(m, 0) >= getBlockLimit(m) + this.getBlockLimitOffset(m);
}
public boolean isBlockLimited(Material m) {
return blockLimits.containsKey(m);
}
/**
* @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 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);
}
/**
* 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);
}
/**
* Get the limit offset for an entity type
* @param t - entity type
* @return offset
*/
public int getEntityLimitOffset(EntityType t) {
return 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);
}
/**
* Get the offset for an entity group
* @param name - entity group
* @return offset
*/
public int getEntityGroupLimitOffset(String name) {
return getEntityGroupLimitsOffset().getOrDefault(name, 0);
getBlockCounts().merge(material, 1, Integer::sum);
setChanged();
}
/**
* Clear all island-specific entity group limits
*/
public void clearEntityGroupLimits() {
entityGroupLimits.clear();
setChanged();
entityGroupLimits.clear();
setChanged();
}
/**
* @return the changed
* Clear all island-specific entity type limits
*/
public boolean isChanged() {
return changed;
public void clearEntityLimits() {
entityLimits.clear();
setChanged();
}
/**
* @param changed the changed to set
* Get the block count for this material for this island
*
* @param m - material
* @return count
*/
public void setChanged(boolean changed) {
this.changed = changed;
public Integer getBlockCount(Material m) {
return getBlockCounts().getOrDefault(m, 0);
}
/**
* Mark changed
* @return the blockCount
*/
public void setChanged() {
this.changed = true;
public Map<Material, Integer> getBlockCounts() {
if (blockCounts == null) {
blockCounts = new EnumMap<>(Material.class);
}
return blockCounts;
}
/**
* Get the block limit for this material for this island
*
* @param m - material
* @return limit or -1 for unlimited
*/
public int getBlockLimit(Material m) {
return getBlockLimits().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);
}
/**
* @return the blockLimits
*/
public Map<Material, Integer> getBlockLimits() {
return Objects.requireNonNullElse(blockLimits, new EnumMap<>(Material.class));
}
/**
* @return the blockLimitsOffset
*/
public Map<Material, Integer> getBlockLimitsOffset() {
if (blockLimitsOffset == null) {
blockLimitsOffset = new EnumMap<>(Material.class);
}
return blockLimitsOffset;
if (blockLimitsOffset == null) {
blockLimitsOffset = new EnumMap<>(Material.class);
}
return blockLimitsOffset;
}
/**
* Set an offset to a block limit. This will increase/decrease the value of the limit.
* @param m material
* @param blockLimitsOffset the blockLimitsOffset to set
* 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<>());
}
/**
* @return the entityGroupLimitsOffset
*/
public Map<String, Integer> getEntityGroupLimitsOffset() {
if (entityGroupLimitsOffset == null) {
entityGroupLimitsOffset = new HashMap<>();
}
return entityGroupLimitsOffset;
if (entityGroupLimitsOffset == null) {
entityGroupLimitsOffset = new HashMap<>();
}
return entityGroupLimitsOffset;
}
/**
* Set an offset to an entity group limit. This will increase/decrease the value of the limit.
* @param name group name
* 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);
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();
}
}

View File

@ -1,7 +1,7 @@
name: Limits
main: world.bentobox.limits.Limits
version: ${version}${build.number}
api-version: 1.16.5
api-version: 2.3.0
authors: tastybento

View File

@ -40,4 +40,91 @@ worlds:
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

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

View File

@ -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
@ -73,74 +80,78 @@ public class JoinListenerTest {
@Before
public void setUp() {
jl = new JoinListener(addon);
// Setup addon
when(addon.getGameModes()).thenReturn(Collections.singletonList(bskyblock));
when(addon.getGameModeName(any())).thenReturn("bskyblock");
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))));
// 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);
// Default is that player has island
when(addon.getIslands()).thenReturn(im);
// Player
when(player.getUniqueId()).thenReturn(UUID.randomUUID());
when(player.getName()).thenReturn("tastybento");
// No permissions by default
when(player.getEffectivePermissions()).thenReturn(Collections.emptySet());
// bsKyBlock
when(bskyblock.getPermissionPrefix()).thenReturn("bskyblock.");
AddonDescription desc = new AddonDescription.Builder("main", "BSkyBlock", "1.0").build();
when(bskyblock.getDescription()).thenReturn(desc);
jl = new JoinListener(addon);
// Setup addon
when(addon.getGameModes()).thenReturn(Collections.singletonList(bskyblock));
when(addon.getGameModeName(any())).thenReturn("bskyblock");
when(addon.getGameModePermPrefix(any())).thenReturn("bskyblock.");
when(addon.getSettings()).thenReturn(settings);
// Settings
when(settings.getGroupLimitDefinitions())
.thenReturn(new ArrayList<>(List.of(new EntityGroup("friendly", new HashSet<>(), -1, null))));
// Island Manager
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
when(player.getUniqueId()).thenReturn(UUID.randomUUID());
when(player.getName()).thenReturn("tastybento");
// No permissions by default
when(player.getEffectivePermissions()).thenReturn(Collections.emptySet());
// bsKyBlock
when(bskyblock.getPermissionPrefix()).thenReturn("bskyblock.");
AddonDescription desc = new AddonDescription.Builder("main", "BSkyBlock", "1.0").build();
when(bskyblock.getDescription()).thenReturn(desc);
// Block limit listener
when(addon.getBlockLimitListener()).thenReturn(bll);
when(bll.getIsland(anyString())).thenReturn(ibc);
// Block limit listener
when(addon.getBlockLimitListener()).thenReturn(bll);
when(bll.getIsland(anyString())).thenReturn(ibc);
// bukkit
PowerMockito.mockStatic(Bukkit.class);
// default is that owner is online
when(owner.isOnline()).thenReturn(true);
when(owner.getPlayer()).thenReturn(player);
when(Bukkit.getOfflinePlayer(any(UUID.class))).thenReturn(owner);
when(Bukkit.getPluginManager()).thenReturn(pim);
// bukkit
PowerMockito.mockStatic(Bukkit.class);
// default is that owner is online
when(owner.isOnline()).thenReturn(true);
when(owner.getPlayer()).thenReturn(player);
when(Bukkit.getOfflinePlayer(any(UUID.class))).thenReturn(owner);
when(Bukkit.getPluginManager()).thenReturn(pim);
// Island
when(island.getOwner()).thenReturn(UUID.randomUUID());
// Island
when(island.getOwner()).thenReturn(UUID.randomUUID());
}
/**
* 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() {
IslandEvent e = new IslandEvent(island, null, false, null, IslandEvent.Reason.BAN);
jl.onNewIsland(e);
verify(island, never()).getWorld();
IslandEvent e = new IslandEvent(island, null, false, null, IslandEvent.Reason.BAN);
jl.onNewIsland(e);
verify(island, never()).getWorld();
}
/**
* 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() {
IslandEvent e = new IslandEvent(island, null, false, null, IslandEvent.Reason.REGISTERED);
jl.onNewIsland(e);
verify(island).getWorld();
IslandEvent e = new IslandEvent(island, null, false, null, IslandEvent.Reason.REGISTERED);
jl.onNewIsland(e);
verify(island).getWorld();
}
/**
* 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() {
IslandEvent e = new IslandEvent(island, null, false, null, IslandEvent.Reason.RESETTED);
jl.onNewIsland(e);
verify(island).getWorld();
IslandEvent e = new IslandEvent(island, null, false, null, IslandEvent.Reason.RESETTED);
jl.onNewIsland(e);
verify(island).getWorld();
}
/**
@ -185,213 +196,228 @@ 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() {
TeamSetownerEvent e = mock(TeamSetownerEvent.class);
when(e.getIsland()).thenReturn(island);
when(e.getNewOwner()).thenReturn(UUID.randomUUID());
jl.onOwnerChange(e);
verify(e, Mockito.times(2)).getIsland();
verify(e).getNewOwner();
TeamSetownerEvent e = mock(TeamSetownerEvent.class);
when(e.getIsland()).thenReturn(island);
when(e.getNewOwner()).thenReturn(UUID.randomUUID());
jl.onOwnerChange(e);
verify(e, Mockito.times(2)).getIsland();
verify(e).getNewOwner();
}
/**
* 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() {
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
jl.onPlayerJoin(e);
verify(addon).getGameModes();
verify(bll).setIsland("unique_id", ibc);
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
jl.onPlayerJoin(e);
verify(addon).getGameModes();
verify(bll).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 testOnPlayerJoinIBCNull() {
ibc = null;
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
jl.onPlayerJoin(e);
verify(addon).getGameModes();
verify(bll, never()).setIsland("unique_id", ibc);
ibc = null;
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
jl.onPlayerJoin(e);
verify(addon).getGameModes();
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() {
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.my.perm.for.game");
perms.add(permAtt);
when(player.getEffectivePermissions()).thenReturn(perms);
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
jl.onPlayerJoin(e);
verify(addon).getGameModes();
verify(bll).setIsland("unique_id", ibc);
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.my.perm.for.game");
perms.add(permAtt);
when(player.getEffectivePermissions()).thenReturn(perms);
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
jl.onPlayerJoin(e);
verify(addon).getGameModes();
verify(bll).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 testOnPlayerJoinWithPermLimitsWrongSize() {
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.my.perm.for.game");
when(permAtt.getValue()).thenReturn(true);
perms.add(permAtt);
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...");
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.my.perm.for.game");
when(permAtt.getValue()).thenReturn(true);
perms.add(permAtt);
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...");
}
/**
* 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() {
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.mumbo.34");
when(permAtt.getValue()).thenReturn(true);
perms.add(permAtt);
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...");
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.mumbo.34");
when(permAtt.getValue()).thenReturn(true);
perms.add(permAtt);
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...");
}
/**
* 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() {
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.*");
when(permAtt.getValue()).thenReturn(true);
perms.add(permAtt);
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...");
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.*");
when(permAtt.getValue()).thenReturn(true);
perms.add(permAtt);
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...");
}
/**
* 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() {
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.STONE.abc");
when(permAtt.getValue()).thenReturn(true);
perms.add(permAtt);
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 an integer! Ignoring...");
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.STONE.abc");
when(permAtt.getValue()).thenReturn(true);
perms.add(permAtt);
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 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() {
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.STONE.24");
when(permAtt.getValue()).thenReturn(true);
perms.add(permAtt);
when(player.getEffectivePermissions()).thenReturn(perms);
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
jl.onPlayerJoin(e);
verify(addon, never()).logError(anyString());
verify(ibc).setBlockLimit(eq(Material.STONE), eq(24));
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.STONE.24");
when(permAtt.getValue()).thenReturn(true);
perms.add(permAtt);
when(player.getEffectivePermissions()).thenReturn(perms);
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
jl.onPlayerJoin(e);
verify(addon, never()).logError(anyString());
verify(ibc).setBlockLimit(eq(Material.STONE), eq(24));
}
/**
* 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() {
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.BAT.24");
when(permAtt.getValue()).thenReturn(true);
perms.add(permAtt);
when(player.getEffectivePermissions()).thenReturn(perms);
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
jl.onPlayerJoin(e);
verify(addon, never()).logError(anyString());
verify(ibc).setEntityLimit(eq(EntityType.BAT), eq(24));
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.BAT.24");
when(permAtt.getValue()).thenReturn(true);
perms.add(permAtt);
when(player.getEffectivePermissions()).thenReturn(perms);
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
jl.onPlayerJoin(e);
verify(addon, never()).logError(anyString());
verify(ibc).setEntityLimit(eq(EntityType.BAT), eq(24));
}
/**
* 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() {
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.friendly.24");
when(permAtt.getValue()).thenReturn(true);
perms.add(permAtt);
when(player.getEffectivePermissions()).thenReturn(perms);
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
jl.onPlayerJoin(e);
verify(addon, never()).logError(anyString());
verify(ibc).setEntityGroupLimit(eq("friendly"), eq(24));
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.friendly.24");
when(permAtt.getValue()).thenReturn(true);
perms.add(permAtt);
when(player.getEffectivePermissions()).thenReturn(perms);
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
jl.onPlayerJoin(e);
verify(addon, never()).logError(anyString());
verify(ibc).setEntityGroupLimit(eq("friendly"), eq(24));
}
/**
* 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() {
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.STONE.24");
when(permAtt.getValue()).thenReturn(true);
perms.add(permAtt);
PermissionAttachmentInfo permAtt2 = mock(PermissionAttachmentInfo.class);
when(permAtt2.getPermission()).thenReturn("bskyblock.island.limit.grass.14");
when(permAtt2.getValue()).thenReturn(true);
perms.add(permAtt2);
PermissionAttachmentInfo permAtt3 = mock(PermissionAttachmentInfo.class);
when(permAtt3.getPermission()).thenReturn("bskyblock.island.limit.dirt.34");
when(permAtt3.getValue()).thenReturn(true);
perms.add(permAtt3);
PermissionAttachmentInfo permAtt4 = mock(PermissionAttachmentInfo.class);
when(permAtt4.getPermission()).thenReturn("bskyblock.island.limit.chicken.34");
when(permAtt4.getValue()).thenReturn(true);
perms.add(permAtt4);
PermissionAttachmentInfo permAtt5 = mock(PermissionAttachmentInfo.class);
when(permAtt5.getPermission()).thenReturn("bskyblock.island.limit.cave_spider.4");
when(permAtt5.getValue()).thenReturn(true);
perms.add(permAtt5);
PermissionAttachmentInfo permAtt6 = mock(PermissionAttachmentInfo.class);
when(permAtt6.getPermission()).thenReturn("bskyblock.island.limit.cave_spider.4");
when(permAtt6.getValue()).thenReturn(false); // negative perm
perms.add(permAtt6);
Set<PermissionAttachmentInfo> perms = new HashSet<>();
PermissionAttachmentInfo permAtt = mock(PermissionAttachmentInfo.class);
when(permAtt.getPermission()).thenReturn("bskyblock.island.limit.STONE.24");
when(permAtt.getValue()).thenReturn(true);
perms.add(permAtt);
PermissionAttachmentInfo permAtt2 = mock(PermissionAttachmentInfo.class);
when(permAtt2.getPermission()).thenReturn("bskyblock.island.limit.short_grass.14");
when(permAtt2.getValue()).thenReturn(true);
perms.add(permAtt2);
PermissionAttachmentInfo permAtt3 = mock(PermissionAttachmentInfo.class);
when(permAtt3.getPermission()).thenReturn("bskyblock.island.limit.dirt.34");
when(permAtt3.getValue()).thenReturn(true);
perms.add(permAtt3);
PermissionAttachmentInfo permAtt4 = mock(PermissionAttachmentInfo.class);
when(permAtt4.getPermission()).thenReturn("bskyblock.island.limit.chicken.34");
when(permAtt4.getValue()).thenReturn(true);
perms.add(permAtt4);
PermissionAttachmentInfo permAtt5 = mock(PermissionAttachmentInfo.class);
when(permAtt5.getPermission()).thenReturn("bskyblock.island.limit.cave_spider.4");
when(permAtt5.getValue()).thenReturn(true);
perms.add(permAtt5);
PermissionAttachmentInfo permAtt6 = mock(PermissionAttachmentInfo.class);
when(permAtt6.getPermission()).thenReturn("bskyblock.island.limit.cave_spider.4");
when(permAtt6.getValue()).thenReturn(false); // negative perm
perms.add(permAtt6);
when(player.getEffectivePermissions()).thenReturn(perms);
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
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.DIRT), eq(34));
verify(ibc).setEntityLimit(eq(EntityType.CHICKEN), eq(34));
verify(ibc).setEntityLimit(eq(EntityType.CAVE_SPIDER), eq(4));
when(player.getEffectivePermissions()).thenReturn(perms);
PlayerJoinEvent e = new PlayerJoinEvent(player, "welcome");
jl.onPlayerJoin(e);
verify(addon, never()).logError(anyString());
verify(ibc).setBlockLimit(eq(Material.STONE), eq(24));
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,40 +481,43 @@ 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() {
IslandEvent e = new IslandEvent(island, null, false, null, IslandEvent.Reason.BAN);
jl.onUnregisterIsland(e);
verify(island, never()).getWorld();
IslandEvent e = new IslandEvent(island, null, false, null, IslandEvent.Reason.BAN);
jl.onUnregisterIsland(e);
verify(island, never()).getWorld();
}
/**
* 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() {
IslandEvent e = new IslandEvent(island, null, false, null, IslandEvent.Reason.UNREGISTERED);
jl.onUnregisterIsland(e);
verify(island).getWorld();
verify(addon, never()).getBlockLimitListener();
IslandEvent e = new IslandEvent(island, null, false, null, IslandEvent.Reason.UNREGISTERED);
jl.onUnregisterIsland(e);
verify(island).getWorld();
verify(addon, never()).getBlockLimitListener();
}
/**
* 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() {
@SuppressWarnings("unchecked")
Map<Material, Integer> map = mock(Map.class);
when(ibc.getBlockLimits()).thenReturn(map);
when(addon.inGameModeWorld(any())).thenReturn(true);
IslandEvent e = new IslandEvent(island, null, false, null, IslandEvent.Reason.UNREGISTERED);
jl.onUnregisterIsland(e);
verify(island).getWorld();
verify(addon).getBlockLimitListener();
verify(map).clear();
@SuppressWarnings("unchecked")
Map<Material, Integer> map = mock(Map.class);
when(ibc.getBlockLimits()).thenReturn(map);
when(addon.inGameModeWorld(any())).thenReturn(true);
IslandEvent e = new IslandEvent(island, null, false, null, IslandEvent.Reason.UNREGISTERED);
jl.onUnregisterIsland(e);
verify(island).getWorld();
verify(addon).getBlockLimitListener();
verify(map).clear();
}
@ -510,6 +539,4 @@ public class JoinListenerTest {
}
}

View 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());
}
}

View File

@ -19,8 +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.bukkit.util.BoundingBox;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;