Merge pull request #228 from BentoBoxWorld/develop

Release 1.26.0
This commit is contained in:
tastybento 2024-11-17 13:49:40 -08:00 committed by GitHub
commit f3c9b4cc44
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 337 additions and 216 deletions

22
pom.xml
View File

@ -39,13 +39,9 @@
</issueManagement>
<distributionManagement>
<snapshotRepository>
<id>codemc-snapshots</id>
<url>https://repo.codemc.org/repository/maven-snapshots</url>
</snapshotRepository>
<repository>
<id>codemc-releases</id>
<url>https://repo.codemc.org/repository/maven-releases</url>
<id>bentoboxworld</id>
<url>https://repo.codemc.org/repository/bentoboxworld/</url>
</repository>
</distributionManagement>
@ -57,14 +53,14 @@
<!-- Non-minecraft related dependencies -->
<powermock.version>2.0.9</powermock.version>
<!-- More visible way how to change dependency versions -->
<spigot.version>1.20.5-R0.1-SNAPSHOT</spigot.version>
<bentobox.version>2.4.1-SNAPSHOT</bentobox.version>
<spigot.version>1.21.3-R0.1-SNAPSHOT</spigot.version>
<bentobox.version>2.7.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.25.0</build.version>
<build.version>1.26.0</build.version>
<sonar.projectKey>BentoBoxWorld_Limits</sonar.projectKey>
<sonar.organization>bentobox-world</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
@ -118,12 +114,12 @@
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots</url>
</repository>
<repository>
<id>codemc</id>
<url>https://repo.codemc.org/repository/maven-snapshots/</url>
<id>bentoboxworld</id>
<url>https://repo.codemc.org/repository/bentoboxworld/</url>
</repository>
<repository>
<id>codemc-repo</id>
<url>https://repo.codemc.org/repository/maven-public/</url>
<id>codemc</id>
<url>https://repo.codemc.org/repository/maven-snapshots/</url>
</repository>
</repositories>

View File

