diff --git a/pom.xml b/pom.xml
index 3147445..772fa0b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,31 +41,27 @@
-
- codemc-snapshots
- https://repo.codemc.org/repository/maven-snapshots
-
- codemc-releases
- https://repo.codemc.org/repository/maven-releases
+ bentoboxworld
+ https://repo.codemc.org/repository/bentoboxworld/
UTF-8
UTF-8
- 17
+ 21
2.0.9
- 1.21.1-R0.1-SNAPSHOT
- 2.5.1-SNAPSHOT
+ 1.21.3-R0.1-SNAPSHOT
+ 2.7.1-SNAPSHOT
${build.version}-SNAPSHOT
-LOCAL
- 2.7.3
+ 2.8.0
BentoBoxWorld_Boxed
bentobox-world
@@ -119,6 +115,10 @@
spigot-repo
https://hub.spigotmc.org/nexus/content/repositories/snapshots
+
+ bentoboxworld
+ https://repo.codemc.org/repository/bentoboxworld/
+
codemc
https://repo.codemc.org/repository/maven-snapshots/
@@ -185,12 +185,6 @@
${spigot.version}
provided
-
- org.spigotmc.....
- spigot
- 1.21-R0.1-SNAPSHOT
- provided
-
org.spigotmc......
spigot
diff --git a/src/main/java/world/bentobox/boxed/generators/biomes/AbstractCopyBiomeProvider.java b/src/main/java/world/bentobox/boxed/generators/biomes/AbstractCopyBiomeProvider.java
index e7a0167..2742599 100644
--- a/src/main/java/world/bentobox/boxed/generators/biomes/AbstractCopyBiomeProvider.java
+++ b/src/main/java/world/bentobox/boxed/generators/biomes/AbstractCopyBiomeProvider.java
@@ -1,8 +1,8 @@
package world.bentobox.boxed.generators.biomes;
-import java.util.Arrays;
import java.util.List;
+import org.bukkit.Registry;
import org.bukkit.World.Environment;
import org.bukkit.block.Biome;
import org.bukkit.generator.BiomeProvider;
@@ -10,8 +10,6 @@ import org.bukkit.generator.WorldInfo;
import org.bukkit.util.Vector;
import org.eclipse.jdt.annotation.Nullable;
-import com.google.common.base.Enums;
-
import world.bentobox.bentobox.BentoBox;
import world.bentobox.boxed.Boxed;
import world.bentobox.boxed.generators.chunks.AbstractBoxedChunkGenerator;
@@ -56,7 +54,7 @@ public abstract class AbstractCopyBiomeProvider extends BiomeProvider {
@Override
public List getBiomes(WorldInfo worldInfo) {
// Return all of them for now!
- return Arrays.stream(Biome.values()).filter(b -> !b.equals(Biome.CUSTOM)).filter(b -> !b.equals(Enums.getIfPresent(Biome.class, "CHERRY_GROVE").orNull())).toList();
+ return Registry.BIOME.stream().filter(b -> !b.equals(Biome.CUSTOM)).toList();
}
}
diff --git a/src/main/java/world/bentobox/boxed/generators/biomes/AbstractSeedBiomeProvider.java b/src/main/java/world/bentobox/boxed/generators/biomes/AbstractSeedBiomeProvider.java
index ac10713..36d3db9 100644
--- a/src/main/java/world/bentobox/boxed/generators/biomes/AbstractSeedBiomeProvider.java
+++ b/src/main/java/world/bentobox/boxed/generators/biomes/AbstractSeedBiomeProvider.java
@@ -11,6 +11,7 @@ import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
+import org.bukkit.Registry;
import org.bukkit.World.Environment;
import org.bukkit.block.Biome;
import org.bukkit.block.BlockFace;
@@ -21,8 +22,6 @@ import org.bukkit.generator.WorldInfo;
import org.bukkit.util.Vector;
import org.eclipse.jdt.annotation.NonNull;
-import com.google.common.base.Enums;
-
import world.bentobox.boxed.Boxed;
/**
@@ -1129,7 +1128,7 @@ public abstract class AbstractSeedBiomeProvider extends BiomeProvider {
}
public static double convertToY(double x) {
- x = Math.max(-1, Math.min(1, x)); // Clamp value
+ x = Math.clamp(x, -1, 1);
if (x >= -1 && x < -0.5) {
return 2 * x + 1;
} else if (x >= -0.5 && x < 0) {
@@ -1196,7 +1195,7 @@ public abstract class AbstractSeedBiomeProvider extends BiomeProvider {
@Override
public List getBiomes(WorldInfo worldInfo) {
// Return all of them for now!
- return Arrays.stream(Biome.values()).filter(b -> !b.equals(Biome.CUSTOM)).toList();
+ return Registry.BIOME.stream().filter(b -> !b.equals(Biome.CUSTOM)).toList();
}
/**
@@ -1215,7 +1214,7 @@ public abstract class AbstractSeedBiomeProvider extends BiomeProvider {
if (split.length == 2) {
try {
double d = Double.parseDouble(split[0]);
- Biome biome = Enums.getIfPresent(Biome.class, split[1].toUpperCase(Locale.ENGLISH)).orNull();
+ Biome biome = Biome.valueOf(split[1].toUpperCase(Locale.ENGLISH));
if (biome == null) {
addon.logError(split[1].toUpperCase(Locale.ENGLISH) + " is an unknown biome on this server.");
result.put(d, Biome.CUSTOM);
diff --git a/src/main/java/world/bentobox/boxed/nms/v1_21_3_R0_1_SNAPSHOT/GetMetaData.java b/src/main/java/world/bentobox/boxed/nms/v1_21_3_R0_1_SNAPSHOT/GetMetaData.java
new file mode 100644
index 0000000..0cf1131
--- /dev/null
+++ b/src/main/java/world/bentobox/boxed/nms/v1_21_3_R0_1_SNAPSHOT/GetMetaData.java
@@ -0,0 +1,5 @@
+package world.bentobox.boxed.nms.v1_21_3_R0_1_SNAPSHOT;
+
+public class GetMetaData extends world.bentobox.boxed.nms.v1_21_R0_1_SNAPSHOT.GetMetaData {
+ // Identical to 1.21
+}
\ No newline at end of file
diff --git a/src/main/resources/addon.yml b/src/main/resources/addon.yml
index 3b7a42a..d048714 100755
--- a/src/main/resources/addon.yml
+++ b/src/main/resources/addon.yml
@@ -1,7 +1,7 @@
name: Boxed
main: world.bentobox.boxed.Boxed
version: ${version}${build.number}
-api-version: 2.5.1
+api-version: 2.7.1
metrics: true
icon: "COMPOSTER"
repository: "BentoBoxWorld/Boxed"
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index b93c28a..e609dc8 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,7 +1,7 @@
name: BentoBox-Boxed
main: world.bentobox.boxed.BoxedPladdon
version: ${project.version}${build.number}
-api-version: "1.19"
+api-version: "1.21"
authors: [tastybento]
contributors: ["The BentoBoxWorld Community"]
diff --git a/src/test/java/world/bentobox/boxed/listeners/EnderPearlListenerTest.java b/src/test/java/world/bentobox/boxed/listeners/EnderPearlListenerTest.java
index 0522a4f..228def6 100644
--- a/src/test/java/world/bentobox/boxed/listeners/EnderPearlListenerTest.java
+++ b/src/test/java/world/bentobox/boxed/listeners/EnderPearlListenerTest.java
@@ -35,6 +35,7 @@ import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.util.BoundingBox;
import org.bukkit.util.Vector;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -55,6 +56,7 @@ import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.util.Util;
import world.bentobox.boxed.Boxed;
import world.bentobox.boxed.Settings;
+import world.bentobox.boxed.mocks.ServerMocks;
/**
* @author tastybento
@@ -102,7 +104,7 @@ public class EnderPearlListenerTest {
*/
@Before
public void setUp() throws Exception {
-
+ ServerMocks.newServer();
// Set up plugin
plugin = mock(BentoBox.class);
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
@@ -170,6 +172,13 @@ public class EnderPearlListenerTest {
epl = new EnderPearlListener(addon);
}
+ @After
+ public void tearDown() {
+ ServerMocks.unsetBukkitServer();
+ User.clearUsers();
+ Mockito.framework().clearInlineMocks();
+ }
+
/**
* Test method for {@link world.bentobox.boxed.listeners.EnderPearlListener#EnderPearlListener(world.bentobox.boxed.Boxed)}.
*/
diff --git a/src/test/java/world/bentobox/boxed/mocks/ServerMocks.java b/src/test/java/world/bentobox/boxed/mocks/ServerMocks.java
new file mode 100644
index 0000000..a4f2f40
--- /dev/null
+++ b/src/test/java/world/bentobox/boxed/mocks/ServerMocks.java
@@ -0,0 +1,118 @@
+package world.bentobox.boxed.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, Object> registers = new HashMap<>();
+
+ doAnswer(invocationGetRegistry -> registers.computeIfAbsent(invocationGetRegistry.getArgument(0), clazz -> {
+ Registry> registry = mock(Registry.class);
+ Map 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() {
+ }
+
+}
\ No newline at end of file