@ -6,6 +6,7 @@ import java.util.List;
import java.util.stream.Collectors;
import org.bukkit.Material;
import org.bukkit.Registry;
import org.bukkit.World;
import org.bukkit.entity.EntityType;
import org.eclipse.jdt.annotation.Nullable;
@ -137,7 +138,7 @@ public class Limits extends Addon {
private void registerPlaceholders(GameModeAddon gm) {
if (getPlugin().getPlaceholdersManager() == null) return;
Arrays.stream(Material.values())
Registry.MATERIAL.stream()
.filter(Material::isBlock)
.forEach(m -> registerCountAndLimitPlaceholders(m, gm));

View File

@ -48,7 +48,7 @@ public class LimitTab implements Tab {
.put(EntityType.IRON_GOLEM, Material.IRON_BLOCK)
.put(EntityType.ILLUSIONER, Material.VILLAGER_SPAWN_EGG)
.put(EntityType.WITHER, Material.WITHER_SKELETON_SKULL)
.put(EntityType.BOAT, Material.OAK_BOAT)
//.put(EntityType.BOAT, Material.OAK_BOAT)
.put(EntityType.ARMOR_STAND, Material.ARMOR_STAND)
.put(EntityType.ITEM_FRAME, Material.ITEM_FRAME)
.put(EntityType.PAINTING, Material.PAINTING)
@ -58,7 +58,7 @@ public class LimitTab implements Tab {
.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)
//.put(EntityType.CHEST_BOAT, Material.OAK_CHEST_BOAT)
.build();
// This is a map of blocks to Items
private static final Map<Material, Material> B2M;

View File

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

View File

@ -21,8 +21,6 @@ admin:
finished: "&a Island recalc finished successfully!"
offset:
unknown: "&c Unknown material or entity [name]."
main:
parameters: ""
description: "allows to manage limits offsets for materials and entities"
set:
parameters: "<player> <material|entity> <number>"

View File

@ -1,7 +1,7 @@
name: BentoBox-Limits
main: world.bentobox.limits.LimitsPladdon
version: ${project.version}${build.number}
api-version: "1.19"
api-version: "1.21"
authors: [tastybento]
contributors: ["The BentoBoxWorld Community"]

View File

@ -1,4 +1,4 @@
package bentobox.addon.limits.listeners;
package world.bentobox.limits;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
@ -26,6 +26,7 @@ import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.PluginManager;
import org.eclipse.jdt.annotation.Nullable;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -41,11 +42,9 @@ 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;
import world.bentobox.limits.listeners.JoinListener;
import world.bentobox.limits.mocks.ServerMocks;
import world.bentobox.limits.objects.IslandBlockCount;
/**
@ -82,6 +81,7 @@ public class JoinListenerTest {
@Before
public void setUp() {
ServerMocks.newServer();
jl = new JoinListener(addon);
// Setup addon
when(addon.getGameModes()).thenReturn(Collections.singletonList(bskyblock));
@ -122,6 +122,11 @@ public class JoinListenerTest {
}
@After
public void tearDown() {
ServerMocks.unsetBukkitServer();
}
/**
* Test method for
* {@link world.bentobox.limits.listeners.JoinListener#onNewIsland(world.bentobox.bentobox.api.events.island.IslandEvent)}.

View File

@ -62,6 +62,7 @@ import world.bentobox.bentobox.managers.FlagsManager;
import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.managers.PlaceholdersManager;
import world.bentobox.limits.mocks.ServerMocks;
/**
* @author tastybento
@ -135,6 +136,7 @@ public class LimitsTest {
*/
@Before
public void setUp() throws Exception {
Server server = ServerMocks.newServer();
// Set up plugin
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
when(plugin.getLogger()).thenReturn(Logger.getAnonymousLogger());
@ -175,7 +177,6 @@ public class LimitsTest {
// 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));
@ -213,7 +214,6 @@ public class LimitsTest {
// Bukkit
PowerMockito.mockStatic(Bukkit.class);
when(Bukkit.getScheduler()).thenReturn(scheduler);
ItemMeta meta = mock(ItemMeta.class);
ItemFactory itemFactory = mock(ItemFactory.class);
@ -239,6 +239,9 @@ public class LimitsTest {
*/
@After
public void tearDown() throws Exception {
ServerMocks.unsetBukkitServer();
User.clearUsers();
Mockito.framework().clearInlineMocks();
deleteAll(new File("database"));
}

View File

@ -0,0 +1,118 @@
package world.bentobox.limits.mocks;
import static org.mockito.ArgumentMatchers.notNull;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.Server;
import org.bukkit.Tag;
import org.bukkit.UnsafeValues;
import org.eclipse.jdt.annotation.NonNull;
public final class ServerMocks {
public static @NonNull Server newServer() {
Server mock = mock(Server.class);
Logger noOp = mock(Logger.class);
when(mock.getLogger()).thenReturn(noOp);
when(mock.isPrimaryThread()).thenReturn(true);
// Unsafe
UnsafeValues unsafe = mock(UnsafeValues.class);
when(mock.getUnsafe()).thenReturn(unsafe);
// Server must be available before tags can be mocked.
Bukkit.setServer(mock);
// Bukkit has a lot of static constants referencing registry values. To initialize those, the
// registries must be able to be fetched before the classes are touched.
Map<Class<? extends Keyed>, Object> registers = new HashMap<>();
doAnswer(invocationGetRegistry -> registers.computeIfAbsent(invocationGetRegistry.getArgument(0), clazz -> {
Registry<?> registry = mock(Registry.class);
Map<NamespacedKey, Keyed> cache = new HashMap<>();
doAnswer(invocationGetEntry -> {
NamespacedKey key = invocationGetEntry.getArgument(0);
// Some classes (like BlockType and ItemType) have extra generics that will be
// erased during runtime calls. To ensure accurate typing, grab the constant's field.
// This approach also allows us to return null for unsupported keys.
Class<? extends Keyed> constantClazz;
try {
//noinspection unchecked
constantClazz = (Class<? extends Keyed>) clazz
.getField(key.getKey().toUpperCase(Locale.ROOT).replace('.', '_')).getType();
} catch (ClassCastException e) {
throw new RuntimeException(e);
} catch (NoSuchFieldException e) {
return null;
}
return cache.computeIfAbsent(key, key1 -> {
Keyed keyed = mock(constantClazz);
doReturn(key).when(keyed).getKey();
return keyed;
});
}).when(registry).get(notNull());
return registry;
})).when(mock).getRegistry(notNull());
// Tags are dependent on registries, but use a different method.
// This will set up blank tags for each constant; all that needs to be done to render them
// functional is to re-mock Tag#getValues.
doAnswer(invocationGetTag -> {
Tag<?> tag = mock(Tag.class);
doReturn(invocationGetTag.getArgument(1)).when(tag).getKey();
doReturn(Set.of()).when(tag).getValues();
doAnswer(invocationIsTagged -> {
Keyed keyed = invocationIsTagged.getArgument(0);
Class<?> type = invocationGetTag.getArgument(2);
if (!type.isAssignableFrom(keyed.getClass())) {
return null;
}
// Since these are mocks, the exact instance might not be equal. Consider equal keys equal.
return tag.getValues().contains(keyed)
|| tag.getValues().stream().anyMatch(value -> value.getKey().equals(keyed.getKey()));
}).when(tag).isTagged(notNull());
return tag;
}).when(mock).getTag(notNull(), notNull(), notNull());
// Once the server is all set up, touch BlockType and ItemType to initialize.
// This prevents issues when trying to access dependent methods from a Material constant.
try {
Class.forName("org.bukkit.inventory.ItemType");
Class.forName("org.bukkit.block.BlockType");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
return mock;
}
public static void unsetBukkitServer() {
try {
Field server = Bukkit.class.getDeclaredField("server");
server.setAccessible(true);
server.set(null, null);
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
private ServerMocks() {
}
}