From 9612a2f9428eea6321af5a6b48bcabc9efd6fb72 Mon Sep 17 00:00:00 2001 From: Intisy Date: Sat, 28 Feb 2026 00:58:52 +0100 Subject: [PATCH 1/8] Add support for newer versions and upgrade to Java 21 --- pom.xml | 29 +- .../slimefun4/api/MinecraftVersion.java | 10 +- .../slimefun4/api/items/ItemGroup.java | 5 +- .../api/items/SlimefunItemStack.java | 8 +- .../core/services/github/GitHubTask.java | 15 +- .../localization/SlimefunLocalization.java | 6 +- .../implementation/SlimefunItems.java | 6 +- .../guide/SurvivalSlimefunGuide.java | 3 +- .../items/androids/ProgrammableAndroid.java | 6 +- .../items/androids/WoodcutterAndroid.java | 13 + .../items/electric/machines/AutoBrewer.java | 2 +- .../implementation/items/medical/Bandage.java | 4 +- .../items/medical/MedicalSupply.java | 4 +- .../implementation/items/medical/Splint.java | 4 +- .../items/weapons/VampireBlade.java | 4 +- .../listeners/DebugFishListener.java | 4 +- .../tasks/CapacitorTextureUpdateTask.java | 6 +- .../slimefun4/utils/ChestMenuUtils.java | 6 +- .../slimefun4/utils/HeadTexture.java | 11 +- .../slimefun4/utils/SlimefunUtils.java | 6 +- .../compatibility/VersionedAttribute.java | 35 +++ .../compatibility/VersionedItemFlag.java | 40 ++- .../compatibility/VersionedPlayerHead.java | 251 ++++++++++++++++++ .../slimefun4/utils/TestMinecraftVersion.java | 21 ++ .../biomes/TestBiomeMapCompatibility.java | 12 +- src/test/resources/biomes/1.21.4+.json | 68 +++++ 26 files changed, 503 insertions(+), 76 deletions(-) create mode 100644 src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedAttribute.java create mode 100644 src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedPlayerHead.java create mode 100644 src/test/resources/biomes/1.21.4+.json diff --git a/pom.xml b/pom.xml index 65280d4459..da00fdc186 100644 --- a/pom.xml +++ b/pom.xml @@ -21,15 +21,14 @@ UTF-8 - - 16 - 16 - + + 21 + 21 21 21 - 1.21.1 + 1.21.4 https://hub.spigotmc.org/javadocs/spigot/ @@ -221,6 +220,14 @@ META-INF/* + + + com.github.Slimefun.dough:dough-api + + io/github/bakedlibs/dough/skins/** + + @@ -355,12 +362,6 @@ - - com.github.Slimefun.dough - dough-api - cb22e71335 - compile - com.github.Slimefun.dough dough-api @@ -402,9 +403,9 @@ - com.github.seeseemelk - MockBukkit-v1.21 - 3.133.2 + com.github.MockBukkit + MockBukkit + v4.106.1 test diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/MinecraftVersion.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/MinecraftVersion.java index afad06e3bc..4aded0899f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/MinecraftVersion.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/MinecraftVersion.java @@ -58,8 +58,16 @@ public enum MinecraftVersion { /** * This constant represents Minecraft (Java Edition) Version 1.21 * ("Tricky Trials") + * This covers versions 1.21.0 through 1.21.3 */ - MINECRAFT_1_21(21, 0, "1.21.x"), + MINECRAFT_1_21(21, 0, 3, "1.21.x"), + + /** + * This constant represents Minecraft (Java Edition) Version 1.21.4+ + * ("The Garden Awakens" and later drops including "Spring to Life", + * "The Copper Age", and "Mounts of Mayhem") + */ + MINECRAFT_1_21_4(21, 4, "1.21.4+"), /** * This constant represents an exceptional state in which we were unable diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemGroup.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemGroup.java index 8524c6a7e7..8bcad0718b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemGroup.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemGroup.java @@ -15,7 +15,6 @@ import org.bukkit.Keyed; import org.bukkit.NamespacedKey; import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -84,9 +83,7 @@ public ItemGroup(NamespacedKey key, ItemStack item, int tier) { this.key = key; ItemMeta meta = item.getItemMeta(); - meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); - meta.addItemFlags(ItemFlag.HIDE_ENCHANTS); - meta.addItemFlags(VersionedItemFlag.HIDE_ADDITIONAL_TOOLTIP); + VersionedItemFlag.addFlags(meta, VersionedItemFlag.HIDE_ATTRIBUTES, VersionedItemFlag.HIDE_ENCHANTS, VersionedItemFlag.HIDE_ADDITIONAL_TOOLTIP); this.item.setItemMeta(meta); this.tier = tier; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/SlimefunItemStack.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/SlimefunItemStack.java index 8a427b249f..dfe519fa96 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/SlimefunItemStack.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/SlimefunItemStack.java @@ -38,8 +38,7 @@ import io.github.bakedlibs.dough.common.CommonPatterns; import io.github.bakedlibs.dough.items.ItemMetaSnapshot; -import io.github.bakedlibs.dough.skins.PlayerHead; -import io.github.bakedlibs.dough.skins.PlayerSkin; +import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPlayerHead; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.api.exceptions.PrematureCodeException; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; @@ -172,7 +171,7 @@ public SlimefunItemStack(@Nonnull String id, @Nonnull Color color, @Nonnull Poti potionMeta.addCustomEffect(effect, true); if (effect.getType().equals(PotionEffectType.SATURATION)) { - im.addItemFlags(VersionedItemFlag.HIDE_ADDITIONAL_TOOLTIP); + VersionedItemFlag.addFlags(im, VersionedItemFlag.HIDE_ADDITIONAL_TOOLTIP); } } }); @@ -284,8 +283,7 @@ public void setAmount(int amount) { return new ItemStack(Material.PLAYER_HEAD); } - PlayerSkin skin = PlayerSkin.fromBase64(getTexture(id, texture)); - return PlayerHead.getItemStack(skin); + return VersionedPlayerHead.getItemStack(getTexture(id, texture)); } private static @Nonnull String getTexture(@Nonnull String id, @Nonnull String texture) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubTask.java index 8b065e3ff4..0b3e4f4a17 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubTask.java @@ -16,8 +16,7 @@ import org.bukkit.Bukkit; -import io.github.bakedlibs.dough.skins.PlayerSkin; -import io.github.bakedlibs.dough.skins.UUIDLookup; +import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPlayerHead; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; /** @@ -133,7 +132,7 @@ private int requestTexture(@Nonnull Contributor contributor, @Nonnull Map uuid = contributor.getUniqueId(); if (!uuid.isPresent()) { - CompletableFuture future = UUIDLookup.getUuidFromUsername(Slimefun.instance(), contributor.getMinecraftName()); + CompletableFuture future = VersionedPlayerHead.lookupUUID(contributor.getMinecraftName()); // Fixes #3241 - Do not wait for more than 30 seconds uuid = Optional.ofNullable(future.get(30, TimeUnit.SECONDS)); @@ -141,10 +140,12 @@ private int requestTexture(@Nonnull Contributor contributor, @Nonnull Map future = PlayerSkin.fromPlayerUUID(Slimefun.instance(), uuid.get()); - Optional skin = Optional.of(future.get().getProfile().getBase64Texture()); - skins.put(contributor.getMinecraftName(), skin.orElse("")); - return skin.orElse(null); + CompletableFuture future = VersionedPlayerHead.fetchSkinTexture(uuid.get()); + String texture = future.get(30, TimeUnit.SECONDS); + if (texture != null) { + skins.put(contributor.getMinecraftName(), texture); + } + return texture; } else { return null; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SlimefunLocalization.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SlimefunLocalization.java index a146a9f620..4984aab7e4 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SlimefunLocalization.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SlimefunLocalization.java @@ -20,13 +20,13 @@ import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import io.github.bakedlibs.dough.common.ChatColors; import io.github.bakedlibs.dough.config.Config; import io.github.bakedlibs.dough.items.CustomItemStack; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; +import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedItemFlag; import io.github.thebusybiscuit.slimefun4.api.SlimefunBranch; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.core.services.LocalizationService; @@ -337,8 +337,8 @@ protected void loadEmbeddedLanguages() { meta.setLore(lore); } - meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); - meta.addItemFlags(ItemFlag.HIDE_ENCHANTS); + VersionedItemFlag.addFlags(meta, VersionedItemFlag.HIDE_ATTRIBUTES); + VersionedItemFlag.addFlags(meta, VersionedItemFlag.HIDE_ENCHANTS); }); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java index 62bc4d59e9..5d647c3f69 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java @@ -9,7 +9,6 @@ import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; -import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; @@ -23,6 +22,7 @@ import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; import io.github.thebusybiscuit.slimefun4.utils.LoreBuilder; import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedEnchantment; +import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedItemFlag; import io.github.thebusybiscuit.slimefun4.utils.itemstack.ColoredFireworkStar; /** @@ -594,11 +594,11 @@ private SlimefunItems() {} static { ItemMeta meta = INDUSTRIAL_MINER.getItemMeta(); - meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); + VersionedItemFlag.addFlags(meta, VersionedItemFlag.HIDE_ATTRIBUTES); INDUSTRIAL_MINER.setItemMeta(meta); ItemMeta meta2 = ADVANCED_INDUSTRIAL_MINER.getItemMeta(); - meta2.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); + VersionedItemFlag.addFlags(meta2, VersionedItemFlag.HIDE_ATTRIBUTES); ADVANCED_INDUSTRIAL_MINER.setItemMeta(meta2); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java index 617816af07..3069ffda21 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java @@ -17,7 +17,6 @@ import org.bukkit.Tag; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; import org.bukkit.inventory.RecipeChoice; @@ -361,7 +360,7 @@ public void openSearch(PlayerProfile profile, String input, boolean addToHistory ItemStack itemstack = CustomItemStack.create(slimefunItem.getItem(), meta -> { ItemGroup itemGroup = slimefunItem.getItemGroup(); meta.setLore(Arrays.asList("", ChatColor.DARK_GRAY + "\u21E8 " + ChatColor.WHITE + itemGroup.getDisplayName(p))); - meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_ENCHANTS, VersionedItemFlag.HIDE_ADDITIONAL_TOOLTIP); + VersionedItemFlag.addFlags(meta, VersionedItemFlag.HIDE_ATTRIBUTES, VersionedItemFlag.HIDE_ENCHANTS, VersionedItemFlag.HIDE_ADDITIONAL_TOOLTIP); }); menu.addItem(index, itemstack); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java index 669327a9bf..548d1d1240 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java @@ -34,8 +34,7 @@ import io.github.bakedlibs.dough.common.CommonPatterns; import io.github.bakedlibs.dough.items.CustomItemStack; import io.github.bakedlibs.dough.items.ItemUtils; -import io.github.bakedlibs.dough.skins.PlayerHead; -import io.github.bakedlibs.dough.skins.PlayerSkin; +import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPlayerHead; import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; @@ -880,11 +879,10 @@ protected void move(Block b, BlockFace face, Block block) { block.setBlockData(blockData); Slimefun.runSync(() -> { - PlayerSkin skin = PlayerSkin.fromBase64(texture); Material type = block.getType(); // Ensure that this Block is still a Player Head if (type == Material.PLAYER_HEAD || type == Material.PLAYER_WALL_HEAD) { - PlayerHead.setSkin(block, skin, true); + VersionedPlayerHead.setSkin(block, texture, true); } }); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/WoodcutterAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/WoodcutterAndroid.java index 0133cb3b25..4060d048cc 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/WoodcutterAndroid.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/WoodcutterAndroid.java @@ -173,6 +173,19 @@ private void replant(@Nonnull Block block) { } } + if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_21_4)) { + switch (logType) { + case PALE_OAK_LOG, + PALE_OAK_WOOD, + STRIPPED_PALE_OAK_LOG, + STRIPPED_PALE_OAK_WOOD -> { + saplingType = Material.PALE_OAK_SAPLING; + soilRequirement = SlimefunTag.DIRT_VARIANTS::isTagged; + } + default -> {} + } + } + if (saplingType != null && soilRequirement != null) { if (soilRequirement.test(block.getRelative(BlockFace.DOWN).getType())) { // Replant the block diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoBrewer.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoBrewer.java index 6dcd35c335..99f7e0eed6 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoBrewer.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoBrewer.java @@ -149,7 +149,7 @@ public AutoBrewer(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipe } @ParametersAreNonnullByDefault - @SuppressWarnings("deprecration") + @SuppressWarnings("deprecation") private ItemStack brewPreBasePotionType(Material input, Material potionType, PotionMeta potion) { PotionData data = potion.getBasePotionData(); PotionType type = data.getType(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Bandage.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Bandage.java index b87882cf6d..d7ee937703 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Bandage.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Bandage.java @@ -5,7 +5,6 @@ import org.bukkit.Effect; import org.bukkit.GameMode; import org.bukkit.Material; -import org.bukkit.attribute.Attribute; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; @@ -16,6 +15,7 @@ import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; +import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedAttribute; import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPotionEffectType; /** @@ -42,7 +42,7 @@ public ItemUseHandler getItemHandler() { Player p = e.getPlayer(); // Player is neither burning nor injured - if (p.getFireTicks() <= 0 && p.getHealth() >= p.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()) { + if (p.getFireTicks() <= 0 && p.getHealth() >= p.getAttribute(VersionedAttribute.MAX_HEALTH).getValue()) { return; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/MedicalSupply.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/MedicalSupply.java index 350376eab8..fbe9b7070e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/MedicalSupply.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/MedicalSupply.java @@ -7,7 +7,6 @@ import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; -import org.bukkit.attribute.Attribute; import org.bukkit.entity.LivingEntity; import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; @@ -18,6 +17,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; +import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedAttribute; import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPotionEffectType; public abstract class MedicalSupply extends SimpleSlimefunItem { @@ -73,7 +73,7 @@ public void clearNegativeEffects(@Nonnull LivingEntity n) { */ public void heal(@Nonnull LivingEntity n) { double health = n.getHealth() + healAmount; - double maxHealth = n.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); + double maxHealth = n.getAttribute(VersionedAttribute.MAX_HEALTH).getValue(); n.setHealth(Math.min(health, maxHealth)); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Splint.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Splint.java index 0a510ff28a..defc00e148 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Splint.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Splint.java @@ -4,7 +4,6 @@ import javax.annotation.ParametersAreNonnullByDefault; import org.bukkit.GameMode; -import org.bukkit.attribute.Attribute; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; @@ -16,6 +15,7 @@ import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; +import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedAttribute; import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPotionEffectType; public class Splint extends SimpleSlimefunItem { @@ -31,7 +31,7 @@ public Splint(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType Player p = e.getPlayer(); // Player is neither burning nor injured - if (p.getFireTicks() <= 0 && p.getHealth() >= p.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()) { + if (p.getFireTicks() <= 0 && p.getHealth() >= p.getAttribute(VersionedAttribute.MAX_HEALTH).getValue()) { return; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/VampireBlade.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/VampireBlade.java index 006db130e2..d9eaa88a5f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/VampireBlade.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/weapons/VampireBlade.java @@ -5,7 +5,6 @@ import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; -import org.bukkit.attribute.Attribute; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -18,6 +17,7 @@ import io.github.thebusybiscuit.slimefun4.core.handlers.WeaponUseHandler; import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; +import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedAttribute; /** * The {@link VampireBlade} is a weapon that applies a Healing effect to any {@link Player} @@ -45,7 +45,7 @@ public VampireBlade(ItemGroup itemGroup, SlimefunItemStack item, RecipeType reci if (ThreadLocalRandom.current().nextInt(100) < getChance()) { SoundEffect.VAMPIRE_BLADE_HEALING_SOUND.playFor(p); double health = p.getHealth() + HEALING_AMOUNT; - double maxHealth = p.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue(); + double maxHealth = p.getAttribute(VersionedAttribute.MAX_HEALTH).getValue(); p.setHealth(Math.min(health, maxHealth)); } }; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/DebugFishListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/DebugFishListener.java index 6bcbffd93b..cb39dacaa5 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/DebugFishListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/DebugFishListener.java @@ -21,7 +21,6 @@ import org.bukkit.inventory.EquipmentSlot; import io.github.bakedlibs.dough.common.ChatColors; -import io.github.bakedlibs.dough.skins.PlayerHead; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetProvider; @@ -30,6 +29,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; +import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPlayerHead; import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag; import me.mrCookieSlime.Slimefun.api.BlockStorage; @@ -95,7 +95,7 @@ private void onRightClick(Player p, Block b, BlockFace face) { Block block = b.getRelative(face); block.setType(Material.PLAYER_HEAD); - PlayerHead.setSkin(block, HeadTexture.MISSING_TEXTURE.getAsSkin(), true); + VersionedPlayerHead.setSkin(block, HeadTexture.MISSING_TEXTURE.getBase64Texture(), true); SoundEffect.DEBUG_FISH_CLICK_SOUND.playFor(p); }, 2L); } else if (BlockStorage.hasBlockInfo(b)) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/CapacitorTextureUpdateTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/CapacitorTextureUpdateTask.java index 4f79580831..fa6587af17 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/CapacitorTextureUpdateTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/CapacitorTextureUpdateTask.java @@ -8,8 +8,7 @@ import org.bukkit.Server; import org.bukkit.block.Block; -import io.github.bakedlibs.dough.skins.PlayerHead; -import io.github.bakedlibs.dough.skins.PlayerSkin; +import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPlayerHead; import io.github.thebusybiscuit.slimefun4.implementation.items.electric.Capacitor; import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; import io.papermc.lib.PaperLib; @@ -75,8 +74,7 @@ public void run() { } private void setTexture(@Nonnull Block b, @Nonnull HeadTexture texture) { - PlayerSkin skin = PlayerSkin.fromHashCode(texture.getUniqueId(), texture.getTexture()); - PlayerHead.setSkin(b, skin, false); + VersionedPlayerHead.setSkinFromHash(b, texture.getUniqueId(), texture.getTexture(), false); PaperLib.getBlockState(b, false).getState().update(true, false); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java index dc31cf2b76..a85ce6ca4b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java @@ -11,7 +11,6 @@ import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.ItemMeta; @@ -20,6 +19,7 @@ import io.github.bakedlibs.dough.items.CustomItemStack; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; +import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedItemFlag; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.MenuClickHandler; @@ -35,7 +35,7 @@ private ChestMenuUtils() {} private static final ItemStack NO_PERMISSION = new SlimefunItemStack("_UI_NO_PERMISSION", Material.BARRIER, "No Permission").item(); private static final ItemStack NOT_RESEARCHED = new SlimefunItemStack("_UI_NOT_RESEARCHED", Material.BARRIER, "Not researched").item(); - private static final ItemStack BACK_BUTTON = new SlimefunItemStack("_UI_BACK", Material.ENCHANTED_BOOK, "&7\u21E6 Back", meta -> meta.addItemFlags(ItemFlag.HIDE_ENCHANTS)).item(); + private static final ItemStack BACK_BUTTON = new SlimefunItemStack("_UI_BACK", Material.ENCHANTED_BOOK, "&7\u21E6 Back", meta -> VersionedItemFlag.addFlags(meta, VersionedItemFlag.HIDE_ENCHANTS)).item(); private static final ItemStack MENU_BUTTON = new SlimefunItemStack("_UI_MENU", Material.COMPARATOR, "&eSettings / Info", "", "&7\u21E8 Click to see more").item(); private static final ItemStack SEARCH_BUTTON = new SlimefunItemStack("_UI_SEARCH", Material.NAME_TAG, "&bSearch").item(); private static final ItemStack WIKI_BUTTON = new SlimefunItemStack("_UI_WIKI", Material.KNOWLEDGE_BOOK, "&3Slimefun Wiki").item(); @@ -154,7 +154,7 @@ public static void updateProgressbar(@Nonnull ChestMenu menu, int slot, int time ItemStack item = indicator.clone(); ItemMeta im = item.getItemMeta(); - im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); + VersionedItemFlag.addFlags(im, VersionedItemFlag.HIDE_ATTRIBUTES); if (im instanceof Damageable damageable) { damageable.setDamage(getDurability(item, timeLeft, time)); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/HeadTexture.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/HeadTexture.java index a4caf14774..be10dfbf53 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/HeadTexture.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/HeadTexture.java @@ -9,7 +9,7 @@ import org.bukkit.inventory.ItemStack; import io.github.bakedlibs.dough.common.CommonPatterns; -import io.github.bakedlibs.dough.skins.PlayerSkin; +import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPlayerHead; /** * This enum holds all currently used Head textures in Slimefun. @@ -163,8 +163,13 @@ public enum HeadTexture { return SlimefunUtils.getCustomHead(getTexture()); } - public @Nonnull PlayerSkin getAsSkin() { - return PlayerSkin.fromHashCode(texture); + /** + * Returns a base64-encoded texture string for this head texture. + * + * @return The base64 texture string + */ + public @Nonnull String getBase64Texture() { + return VersionedPlayerHead.hashToBase64(texture); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java index ed5bdb9b4d..b44f530cb8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java @@ -29,8 +29,7 @@ import io.github.bakedlibs.dough.common.CommonPatterns; import io.github.bakedlibs.dough.items.ItemMetaSnapshot; -import io.github.bakedlibs.dough.skins.PlayerHead; -import io.github.bakedlibs.dough.skins.PlayerSkin; +import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedPlayerHead; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.api.events.SlimefunItemSpawnEvent; import io.github.thebusybiscuit.slimefun4.api.exceptions.PrematureCodeException; @@ -241,8 +240,7 @@ public static boolean isRadioactive(@Nullable ItemStack item) { base64 = Base64.getEncoder().encodeToString(("{\"textures\":{\"SKIN\":{\"url\":\"http://textures.minecraft.net/texture/" + texture + "\"}}}").getBytes(StandardCharsets.UTF_8)); } - PlayerSkin skin = PlayerSkin.fromBase64(base64); - return PlayerHead.getItemStack(skin); + return VersionedPlayerHead.getItemStack(base64); } public static boolean containsSimilarItem(Inventory inventory, ItemStack item, boolean checkLore) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedAttribute.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedAttribute.java new file mode 100644 index 0000000000..06fb68529a --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedAttribute.java @@ -0,0 +1,35 @@ +package io.github.thebusybiscuit.slimefun4.utils.compatibility; + +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.attribute.Attribute; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Compatibility layer for {@link Attribute} constants that were renamed + * when {@link Attribute} changed from an enum to an interface in Minecraft 1.21.2+. + * + *

In 1.21.2+, {@code Attribute.GENERIC_MAX_HEALTH} was renamed to + * {@code Attribute.MAX_HEALTH}. Using the registry-based lookup ensures + * compatibility across both old and new API versions.

+ */ +public class VersionedAttribute { + + /** + * The max health attribute. + * Was {@code GENERIC_MAX_HEALTH} pre-1.21.2, renamed to {@code MAX_HEALTH} in 1.21.2+. + */ + public static final Attribute MAX_HEALTH; + + static { + // Registry key is "generic.max_health" across all versions + MAX_HEALTH = getKey("generic.max_health"); + } + + @Nullable + private static Attribute getKey(@Nonnull String key) { + return Registry.ATTRIBUTE.get(NamespacedKey.minecraft(key)); + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedItemFlag.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedItemFlag.java index 507a903a23..81e9d22dce 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedItemFlag.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedItemFlag.java @@ -6,20 +6,52 @@ import javax.annotation.Nullable; import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.meta.ItemMeta; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; public class VersionedItemFlag { - public static final ItemFlag HIDE_ADDITIONAL_TOOLTIP; + public static final @Nullable ItemFlag HIDE_ADDITIONAL_TOOLTIP; + + // HIDE_ATTRIBUTES and HIDE_ENCHANTS were removed in 1.21.5+ in favor of + // the tooltip_display component. We resolve them via reflection so the + // plugin does not crash on newer versions where these constants no longer exist. + public static final @Nullable ItemFlag HIDE_ATTRIBUTES; + public static final @Nullable ItemFlag HIDE_ENCHANTS; static { MinecraftVersion version = Slimefun.getMinecraftVersion(); - HIDE_ADDITIONAL_TOOLTIP = version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5) - ? ItemFlag.HIDE_ADDITIONAL_TOOLTIP - : getKey("HIDE_POTION_EFFECTS"); + // In 1.20.5+ HIDE_POTION_EFFECTS was renamed to HIDE_ADDITIONAL_TOOLTIP. + // In 1.21.5+ HIDE_ADDITIONAL_TOOLTIP was removed in favor of tooltip_display component. + // We use reflection for both paths to be safe across all versions. + if (version.isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)) { + ItemFlag flag = getKey("HIDE_ADDITIONAL_TOOLTIP"); + HIDE_ADDITIONAL_TOOLTIP = flag != null ? flag : getKey("HIDE_POTION_EFFECTS"); + } else { + HIDE_ADDITIONAL_TOOLTIP = getKey("HIDE_POTION_EFFECTS"); + } + + HIDE_ATTRIBUTES = getKey("HIDE_ATTRIBUTES"); + HIDE_ENCHANTS = getKey("HIDE_ENCHANTS"); + } + + /** + * Safely adds {@link ItemFlag}s to the given {@link ItemMeta}, skipping any + * {@code null} flags. This is necessary because some flags may not exist on + * the running Minecraft version (e.g. HIDE_ATTRIBUTES was removed in 1.21.5). + * + * @param meta The {@link ItemMeta} to add flags to + * @param flags The flags to add (nulls are silently ignored) + */ + public static void addFlags(@Nonnull ItemMeta meta, @Nullable ItemFlag... flags) { + for (ItemFlag flag : flags) { + if (flag != null) { + meta.addItemFlags(flag); + } + } } @Nullable diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedPlayerHead.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedPlayerHead.java new file mode 100644 index 0000000000..f9d129c041 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedPlayerHead.java @@ -0,0 +1,251 @@ +package io.github.thebusybiscuit.slimefun4.utils.compatibility; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.Base64; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Skull; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.profile.PlayerProfile; +import org.bukkit.profile.PlayerTextures; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +/** + * Replacement for dough's {@code PlayerSkin}, {@code PlayerHead}, and {@code CustomGameProfile} + * that avoids extending {@code com.mojang.authlib.GameProfile}, which became {@code final} + * in Minecraft 1.21.5+. + * + *

Uses the Bukkit {@link PlayerProfile} API (available since MC 1.18) instead of + * authlib reflection, making this forward-compatible with all future versions.

+ */ +public final class VersionedPlayerHead { + + private static final String PROFILE_NAME = "CS-CoreLib"; + + private VersionedPlayerHead() {} + + /** + * Creates a player head {@link ItemStack} with the given base64-encoded texture. + * + * @param base64 The base64-encoded texture JSON string + * @return An {@link ItemStack} with the texture applied + */ + public static @Nonnull ItemStack getItemStack(@Nonnull String base64) { + ItemStack item = new ItemStack(Material.PLAYER_HEAD); + SkullMeta meta = (SkullMeta) item.getItemMeta(); + + applyTextureToMeta(meta, base64); + + item.setItemMeta(meta); + return item; + } + + /** + * Applies a base64-encoded texture to the given {@link SkullMeta}. + * + * @param meta The {@link SkullMeta} to modify + * @param base64 The base64-encoded texture JSON string + */ + public static void applyTextureToMeta(@Nonnull SkullMeta meta, @Nonnull String base64) { + UUID uuid = UUID.nameUUIDFromBytes(base64.getBytes(StandardCharsets.UTF_8)); + URL skinUrl = extractSkinUrl(base64); + + if (skinUrl != null) { + PlayerProfile profile = Bukkit.createPlayerProfile(uuid, PROFILE_NAME); + PlayerTextures textures = profile.getTextures(); + textures.setSkin(skinUrl); + profile.setTextures(textures); + meta.setOwnerProfile(profile); + } + } + + /** + * Sets the skin texture on a player head block using a base64-encoded texture. + * + * @param block The {@link Block} to update (must be PLAYER_HEAD or PLAYER_WALL_HEAD) + * @param base64 The base64-encoded texture JSON string + * @param sendBlockUpdate Whether to send a block update to clients + */ + public static void setSkin(@Nonnull Block block, @Nonnull String base64, boolean sendBlockUpdate) { + Material material = block.getType(); + if (material != Material.PLAYER_HEAD && material != Material.PLAYER_WALL_HEAD) { + return; + } + + UUID uuid = UUID.nameUUIDFromBytes(base64.getBytes(StandardCharsets.UTF_8)); + URL skinUrl = extractSkinUrl(base64); + + if (skinUrl != null) { + Skull skull = (Skull) block.getState(); + PlayerProfile profile = Bukkit.createPlayerProfile(uuid, PROFILE_NAME); + PlayerTextures textures = profile.getTextures(); + textures.setSkin(skinUrl); + profile.setTextures(textures); + skull.setOwnerProfile(profile); + skull.update(sendBlockUpdate, false); + } + } + + /** + * Sets the skin texture on a player head block using a texture hash code and a specific UUID. + * + * @param block The {@link Block} to update + * @param uuid The {@link UUID} to use for the profile + * @param hashCode The hex texture hash code + * @param sendBlockUpdate Whether to send a block update to clients + */ + public static void setSkinFromHash(@Nonnull Block block, @Nonnull UUID uuid, @Nonnull String hashCode, boolean sendBlockUpdate) { + Material material = block.getType(); + if (material != Material.PLAYER_HEAD && material != Material.PLAYER_WALL_HEAD) { + return; + } + + URL skinUrl = getTextureUrl(hashCode); + + if (skinUrl != null) { + Skull skull = (Skull) block.getState(); + PlayerProfile profile = Bukkit.createPlayerProfile(uuid, PROFILE_NAME); + PlayerTextures textures = profile.getTextures(); + textures.setSkin(skinUrl); + profile.setTextures(textures); + skull.setOwnerProfile(profile); + skull.update(sendBlockUpdate, false); + } + } + + /** + * Converts a hex hash code to a base64-encoded texture string. + * + * @param hashCode The hex texture hash code + * @return A base64-encoded texture JSON string + */ + public static @Nonnull String hashToBase64(@Nonnull String hashCode) { + String value = "{\"textures\":{\"SKIN\":{\"url\":\"http://textures.minecraft.net/texture/" + hashCode + "\"}}}"; + return Base64.getEncoder().encodeToString(value.getBytes(StandardCharsets.UTF_8)); + } + + /** + * Fetches a player's skin texture (base64) from the Mojang session server. + * + * @param playerUuid The player's {@link UUID} + * @return A {@link CompletableFuture} containing the base64 texture string, or null if not found + */ + public static @Nonnull CompletableFuture fetchSkinTexture(@Nonnull UUID playerUuid) { + return CompletableFuture.supplyAsync(() -> { + try { + String targetUrl = "https://sessionserver.mojang.com/session/minecraft/profile/" + + playerUuid.toString().replace("-", "") + "?unsigned=false"; + + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(targetUrl)) + .timeout(Duration.ofSeconds(30)) + .GET() + .build(); + + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + JsonObject obj = JsonParser.parseString(response.body()).getAsJsonObject(); + + if (obj.has("error")) { + throw new RuntimeException(obj.get("error").getAsString()); + } + + for (JsonElement el : obj.get("properties").getAsJsonArray()) { + if (el.isJsonObject() && el.getAsJsonObject().get("name").getAsString().equals("textures")) { + return el.getAsJsonObject().get("value").getAsString(); + } + } + + return null; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + /** + * Looks up a player's UUID from their username using the playerdb.co API. + * + * @param username The Minecraft username + * @return A {@link CompletableFuture} containing the player's UUID, or null if not found + */ + public static @Nonnull CompletableFuture lookupUUID(@Nonnull String username) { + return CompletableFuture.supplyAsync(() -> { + try { + String targetUrl = "https://playerdb.co/api/player/minecraft/" + username; + + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(targetUrl)) + .timeout(Duration.ofSeconds(30)) + .header("user-agent", "Mozilla/5.0 Dough (+https://github.com/baked-libs/dough)") + .GET() + .build(); + + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + JsonObject jsonObject = JsonParser.parseString(response.body()).getAsJsonObject(); + + if (jsonObject.get("success").getAsBoolean()) { + JsonObject data = jsonObject.getAsJsonObject("data"); + JsonObject player = data.getAsJsonObject("player"); + return UUID.fromString(player.get("id").getAsString()); + } + + return null; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + /** + * Gets the texture URL from a hex hash code. + */ + @Nullable + private static URL getTextureUrl(@Nonnull String hashCode) { + try { + return URI.create("http://textures.minecraft.net/texture/" + hashCode).toURL(); + } catch (MalformedURLException e) { + return null; + } + } + + /** + * Extracts the skin URL from a base64-encoded texture string. + */ + @Nullable + private static URL extractSkinUrl(@Nonnull String base64) { + try { + String decoded = new String(Base64.getDecoder().decode(base64), StandardCharsets.UTF_8); + JsonObject json = JsonParser.parseString(decoded).getAsJsonObject(); + String url = json.getAsJsonObject("textures").getAsJsonObject("SKIN").get("url").getAsString(); + return URI.create(url).toURL(); + } catch (Exception e) { + return null; + } + } +} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestMinecraftVersion.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestMinecraftVersion.java index 74a2622cce..9b7a993daf 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestMinecraftVersion.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestMinecraftVersion.java @@ -14,10 +14,12 @@ void testMatches() { Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_16.isMinecraftVersion(16, -1)); Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_17.isMinecraftVersion(17, -1)); Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_20_5.isMinecraftVersion(20, 5)); + Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_21_4.isMinecraftVersion(21, 4)); Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_17.isMinecraftVersion(16, -1)); Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_16.isMinecraftVersion(0, -1)); Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_20_5.isMinecraftVersion(20, 4)); + Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_21_4.isMinecraftVersion(21, 3)); } @Test @@ -29,6 +31,17 @@ void testMatchesMinor() { Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_20.isMinecraftVersion(20, 4)); Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_20_5.isMinecraftVersion(20, 6)); + // 1.21.x covers 1.21.0 through 1.21.3 + Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_21.isMinecraftVersion(21, 0)); + Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_21.isMinecraftVersion(21, 3)); + Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_21.isMinecraftVersion(21, 4)); + + // 1.21.4+ covers 1.21.4 and above + Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_21_4.isMinecraftVersion(21, 4)); + Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_21_4.isMinecraftVersion(21, 5)); + Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_21_4.isMinecraftVersion(21, 11)); + Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_21_4.isMinecraftVersion(21, 3)); + Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_20.isMinecraftVersion(20, 5)); Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_16.isMinecraftVersion(17, 1)); Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_20_5.isMinecraftVersion(20, 4)); @@ -42,8 +55,11 @@ void testAtLeast() { Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_17.isAtLeast(MinecraftVersion.MINECRAFT_1_17)); Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_20.isAtLeast(MinecraftVersion.MINECRAFT_1_20)); Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_20_5.isAtLeast(MinecraftVersion.MINECRAFT_1_20)); + Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_21_4.isAtLeast(MinecraftVersion.MINECRAFT_1_21)); + Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_21_4.isAtLeast(MinecraftVersion.MINECRAFT_1_21_4)); Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_17.isAtLeast(MinecraftVersion.MINECRAFT_1_18)); + Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_21.isAtLeast(MinecraftVersion.MINECRAFT_1_21_4)); } @Test @@ -82,6 +98,11 @@ void testIsBeforeMinor() { Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_20_5.isBefore(20, 4)); Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_20_5.isBefore(20, 5)); Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_20_5.isBefore(20, 6)); + + // 1.21.4+ version boundary tests + Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_21_4.isBefore(21, 3)); + Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_21_4.isBefore(21, 4)); + Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_21_4.isBefore(21, 5)); } @Test diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapCompatibility.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapCompatibility.java index d7ffca7d79..6dc1c8b3c7 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapCompatibility.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapCompatibility.java @@ -107,7 +107,8 @@ void testCompatibilities(String name, MinecraftVersion version) { MinecraftVersion.MINECRAFT_1_18, MinecraftVersion.MINECRAFT_1_19, MinecraftVersion.MINECRAFT_1_20, - MinecraftVersion.MINECRAFT_1_21 + MinecraftVersion.MINECRAFT_1_21, + MinecraftVersion.MINECRAFT_1_21_4 }); testCases.put("oil_v1.16", new MinecraftVersion[] { @@ -119,7 +120,8 @@ void testCompatibilities(String name, MinecraftVersion version) { MinecraftVersion.MINECRAFT_1_18, MinecraftVersion.MINECRAFT_1_19, MinecraftVersion.MINECRAFT_1_20, - MinecraftVersion.MINECRAFT_1_21 + MinecraftVersion.MINECRAFT_1_21, + MinecraftVersion.MINECRAFT_1_21_4 }); testCases.put("salt_v1.16", new MinecraftVersion[] { @@ -131,7 +133,8 @@ void testCompatibilities(String name, MinecraftVersion version) { MinecraftVersion.MINECRAFT_1_18, MinecraftVersion.MINECRAFT_1_19, MinecraftVersion.MINECRAFT_1_20, - MinecraftVersion.MINECRAFT_1_21 + MinecraftVersion.MINECRAFT_1_21, + MinecraftVersion.MINECRAFT_1_21_4 }); testCases.put("uranium_v1.16", new MinecraftVersion[] { @@ -146,7 +149,8 @@ void testCompatibilities(String name, MinecraftVersion version) { MinecraftVersion.MINECRAFT_1_18, MinecraftVersion.MINECRAFT_1_19, MinecraftVersion.MINECRAFT_1_20, - MinecraftVersion.MINECRAFT_1_21 + MinecraftVersion.MINECRAFT_1_21, + MinecraftVersion.MINECRAFT_1_21_4 }); // @formatter:on diff --git a/src/test/resources/biomes/1.21.4+.json b/src/test/resources/biomes/1.21.4+.json new file mode 100644 index 0000000000..643e7e18ea --- /dev/null +++ b/src/test/resources/biomes/1.21.4+.json @@ -0,0 +1,68 @@ +[ + "minecraft:badlands", + "minecraft:bamboo_jungle", + "minecraft:basalt_deltas", + "minecraft:beach", + "minecraft:birch_forest", + "minecraft:cherry_grove", + "minecraft:cold_ocean", + "minecraft:crimson_forest", + "minecraft:custom", + "minecraft:dark_forest", + "minecraft:deep_cold_ocean", + "minecraft:deep_dark", + "minecraft:deep_frozen_ocean", + "minecraft:deep_lukewarm_ocean", + "minecraft:deep_ocean", + "minecraft:desert", + "minecraft:dripstone_caves", + "minecraft:end_barrens", + "minecraft:end_highlands", + "minecraft:end_midlands", + "minecraft:eroded_badlands", + "minecraft:flower_forest", + "minecraft:forest", + "minecraft:frozen_ocean", + "minecraft:frozen_peaks", + "minecraft:frozen_river", + "minecraft:grove", + "minecraft:ice_spikes", + "minecraft:jagged_peaks", + "minecraft:jungle", + "minecraft:lukewarm_ocean", + "minecraft:lush_caves", + "minecraft:mangrove_swamp", + "minecraft:meadow", + "minecraft:mushroom_fields", + "minecraft:nether_wastes", + "minecraft:ocean", + "minecraft:old_growth_birch_forest", + "minecraft:old_growth_pine_taiga", + "minecraft:old_growth_spruce_taiga", + "minecraft:pale_garden", + "minecraft:plains", + "minecraft:river", + "minecraft:savanna", + "minecraft:savanna_plateau", + "minecraft:small_end_islands", + "minecraft:snowy_beach", + "minecraft:snowy_plains", + "minecraft:snowy_slopes", + "minecraft:snowy_taiga", + "minecraft:soul_sand_valley", + "minecraft:sparse_jungle", + "minecraft:stony_peaks", + "minecraft:stony_shore", + "minecraft:sunflower_plains", + "minecraft:swamp", + "minecraft:taiga", + "minecraft:the_end", + "minecraft:the_void", + "minecraft:warm_ocean", + "minecraft:warped_forest", + "minecraft:windswept_forest", + "minecraft:windswept_gravelly_hills", + "minecraft:windswept_hills", + "minecraft:windswept_savanna", + "minecraft:wooded_badlands" +] From 89fa8774ccc49a8bbbe0900c43a98030febb1cd5 Mon Sep 17 00:00:00 2001 From: Intisy Date: Tue, 3 Mar 2026 23:22:53 +0100 Subject: [PATCH 2/8] Refractor a couple comments --- pom.xml | 2 +- .../compatibility/VersionedAttribute.java | 14 +---- .../compatibility/VersionedItemFlag.java | 9 +-- .../compatibility/VersionedPlayerHead.java | 61 +------------------ 4 files changed, 5 insertions(+), 81 deletions(-) diff --git a/pom.xml b/pom.xml index da00fdc186..bdf9577d44 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ UTF-8 - + 21 21 21 diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedAttribute.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedAttribute.java index 06fb68529a..7736453157 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedAttribute.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedAttribute.java @@ -7,23 +7,13 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; -/** - * Compatibility layer for {@link Attribute} constants that were renamed - * when {@link Attribute} changed from an enum to an interface in Minecraft 1.21.2+. - * - *

In 1.21.2+, {@code Attribute.GENERIC_MAX_HEALTH} was renamed to - * {@code Attribute.MAX_HEALTH}. Using the registry-based lookup ensures - * compatibility across both old and new API versions.

- */ +// https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/src/main/java/org/bukkit/craftbukkit/legacy/FieldRename.java?until=2a6207fe150b6165722fce94c83cc1f206620ab5&untilPath=src%2Fmain%2Fjava%2Forg%2Fbukkit%2Fcraftbukkit%2Flegacy%2FFieldRename.java#112-157 public class VersionedAttribute { - /** - * The max health attribute. - * Was {@code GENERIC_MAX_HEALTH} pre-1.21.2, renamed to {@code MAX_HEALTH} in 1.21.2+. - */ public static final Attribute MAX_HEALTH; static { + // Attribute.GENERIC_MAX_HEALTH was renamed to Attribute.MAX_HEALTH in Minecraft 1.21.2+. // Registry key is "generic.max_health" across all versions MAX_HEALTH = getKey("generic.max_health"); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedItemFlag.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedItemFlag.java index 81e9d22dce..7c933b083c 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedItemFlag.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedItemFlag.java @@ -38,14 +38,7 @@ public class VersionedItemFlag { HIDE_ENCHANTS = getKey("HIDE_ENCHANTS"); } - /** - * Safely adds {@link ItemFlag}s to the given {@link ItemMeta}, skipping any - * {@code null} flags. This is necessary because some flags may not exist on - * the running Minecraft version (e.g. HIDE_ATTRIBUTES was removed in 1.21.5). - * - * @param meta The {@link ItemMeta} to add flags to - * @param flags The flags to add (nulls are silently ignored) - */ + // Safely adds ItemFlags to ItemMeta, skipping null flags that don't exist in the current Minecraft version public static void addFlags(@Nonnull ItemMeta meta, @Nullable ItemFlag... flags) { for (ItemFlag flag : flags) { if (flag != null) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedPlayerHead.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedPlayerHead.java index f9d129c041..477144368e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedPlayerHead.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/compatibility/VersionedPlayerHead.java @@ -28,26 +28,12 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; -/** - * Replacement for dough's {@code PlayerSkin}, {@code PlayerHead}, and {@code CustomGameProfile} - * that avoids extending {@code com.mojang.authlib.GameProfile}, which became {@code final} - * in Minecraft 1.21.5+. - * - *

Uses the Bukkit {@link PlayerProfile} API (available since MC 1.18) instead of - * authlib reflection, making this forward-compatible with all future versions.

- */ public final class VersionedPlayerHead { private static final String PROFILE_NAME = "CS-CoreLib"; private VersionedPlayerHead() {} - /** - * Creates a player head {@link ItemStack} with the given base64-encoded texture. - * - * @param base64 The base64-encoded texture JSON string - * @return An {@link ItemStack} with the texture applied - */ public static @Nonnull ItemStack getItemStack(@Nonnull String base64) { ItemStack item = new ItemStack(Material.PLAYER_HEAD); SkullMeta meta = (SkullMeta) item.getItemMeta(); @@ -58,12 +44,6 @@ private VersionedPlayerHead() {} return item; } - /** - * Applies a base64-encoded texture to the given {@link SkullMeta}. - * - * @param meta The {@link SkullMeta} to modify - * @param base64 The base64-encoded texture JSON string - */ public static void applyTextureToMeta(@Nonnull SkullMeta meta, @Nonnull String base64) { UUID uuid = UUID.nameUUIDFromBytes(base64.getBytes(StandardCharsets.UTF_8)); URL skinUrl = extractSkinUrl(base64); @@ -77,13 +57,6 @@ public static void applyTextureToMeta(@Nonnull SkullMeta meta, @Nonnull String b } } - /** - * Sets the skin texture on a player head block using a base64-encoded texture. - * - * @param block The {@link Block} to update (must be PLAYER_HEAD or PLAYER_WALL_HEAD) - * @param base64 The base64-encoded texture JSON string - * @param sendBlockUpdate Whether to send a block update to clients - */ public static void setSkin(@Nonnull Block block, @Nonnull String base64, boolean sendBlockUpdate) { Material material = block.getType(); if (material != Material.PLAYER_HEAD && material != Material.PLAYER_WALL_HEAD) { @@ -104,14 +77,6 @@ public static void setSkin(@Nonnull Block block, @Nonnull String base64, boolean } } - /** - * Sets the skin texture on a player head block using a texture hash code and a specific UUID. - * - * @param block The {@link Block} to update - * @param uuid The {@link UUID} to use for the profile - * @param hashCode The hex texture hash code - * @param sendBlockUpdate Whether to send a block update to clients - */ public static void setSkinFromHash(@Nonnull Block block, @Nonnull UUID uuid, @Nonnull String hashCode, boolean sendBlockUpdate) { Material material = block.getType(); if (material != Material.PLAYER_HEAD && material != Material.PLAYER_WALL_HEAD) { @@ -131,23 +96,11 @@ public static void setSkinFromHash(@Nonnull Block block, @Nonnull UUID uuid, @No } } - /** - * Converts a hex hash code to a base64-encoded texture string. - * - * @param hashCode The hex texture hash code - * @return A base64-encoded texture JSON string - */ public static @Nonnull String hashToBase64(@Nonnull String hashCode) { String value = "{\"textures\":{\"SKIN\":{\"url\":\"http://textures.minecraft.net/texture/" + hashCode + "\"}}}"; return Base64.getEncoder().encodeToString(value.getBytes(StandardCharsets.UTF_8)); } - /** - * Fetches a player's skin texture (base64) from the Mojang session server. - * - * @param playerUuid The player's {@link UUID} - * @return A {@link CompletableFuture} containing the base64 texture string, or null if not found - */ public static @Nonnull CompletableFuture fetchSkinTexture(@Nonnull UUID playerUuid) { return CompletableFuture.supplyAsync(() -> { try { @@ -184,12 +137,6 @@ public static void setSkinFromHash(@Nonnull Block block, @Nonnull UUID uuid, @No }); } - /** - * Looks up a player's UUID from their username using the playerdb.co API. - * - * @param username The Minecraft username - * @return A {@link CompletableFuture} containing the player's UUID, or null if not found - */ public static @Nonnull CompletableFuture lookupUUID(@Nonnull String username) { return CompletableFuture.supplyAsync(() -> { try { @@ -222,9 +169,6 @@ public static void setSkinFromHash(@Nonnull Block block, @Nonnull UUID uuid, @No }); } - /** - * Gets the texture URL from a hex hash code. - */ @Nullable private static URL getTextureUrl(@Nonnull String hashCode) { try { @@ -234,9 +178,6 @@ private static URL getTextureUrl(@Nonnull String hashCode) { } } - /** - * Extracts the skin URL from a base64-encoded texture string. - */ @Nullable private static URL extractSkinUrl(@Nonnull String base64) { try { @@ -248,4 +189,4 @@ private static URL extractSkinUrl(@Nonnull String base64) { return null; } } -} +} \ No newline at end of file From 9d94d7d712bba1a60aa4a3a44c5a6a6fe7e3a72a Mon Sep 17 00:00:00 2001 From: Intisy Date: Thu, 5 Mar 2026 15:17:34 +0100 Subject: [PATCH 3/8] Migrate to Slimefun5 and update CI/templates --- .github/CODEOWNERS | 18 +-- .github/CODE_OF_CONDUCT.md | 15 +-- .github/ISSUE_TEMPLATE.md | 2 +- .github/ISSUE_TEMPLATE/bug-report.yaml | 39 +++---- .github/ISSUE_TEMPLATE/config.yml | 5 +- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .github/workflows/auto-approve.yml | 4 +- .github/workflows/auto-squash.yml | 8 +- .github/workflows/close-invalid-issues.yml | 15 ++- .github/workflows/discord-webhook.yml | 45 -------- .github/workflows/duplicates.yml | 2 +- .github/workflows/e2e-testing.yml | 81 ------------- .github/workflows/label-resolved-issues.yml | 4 +- .github/workflows/merge-conflicts.yml | 4 +- .github/workflows/pr-labels.yml | 2 +- .github/workflows/preview-builds.yml | 82 ------------- .github/workflows/publish-build.yml | 58 ---------- .github/workflows/pull-request.yml | 6 +- .github/workflows/release-candidates.yml | 78 ------------- .github/workflows/release.yml | 54 +++++++++ .github/workflows/sonarcloud.yml | 50 -------- .github/workflows/translator-webhook.yml | 26 ----- README.md | 121 +++++--------------- 23 files changed, 131 insertions(+), 590 deletions(-) delete mode 100644 .github/workflows/discord-webhook.yml delete mode 100644 .github/workflows/e2e-testing.yml delete mode 100644 .github/workflows/preview-builds.yml delete mode 100644 .github/workflows/publish-build.yml delete mode 100644 .github/workflows/release-candidates.yml create mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/sonarcloud.yml delete mode 100644 .github/workflows/translator-webhook.yml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d2293a4e33..ef5ef3dfe1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,16 +1,2 @@ -# Modifications to the source code should be handled by the code review team -*.java @Slimefun/code-reviewers - -# Modifications to sensitive files should be reviewed by maintainers -/.github/ @Slimefun/slimefun4-maintainers -pom.xml @Slimefun/slimefun4-maintainers -CONTRIBUTING.md @Slimefun/slimefun4-maintainers - -# Changes to the Issue templates need to be checked by the triage team -/.github/ISSUE_TEMPLATE/ @Slimefun/bug-testers - -# Our wiki lookup file will be reviewed by the wiki staff team -/src/main/resources/wiki.json @Slimefun/wiki-staff - -# This file is handled by TheBusyBiscuit (admins have overwrite access anyway) -/.github/CODEOWNERS @TheBusyBiscuit +# All changes are reviewed by the maintainers +* @Slimefun5/maintainers diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index 0a2e285211..a6e04fc4ac 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -1,4 +1,4 @@ -# Slimefun4 - Code of Conduct +# Slimefun5 - Code of Conduct ### What is a Code of Conduct? > A code of conduct is a document that establishes expectations for behavior for your project’s participants. > Adopting, and enforcing, a code of conduct can help create a positive social atmosphere for your community. @@ -7,8 +7,7 @@ This document should serve the purpose of outlining the behaviour we expect from any participant of the project. ## :mag_right: Scope -This Code of Conduct applies to all sections of the [Slimefun4 GitHub repository](https://github.com/Slimefun/Slimefun4), our [Slimefun GitHub organization](https://github.com/Slimefun) and all repositories owned by said organization.
-For our official Discord server, please refer to our article on [Discord Rules](https://github.com/Slimefun/Slimefun4/wiki/Discord-Rules). +This Code of Conduct applies to all sections of the [Slimefun5 GitHub repository](https://github.com/Slimefun5/Slimefun5) and our [Slimefun5 GitHub organization](https://github.com/Slimefun5). Everyone who engages with this project on any of these repositories is expected to follow the Code of Conduct.
This includes maintainers, contributors, sponsors and anyone who engages in the "Issues" section on GitHub. @@ -18,8 +17,7 @@ This is an Open-Source project, anyone is welcome to engage and contribute!
We generally expect users to engage in the Issues section by reporting bugs or commenting on bug reports to give additional context, help, guidance or to propose possible solutions and fixes. Pull Requests are very much welcome and encouraged! They keep the project alive, so if you see an Issue and know how to fix it, feel free to create a Pull Request! -Issues that are considered "good first issues", indicated by the [good first issue](https://github.com/Slimefun/Slimefun4/labels/good%20first%20issue) label, are generally expected to be beginner-friendly. -And even if you shouldn't know where to start or how to proceed, our [Discord Server](https://discord.gg/slimefun) and its community will be there for you! +Issues that are considered "good first issues", indicated by the [good first issue](https://github.com/Slimefun5/Slimefun5/labels/good%20first%20issue) label, are generally expected to be beginner-friendly. When commenting, please keep in mind that this software is offered for **free**. Don't expect to receive lightning-fast replies 24 hours a day. Everyone here works on this project in their free time and usually has work, school, university or family to take care of, so we appreciate patience and understanding. @@ -54,13 +52,12 @@ comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. -You can see a list of people who are recognized as "project maintainers" for Slimefun on the Slimefun GitHub organization:
-https://github.com/orgs/Slimefun/people +You can see a list of people who are recognized as "project maintainers" for Slimefun on the Slimefun5 GitHub organization:
+https://github.com/orgs/Slimefun5/people ## :wrench: Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders (labelled on Discord as "Admins" or "Moderators") responsible for enforcement on our [Discord Server](discord.gg/slimefun). -If you want your issue to be handled discreetly, message `TheBusyBiscuit#2610` or `Walshy#9709` privately on Discord and state your concerns. +reported to the project maintainers via [GitHub Issues](https://github.com/Slimefun5/Slimefun5/issues). All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 08c508502f..96c9f3ba09 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,3 +1,3 @@ THIS ISSUE IS INVALID. -TO REPORT A BUG, GO HERE -> https://github.com/Slimefun/Slimefun4/issues/new/choose +TO REPORT A BUG, GO HERE -> https://github.com/Slimefun5/Slimefun5/issues/new/choose diff --git a/.github/ISSUE_TEMPLATE/bug-report.yaml b/.github/ISSUE_TEMPLATE/bug-report.yaml index fcc3435e70..3e14809431 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yaml +++ b/.github/ISSUE_TEMPLATE/bug-report.yaml @@ -1,28 +1,25 @@ name: Bug Report -description: Report a Bug or an Issue with Slimefun 4. +description: Report a Bug or an Issue with Slimefun. labels: ['🎯 Needs testing', '🐞 Bug Report'] body: - type: markdown attributes: value: | - ## 👋 Welcome to the Slimefun Bug Tracker - If you need any help to identify the problem, visit our [Discord server](https://discord.gg/slimefun) and see if others experience a similar issue. - Also take a look at our [Troubleshooting Guide](https://github.com/Slimefun/Slimefun4/wiki/How-to-report-bugs) and the list of [existing Issues](https://github.com/Slimefun/Slimefun4/issues). + ## Bug Tracker + Take a look at our [Troubleshooting Guide](https://github.com/Slimefun/Slimefun4/wiki/How-to-report-bugs) and the list of [existing Issues](https://github.com/Slimefun5/Slimefun5/issues).
Fields marked with an asterisk (*) are required.
- id: checklist type: checkboxes attributes: - label: '❗ Checklist' + label: 'Checklist' description: Please go through this checklist before creating the issue. options: - label: I am using the official english version of Slimefun and did not modify the jar. required: true - - label: I downloaded the official version from the new build site [Blob Builds](https://blob.build/). - required: true - - label: I am using an up to date "DEV" (not "RC") version of Slimefun. + - label: I downloaded the latest release from [GitHub Releases](https://github.com/Slimefun5/Slimefun5/releases). required: true - label: I am aware that issues related to Slimefun addons need to be reported on their bug trackers and not here. required: true @@ -34,7 +31,7 @@ body: validations: required: true attributes: - label: '📍 Description' + label: 'Description' description: | A clear and detailed description of what went wrong. The more information you can provide, the easier we can handle this problem. @@ -46,7 +43,7 @@ body: validations: required: true attributes: - label: '📑 Reproduction Steps' + label: 'Reproduction Steps' description: | Tell us the exact steps to reproduce this issue, the more detailed the easier we can reproduce it. placeholder: | @@ -59,7 +56,7 @@ body: validations: required: true attributes: - label: '💡 Expected Behavior' + label: 'Expected Behavior' description: | What were you expecting to happen? What do you think would have been the correct behaviour? @@ -69,7 +66,7 @@ body: - id: media type: textarea attributes: - label: '📷 Screenshots / Videos' + label: 'Screenshots / Videos' description: | The best way to illustrate in an issue is by recording a Video or taking a Screenshot. If you can capture any footage of the bug happening, it would help us out a lot! @@ -79,7 +76,7 @@ body: - id: server-log type: input attributes: - label: '📜 Server Log' + label: 'Server Log' description: | Take a look at your Server Log and upload any error messages from Slimefun to a pasting site (e.g. https://pastebin.com/). If you are unsure about it, post your full log, you can find it under /logs/latest.log @@ -88,7 +85,7 @@ body: - id: error-reports type: input attributes: - label: '📂 `/error-reports/` folder' + label: '`/error-reports/` folder' description: | Check the folder `/plugins/Slimefun/error-reports/` and upload any files inside that folder to a pasting site (e.g. https://pastebin.com/). placeholder: https://pastebin.com/... @@ -98,13 +95,12 @@ body: validations: required: true attributes: - label: '💻 Server Software' + label: 'Server Software' description: 'Please select the software your Server is running on' options: - Spigot - Paper - Purpur - - Airplane - Other (please specify in your description) - id: minecraft-version @@ -112,9 +108,10 @@ body: validations: required: true attributes: - label: '🎮 Minecraft Version' + label: 'Minecraft Version' description: 'Please select the Minecraft version of the server' options: + - 1.21.x - 1.20.x - 1.19.x - 1.18.x @@ -127,7 +124,7 @@ body: validations: required: true attributes: - label: '⭐ Slimefun version' + label: 'Slimefun version' description: | **"latest" is not a version number, we need the exact version.** We recommend running "/sf versions" and uploading a screenshot of that. @@ -137,7 +134,7 @@ body: - id: other-versions type: textarea attributes: - label: '🧭 Other plugins' + label: 'Other plugins' description: | If your issue is related to another plugin, make sure to include this here! placeholder: The issue is related to plugin [...], version [...] @@ -145,8 +142,6 @@ body: - type: markdown attributes: value: | - ## ❤️ Thank you for submitting your bug report! + ## Thank you for submitting your bug report! If you find any additional info that can help to identify this problem, don't hesitate to comment on your issue! Any additional info can help us fix this bug faster. - In the meantime, try visiting our [Discord server](https://discord.gg/slimefun). - Perhaps someone else has experienced a similar issue. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index b14ef722f3..b4c81820d9 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,11 +1,8 @@ blank_issues_enabled: false contact_links: - name: Code of Conduct - url: https://github.com/Slimefun/Slimefun4/blob/master/.github/CODE_OF_CONDUCT.md + url: https://github.com/Slimefun5/Slimefun5/blob/master/.github/CODE_OF_CONDUCT.md about: Please read this before posting - name: Bug Report Guidelines url: https://github.com/Slimefun/Slimefun4/wiki/How-to-report-bugs about: Guidelines on how to make good Bug reports - - name: Discord Server (for Questions and Suggestions) - url: https://discord.gg/slimefun - about: Please ask and answer questions here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 0ebdee6426..7b2f4c2386 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -17,7 +17,7 @@ - [ ] I have fully tested the proposed changes and promise that they will not break everything into chaos. - [ ] I have also tested the proposed changes in combination with various popular addons and can confirm my changes do not break them. -- [ ] I have made sure that the proposed changes do not break compatibility across the supported Minecraft versions (1.16.* - 1.20.*). +- [ ] I have made sure that the proposed changes do not break compatibility across the supported Minecraft versions (1.16.* - 1.21.*). - [ ] I followed the existing code standards and didn't mess up the formatting. - [ ] I did my best to add documentation to any public classes or methods I added. - [ ] I have added `Nonnull` and `Nullable` annotations to my methods to indicate their behaviour for null values diff --git a/.github/workflows/auto-approve.yml b/.github/workflows/auto-approve.yml index 8f3836fad9..913a1e7be9 100644 --- a/.github/workflows/auto-approve.yml +++ b/.github/workflows/auto-approve.yml @@ -16,11 +16,11 @@ jobs: pull-requests: write # Only run this on the main repo - if: github.event.pull_request.head.repo.full_name == 'Slimefun/Slimefun4' + if: github.event.pull_request.head.repo.full_name == 'Slimefun5/Slimefun5' steps: - name: Approve via actions uses: hmarr/auto-approve-action@v4.0.0 - if: github.actor == 'TheBusyBot' || github.actor == 'renovate[bot]' + if: github.actor == 'renovate[bot]' with: github-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/auto-squash.yml b/.github/workflows/auto-squash.yml index 8b8ef1f434..8f210d6e51 100644 --- a/.github/workflows/auto-squash.yml +++ b/.github/workflows/auto-squash.yml @@ -18,13 +18,13 @@ jobs: runs-on: ubuntu-latest ## Only run this on the main repo - if: github.event.pull_request.head.repo.full_name == 'Slimefun/Slimefun4' + if: github.event.pull_request.head.repo.full_name == 'Slimefun5/Slimefun5' steps: - name: Auto squash uses: pascalgn/automerge-action@v0.16.4 env: - GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} UPDATE_RETRIES: 0 MERGE_METHOD: squash MERGE_FORKS: false @@ -38,13 +38,13 @@ jobs: runs-on: ubuntu-latest ## Only run this on the main repo - if: github.event.pull_request.head.repo.full_name == 'Slimefun/Slimefun4' + if: github.event.pull_request.head.repo.full_name == 'Slimefun5/Slimefun5' steps: - name: Auto squash uses: pascalgn/automerge-action@v0.16.4 env: - GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} UPDATE_RETRIES: 0 MERGE_METHOD: squash MERGE_FORKS: false diff --git a/.github/workflows/close-invalid-issues.yml b/.github/workflows/close-invalid-issues.yml index 705f6ab9a5..3372a5dfa2 100644 --- a/.github/workflows/close-invalid-issues.yml +++ b/.github/workflows/close-invalid-issues.yml @@ -4,6 +4,10 @@ on: issues: types: [opened] +permissions: + contents: read + issues: write + jobs: comment: @@ -15,23 +19,22 @@ jobs: - name: Close Issue uses: maxkomarychev/octions/octions/issues/update@master with: - token: ${{ secrets.ACCESS_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} issue_number: ${{ github.event.issue.number }} state: closed - name: Add invalid label uses: maxkomarychev/octions/octions/issues/add-labels@master with: - token: ${{ secrets.ACCESS_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} issue_number: ${{ github.event.issue.number }} labels: 'invalid' - name: Create a comment uses: maxkomarychev/octions/octions/issues/create-comment@master with: - token: ${{ secrets.ACCESS_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} issue_number: ${{ github.event.issue.number }} body: |- Your issue seems to be missing our template. - [Click here to create a bug report](https://github.com/Slimefun/Slimefun4/issues/new/choose) + [Click here to create a bug report](https://github.com/Slimefun5/Slimefun5/issues/new/choose) - Please remember that this Bug Tracker is exclusively reserved for Bug reports, any other form - of discussion, like suggestions or questions should be posted on our discord server (You can find a link [on our main page](https://github.com/Slimefun/Slimefun4#discord)). + Please remember that this Bug Tracker is exclusively reserved for Bug reports. diff --git a/.github/workflows/discord-webhook.yml b/.github/workflows/discord-webhook.yml deleted file mode 100644 index 6735d5d642..0000000000 --- a/.github/workflows/discord-webhook.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Discord Webhook - -on: - push: - paths: - - 'src/**' - - '!src/main/resources/languages/**' - - 'pom.xml' - -permissions: - contents: read - -jobs: - report: - - name: Discord Webhook - runs-on: ubuntu-latest - - ## Only run this on the main repo - if: github.repository == 'Slimefun/Slimefun4' - - steps: - - name: Checkout repository - uses: actions/checkout@v4.2.2 - - - name: Set up Java JDK 21 - uses: actions/setup-java@v4.6.0 - with: - distribution: 'adopt' - java-version: '21' - java-package: jdk - architecture: x64 - - - name: Cache Maven packages - uses: actions/cache@v4 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - - - name: Run Discord Webhook - uses: baked-libs/discord-webhook@1.5.1 - with: - id: ${{ secrets.DISCORD_WEBHOOK_ID }} - token: ${{ secrets.DISCORD_WEBHOOK_TOKEN }} diff --git a/.github/workflows/duplicates.yml b/.github/workflows/duplicates.yml index 7cb94d0dcb..930a3fde7c 100644 --- a/.github/workflows/duplicates.yml +++ b/.github/workflows/duplicates.yml @@ -20,6 +20,6 @@ jobs: - name: Add label to the Issue uses: maxkomarychev/octions/octions/issues/add-labels@master with: - token: ${{ secrets.ACCESS_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} issue_number: ${{ github.event.issue.number }} labels: '🚩 Duplicate' diff --git a/.github/workflows/e2e-testing.yml b/.github/workflows/e2e-testing.yml deleted file mode 100644 index e6be9ca39a..0000000000 --- a/.github/workflows/e2e-testing.yml +++ /dev/null @@ -1,81 +0,0 @@ -name: End to End Testing - -on: - workflow_call: - inputs: - artifact-name: - description: 'Slimefun artifact name' - required: true - type: string - -jobs: - e2e-testing: - name: End to End Testing - runs-on: ubuntu-latest - timeout-minutes: 5 - - strategy: - matrix: - include: - - mcVersion: '1.16.5' - javaVersion: '16' - - mcVersion: '1.17.1' - javaVersion: '17' - - mcVersion: '1.18.2' - javaVersion: '18' - - mcVersion: '1.19.4' - javaVersion: '19' - - mcVersion: '1.20.4' - javaVersion: '20' - - mcVersion: '1.20.6' - javaVersion: '21' - #- mcVersion: 'latest' - # javaVersion: '21' - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up JDK - uses: actions/setup-java@v4.6.0 - with: - distribution: temurin - java-version: ${{ matrix.javaVersion }} - java-package: jdk - architecture: x64 - - - name: Setup server - run: | - echo 'eula=true' > eula.txt - mkdir plugins - - - name: Download ${{ matrix.mcVersion }} Paper - run: | - VERSION="${{ matrix.mcVersion }}" - if [ "$VERSION" == "latest" ]; then - VERSION=$(curl https://api.papermc.io/v2/projects/paper/ -s | jq -r '.versions[-1]') - fi - - BUILD_JAR=$(curl -s "https://api.papermc.io/v2/projects/paper/versions/$VERSION/builds" \ - | jq '.builds[-1] | "\(.build) \(.downloads.application.name)"' -r) - BUILD=$(echo "$BUILD_JAR" | awk '{print $1}') - JAR_FILE=$(echo "$BUILD_JAR" | awk '{print $2}') - - echo "Downloading... https://api.papermc.io/v2/projects/paper/versions/$VERSION/builds/$BUILD/downloads/$JAR_FILE" - curl -o paper.jar \ - "https://api.papermc.io/v2/projects/paper/versions/$VERSION/builds/$BUILD/downloads/$JAR_FILE" - - - name: Download Slimefun - uses: actions/download-artifact@v4 - with: - name: ${{ inputs.artifact-name }} - path: plugins/ - - - name: Download e2e-tester - run: | - curl -o e2e-tester.jar https://preview-builds.walshy.dev/download/e2e-tester/main/latest - mv e2e-tester.jar plugins/e2e-tester.jar - - - name: Run server - run: | - java -jar paper.jar --nogui diff --git a/.github/workflows/label-resolved-issues.yml b/.github/workflows/label-resolved-issues.yml index 5a54fb3144..d7acde26c0 100644 --- a/.github/workflows/label-resolved-issues.yml +++ b/.github/workflows/label-resolved-issues.yml @@ -20,13 +20,13 @@ jobs: uses: TheBusyBiscuit/recently-closed-issues@1.1.0 id: resolved with: - token: ${{ secrets.ACCESS_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} max_commits: 20 - name: Add label if: contains(steps.resolved.outputs.issues, github.event.issue.number) uses: maxkomarychev/octions/octions/issues/add-labels@master with: - token: ${{ secrets.ACCESS_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} issue_number: ${{ github.event.issue.number }} labels: '✔ Resolved' diff --git a/.github/workflows/merge-conflicts.yml b/.github/workflows/merge-conflicts.yml index 5ac09a0a50..bdae7d0998 100644 --- a/.github/workflows/merge-conflicts.yml +++ b/.github/workflows/merge-conflicts.yml @@ -11,7 +11,7 @@ permissions: jobs: validate: - if: github.repository == 'Slimefun/Slimefun4' + if: github.repository == 'Slimefun5/Slimefun5' name: Check for merge conflicts runs-on: ubuntu-latest @@ -19,4 +19,4 @@ jobs: - uses: mschilde/auto-label-merge-conflicts@master with: CONFLICT_LABEL_NAME: '⚡ Merge Conflicts' - GITHUB_TOKEN: "${{ secrets.ACCESS_TOKEN }}" + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/pr-labels.yml b/.github/workflows/pr-labels.yml index b857b2faa6..38e759665a 100644 --- a/.github/workflows/pr-labels.yml +++ b/.github/workflows/pr-labels.yml @@ -14,7 +14,7 @@ jobs: name: Pull Request Labels runs-on: ubuntu-latest - if: github.repository == 'Slimefun/Slimefun4' + if: github.repository == 'Slimefun5/Slimefun5' steps: - uses: baked-libs/pull-request-labels@v1.1 diff --git a/.github/workflows/preview-builds.yml b/.github/workflows/preview-builds.yml deleted file mode 100644 index b9e7b5d26a..0000000000 --- a/.github/workflows/preview-builds.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: Preview builds - -on: - workflow_run: - workflows: ["Pull Request"] - types: - - completed - -permissions: - contents: read - pull-requests: write - -jobs: - preview: - if: ${{ github.repository_owner == 'Slimefun' && github.event.workflow_run.conclusion == 'success' }} - name: Build and Publish the jar - runs-on: ubuntu-latest - - steps: - # Kinda jank way to grab the PR and commit hash and then download the artifact - # TODO: Move this code to our own mini-action - - name: Grab PR & run ID and download the artifact - uses: actions/github-script@v7 - with: - script: | - const allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.payload.workflow_run.id, - }); - - for (const artifact of allArtifacts.data.artifacts) { - // Extract the PR number and commit hash from the artifact name - const match = /^slimefun-(\d+)-([a-f0-9]{8})$/.exec(artifact.name); - if (match) { - require("fs").appendFileSync( - process.env.GITHUB_ENV, - `\nPR_NUMBER=${match[1]}` + - `\nCOMMIT_HASH=${match[2]}` - ); - - const download = await github.rest.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: artifact.id, - archive_format: 'zip', - }); - require('fs').writeFileSync(`${process.env.GITHUB_WORKSPACE}/preview.zip`, Buffer.from(download.data)) - - break; - } - } - - # Unzip the artifact - - name: Unzip - run: | - unzip preview.zip - rm preview.zip - mv 'Slimefun vPreview Build #${{ env.PR_NUMBER }}-${{ env.COMMIT_HASH }}.jar' preview.jar - - - name: Upload to preview service - run: | - curl -X POST \ - -H 'Authorization: ${{ secrets.PUBLISH_TOKEN }}' \ - -H "X-Checksum: $(sha256sum 'preview.jar' | awk '{print $1}')" \ - --data-binary '@preview.jar' \ - https://preview-builds.walshy.dev/upload/Slimefun/${{ env.PR_NUMBER }}/${{ env.COMMIT_HASH }} - - - name: Post comment - uses: marocchino/sticky-pull-request-comment@v2 - with: - number: ${{ env.PR_NUMBER }} - message: | - ### Slimefun preview build - - A Slimefun preview build is available for testing! - Commit: ${{ env.COMMIT_HASH }} - - https://preview-builds.walshy.dev/download/Slimefun/${{ env.PR_NUMBER }}/${{ env.COMMIT_HASH }} - - > **Note**: This is not a supported build and is only here for the purposes of testing. - > Do not run this on a live server and do not report bugs anywhere but this PR! diff --git a/.github/workflows/publish-build.yml b/.github/workflows/publish-build.yml deleted file mode 100644 index 31e94e16a2..0000000000 --- a/.github/workflows/publish-build.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Publish build - -on: - push: - branches: - - master - - stable - - experimental - -jobs: - publish: - name: Upload build - runs-on: ubuntu-latest - if: contains(github.event.head_commit.message, '[ci skip]') == false - - steps: - - uses: actions/checkout@v4 - - - name: Set up JDK 21 - uses: actions/setup-java@v4.6.0 - with: - distribution: 'adopt' - java-version: '21' - java-package: jdk - architecture: x64 - - - name: Build with Maven - run: mvn clean package - - - name: Upload Dev build - uses: WalshyDev/blob-builds/gh-action@ea9ecd9266c902c6627f884e657560d0fa6b61dd - if: github.ref == 'refs/heads/master' - with: - project: Slimefun4 - releaseChannel: Dev - apiToken: ${{ secrets.BLOB_BUILDS_API_TOKEN }} - file: './target/Slimefun v4.9-UNOFFICIAL.jar' - releaseNotes: ${{ github.event.head_commit.message }} - - - name: Upload RC build - uses: WalshyDev/blob-builds/gh-action@ea9ecd9266c902c6627f884e657560d0fa6b61dd - if: github.ref == 'refs/heads/stable' - with: - project: Slimefun4 - releaseChannel: 'RC' - apiToken: ${{ secrets.BLOB_BUILDS_API_TOKEN }} - file: './target/Slimefun v4.9-UNOFFICIAL.jar' - releaseNotes: ${{ github.event.head_commit.message }} - - - name: Upload Experimental build - uses: WalshyDev/blob-builds/gh-action@ea9ecd9266c902c6627f884e657560d0fa6b61dd - if: github.ref == 'refs/heads/experimental' - with: - project: Slimefun4 - releaseChannel: 'Experimental' - apiToken: ${{ secrets.BLOB_BUILDS_API_TOKEN }} - file: './target/Slimefun v4.9-UNOFFICIAL.jar' - releaseNotes: ${{ github.event.head_commit.message }} diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 28e0d47a98..c56a81b5d8 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -55,8 +55,4 @@ jobs: name: slimefun-${{ github.event.number }}-${{ env.SHORT_COMMIT_HASH }} path: 'target/Slimefun v${{ env.JAR_VERSION }}.jar' - call-workflows: - needs: [setup-preview-build] - uses: ./.github/workflows/e2e-testing.yml - with: - artifact-name: slimefun-${{ github.event.number }}-${{ needs.setup-preview-build.outputs.short-commit-hash }} + diff --git a/.github/workflows/release-candidates.yml b/.github/workflows/release-candidates.yml deleted file mode 100644 index e330af4b09..0000000000 --- a/.github/workflows/release-candidates.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: Create new Release Candidate - -on: - workflow_dispatch: - inputs: - number: - description: 'RC number (e.g. 15)' - required: true - release_date: - description: 'Date of release (e.g. 12-apr-2021)' - required: true - -jobs: - release: - - name: Create new release - runs-on: ubuntu-latest - - steps: - - - name: Checkout repository - uses: actions/checkout@v4 - with: - ref: 'stable' - - - name: Merge latest commits into 'stable' - uses: devmasx/merge-branch@1.4.0 - with: - type: now - from_branch: 'master' - target_branch: 'stable' - github_token: ${{ secrets.GITHUB_TOKEN }} - - - name: Get the latest commit sha - id: latest - run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - - - name: Create Release - id: create_release - uses: actions/create-release@v1.1.4 - env: - GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} - with: - tag_name: RC-${{ github.event.inputs.number }} - release_name: Release Candidate ${{ github.event.inputs.number }} (git ${{ steps.latest.outputs.sha_short }}) - draft: false - prerelease: false - body: | - ## 💾 Download link - This release candidate of Slimefun4 can be downloaded here: - https://blob.build/project/Slimefun4/RC - - ### ❓ How to install Slimefun - Simply drag & drop the Slimefun4 jar file into the `/plugins/` directory of your server. - If you need any help installing Slimefun, feel free to check out our wiki article on [How to install Slimefun](https://github.com/Slimefun/Slimefun4/wiki/Installing-Slimefun). - - ## 📝 Change log - You can find a short summary of all the changes that are included in this release right here: - https://github.com/Slimefun/Slimefun4/blob/master/CHANGELOG.md#release-candidate-${{ github.event.inputs.number }}-${{ github.event.inputs.release_date }} - - ## 📦 Maven dependency reference - If you want to develop an addon for Slimefun ([Developer Reference](https://github.com/Slimefun/Slimefun4/wiki/Developer-Guide)), then you can build your project against this specific version of Slimefun using the following `pom.xml` dependency: - ```xml - - - jitpack.io - https://jitpack.io - - - - - - com.github.Slimefun - Slimefun4 - RC-${{ github.event.inputs.number }} - - - ``` diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..4c240ff41a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,54 @@ +name: Release + +on: + push: + tags: + - 'v*' + +permissions: + contents: write + +jobs: + release: + name: Merge, Build and Release + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Merge tag into master + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git checkout master + git merge ${{ github.sha }} --no-edit + git push origin master + + - name: Set up JDK 21 + uses: actions/setup-java@v4.6.0 + with: + distribution: 'adopt' + java-version: '21' + java-package: jdk + architecture: x64 + + - name: Cache Maven packages + uses: actions/cache@v4 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + + - name: Build with Maven + run: mvn clean package -Dmaven.test.skip=true --file pom.xml + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + files: 'target/Slimefun v4.9-UNOFFICIAL.jar' + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml deleted file mode 100644 index 2702fbb6c8..0000000000 --- a/.github/workflows/sonarcloud.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: SonarCloud Scanner - -on: - pull_request: - types: [opened, synchronize, reopened] - -permissions: - contents: read - -jobs: - scan: - - name: SonarCloud Scanner - runs-on: ubuntu-latest - - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - - steps: - - name: Checkout repository - uses: actions/checkout@v4.2.2 - with: - fetch-depth: 0 - - - name: Set up JDK 21 - uses: actions/setup-java@v4.6.0 - with: - distribution: 'adopt' - java-version: '21' - java-package: jdk - architecture: x64 - - - name: Cache SonarCloud packages - uses: actions/cache@v4 - with: - path: ~/.sonar/cache - key: ${{ runner.os }}-sonar - restore-keys: ${{ runner.os }}-sonar - - - name: Cache Maven packages - uses: actions/cache@v4 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - - - name: SonarCloud analysis - run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar - if: ${{ env.SONAR_TOKEN != 0 }} diff --git a/.github/workflows/translator-webhook.yml b/.github/workflows/translator-webhook.yml deleted file mode 100644 index ec8328f899..0000000000 --- a/.github/workflows/translator-webhook.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Translation Notifier - -on: - push: - branches: - - master - paths: - - 'src/main/resources/languages/en/**.yml' - -permissions: - contents: read - -jobs: - notify: - - name: Translation-Notifier - runs-on: ubuntu-latest - if: github.repository == 'Slimefun/Slimefun4' - - steps: - - name: Discord Notification - uses: Ilshidur/action-discord@master - with: - args: '<@&665202905271369776> New strings have been added to Slimefun4''s language files. You can translate them at https://crowdin.com/project/slimefun' - env: - DISCORD_WEBHOOK: ${{ secrets.TRANSLATOR_WEBHOOK }} diff --git a/README.md b/README.md index affc3ed96c..80fb614e51 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,39 @@ -# Slimefun 4 -*Looking for the download link? [**Click here**](https://github.com/Slimefun/Slimefun4/blob/master/README.md#floppy_disk-download-slimefun-4)* +# Slimefun 5 (Continued Fork) -Slimefun is a plugin which aims to turn your Spigot Server into a modpack without ever installing a single mod. It offers everything you could possibly imagine. From Backpacks to Jetpacks! Slimefun lets every player decide on their own how much they want to dive into Magic or Tech.
+> **This is a community-maintained fork of [Slimefun4](https://github.com/Slimefun/Slimefun4), which was discontinued by its original developers. This fork continues development with support for modern Minecraft versions.** + +Slimefun is a plugin which aims to turn your Spigot Server into a modpack without ever installing a single mod. From Backpacks to Jetpacks! Slimefun lets every player decide on their own how much they want to dive into Magic or Tech.
We got everything from magical wands to nuclear reactors.
We feature a magical altar, an electric power grid and even item transport systems. This project originally started back **in 2013** and has grown ever since.
-From one single person working on this plugin back then, we grew to a community of thousands of players and hundreds of contributors to this project.
It currently adds over **500 new items and recipes** to Minecraft ([Read more about the history of this project](https://github.com/Slimefun/Slimefun4/wiki/Slimefun-in-a-nutshell)). -But it also comes with a lot of addons! Check out our [addons](https://github.com/Slimefun/Slimefun4/wiki/Addons), you may find exactly what you were looking for. +Check out the available [addons](https://github.com/Slimefun/Slimefun4/wiki/Addons) — they may have exactly what you were looking for. ### Quick navigation -* **[:floppy_disk: Download Slimefun4](#floppy_disk-download-slimefun-4)** +* **[:floppy_disk: Download](#floppy_disk-download)** * **[:framed_picture: Screenshots](#framed_picture-screenshots)** -* **[:headphones: Discord Support Server](#headphones-discord)** -* **[:beetle: Bug Tracker](https://github.com/Slimefun/Slimefun4/issues)** +* **[:beetle: Bug Tracker](https://github.com/Slimefun5/Slimefun5/issues)** * **[:open_book: Wiki](https://github.com/Slimefun/Slimefun4/wiki)** * **[:interrobang: FAQ](https://github.com/Slimefun/Slimefun4/wiki/FAQ)** -* **[:handshake: How to contribute](https://github.com/Slimefun/Slimefun4/blob/master/CONTRIBUTING.md)** +* **[:handshake: How to contribute](https://github.com/Slimefun5/Slimefun5/blob/master/CONTRIBUTING.md)** -## :floppy_disk: Download Slimefun 4 +## :floppy_disk: Download Slimefun requires your Minecraft Server to be running on [Spigot](https://spigotmc.org/), [Paper](https://papermc.io/) or on any fork of these.
(See also: [How to install Slimefun](https://github.com/Slimefun/Slimefun4/wiki/Installing-Slimefun)) -Slimefun 4 can be downloaded **for free** on our builds page.
-We currently provide two distinct versions of Slimefun, development builds and "stable" builds.
-Here is a full summary of the differences between the two different versions of Slimefun. - -| | development (latest) | "stable" | -| ------------------ | -------- | -------- | -| **Minecraft version(s)** | :video_game: **1.16.\* - 1.20.\*** | :video_game: **1.16.\* - 1.20.\*** | -| **Java version** | :computer: **Java 16 (or higher)** | :computer: **Java 16 (or higher)** | -| **automatic updates** | :heavy_check_mark: | :heavy_check_mark: | -| **frequent updates** | :heavy_check_mark: | :x: | -| **latest content** | :heavy_check_mark: | :x: | -| **Discord support** | :heavy_check_mark: | :x: | -| **Bug Reports** | :heavy_check_mark: | :x: | -| **testing before release** | :x: | :heavy_check_mark: | -| **change logs** | :x: | :memo: **[change log](https://github.com/Slimefun/Slimefun4/blob/master/CHANGELOG.md)** | -| **Download links** | :floppy_disk: **[download latest](https://blob.build/project/Slimefun4/Dev)** | :floppy_disk: **[download "stable"](https://blob.build/project/Slimefun4/RC)** | - -**:exclamation: We wholeheartedly recommend you to use _development builds_, they are the most recent version of Slimefun and also receive the most frequent updates! In fact, "stable" builds are so outdated that we won't accept bug reports from them at all.** -
- Here's why... - -"Stable" builds do not receive frequent updates or fast patches. As time goes on, bugs are fixed but it will take some time until these fixes make it into a "stable" build. We will also not accept or review any bug reports from "stable" builds. They are in fact just old development builds that seemed to run fine without any __major__ issues. - -**:question: Why use a "stable" build then?**
-While "stable" builds most definitely contain more bugs than development builds due to their very slow update schedule. you can be sure that they will not include __game-breaking__ issues, but rest assured that development builds almost never contain such issues either. If your server or business however heavily depends on a version of Slimefun that does not change/update a lot, you are forgiven if you choose the "stable" branch. But development builds will bring you the best experience, both in terms of features and bug fixes. - -**:question: What exactly are these "stable" builds then and why do you put them in quotes?**
-"Stable" builds are literally just outdated development builds that seemed to run fine without any __major__ issues. But they are far from bug-free hence why actually calling them stable would be hypocritical. However these builds can only really stay "stable" if there are enough people using development builds and report any bugs they come across. Otherwise potential issues may go unnoticed and slip into a "stable" build. Again, we really recommend you to choose the development builds. But since a few people really wanted "stable" builds, they are now an option too. +| | This fork | +| ------------------ | -------- | +| **Minecraft version(s)** | :video_game: **1.16.\* - 1.21.\*** | +| **Java version** | :computer: **Java 21 (or higher)** | +| **Downloads** | :floppy_disk: **[GitHub Releases](https://github.com/Slimefun5/Slimefun5/releases)** | -
+Download the latest JAR from the [Releases page](https://github.com/Slimefun5/Slimefun5/releases) and drop it into your server's `plugins/` folder. ## :framed_picture: Screenshots So what does Slimefun look like?
-Well, we asked some users on our [Discord server](#headphones-discord) to send us some screenshots, so see for yourself: +Here are some screenshots from the community: | Reactors and electricity | Awesome factories | Magic and Altars | | :-------------------------------------------: | :--------------------------------------: | :----------------------------------------: | | ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase1.png) | ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase6.png) | ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase5.png) | @@ -65,93 +41,50 @@ Well, we asked some users on our [Discord server](#headphones-discord) to send u | ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase4.png) | ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase3.png) | ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase2.png) | | *Screenshot provided by GalaxyKat11#3816* | *Screenshot provided by TamThan#7987* | *Screenshot provided by Kilaruna#4981* | -## :headphones: Discord -You can find Slimefun's community on Discord and connect with **over 7000** users of this plugin from all over the world.
-Click the badge down below to join the server for suggestions/questions or other discussions about this plugin.
-We are also hosting a community event every so often, join us to find out more.
-**Important: We don't accept bug reports on discord, please use our [Issue Tracker](https://github.com/Slimefun/Slimefun4/issues) to submit bug reports!** - -Due to the sheer size of this discord server, we need to enforce some [important rules](https://github.com/Slimefun/Slimefun4/wiki/Discord-Rules).
-Not following these rules can lead to a kick or even a ban from the server. - -

- - Discord Invite - -

- ## :open_book: Wiki -Slimefun has a (detailed and well-maintained - *cough*) Wiki for new players, maybe also consider -expanding the wiki to help grow our community and help out new users of this plugin. +The upstream Slimefun wiki remains a great resource for getting started:
https://github.com/Slimefun/Slimefun4/wiki #### :star: Highlighted Articles * [What is Slimefun?](https://github.com/Slimefun/Slimefun4/wiki/Slimefun-in-a-nutshell) * [How to install Slimefun](https://github.com/Slimefun/Slimefun4/wiki/Installing-Slimefun) * [Addons for Slimefun 4](https://github.com/Slimefun/Slimefun4/wiki/Addons) -* [How to create an Addon for Slimefun 4](https://github.com/Slimefun/Slimefun4/wiki/Developer-Guide) +* [How to create an Addon](https://github.com/Slimefun/Slimefun4/wiki/Developer-Guide) * [Getting Started](https://github.com/Slimefun/Slimefun4/wiki/Getting-Started) * [Frequently Asked Questions](https://github.com/Slimefun/Slimefun4/wiki/FAQ) * [Common issues](https://github.com/Slimefun/Slimefun4/wiki/Common-Issues) -* [Help us expand the Wiki!](https://github.com/Slimefun/Slimefun4/wiki/Expanding-the-Wiki) -* [Help us translate Slimefun!](https://github.com/Slimefun/Slimefun4/wiki/Translating-Slimefun) The wiki is entirely community-run, so if you find an article missing, feel free to write one and share it with others. ## :handshake: Contributing to this project -Slimefun 4 is an Open-Source project and licensed under -[GNU GPLv3](https://github.com/Slimefun/Slimefun4/blob/master/LICENSE).
-**Over 200 people have already contributed to this amazing project. You guys are awesome! :heart:**
-Please consider helping us maintain this project too, your engagement keeps the project alive! - -You can find more info on how to contribute to this project in our [CONTRIBUTING.md](https://github.com/Slimefun/Slimefun4/blob/master/CONTRIBUTING.md). +Slimefun is an Open-Source project and licensed under +[GNU GPLv3](https://github.com/Slimefun5/Slimefun5/blob/master/LICENSE).
+Pull requests are welcome! Please read our [CONTRIBUTING.md](https://github.com/Slimefun5/Slimefun5/blob/master/CONTRIBUTING.md) before submitting. ## :exclamation: Disclaimers -Slimefun4 uses various systems that collect usage information or download automatic updates as well as the latest information about the project. +This fork uses various systems that collect usage information or connect to external services. We do not collect any personal information from you but there are some services that may gather or download some form of data. -You can opt-out of the Auto-Updater and stats collection at any time! - -
- Automatic updates - -Slimefun4 uses an Auto-Updater which connects to https://thebusybiscuit.github.io/builds/ to check for and download updates.
-This behaviour is enabled by default but can be turned off under `/plugins/Slimefun/config.yml`.
-We highly recommend you to keep this on at any time though, as you could be missing out on important patches. -
-
Metrics and Statistics -Slimefun4 uses [bStats](https://bstats.org/plugin/bukkit/Slimefun/4574) to collect anonymous information about the usage of this plugin.
+Slimefun uses [bStats](https://bstats.org/plugin/bukkit/Slimefun/4574) to collect anonymous information about the usage of this plugin.
This is solely for statistical purposes, as we are interested in how Servers/Players use this plugin.
All available data is anonymous and aggregated, at no point can we see individual server or player information.
All of the collected data is publicly accessible: https://bstats.org/plugin/bukkit/Slimefun/4574 -You can also disable this behaviour under `/plugins/bStats/config.yml`.
+You can disable this under `/plugins/bStats/config.yml`.
For more info see [bStats' Privacy Policy](https://bstats.org/privacy-policy) - -Our [bStats Module](https://github.com/Slimefun/MetricsModule) is downloaded automatically when installing this Plugin, this module will automatically update on server starts independently from the main plugin. This way we can automatically roll out updates to the bStats module, in cases of severe performance issues for example where live data and insight into what is impacting performance can be crucial. -These updates can of course be disabled under `/plugins/Slimefun/config.yml`. To disable metrics collection as a whole, see the paragraph above. - ---- - -Slimefun also uses its own analytics system to collect anonymous information about the performance of this plugin.
-This is solely for statistical purposes, as we are interested in how it's performing for all servers.
-All available data is anonymous and aggregated, at no point can we see individual server information.
- -You can also disable this behaviour under `/plugins/Slimefun/config.yml`.
-
GitHub Integration -Lastly, Slimefun4 connects to https://api.github.com/ to gather information about this open-source project.
+Slimefun connects to https://api.github.com/ to gather information about this open-source project.
No information about you or your Minecraft Server is sent to GitHub. This information includes (but is not limited to) -* list of contributors, their username and profile link (from the repositories `Slimefun/Slimefun4`, `Slimefun/Slimefun-Wiki` and `Slimefun/Resourcepack`) +* list of contributors, their username and profile link * amount of open issues in this repository * amount of pending pull requests in this repository * amount of stars in this repository @@ -160,6 +93,6 @@ This information includes (but is not limited to) * date of the last commit to this repository
-Additionally the plugin connects to [textures.minecraft.net](https://www.minecraft.net/en-us) to retrieve the Minecraft skins of our contributors (if possible).
+Additionally the plugin connects to [textures.minecraft.net](https://www.minecraft.net/en-us) to retrieve the Minecraft skins of contributors (if possible).
*Note that Slimefun is not associated with `Mojang Studios` or `Minecraft`.* From df43b54a289ce7db330937b5b87f360376619c6d Mon Sep 17 00:00:00 2001 From: Intisy Date: Thu, 5 Mar 2026 15:47:04 +0100 Subject: [PATCH 4/8] Switch default branch from master to stable --- .github/ISSUE_TEMPLATE/config.yml | 2 +- .github/workflows/maven-compiler.yml | 2 +- .github/workflows/merge-conflicts.yml | 2 +- .github/workflows/pull-request.yml | 2 -- .github/workflows/release.yml | 6 +++--- .github/workflows/yaml-linter.yml | 2 +- README.md | 6 +++--- 7 files changed, 10 insertions(+), 12 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index b4c81820d9..4a69e7cfd6 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,7 +1,7 @@ blank_issues_enabled: false contact_links: - name: Code of Conduct - url: https://github.com/Slimefun5/Slimefun5/blob/master/.github/CODE_OF_CONDUCT.md + url: https://github.com/Slimefun5/Slimefun5/blob/stable/.github/CODE_OF_CONDUCT.md about: Please read this before posting - name: Bug Report Guidelines url: https://github.com/Slimefun/Slimefun4/wiki/How-to-report-bugs diff --git a/.github/workflows/maven-compiler.yml b/.github/workflows/maven-compiler.yml index fa79dc66ca..2e39915984 100644 --- a/.github/workflows/maven-compiler.yml +++ b/.github/workflows/maven-compiler.yml @@ -3,7 +3,7 @@ name: Java CI on: push: branches: - - master + - stable paths: - 'src/**' - 'pom.xml' diff --git a/.github/workflows/merge-conflicts.yml b/.github/workflows/merge-conflicts.yml index bdae7d0998..e12d2c476f 100644 --- a/.github/workflows/merge-conflicts.yml +++ b/.github/workflows/merge-conflicts.yml @@ -3,7 +3,7 @@ name: Merge Conflicts on: push: branches: - - master + - stable permissions: contents: read diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index c56a81b5d8..c3a44b5eab 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -54,5 +54,3 @@ jobs: with: name: slimefun-${{ github.event.number }}-${{ env.SHORT_COMMIT_HASH }} path: 'target/Slimefun v${{ env.JAR_VERSION }}.jar' - - diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4c240ff41a..5402876a23 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,13 +19,13 @@ jobs: with: fetch-depth: 0 - - name: Merge tag into master + - name: Merge tag into stable run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" - git checkout master + git checkout stable git merge ${{ github.sha }} --no-edit - git push origin master + git push origin stable - name: Set up JDK 21 uses: actions/setup-java@v4.6.0 diff --git a/.github/workflows/yaml-linter.yml b/.github/workflows/yaml-linter.yml index a1e22c99c5..f54d74173f 100644 --- a/.github/workflows/yaml-linter.yml +++ b/.github/workflows/yaml-linter.yml @@ -6,7 +6,7 @@ on: - '**.yml' pull_request: branches: - - master + - stable permissions: contents: read diff --git a/README.md b/README.md index 80fb614e51..b4608c892d 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Check out the available [addons](https://github.com/Slimefun/Slimefun4/wiki/Addo * **[:beetle: Bug Tracker](https://github.com/Slimefun5/Slimefun5/issues)** * **[:open_book: Wiki](https://github.com/Slimefun/Slimefun4/wiki)** * **[:interrobang: FAQ](https://github.com/Slimefun/Slimefun4/wiki/FAQ)** -* **[:handshake: How to contribute](https://github.com/Slimefun5/Slimefun5/blob/master/CONTRIBUTING.md)** +* **[:handshake: How to contribute](https://github.com/Slimefun5/Slimefun5/blob/stable/CONTRIBUTING.md)** ## :floppy_disk: Download Slimefun requires your Minecraft Server to be running on [Spigot](https://spigotmc.org/), [Paper](https://papermc.io/) or on any fork of these.
@@ -58,8 +58,8 @@ The wiki is entirely community-run, so if you find an article missing, feel free ## :handshake: Contributing to this project Slimefun is an Open-Source project and licensed under -[GNU GPLv3](https://github.com/Slimefun5/Slimefun5/blob/master/LICENSE).
-Pull requests are welcome! Please read our [CONTRIBUTING.md](https://github.com/Slimefun5/Slimefun5/blob/master/CONTRIBUTING.md) before submitting. +[GNU GPLv3](https://github.com/Slimefun5/Slimefun5/blob/stable/LICENSE).
+Pull requests are welcome! Please read our [CONTRIBUTING.md](https://github.com/Slimefun5/Slimefun5/blob/stable/CONTRIBUTING.md) before submitting. ## :exclamation: Disclaimers This fork uses various systems that collect usage information or connect to external services. From 577ea54d4376a0af8e12b690c89a3b2cbe4fcbdb Mon Sep 17 00:00:00 2001 From: Intisy Date: Thu, 5 Mar 2026 15:59:56 +0100 Subject: [PATCH 5/8] Bump default version to 5.0.0 and update workflows --- .github/workflows/pull-request.yml | 2 +- .github/workflows/release.yml | 8 +++++++- pom.xml | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index c3a44b5eab..dc03cf8137 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -44,7 +44,7 @@ jobs: echo "SHORT_COMMIT_HASH=$SHORT_COMMIT_HASH" >> "$GITHUB_ENV" echo "SHORT_COMMIT_HASH=$SHORT_COMMIT_HASH" >> "$GITHUB_OUTPUT" echo "JAR_VERSION=$JAR_VERSION" >> "$GITHUB_ENV" - sed -i "s/4.9-UNOFFICIAL<\/version>/$JAR_VERSION<\/version>/g" pom.xml + sed -i "s/5.0.0-UNOFFICIAL<\/version>/$JAR_VERSION<\/version>/g" pom.xml - name: Build with Maven run: mvn package diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5402876a23..8b9ca96708 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,6 +27,12 @@ jobs: git merge ${{ github.sha }} --no-edit git push origin stable + - name: Set version from tag + run: | + VERSION="${GITHUB_REF_NAME#v}" + echo "VERSION=$VERSION" >> "$GITHUB_ENV" + sed -i "s/5.0.0-UNOFFICIAL<\/version>/$VERSION<\/version>/g" pom.xml + - name: Set up JDK 21 uses: actions/setup-java@v4.6.0 with: @@ -48,7 +54,7 @@ jobs: - name: Create GitHub Release uses: softprops/action-gh-release@v2 with: - files: 'target/Slimefun v4.9-UNOFFICIAL.jar' + files: 'target/Slimefun v${{ env.VERSION }}.jar' generate_release_notes: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/pom.xml b/pom.xml index bdf9577d44..665611c427 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ - 4.9-UNOFFICIAL + 5.0.0-UNOFFICIAL 2013 jar From 4fd3529f59c8d1419b03f3331977c2afc2b100c4 Mon Sep 17 00:00:00 2001 From: Intisy Date: Tue, 10 Mar 2026 21:52:00 +0100 Subject: [PATCH 6/8] Migrate project build from Maven to Gradle --- .../{maven-compiler.yml => gradle-build.yml} | 20 +- .github/workflows/javadocs.yml | 14 +- .github/workflows/pull-request.yml | 27 +- .github/workflows/release.yml | 24 +- .gitignore | 4 +- build.gradle.kts | 121 ++++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 7 + gradlew | 251 ++++++++ gradlew.bat | 94 +++ pom.xml | 541 ------------------ settings.gradle.kts | 1 + .../slimefun4/implementation/Slimefun.java | 3 +- src/main/resources/plugin.yml | 2 +- .../slimefun4/TestPluginClass.java | 2 +- .../events/TestSlimefunBlockBreakEvent.java | 23 +- .../events/TestSlimefunBlockPlaceEvent.java | 27 +- .../TestSlimefunRegistryFinalizedEvent.java | 9 +- .../api/events/TestTalismanActivateEvent.java | 46 +- .../api/geo/TestResourceRegistration.java | 2 +- .../slimefun4/api/gps/TestWaypoints.java | 9 +- .../settings/TestDoubleRangeSetting.java | 2 +- .../api/items/settings/TestEnumSetting.java | 2 +- .../items/settings/TestIntRangeSetting.java | 2 +- .../api/items/settings/TestItemSettings.java | 2 +- .../settings/TestMaterialTagSetting.java | 2 +- .../profiles/TestAsyncProfileLoadEvent.java | 13 +- .../api/profiles/TestGuideHistory.java | 4 +- .../api/profiles/TestPlayerBackpacks.java | 4 +- .../api/profiles/TestPlayerProfile.java | 6 +- .../core/commands/TestBackpackCommand.java | 11 +- .../core/commands/TestChargeCommand.java | 4 +- .../core/commands/TestDebugFishCommand.java | 9 +- .../core/commands/TestGuideCommand.java | 9 +- .../core/commands/TestResearchCommand.java | 15 +- .../core/debug/TestDebugLogging.java | 2 +- .../core/guide/TestGuideOpening.java | 4 +- .../core/multiblocks/TestMultiBlocks.java | 2 +- .../core/networks/TestNetworkManager.java | 4 +- .../researching/TestProfileResearches.java | 4 +- .../researching/TestResearchUnlocking.java | 11 +- .../core/researching/TestResearches.java | 11 +- .../core/services/TestBlockDataService.java | 2 +- .../services/TestCustomTextureService.java | 2 +- .../core/services/TestItemDataService.java | 2 +- .../core/services/TestPermissionsService.java | 4 +- .../core/services/TestRecipeService.java | 7 +- .../core/services/TestUpdaterService.java | 2 +- .../AbstractLocaleRegexChecker.java | 2 +- .../items/TestDamageableItem.java | 4 +- .../items/TestRadioactiveItem.java | 2 +- .../items/TestSlimefunItem.java | 2 +- .../autocrafters/TestAbstractRecipe.java | 2 +- .../items/autocrafters/TestAutoCrafter.java | 6 +- .../items/backpacks/TestEnderBackpack.java | 4 +- .../items/food/TestDietCookie.java | 11 +- .../items/food/TestMeatJerky.java | 6 +- .../items/food/TestMonsterJerky.java | 6 +- .../items/tools/TestClimbingPick.java | 13 +- .../items/tools/TestPortableDustbin.java | 4 +- .../items/tools/TestTapeMeasure.java | 15 +- .../listeners/TestAnvilListener.java | 4 +- .../listeners/TestBackpackListener.java | 14 +- .../listeners/TestBeeListener.java | 19 +- .../listeners/TestBrewingStandListener.java | 4 +- .../listeners/TestCargoNodeListener.java | 4 +- .../TestCartographyTableListener.java | 4 +- .../listeners/TestCauldronListener.java | 6 +- .../listeners/TestCoolerListener.java | 11 +- .../listeners/TestCraftingTableListener.java | 8 +- .../listeners/TestDeathpointListener.java | 12 +- .../listeners/TestFireworksListener.java | 21 +- .../listeners/TestGrindstoneListener.java | 4 +- .../listeners/TestIronGolemListener.java | 4 +- .../listeners/TestItemPickupListener.java | 16 +- .../listeners/TestMultiblockListener.java | 11 +- .../listeners/TestNetworkListener.java | 4 +- .../listeners/TestPiglinListener.java | 8 +- .../listeners/TestPlayerProfileListener.java | 14 +- .../listeners/TestSlimefunGuideListener.java | 10 +- .../TestSlimefunItemInteractListener.java | 47 +- .../listeners/TestSmithingTableListener.java | 8 +- .../listeners/TestSoulboundListener.java | 21 +- .../TestVillagerTradingListener.java | 4 +- .../registration/TestItemGroups.java | 4 +- .../registration/TestItemHandlers.java | 2 +- .../registration/TestRechargeableItems.java | 2 +- .../registration/TestRegistration.java | 2 +- .../TestSlimefunItemRegistration.java | 2 +- .../implementation/tasks/TestArmorTask.java | 4 +- .../storage/backend/TestLegacyBackend.java | 4 +- .../slimefun4/test/TestUtilities.java | 9 +- .../test/mocks/InventoryViewWrapper.java | 8 +- .../test/presets/SlimefunItemTest.java | 4 +- .../slimefun4/utils/TestChargeUtils.java | 2 +- .../slimefun4/utils/TestFireworkUtils.java | 4 +- .../utils/TestInfiniteBlockGenerators.java | 15 +- .../slimefun4/utils/TestItemStackWrapper.java | 2 +- .../slimefun4/utils/TestLoreComparison.java | 2 +- .../slimefun4/utils/TestSoulboundItem.java | 2 +- .../slimefun4/utils/biomes/TestBiomeMap.java | 2 +- .../biomes/TestBiomeMapCompatibility.java | 2 +- .../utils/biomes/TestBiomeMapParser.java | 2 +- .../utils/tags/TestSlimefunTags.java | 2 +- .../slimefun4/utils/tags/TestTagParser.java | 2 +- 105 files changed, 897 insertions(+), 885 deletions(-) rename .github/workflows/{maven-compiler.yml => gradle-build.yml} (61%) create mode 100644 build.gradle.kts create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat delete mode 100644 pom.xml create mode 100644 settings.gradle.kts diff --git a/.github/workflows/maven-compiler.yml b/.github/workflows/gradle-build.yml similarity index 61% rename from .github/workflows/maven-compiler.yml rename to .github/workflows/gradle-build.yml index 2e39915984..cb883ef311 100644 --- a/.github/workflows/maven-compiler.yml +++ b/.github/workflows/gradle-build.yml @@ -6,12 +6,14 @@ on: - stable paths: - 'src/**' - - 'pom.xml' + - 'build.gradle.kts' + - 'settings.gradle.kts' pull_request: paths: - '.github/workflows/**' - 'src/**' - - 'pom.xml' + - 'build.gradle.kts' + - 'settings.gradle.kts' - 'CHANGELOG.md' permissions: @@ -20,7 +22,7 @@ permissions: jobs: build: - name: Maven build + name: Gradle build runs-on: ubuntu-latest steps: @@ -35,12 +37,6 @@ jobs: java-package: jdk architecture: x64 - - name: Cache Maven packages - uses: actions/cache@v4 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - - - name: Build with Maven - run: mvn package --file pom.xml + - name: Build with Gradle + uses: gradle/actions/setup-gradle@v4 + - run: ./gradlew shadowJar diff --git a/.github/workflows/javadocs.yml b/.github/workflows/javadocs.yml index f628c2a692..37b884a73b 100644 --- a/.github/workflows/javadocs.yml +++ b/.github/workflows/javadocs.yml @@ -4,14 +4,14 @@ on: push: paths: - 'src/**' - - 'pom.xml' + - 'build.gradle.kts' permissions: contents: read jobs: build: - name: Maven build + name: Gradle Javadocs runs-on: ubuntu-latest steps: @@ -26,12 +26,6 @@ jobs: java-package: jdk architecture: x64 - - name: Cache Maven packages - uses: actions/cache@v4 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - - name: Build Javadocs - run: mvn javadoc:javadoc + uses: gradle/actions/setup-gradle@v4 + - run: ./gradlew javadoc diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index dc03cf8137..5121b3791e 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -5,17 +5,16 @@ on: paths: - '.github/workflows/**' - 'src/**' - - 'pom.xml' + - 'build.gradle.kts' + - 'settings.gradle.kts' permissions: contents: read jobs: - setup-preview-build: + preview-build: name: Preview build runs-on: ubuntu-latest - outputs: - short-commit-hash: ${{ steps.env-setup.outputs.SHORT_COMMIT_HASH }} steps: - name: Checkout repository @@ -29,28 +28,20 @@ jobs: java-package: jdk architecture: x64 - - name: Cache Maven packages - uses: actions/cache@v4 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - - # Setup for the preview build - - id: env-setup + - name: Set preview version run: | SHORT_COMMIT_HASH=$(git rev-parse --short=8 ${{ github.sha }}) JAR_VERSION="Preview Build #${{ github.event.number }}-$SHORT_COMMIT_HASH" echo "SHORT_COMMIT_HASH=$SHORT_COMMIT_HASH" >> "$GITHUB_ENV" - echo "SHORT_COMMIT_HASH=$SHORT_COMMIT_HASH" >> "$GITHUB_OUTPUT" echo "JAR_VERSION=$JAR_VERSION" >> "$GITHUB_ENV" - sed -i "s/5.0.0-UNOFFICIAL<\/version>/$JAR_VERSION<\/version>/g" pom.xml + sed -i "s/version = \"5.0.0-UNOFFICIAL\"/version = \"$JAR_VERSION\"/" build.gradle.kts - - name: Build with Maven - run: mvn package + - name: Build with Gradle + uses: gradle/actions/setup-gradle@v4 + - run: ./gradlew shadowJar - name: Upload the artifact uses: actions/upload-artifact@v4 with: name: slimefun-${{ github.event.number }}-${{ env.SHORT_COMMIT_HASH }} - path: 'target/Slimefun v${{ env.JAR_VERSION }}.jar' + path: 'build/libs/Slimefun v${{ env.JAR_VERSION }}.jar' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8b9ca96708..d2f44005e5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,12 +27,6 @@ jobs: git merge ${{ github.sha }} --no-edit git push origin stable - - name: Set version from tag - run: | - VERSION="${GITHUB_REF_NAME#v}" - echo "VERSION=$VERSION" >> "$GITHUB_ENV" - sed -i "s/5.0.0-UNOFFICIAL<\/version>/$VERSION<\/version>/g" pom.xml - - name: Set up JDK 21 uses: actions/setup-java@v4.6.0 with: @@ -41,20 +35,20 @@ jobs: java-package: jdk architecture: x64 - - name: Cache Maven packages - uses: actions/cache@v4 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 + - name: Set version from tag + run: | + VERSION="${GITHUB_REF_NAME#v}" + echo "VERSION=$VERSION" >> "$GITHUB_ENV" + sed -i "s/version = \"5.0.0-UNOFFICIAL\"/version = \"$VERSION\"/" build.gradle.kts - - name: Build with Maven - run: mvn clean package -Dmaven.test.skip=true --file pom.xml + - name: Build with Gradle + uses: gradle/actions/setup-gradle@v4 + - run: ./gradlew shadowJar - name: Create GitHub Release uses: softprops/action-gh-release@v2 with: - files: 'target/Slimefun v${{ env.VERSION }}.jar' + files: 'build/libs/Slimefun v${{ env.VERSION }}.jar' generate_release_notes: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index a6d46cc670..4a2c3ea15a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /bin/ +/build/ /target/ /plugins/ /sonar/ @@ -7,6 +8,7 @@ /.vscode/ /data-storage/ /javadocs/ +/.gradle/ dependency-reduced-pom.xml @@ -15,4 +17,4 @@ dependency-reduced-pom.xml .project *.iml *.bak -.DS_Store \ No newline at end of file +.DS_Store diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000000..83148307bf --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,121 @@ +plugins { + java + id("com.gradleup.shadow") version "9.3.2" +} + +group = "com.github.slimefun" +version = "5.0.0-UNOFFICIAL" +description = "Slimefun is a Paper plugin that simulates a modpack-like atmosphere by adding over 500 new items and recipes to your Minecraft Server." + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(21)) + } +} + +repositories { + mavenCentral() + maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots") // Spigot + maven("https://repo.papermc.io/repository/maven-public/") // Paper + maven("https://jitpack.io") // dough, MockBukkit, ItemsAdder + maven("https://maven.enginehub.org/repo/") // WorldEdit + maven("https://repo.extendedclip.com/content/repositories/placeholderapi") // PlaceholderAPI + maven("https://nexus.neetgames.com/repository/maven-public") // mcMMO + maven("https://repo.walshy.dev/public") // ClearLag + maven("https://repo.codemc.io/repository/maven-public/") // Orebfuscator +} + +dependencies { + // Shaded dependencies (bundled into the final jar) + implementation("com.github.Slimefun.dough:dough-api:cb22e71335") + implementation("io.papermc:paperlib:1.0.8") + implementation("commons-lang:commons-lang:2.6") + + // Compile-only (provided at runtime by the server) + compileOnly("com.google.code.findbugs:jsr305:3.0.2") + compileOnly("io.papermc.paper:paper-api:1.21.11-R0.1-SNAPSHOT") + compileOnly("com.mojang:authlib:6.0.52") { isTransitive = false } + + // Third-party plugin integrations (soft dependencies) + compileOnly("com.sk89q.worldedit:worldedit-core:7.3.9") { isTransitive = false } + compileOnly("com.sk89q.worldedit:worldedit-bukkit:7.3.9") { isTransitive = false } + compileOnly("com.gmail.nossr50.mcMMO:mcMMO:2.2.029") { isTransitive = false } + compileOnly("me.clip:placeholderapi:2.11.6") { isTransitive = false } + compileOnly("me.minebuilders:clearlag-core:3.1.6") { isTransitive = false } + compileOnly("com.github.LoneDev6:itemsadder-api:3.6.1") { isTransitive = false } + compileOnly("net.imprex:orebfuscator-api:5.4.0") { isTransitive = false } + + // Testing + // Note: paper-api version must match what MockBukkit was built against (1.21.11). + testImplementation(platform("org.junit:junit-bom:5.11.4")) + testImplementation("org.junit.jupiter:junit-jupiter") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") + testImplementation("org.mockito:mockito-core:5.15.2") + testImplementation("org.slf4j:slf4j-simple:2.0.16") + testImplementation("org.mockbukkit.mockbukkit:mockbukkit-v1.21:4.107.0") { + exclude(group = "org.jetbrains", module = "annotations") + } +} + +// Make compileOnly dependencies available on the test classpath +// (mirrors Maven's 'provided' scope behavior — tests need paper-api, jsr305, etc.) +configurations { + testImplementation { + extendsFrom(configurations.compileOnly.get()) + } +} + +tasks { + compileJava { + options.encoding = "UTF-8" + options.compilerArgs.add("-Xlint:-deprecation") + exclude("**/package-info.java") + } + + compileTestJava { + options.encoding = "UTF-8" + } + + processResources { + // Replace ${version} in plugin.yml with the project version + filesMatching("plugin.yml") { + expand("version" to project.version) + } + } + + jar { + // Disable the default jar — only shadowJar should be produced + enabled = false + } + + shadowJar { + // Output: "Slimefun v5.0.0.jar" + archiveFileName.set("Slimefun v${project.version}.jar") + + // Relocate shaded dependencies to avoid classpath conflicts + relocate("io.github.bakedlibs.dough", "io.github.thebusybiscuit.slimefun4.libraries.dough") + relocate("io.papermc.lib", "io.github.thebusybiscuit.slimefun4.libraries.paperlib") + relocate("org.apache.commons.lang", "io.github.thebusybiscuit.slimefun4.libraries.commons.lang") + + // Exclude META-INF from all shaded dependencies + exclude("META-INF/**") + + // Exclude dough skins package - replaced by VersionedPlayerHead + // to avoid IncompatibleClassChangeError with final GameProfile in MC 1.21.5+ + exclude("io/github/bakedlibs/dough/skins/**") + + // Include LICENSE + from(rootProject.projectDir) { + include("LICENSE") + } + } + + test { + useJUnitPlatform() + } + + // Make 'build' produce the shaded jar + build { + dependsOn(shadowJar) + } +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..a4b76b9530d66f5e68d973ea569d8e19de379189 GIT binary patch literal 43583 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 yu?e%!_ptzGB|8GrCfu%p?(_ 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 GZ~q4|mN%#X literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..37f78a6af8 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000000..f3b75f3b0d --- /dev/null +++ b/gradlew @@ -0,0 +1,251 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000000..9d21a21834 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 665611c427..0000000000 --- a/pom.xml +++ /dev/null @@ -1,541 +0,0 @@ - - - - 4.0.0 - com.github.slimefun - Slimefun - - - - 5.0.0-UNOFFICIAL - 2013 - jar - - - Slimefun is a Paper plugin that simulates a modpack-like atmosphere by adding over 500 new items and recipes to your Minecraft Server. - https://github.com/Slimefun/Slimefun4 - - - - UTF-8 - - - 21 - 21 - 21 - 21 - - - 1.21.4 - https://hub.spigotmc.org/javadocs/spigot/ - - - Slimefun_Slimefun4 - slimefun - https://sonarcloud.io - DEBUG - target/site/jacoco/jacoco.xml - - - - - GitHub Issues - https://github.com/Slimefun/Slimefun4/issues - - - - - - GNU General Public License v3.0 - https://github.com/Slimefun/Slimefun4/blob/master/LICENSE - repo - - - - - - - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots - - - - paper-repo - https://repo.papermc.io/repository/maven-public/ - - - - jitpack.io - https://jitpack.io - - - - worldedit-repo - https://maven.enginehub.org/repo/ - - - - placeholderapi-repo - https://repo.extendedclip.com/content/repositories/placeholderapi - - - - mcmmo-repo - https://nexus.neetgames.com/repository/maven-public - - - - walshy-public - https://repo.walshy.dev/public - - - - codemc-repo - https://repo.codemc.io/repository/maven-public/ - - - - - - ${project.basedir}/src/main/java - - - ${project.basedir}/src/test/java - - - clean package - - - ${project.name} v${project.version} - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.13.0 - - - - - - **/package-info.java - - - - - - - org.apache.maven.plugins - maven-source-plugin - 3.3.1 - - - - attach-sources - - jar - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.5.2 - - - org.junit.jupiter:junit-jupiter - false - - - - - - org.sonarsource.scanner.maven - sonar-maven-plugin - 5.0.0.4389 - - - - - org.jacoco - jacoco-maven-plugin - 0.8.12 - - - - prepare - - - prepare-agent - - - - - report - test - - - report - - - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.6.0 - - - - - - io.github.bakedlibs.dough - io.github.thebusybiscuit.slimefun4.libraries.dough - - - io.papermc.lib - io.github.thebusybiscuit.slimefun4.libraries.paperlib - - - org.apache.commons.lang - io.github.thebusybiscuit.slimefun4.libraries.commons.lang - - - - - - - *:* - - META-INF/* - - - - - com.github.Slimefun.dough:dough-api - - io/github/bakedlibs/dough/skins/** - - - - - - - - package - - shade - - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.11.2 - - - ${project.basedir} - javadocs - - Slimefun4 - Javadocs - Slimefun4 - Javadocs - false - -html5 - - - - ${paper.javadocs} - - - - - - Slimefun4 - API - io.github.thebusybiscuit.slimefun4.api* - - - Slimefun4 - Core packages - io.github.thebusybiscuit.slimefun4.core* - - - Slimefun4 - Implementations - io.github.thebusybiscuit.slimefun4.implementation* - - - Slimefun4 - Integrations with other - plugins - io.github.thebusybiscuit.slimefun4.integrations* - - - Slimefun4 - Common utility packages - io.github.thebusybiscuit.slimefun4.utils* - - - Slimefun4 - Items - io.github.thebusybiscuit.slimefun4.implementation.items* - - - Slimefun4 - Multiblocks - io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks* - - - Slimefun4 - Electrical Machines - io.github.thebusybiscuit.slimefun4.implementation.items.electric* - - - Slimefun4 - Old packages - me.mrCookieSlime.Slimefun* - - - - - - - - - - - ${basedir}/src/main/resources - true - - - plugin.yml - config.yml - item-models.yml - - wiki.json - languages/translators.json - - tags/*.json - biome-maps/*.json - - languages/**/*.yml - - - - - - ${basedir} - false - - - LICENSE - - - - - - - - - org.junit - junit-bom - 5.11.4 - pom - import - - - - - - - - com.google.code.findbugs - jsr305 - 3.0.2 - provided - - - - - - com.github.Slimefun.dough - dough-api - cb22e71335 - compile - - - io.papermc - paperlib - 1.0.8 - compile - - - - - io.papermc.paper - paper-api - ${paper.version}-R0.1-SNAPSHOT - provided - - - - - org.junit.jupiter - junit-jupiter - test - - - org.mockito - mockito-core - 5.15.2 - test - - - org.slf4j - slf4j-simple - 2.0.16 - test - - - - com.github.MockBukkit - MockBukkit - v4.106.1 - test - - - - - - org.jetbrains - annotations - - - - - - - com.sk89q.worldedit - worldedit-core - 7.3.9 - provided - - - - - * - * - - - - - com.sk89q.worldedit - worldedit-bukkit - 7.3.9 - provided - - - - - * - * - - - - - com.gmail.nossr50.mcMMO - mcMMO - 2.2.029 - provided - - - - - * - * - - - - - me.clip - placeholderapi - 2.11.6 - provided - - - - - * - * - - - - - me.minebuilders - clearlag-core - 3.1.6 - provided - - - - - * - * - - - - - com.github.LoneDev6 - itemsadder-api - 3.6.1 - provided - - - - - * - * - - - - - net.imprex - orebfuscator-api - 5.4.0 - provided - - - - - * - * - - - - - - commons-lang - commons-lang - 2.6 - compile - - - com.mojang - authlib - 6.0.52 - provided - - - - * - * - - - - - diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000000..cd93ad2c35 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "Slimefun" diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java index 1be851ba17..261a37a706 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java @@ -218,7 +218,8 @@ public Slimefun() { // Check that we got loaded by MockBukkit rather than Bukkit's loader // TODO: This is very much a hack and we can hopefully move to a more native way in the future - if (getClassLoader().getClass().getPackageName().startsWith("be.seeseemelk.mockbukkit")) { + String classLoaderPackage = getClassLoader().getClass().getPackageName(); + if (classLoaderPackage.startsWith("be.seeseemelk.mockbukkit") || classLoaderPackage.startsWith("org.mockbukkit.mockbukkit")) { minecraftVersion = MinecraftVersion.UNIT_TEST; } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 5e5a3adbe5..a06a8fb73c 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ # Name and version name: Slimefun -version: ${project.version} +version: ${version} # Project metadata author: The Slimefun 4 Community diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/TestPluginClass.java b/src/test/java/io/github/thebusybiscuit/slimefun4/TestPluginClass.java index 1d22dd98ed..c51a1a2934 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/TestPluginClass.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/TestPluginClass.java @@ -9,7 +9,7 @@ import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestPluginClass { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestSlimefunBlockBreakEvent.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestSlimefunBlockBreakEvent.java index 9eb9225213..62dbdbf729 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestSlimefunBlockBreakEvent.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestSlimefunBlockBreakEvent.java @@ -1,9 +1,12 @@ package io.github.thebusybiscuit.slimefun4.api.events; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.block.BlockMock; -import be.seeseemelk.mockbukkit.entity.PlayerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventFilterMatcher.hasFiredFilteredEvent; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.block.BlockMock; +import org.mockbukkit.mockbukkit.entity.PlayerMock; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BlockListener; @@ -64,7 +67,7 @@ void testEventIsFired() { BlockStorage.addBlockInfo(block, "id", "FOOD_COMPOSTER"); server.getPluginManager().callEvent(new BlockBreakEvent(block, player)); - server.getPluginManager().assertEventFired(SlimefunBlockBreakEvent.class, e -> true); + assertThat(server.getPluginManager(), hasFiredFilteredEvent(SlimefunBlockBreakEvent.class, e -> true)); } @Test @@ -81,14 +84,14 @@ void testGetters() { BlockStorage.addBlockInfo(block, "id", "FOOD_COMPOSTER"); server.getPluginManager().callEvent(new BlockBreakEvent(block, player)); - server.getPluginManager().assertEventFired(SlimefunBlockBreakEvent.class, e -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(SlimefunBlockBreakEvent.class, e -> { Assertions.assertEquals(block, e.getBlockBroken()); Assertions.assertEquals(slimefunItem, e.getSlimefunItem()); Assertions.assertEquals(itemStack, e.getHeldItem()); Assertions.assertEquals(player, e.getPlayer()); Assertions.assertFalse(e.isCancelled()); return true; - }); + })); } @Test @@ -113,11 +116,11 @@ public void onBlockBreak(SlimefunBlockBreakEvent event) { BlockBreakEvent blockBreakEvent = new BlockBreakEvent(block, player); server.getPluginManager().callEvent(blockBreakEvent); - server.getPluginManager().assertEventFired(SlimefunBlockBreakEvent.class, e -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(SlimefunBlockBreakEvent.class, e -> { Assertions.assertTrue(e.isCancelled()); Assertions.assertTrue(blockBreakEvent.isCancelled()); return true; - }); + })); } @Test @@ -135,7 +138,7 @@ void testBlockBreaksGetQueuedForDeletion() { BlockBreakEvent blockBreakEvent = new BlockBreakEvent(block, player); server.getPluginManager().callEvent(blockBreakEvent); - server.getPluginManager().assertEventFired(SlimefunBlockBreakEvent.class, e -> true); + assertThat(server.getPluginManager(), hasFiredFilteredEvent(SlimefunBlockBreakEvent.class, e -> true)); Assertions.assertTrue(Slimefun.getTickerTask().isDeletedSoon(block.getLocation())); } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestSlimefunBlockPlaceEvent.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestSlimefunBlockPlaceEvent.java index c33db57184..e1ebdc0c3d 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestSlimefunBlockPlaceEvent.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestSlimefunBlockPlaceEvent.java @@ -1,9 +1,12 @@ package io.github.thebusybiscuit.slimefun4.api.events; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.block.BlockMock; -import be.seeseemelk.mockbukkit.entity.PlayerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventFilterMatcher.hasFiredFilteredEvent; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.block.BlockMock; +import org.mockbukkit.mockbukkit.entity.PlayerMock; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BlockListener; @@ -74,7 +77,7 @@ void testEventIsFired() { ); server.getPluginManager().callEvent(blockPlaceEvent); - server.getPluginManager().assertEventFired(SlimefunBlockPlaceEvent.class, e -> true); + assertThat(server.getPluginManager(), hasFiredFilteredEvent(SlimefunBlockPlaceEvent.class, e -> true)); } @Test @@ -97,14 +100,14 @@ void testGetters() { ); server.getPluginManager().callEvent(blockPlaceEvent); - server.getPluginManager().assertEventFired(SlimefunBlockPlaceEvent.class, e -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(SlimefunBlockPlaceEvent.class, e -> { Assertions.assertEquals(block, e.getBlockPlaced()); Assertions.assertEquals(slimefunItem, e.getSlimefunItem()); Assertions.assertEquals(itemStack, e.getItemStack()); Assertions.assertEquals(player, e.getPlayer()); Assertions.assertFalse(e.isCancelled()); return true; - }); + })); } @Test @@ -134,11 +137,11 @@ public void onBlockPlace(SlimefunBlockPlaceEvent event) { ); server.getPluginManager().callEvent(blockPlaceEvent); - server.getPluginManager().assertEventFired(SlimefunBlockPlaceEvent.class, e -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(SlimefunBlockPlaceEvent.class, e -> { Assertions.assertTrue(e.isCancelled()); Assertions.assertTrue(blockPlaceEvent.isCancelled()); return true; - }); + })); } @Test @@ -162,14 +165,14 @@ void testBlockPlacementBeforeFullDeletion() { ); server.getPluginManager().callEvent(firstBlockPlaceEvent); - server.getPluginManager().assertEventFired(SlimefunBlockPlaceEvent.class, e -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(SlimefunBlockPlaceEvent.class, e -> { Assertions.assertFalse(e.isCancelled()); return true; - }); + })); // Break block server.getPluginManager().callEvent(new BlockBreakEvent(firstBlock, player)); - server.getPluginManager().assertEventFired(SlimefunBlockBreakEvent.class, e -> true); + assertThat(server.getPluginManager(), hasFiredFilteredEvent(SlimefunBlockBreakEvent.class, e -> true)); // Assert that the block is not fully deleted Assertions.assertTrue(Slimefun.getTickerTask().isDeletedSoon(firstBlock.getLocation())); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestSlimefunRegistryFinalizedEvent.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestSlimefunRegistryFinalizedEvent.java index bef63828c9..65347caa32 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestSlimefunRegistryFinalizedEvent.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestSlimefunRegistryFinalizedEvent.java @@ -7,8 +7,11 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventFilterMatcher.hasFiredFilteredEvent; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.implementation.setup.PostSetup; @@ -35,7 +38,7 @@ void testEventIsFired() { Assertions.assertDoesNotThrow(() -> PostSetup.loadItems()); // Make sure post setup sent the event - server.getPluginManager().assertEventFired(SlimefunItemRegistryFinalizedEvent.class, ignored -> true); + assertThat(server.getPluginManager(), hasFiredFilteredEvent(SlimefunItemRegistryFinalizedEvent.class, ignored -> true)); server.getPluginManager().clearEvents(); } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestTalismanActivateEvent.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestTalismanActivateEvent.java index 40cfc61fe5..7cff40b81f 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestTalismanActivateEvent.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/events/TestTalismanActivateEvent.java @@ -1,7 +1,11 @@ package io.github.thebusybiscuit.slimefun4.api.events; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.not; +import static org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventFilterMatcher.hasFiredFilteredEvent; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; @@ -71,27 +75,21 @@ void activateAnvilTalisman(boolean enderVariant, boolean inEnderChest) { void testEventIsFired() { // Assert the talisman activates in the inventory activateAnvilTalisman(false, false); - server.getPluginManager().assertEventFired(TalismanActivateEvent.class, ignored -> true); + assertThat(server.getPluginManager(), hasFiredFilteredEvent(TalismanActivateEvent.class, ignored -> true)); server.getPluginManager().clearEvents(); // Assert the talisman activates in the ender chest activateAnvilTalisman(true, true); - server.getPluginManager().assertEventFired(TalismanActivateEvent.class, ignored -> true); + assertThat(server.getPluginManager(), hasFiredFilteredEvent(TalismanActivateEvent.class, ignored -> true)); server.getPluginManager().clearEvents(); // Assert the normal talisman does not activate in the ender chest activateAnvilTalisman(false, true); - Assertions.assertThrows( - AssertionError.class, - () -> server.getPluginManager().assertEventFired(TalismanActivateEvent.class, ignored -> true) - ); + assertThat(server.getPluginManager(), not(hasFiredFilteredEvent(TalismanActivateEvent.class, ignored -> true))); // Assert the ender talisman does not activate in the inventory activateAnvilTalisman(true, false); - Assertions.assertThrows( - AssertionError.class, - () -> server.getPluginManager().assertEventFired(TalismanActivateEvent.class, ignored -> true) - ); + assertThat(server.getPluginManager(), not(hasFiredFilteredEvent(TalismanActivateEvent.class, ignored -> true))); } @Test @@ -99,22 +97,22 @@ void testEventIsFired() { void testEventFields() { // Assert the talisman activates in the inventory activateAnvilTalisman(false, false); - server.getPluginManager().assertEventFired(TalismanActivateEvent.class, event -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(TalismanActivateEvent.class, event -> { Assertions.assertEquals(talisman, event.getTalisman()); Assertions.assertEquals(talisman.getItem(), event.getTalismanItem()); Assertions.assertEquals(player, event.getPlayer()); return true; - }); + })); server.getPluginManager().clearEvents(); // Assert the talisman activates in the ender chest activateAnvilTalisman(true, true); - server.getPluginManager().assertEventFired(TalismanActivateEvent.class, event -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(TalismanActivateEvent.class, event -> { Assertions.assertEquals(enderTalisman, event.getTalisman()); Assertions.assertEquals(enderTalisman.getItem(), event.getTalismanItem()); Assertions.assertEquals(player, event.getPlayer()); return true; - }); + })); server.getPluginManager().clearEvents(); } @@ -130,18 +128,18 @@ public void onTalismanActivate(TalismanActivateEvent event) { // Assert the talisman activates in the inventory activateAnvilTalisman(false, false); - server.getPluginManager().assertEventFired(TalismanActivateEvent.class, event -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(TalismanActivateEvent.class, event -> { Assertions.assertTrue(event.isCancelled()); return true; - }); + })); server.getPluginManager().clearEvents(); // Assert the talisman activates in the ender chest activateAnvilTalisman(true, true); - server.getPluginManager().assertEventFired(TalismanActivateEvent.class, event -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(TalismanActivateEvent.class, event -> { Assertions.assertTrue(event.isCancelled()); return true; - }); + })); server.getPluginManager().clearEvents(); } @@ -157,18 +155,18 @@ public void onTalismanActivate(TalismanActivateEvent event) { // Assert the talisman activates in the inventory activateAnvilTalisman(false, false); - server.getPluginManager().assertEventFired(TalismanActivateEvent.class, event -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(TalismanActivateEvent.class, event -> { Assertions.assertTrue(event.preventsConsumption()); return true; - }); + })); server.getPluginManager().clearEvents(); // Assert the talisman activates in the ender chest activateAnvilTalisman(true, true); - server.getPluginManager().assertEventFired(TalismanActivateEvent.class, event -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(TalismanActivateEvent.class, event -> { Assertions.assertTrue(event.preventsConsumption()); return true; - }); + })); server.getPluginManager().clearEvents(); } } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/geo/TestResourceRegistration.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/geo/TestResourceRegistration.java index 9fba77c29f..81b666a107 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/geo/TestResourceRegistration.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/geo/TestResourceRegistration.java @@ -23,7 +23,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.resources.GEOResourcesSetup; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; @TestMethodOrder(value = OrderAnnotation.class) class TestResourceRegistration { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/gps/TestWaypoints.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/gps/TestWaypoints.java index 3b769c44a0..e07311f37a 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/gps/TestWaypoints.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/gps/TestWaypoints.java @@ -16,8 +16,11 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import io.github.thebusybiscuit.slimefun4.utils.FileUtils; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventFilterMatcher.hasFiredFilteredEvent; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestWaypoints { @@ -114,7 +117,7 @@ void testWaypointEvent() throws InterruptedException { TestUtilities.awaitProfile(player); network.addWaypoint(player, "Hello world", player.getLocation()); - server.getPluginManager().assertEventFired(WaypointCreateEvent.class, event -> event.getPlayer() == player); + assertThat(server.getPluginManager(), hasFiredFilteredEvent(WaypointCreateEvent.class, event -> event.getPlayer() == player)); } @Test diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestDoubleRangeSetting.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestDoubleRangeSetting.java index d13d0db64b..30a324739c 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestDoubleRangeSetting.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestDoubleRangeSetting.java @@ -12,7 +12,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestDoubleRangeSetting { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestEnumSetting.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestEnumSetting.java index 46df470c91..a61e1485b0 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestEnumSetting.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestEnumSetting.java @@ -12,7 +12,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestEnumSetting { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestIntRangeSetting.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestIntRangeSetting.java index cfb12eb0fc..87de5f5d7c 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestIntRangeSetting.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestIntRangeSetting.java @@ -12,7 +12,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestIntRangeSetting { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestItemSettings.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestItemSettings.java index 0e043ed7f2..271aaae1b1 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestItemSettings.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestItemSettings.java @@ -15,7 +15,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestItemSettings { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestMaterialTagSetting.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestMaterialTagSetting.java index a62928efec..da369984f2 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestMaterialTagSetting.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/items/settings/TestMaterialTagSetting.java @@ -18,7 +18,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestMaterialTagSetting { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/profiles/TestAsyncProfileLoadEvent.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/profiles/TestAsyncProfileLoadEvent.java index 17ea900f19..cd58c3ac7c 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/profiles/TestAsyncProfileLoadEvent.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/profiles/TestAsyncProfileLoadEvent.java @@ -14,9 +14,12 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import io.github.thebusybiscuit.slimefun4.test.mocks.MockProfile; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.entity.OfflinePlayerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventFilterMatcher.hasFiredFilteredEvent; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.entity.OfflinePlayerMock; class TestAsyncProfileLoadEvent { @@ -41,7 +44,7 @@ void testEventFired() throws InterruptedException { OfflinePlayer player = new OfflinePlayerMock("EventFire"); TestUtilities.awaitProfile(player); - server.getPluginManager().assertEventFired(AsyncProfileLoadEvent.class, Event::isAsynchronous); + assertThat(server.getPluginManager(), hasFiredFilteredEvent(AsyncProfileLoadEvent.class, Event::isAsynchronous)); } @Test @@ -52,7 +55,7 @@ void testEventGetter() throws InterruptedException { OfflinePlayer player = new OfflinePlayerMock("GetProfile"); PlayerProfile profile = TestUtilities.awaitProfile(player); - server.getPluginManager().assertEventFired(AsyncProfileLoadEvent.class, e -> e.getProfile().equals(profile)); + assertThat(server.getPluginManager(), hasFiredFilteredEvent(AsyncProfileLoadEvent.class, e -> e.getProfile().equals(profile))); } @Test diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/profiles/TestGuideHistory.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/profiles/TestGuideHistory.java index 214cca3c0c..27db36ecfa 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/profiles/TestGuideHistory.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/profiles/TestGuideHistory.java @@ -18,8 +18,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestGuideHistory { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/profiles/TestPlayerBackpacks.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/profiles/TestPlayerBackpacks.java index 90d475d479..a0e5b1733a 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/profiles/TestPlayerBackpacks.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/profiles/TestPlayerBackpacks.java @@ -14,8 +14,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestPlayerBackpacks { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/api/profiles/TestPlayerProfile.java b/src/test/java/io/github/thebusybiscuit/slimefun4/api/profiles/TestPlayerProfile.java index 61c49f0c32..5ef860eea5 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/api/profiles/TestPlayerProfile.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/api/profiles/TestPlayerProfile.java @@ -16,9 +16,9 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.entity.OfflinePlayerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.entity.OfflinePlayerMock; class TestPlayerProfile { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestBackpackCommand.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestBackpackCommand.java index 8443fdd0f5..0411e583c8 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestBackpackCommand.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestBackpackCommand.java @@ -21,8 +21,11 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.command.CommandResultSucceedMatcher.hasSucceeded; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestBackpackCommand { @@ -61,7 +64,7 @@ void testValidBackpack() throws InterruptedException { PlayerProfile profile = TestUtilities.awaitProfile(player); PlayerBackpack backpack = profile.createBackpack(54); - server.execute("slimefun", player, "backpack", player.getName(), String.valueOf(backpack.getId())).assertSucceeded(); + assertThat(server.execute("slimefun", player, "backpack", player.getName(), String.valueOf(backpack.getId())), hasSucceeded()); Assertions.assertTrue(hasBackpack(player, backpack.getId())); } @@ -74,7 +77,7 @@ void testNonExistentBackpacks(String id) throws InterruptedException { player.setOp(true); TestUtilities.awaitProfile(player); - server.execute("slimefun", player, "backpack", player.getName(), id).assertSucceeded(); + assertThat(server.execute("slimefun", player, "backpack", player.getName(), id), hasSucceeded()); if (CommonPatterns.NUMERIC.matcher(id).matches()) { Assertions.assertFalse(hasBackpack(player, Integer.parseInt(id))); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestChargeCommand.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestChargeCommand.java index 6a10937092..f218ca0bb2 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestChargeCommand.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestChargeCommand.java @@ -18,8 +18,8 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import io.github.thebusybiscuit.slimefun4.utils.LoreBuilder; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestChargeCommand { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestDebugFishCommand.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestDebugFishCommand.java index e91cd45e14..d3b39e82b3 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestDebugFishCommand.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestDebugFishCommand.java @@ -12,8 +12,11 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.command.CommandResultSucceedMatcher.hasSucceeded; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestDebugFishCommand { @@ -36,7 +39,7 @@ public static void unload() { void testCommand(boolean op) { Player player = server.addPlayer(); player.setOp(op); - server.execute("slimefun", player, "debug_fish").assertSucceeded(); + assertThat(server.execute("slimefun", player, "debug_fish"), hasSucceeded()); Assertions.assertEquals(op, SlimefunUtils.containsSimilarItem(player.getInventory(), SlimefunItems.DEBUG_FISH.item(), true)); } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestGuideCommand.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestGuideCommand.java index 57560503a7..564ebb880b 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestGuideCommand.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestGuideCommand.java @@ -14,8 +14,11 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.command.CommandResultSucceedMatcher.hasSucceeded; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestGuideCommand { @@ -39,7 +42,7 @@ void testCommand(boolean op) { Player player = server.addPlayer(); player.setOp(op); boolean hasPermission = player.hasPermission("slimefun.command.guide"); - server.execute("slimefun", player, "guide").assertSucceeded(); + assertThat(server.execute("slimefun", player, "guide"), hasSucceeded()); ItemStack guide = SlimefunGuide.getItem(SlimefunGuideMode.SURVIVAL_MODE); Assertions.assertEquals(hasPermission, SlimefunUtils.containsSimilarItem(player.getInventory(), guide, true)); } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestResearchCommand.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestResearchCommand.java index 00fdecdb9a..f26cba543b 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestResearchCommand.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/commands/TestResearchCommand.java @@ -13,8 +13,11 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.command.CommandResultSucceedMatcher.hasSucceeded; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestResearchCommand { @@ -46,7 +49,7 @@ void testResearchAll() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); - server.executeConsole("slimefun", "research", player.getName(), "all").assertSucceeded(); + assertThat(server.executeConsole("slimefun", "research", player.getName(), "all"), hasSucceeded()); Assertions.assertTrue(profile.hasUnlocked(research)); Assertions.assertTrue(profile.hasUnlocked(research2)); @@ -59,7 +62,7 @@ void testResearchSpecific() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); - server.executeConsole("slimefun", "research", player.getName(), research.getKey().toString()).assertSucceeded(); + assertThat(server.executeConsole("slimefun", "research", player.getName(), research.getKey().toString()), hasSucceeded()); Assertions.assertTrue(profile.hasUnlocked(research)); Assertions.assertFalse(profile.hasUnlocked(research2)); @@ -72,12 +75,12 @@ void testResearchReset() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); - server.executeConsole("slimefun", "research", player.getName(), "all").assertSucceeded(); + assertThat(server.executeConsole("slimefun", "research", player.getName(), "all"), hasSucceeded()); Assertions.assertTrue(profile.hasUnlocked(research)); Assertions.assertTrue(profile.hasUnlocked(research2)); - server.executeConsole("slimefun", "research", player.getName(), "reset").assertSucceeded(); + assertThat(server.executeConsole("slimefun", "research", player.getName(), "reset"), hasSucceeded()); Assertions.assertFalse(profile.hasUnlocked(research)); Assertions.assertFalse(profile.hasUnlocked(research2)); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/debug/TestDebugLogging.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/debug/TestDebugLogging.java index cc7caf76ca..15faf0eef5 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/debug/TestDebugLogging.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/debug/TestDebugLogging.java @@ -14,7 +14,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestDebugLogging { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/guide/TestGuideOpening.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/guide/TestGuideOpening.java index b7a9a20d1c..23067de9f5 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/guide/TestGuideOpening.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/guide/TestGuideOpening.java @@ -25,8 +25,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestGuideOpening { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/multiblocks/TestMultiBlocks.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/multiblocks/TestMultiBlocks.java index 93fb5ef75f..11d18b8037 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/multiblocks/TestMultiBlocks.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/multiblocks/TestMultiBlocks.java @@ -13,7 +13,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestMultiBlocks { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/networks/TestNetworkManager.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/networks/TestNetworkManager.java index 4ac8db287e..c17e683b20 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/networks/TestNetworkManager.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/networks/TestNetworkManager.java @@ -21,8 +21,8 @@ import io.github.thebusybiscuit.slimefun4.core.networks.cargo.CargoNet; import io.github.thebusybiscuit.slimefun4.test.mocks.MockNetwork; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestNetworkManager { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/researching/TestProfileResearches.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/researching/TestProfileResearches.java index c6072275eb..49a151b3cf 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/researching/TestProfileResearches.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/researching/TestProfileResearches.java @@ -15,8 +15,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestProfileResearches { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/researching/TestResearchUnlocking.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/researching/TestResearchUnlocking.java index 7d376cc111..e1d189c09d 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/researching/TestResearchUnlocking.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/researching/TestResearchUnlocking.java @@ -19,8 +19,11 @@ import io.github.thebusybiscuit.slimefun4.api.researches.Research; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventFilterMatcher.hasFiredFilteredEvent; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestResearchUnlocking { @@ -63,12 +66,12 @@ void testUnlock(boolean instant) throws InterruptedException { Player p = awaitUnlock(player, research, instant); Optional profile = PlayerProfile.find(p); - server.getPluginManager().assertEventFired(ResearchUnlockEvent.class, event -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(ResearchUnlockEvent.class, event -> { Assertions.assertEquals(p, event.getPlayer()); Assertions.assertEquals(research, event.getResearch()); Assertions.assertFalse(event.isCancelled()); return true; - }); + })); Assertions.assertEquals(player, p); Assertions.assertTrue(profile.isPresent()); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/researching/TestResearches.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/researching/TestResearches.java index 21bb2b2f3e..4f7b165ed5 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/researching/TestResearches.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/researching/TestResearches.java @@ -22,8 +22,11 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventFilterMatcher.hasFiredFilteredEvent; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestResearches { @@ -203,13 +206,13 @@ void testPreCanUnlockResearchEvent() throws InterruptedException { research.unlockFromGuide(guide, player, profile, sfItem, sfItem.getItemGroup(), 0); - server.getPluginManager().assertEventFired(PlayerPreResearchEvent.class, event -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(PlayerPreResearchEvent.class, event -> { Assertions.assertEquals(player, event.getPlayer()); Assertions.assertEquals(research, event.getResearch()); Assertions.assertEquals(sfItem, event.getSlimefunItem()); Assertions.assertFalse(event.isCancelled()); return true; - }); + })); } } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestBlockDataService.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestBlockDataService.java index 909f050f26..a183ce4d25 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestBlockDataService.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestBlockDataService.java @@ -10,7 +10,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestBlockDataService { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestCustomTextureService.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestCustomTextureService.java index 919de0d374..54351b004a 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestCustomTextureService.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestCustomTextureService.java @@ -15,7 +15,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestCustomTextureService { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestItemDataService.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestItemDataService.java index ec323ff6f4..8ecc13ff79 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestItemDataService.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestItemDataService.java @@ -14,7 +14,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestItemDataService { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestPermissionsService.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestPermissionsService.java index 0c0bf143e3..01907f75d3 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestPermissionsService.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestPermissionsService.java @@ -20,8 +20,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestPermissionsService { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestRecipeService.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestRecipeService.java index bc30dbf583..de0e323035 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestRecipeService.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestRecipeService.java @@ -21,8 +21,8 @@ import io.github.bakedlibs.dough.recipes.RecipeSnapshot; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestRecipeService { @@ -46,7 +46,8 @@ void testRecipe() { MinecraftRecipeService service = new MinecraftRecipeService(plugin); NamespacedKey key = new NamespacedKey(plugin, "furnace_recipe_test"); - ItemStack result = new ItemStack(Material.EMERALD_BLOCK); + // Use DRAGON_EGG as it has no pre-existing vanilla recipe in MockBukkit + ItemStack result = new ItemStack(Material.DRAGON_EGG); FurnaceRecipe recipe = new FurnaceRecipe(key, result, new MaterialChoice(Material.DIAMOND), 1, 2); server.addRecipe(recipe); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestUpdaterService.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestUpdaterService.java index 4de8e01e62..768bcf0da4 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestUpdaterService.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/TestUpdaterService.java @@ -11,7 +11,7 @@ import io.github.thebusybiscuit.slimefun4.api.SlimefunBranch; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestUpdaterService { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/AbstractLocaleRegexChecker.java b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/AbstractLocaleRegexChecker.java index df8668f285..abab336655 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/AbstractLocaleRegexChecker.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/core/services/localization/AbstractLocaleRegexChecker.java @@ -24,7 +24,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.provider.Arguments; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class AbstractLocaleRegexChecker { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestDamageableItem.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestDamageableItem.java index 7a97e33cf3..493dded997 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestDamageableItem.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestDamageableItem.java @@ -21,8 +21,8 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import io.github.thebusybiscuit.slimefun4.test.mocks.MockDamageable; import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedEnchantment; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestDamageableItem { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestRadioactiveItem.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestRadioactiveItem.java index 6c7853da2d..065cdf8415 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestRadioactiveItem.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestRadioactiveItem.java @@ -16,7 +16,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestRadioactiveItem { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestSlimefunItem.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestSlimefunItem.java index 421a4248f3..0befb3b94e 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestSlimefunItem.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/TestSlimefunItem.java @@ -18,7 +18,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestSlimefunItem { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/TestAbstractRecipe.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/TestAbstractRecipe.java index 2fa377c86e..1edb47702c 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/TestAbstractRecipe.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/TestAbstractRecipe.java @@ -21,7 +21,7 @@ import io.github.bakedlibs.dough.items.CustomItemStack; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestAbstractRecipe { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/TestAutoCrafter.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/TestAutoCrafter.java index 0158b7cb86..9312cac42d 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/TestAutoCrafter.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/TestAutoCrafter.java @@ -21,9 +21,9 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.inventory.ChestInventoryMock; -import be.seeseemelk.mockbukkit.inventory.InventoryMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.inventory.ChestInventoryMock; +import org.mockbukkit.mockbukkit.inventory.InventoryMock; class TestAutoCrafter { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/backpacks/TestEnderBackpack.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/backpacks/TestEnderBackpack.java index 62b22112a1..3ef90400bd 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/backpacks/TestEnderBackpack.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/backpacks/TestEnderBackpack.java @@ -15,8 +15,8 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import io.github.thebusybiscuit.slimefun4.test.presets.SlimefunItemTest; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestEnderBackpack implements SlimefunItemTest { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/TestDietCookie.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/TestDietCookie.java index 693e5f03cf..daf63f4d82 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/TestDietCookie.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/TestDietCookie.java @@ -16,9 +16,12 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import io.github.thebusybiscuit.slimefun4.test.presets.SlimefunItemTest; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.entity.PlayerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.sound.SoundReceiverSoundHeardMatcher.hasHeard; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.entity.PlayerMock; class TestDietCookie implements SlimefunItemTest { @@ -52,7 +55,7 @@ void testConsumptionBehaviour() { simulateConsumption(player, cookie); - player.assertSoundHeard(SoundEffect.DIET_COOKIE_CONSUME_SOUND.getDefaultSoundId()); + assertThat(player, hasHeard(SoundEffect.DIET_COOKIE_CONSUME_SOUND.getDefaultSoundId())); Assertions.assertTrue(player.hasPotionEffect(PotionEffectType.LEVITATION)); } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/TestMeatJerky.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/TestMeatJerky.java index ea78037705..b91affafb6 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/TestMeatJerky.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/TestMeatJerky.java @@ -14,9 +14,9 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import io.github.thebusybiscuit.slimefun4.test.presets.SlimefunItemTest; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.entity.PlayerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.entity.PlayerMock; class TestMeatJerky implements SlimefunItemTest { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/TestMonsterJerky.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/TestMonsterJerky.java index ed279f4e93..e033f7e0b5 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/TestMonsterJerky.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/TestMonsterJerky.java @@ -15,9 +15,9 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import io.github.thebusybiscuit.slimefun4.test.presets.SlimefunItemTest; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.entity.PlayerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.entity.PlayerMock; class TestMonsterJerky implements SlimefunItemTest { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TestClimbingPick.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TestClimbingPick.java index 9a43bc12f5..21ea2d860f 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TestClimbingPick.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TestClimbingPick.java @@ -28,10 +28,13 @@ import io.github.thebusybiscuit.slimefun4.utils.compatibility.VersionedEnchantment; import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.block.BlockMock; -import be.seeseemelk.mockbukkit.entity.PlayerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventFilterMatcher.hasFiredFilteredEvent; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.block.BlockMock; +import org.mockbukkit.mockbukkit.entity.PlayerMock; class TestClimbingPick implements SlimefunItemTest { @@ -139,7 +142,7 @@ void testItemUse(BlockFace face) { if (shouldFireEvent) { Assertions.assertTrue(pick.getClimbingSpeed(block.getType()) > 0); Assertions.assertTrue(player.getVelocity().length() > 0); - server.getPluginManager().assertEventFired(ClimbingPickLaunchEvent.class, e -> e.getPlayer() == player && e.getPick() == pick); + assertThat(server.getPluginManager(), hasFiredFilteredEvent(ClimbingPickLaunchEvent.class, e -> e.getPlayer() == player && e.getPick() == pick)); } else { Assertions.assertEquals(0, player.getVelocity().length()); } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TestPortableDustbin.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TestPortableDustbin.java index 8b9d710a37..a62767fde5 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TestPortableDustbin.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TestPortableDustbin.java @@ -16,8 +16,8 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import io.github.thebusybiscuit.slimefun4.test.presets.SlimefunItemTest; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestPortableDustbin implements SlimefunItemTest { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TestTapeMeasure.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TestTapeMeasure.java index 6a05e5c34e..76526057d1 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TestTapeMeasure.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TestTapeMeasure.java @@ -21,11 +21,14 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import io.github.thebusybiscuit.slimefun4.test.presets.SlimefunItemTest; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.WorldMock; -import be.seeseemelk.mockbukkit.block.BlockMock; -import be.seeseemelk.mockbukkit.entity.PlayerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.sound.SoundReceiverSoundHeardMatcher.hasHeard; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.world.WorldMock; +import org.mockbukkit.mockbukkit.block.BlockMock; +import org.mockbukkit.mockbukkit.entity.PlayerMock; class TestTapeMeasure implements SlimefunItemTest { @@ -108,7 +111,7 @@ void testMeasuringFeedback() { player.setSneaking(false); simulateRightClickBlock(player, tm, item, block2, BlockFace.UP); - player.assertSoundHeard(Sound.ITEM_BOOK_PUT); + assertThat(player, hasHeard(Sound.ITEM_BOOK_PUT)); } @Test diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestAnvilListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestAnvilListener.java index 52fc8fad5e..58fbae5fd1 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestAnvilListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestAnvilListener.java @@ -23,8 +23,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.AnvilListener; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestAnvilListener { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestBackpackListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestBackpackListener.java index f8e1b299a0..2a942ab963 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestBackpackListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestBackpackListener.java @@ -1,8 +1,8 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.entity.ItemEntityMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.entity.ItemMock; import io.github.bakedlibs.dough.items.CustomItemStack; import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException; import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; @@ -127,7 +127,7 @@ void testBackpackDropNormalItem() throws InterruptedException { Player player = server.addPlayer(); openMockBackpack(player, "DROP_NORMAL_ITEM_BACKPACK_TEST", 27); - Item item = new ItemEntityMock(server, UUID.randomUUID(), new ItemStack(Material.SUGAR_CANE)); + Item item = new ItemMock(server, UUID.randomUUID(), new ItemStack(Material.SUGAR_CANE)); PlayerDropItemEvent event = new PlayerDropItemEvent(player, item); listener.onItemDrop(event); @@ -136,10 +136,12 @@ void testBackpackDropNormalItem() throws InterruptedException { private boolean isAllowed(String id, ItemStack item) throws InterruptedException { Player player = server.addPlayer(); - Inventory inv = openMockBackpack(player, id, 9).getInventory(); + openMockBackpack(player, id, 9); + // Use the view's top inventory so getCurrentItem() sees the item + Inventory topInv = player.getOpenInventory().getTopInventory(); int slot = 7; - inv.setItem(slot, item); + topInv.setItem(slot, item); InventoryClickEvent event = new InventoryClickEvent(player.getOpenInventory(), SlotType.CONTAINER, slot, ClickType.LEFT, InventoryAction.PICKUP_ONE); listener.onClick(event); return !event.isCancelled(); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestBeeListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestBeeListener.java index fbc563ea6f..12e220d74c 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestBeeListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestBeeListener.java @@ -1,10 +1,18 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners; +import java.util.EnumMap; + +import com.google.common.base.Function; +import com.google.common.base.Functions; +import com.google.common.collect.ImmutableMap; + import org.bukkit.Material; +import org.bukkit.damage.DamageSource; import org.bukkit.entity.Bee; import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityDamageEvent.DamageModifier; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; @@ -20,8 +28,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.entity.BeeListener; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestBeeListener { @@ -41,6 +49,7 @@ public static void unload() { MockBukkit.unmock(); } + @SuppressWarnings("deprecation") @ParameterizedTest @DisplayName("Test Bee damage protection") @ValueSource(booleans = { true, false }) @@ -62,7 +71,11 @@ void testBeeDamage(boolean hasArmor) throws InterruptedException { double damage = 7.5; Bee bee = Mockito.mock(Bee.class); - EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(bee, player, DamageCause.ENTITY_ATTACK, damage); + DamageSource source = Mockito.mock(DamageSource.class); + EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(bee, player, DamageCause.ENTITY_ATTACK, source, + new EnumMap<>(ImmutableMap.of(DamageModifier.BASE, damage)), + new EnumMap>(ImmutableMap.of(DamageModifier.BASE, Functions.constant(-0.0))), + false); listener.onDamage(event); if (hasArmor) { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestBrewingStandListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestBrewingStandListener.java index 660656cd07..6fd1924bbf 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestBrewingStandListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestBrewingStandListener.java @@ -25,8 +25,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.BrewingStandListener; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestBrewingStandListener { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCargoNodeListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCargoNodeListener.java index 721ab21ea2..a8423bc3d6 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCargoNodeListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCargoNodeListener.java @@ -24,8 +24,8 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import io.github.thebusybiscuit.slimefun4.test.providers.SlimefunItemsSource; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestCargoNodeListener { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCartographyTableListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCartographyTableListener.java index b872c45341..aaec28dd2f 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCartographyTableListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCartographyTableListener.java @@ -23,8 +23,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.CartographyTableListener; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestCartographyTableListener { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCauldronListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCauldronListener.java index c3072d162e..f90d3498aa 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCauldronListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCauldronListener.java @@ -22,9 +22,9 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.CauldronListener; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.block.BlockMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.block.BlockMock; class TestCauldronListener { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCoolerListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCoolerListener.java index 2793b76e11..18947f26ae 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCoolerListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCoolerListener.java @@ -25,8 +25,11 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler; import io.github.thebusybiscuit.slimefun4.implementation.items.food.Juice; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventFilterMatcher.hasFiredFilteredEvent; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestCoolerListener { @@ -78,10 +81,10 @@ void testCoolerUsage() throws InterruptedException { new BackpackListener().setBackpackId(player, personalCooler, 1, backpack.getId()); player.getInventory().setItem(7, personalCooler); - FoodLevelChangeEvent event = new FoodLevelChangeEvent(player, 16); + FoodLevelChangeEvent event = new FoodLevelChangeEvent(player, 16, null); listener.onHungerLoss(event); Assertions.assertTrue(player.hasPotionEffect(PotionEffectType.HEALTH_BOOST)); - server.getPluginManager().assertEventFired(CoolerFeedPlayerEvent.class, e -> e.getPlayer() == player && e.getCooler() == cooler); + assertThat(server.getPluginManager(), hasFiredFilteredEvent(CoolerFeedPlayerEvent.class, e -> e.getPlayer() == player && e.getCooler() == cooler)); } } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCraftingTableListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCraftingTableListener.java index e78d3f00fd..cc58d134d4 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCraftingTableListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestCraftingTableListener.java @@ -28,8 +28,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.CraftingTableListener; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestCraftingTableListener { @@ -54,6 +54,8 @@ private CraftItemEvent mockCraftingEvent(ItemStack item) { Player player = server.addPlayer(); CraftingInventory inv = Mockito.mock(CraftingInventory.class); + Mockito.when(inv.getType()).thenReturn(org.bukkit.event.inventory.InventoryType.CRAFTING); + Mockito.when(inv.getSize()).thenReturn(10); Mockito.when(inv.getContents()).thenReturn(new ItemStack[] { item, null, null, null, null, null, null, null, null }); InventoryView view = player.openInventory(inv); @@ -67,6 +69,8 @@ private PrepareItemCraftEvent mockPreCraftingEvent(ItemStack item) { Player player = server.addPlayer(); CraftingInventory inv = Mockito.mock(CraftingInventory.class); + Mockito.when(inv.getType()).thenReturn(org.bukkit.event.inventory.InventoryType.CRAFTING); + Mockito.when(inv.getSize()).thenReturn(10); MutableObject result = new MutableObject(new ItemStack(Material.EMERALD)); Mockito.doAnswer(invocation -> { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestDeathpointListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestDeathpointListener.java index c47d93a9d7..04f4692083 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestDeathpointListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestDeathpointListener.java @@ -12,8 +12,12 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.not; +import static org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventFilterMatcher.hasFiredFilteredEvent; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestDeathpointListener { @@ -39,7 +43,7 @@ void testNoTransmitter() throws InterruptedException { TestUtilities.awaitProfile(player); player.setHealth(0); - Assertions.assertThrows(AssertionError.class, () -> server.getPluginManager().assertEventFired(WaypointCreateEvent.class, event -> event.getPlayer() == player && event.isDeathpoint())); + assertThat(server.getPluginManager(), not(hasFiredFilteredEvent(WaypointCreateEvent.class, event -> event.getPlayer() == player && event.isDeathpoint()))); } @Test @@ -50,7 +54,7 @@ void testTransmitter() throws InterruptedException { player.getInventory().setItem(8, SlimefunItems.GPS_EMERGENCY_TRANSMITTER.item()); player.setHealth(0); - server.getPluginManager().assertEventFired(WaypointCreateEvent.class, event -> event.getPlayer() == player && event.isDeathpoint()); + assertThat(server.getPluginManager(), hasFiredFilteredEvent(WaypointCreateEvent.class, event -> event.getPlayer() == player && event.isDeathpoint())); } } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestFireworksListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestFireworksListener.java index bcea6c1817..2bc185d124 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestFireworksListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestFireworksListener.java @@ -1,10 +1,18 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners; +import java.util.EnumMap; + +import com.google.common.base.Function; +import com.google.common.base.Functions; +import com.google.common.collect.ImmutableMap; + import org.bukkit.Color; +import org.bukkit.damage.DamageSource; import org.bukkit.entity.Firework; import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityDamageEvent.DamageModifier; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; @@ -15,8 +23,10 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.entity.FireworksListener; import io.github.thebusybiscuit.slimefun4.utils.FireworkUtils; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockito.Mockito; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestFireworksListener { @@ -33,13 +43,18 @@ public static void unload() { MockBukkit.unmock(); } + @SuppressWarnings("deprecation") @Test @DisplayName("Test if Fireworks from Research cause no damage") void testFireworkDamage() { Player player = server.addPlayer(); Firework firework = FireworkUtils.createFirework(player.getLocation(), Color.BLUE); - EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(firework, player, DamageCause.ENTITY_EXPLOSION, 6.0); + DamageSource source = Mockito.mock(DamageSource.class); + EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(firework, player, DamageCause.ENTITY_EXPLOSION, source, + new EnumMap<>(ImmutableMap.of(DamageModifier.BASE, 6.0)), + new EnumMap>(ImmutableMap.of(DamageModifier.BASE, Functions.constant(-0.0))), + false); server.getPluginManager().callEvent(event); Assertions.assertTrue(event.isCancelled()); } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestGrindstoneListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestGrindstoneListener.java index fa62fca496..d9c45e6437 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestGrindstoneListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestGrindstoneListener.java @@ -27,8 +27,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.GrindstoneListener; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestGrindstoneListener { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestIronGolemListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestIronGolemListener.java index 2877ee683b..30b618df36 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestIronGolemListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestIronGolemListener.java @@ -21,8 +21,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.entity.IronGolemListener; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestIronGolemListener { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestItemPickupListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestItemPickupListener.java index b5f35bccfa..b92bf10cc2 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestItemPickupListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestItemPickupListener.java @@ -21,10 +21,10 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.entity.ItemEntityMock; -import be.seeseemelk.mockbukkit.inventory.HopperInventoryMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.entity.ItemMock; +import org.mockbukkit.mockbukkit.inventory.HopperInventoryMock; class TestItemPickupListener { @@ -48,7 +48,7 @@ public static void unload() { @ValueSource(booleans = { true, false }) void testNoPickupFlagForEntities(boolean flag) { Player player = server.addPlayer(); - Item item = new ItemEntityMock(server, UUID.randomUUID(), new ItemStack(Material.COMPASS)); + Item item = new ItemMock(server, UUID.randomUUID(), new ItemStack(Material.COMPASS)); if (flag) { SlimefunUtils.markAsNoPickup(item, "Unit Test"); @@ -64,7 +64,7 @@ void testNoPickupFlagForEntities(boolean flag) { @ValueSource(booleans = { true, false }) void testNoPickupFlagForInventories(boolean flag) { Inventory inventory = new HopperInventoryMock(null); - Item item = new ItemEntityMock(server, UUID.randomUUID(), new ItemStack(Material.COMPASS)); + Item item = new ItemMock(server, UUID.randomUUID(), new ItemStack(Material.COMPASS)); if (flag) { SlimefunUtils.markAsNoPickup(item, "Unit Test"); @@ -89,7 +89,7 @@ void testAltarProbeForEntities(boolean flag) { } AtomicBoolean removed = new AtomicBoolean(false); - Item item = new ItemEntityMock(server, UUID.randomUUID(), stack) { + Item item = new ItemMock(server, UUID.randomUUID(), stack) { @Override public void remove() { @@ -117,7 +117,7 @@ void testAltarProbeForInventories(boolean flag) { } AtomicBoolean removed = new AtomicBoolean(false); - Item item = new ItemEntityMock(server, UUID.randomUUID(), stack) { + Item item = new ItemMock(server, UUID.randomUUID(), stack) { @Override public void remove() { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestMultiblockListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestMultiblockListener.java index e0420d1645..8490d5a151 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestMultiblockListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestMultiblockListener.java @@ -22,8 +22,11 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventFilterMatcher.hasFiredFilteredEvent; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestMultiblockListener { @@ -81,12 +84,12 @@ void testMultiblock() { Assertions.assertEquals(Result.DENY, event.useInteractedBlock()); - server.getPluginManager().assertEventFired(MultiBlockInteractEvent.class, e -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(MultiBlockInteractEvent.class, e -> { Assertions.assertEquals(player, e.getPlayer()); Assertions.assertEquals(self, e.getClickedBlock()); Assertions.assertEquals(BlockFace.NORTH, e.getClickedFace()); Assertions.assertEquals(multiblock, e.getMultiBlock()); return true; - }); + })); } } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestNetworkListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestNetworkListener.java index b6ef3148d6..5e8837ca42 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestNetworkListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestNetworkListener.java @@ -18,8 +18,8 @@ import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestNetworkListener { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestPiglinListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestPiglinListener.java index 2c912148cf..9a126bd2b2 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestPiglinListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestPiglinListener.java @@ -25,9 +25,9 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.entity.PiglinListener; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.entity.ItemEntityMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.entity.ItemMock; class TestPiglinListener { @@ -51,7 +51,7 @@ private EntityPickupItemEvent createPickupEvent(ItemStack item) { Piglin piglin = Mockito.mock(Piglin.class); Mockito.when(piglin.getType()).thenReturn(EntityType.PIGLIN); - Item itemEntity = new ItemEntityMock(server, UUID.randomUUID(), item); + Item itemEntity = new ItemMock(server, UUID.randomUUID(), item); return new EntityPickupItemEvent(piglin, itemEntity, 1); } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestPlayerProfileListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestPlayerProfileListener.java index 0ee300a138..1d96d3679d 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestPlayerProfileListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestPlayerProfileListener.java @@ -1,5 +1,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners; +import net.kyori.adventure.text.Component; + import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerKickEvent; import org.bukkit.event.player.PlayerQuitEvent; @@ -13,8 +15,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestPlayerProfileListener { @@ -39,7 +41,7 @@ public static void unload() { void testPlayerLeave() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); - PlayerQuitEvent event = new PlayerQuitEvent(player, "bye"); + PlayerQuitEvent event = new PlayerQuitEvent(player, Component.text("bye"), PlayerQuitEvent.QuitReason.DISCONNECTED); listener.onDisconnect(event); Assertions.assertTrue(profile.isMarkedForDeletion()); @@ -49,7 +51,7 @@ void testPlayerLeave() throws InterruptedException { @DisplayName("Test PlayerProfile being unloaded when Player leaves") void testUnloadedPlayerLeave() { Player player = server.addPlayer(); - PlayerQuitEvent event = new PlayerQuitEvent(player, "bye"); + PlayerQuitEvent event = new PlayerQuitEvent(player, Component.text("bye"), PlayerQuitEvent.QuitReason.DISCONNECTED); listener.onDisconnect(event); Assertions.assertFalse(PlayerProfile.find(player).isPresent()); @@ -60,7 +62,7 @@ void testUnloadedPlayerLeave() { void testPlayerKick() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); - PlayerKickEvent event = new PlayerKickEvent(player, "You're not welcome anymore", "bye"); + PlayerKickEvent event = new PlayerKickEvent(player, Component.text("You're not welcome anymore"), Component.text("bye"), PlayerKickEvent.Cause.PLUGIN); listener.onKick(event); Assertions.assertTrue(profile.isMarkedForDeletion()); @@ -70,7 +72,7 @@ void testPlayerKick() throws InterruptedException { @DisplayName("Test PlayerProfile being unloaded when Player is kicked") void testUnloadedPlayerKick() { Player player = server.addPlayer(); - PlayerKickEvent event = new PlayerKickEvent(player, "You're not welcome anymore", "bye"); + PlayerKickEvent event = new PlayerKickEvent(player, Component.text("You're not welcome anymore"), Component.text("bye"), PlayerKickEvent.Cause.PLUGIN); listener.onKick(event); Assertions.assertFalse(PlayerProfile.find(player).isPresent()); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSlimefunGuideListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSlimefunGuideListener.java index 6b58f849b7..01c4964eec 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSlimefunGuideListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSlimefunGuideListener.java @@ -2,6 +2,8 @@ import java.util.stream.Stream; +import net.kyori.adventure.text.Component; + import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.inventory.ItemStack; @@ -17,9 +19,9 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.entity.PlayerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.entity.PlayerMock; class TestSlimefunGuideListener { @@ -48,7 +50,7 @@ void testFirstJoin(boolean hasPlayedBefore, boolean giveSlimefunGuide) { server.getPlayerList().setLastSeen(player.getUniqueId(), System.currentTimeMillis()); } - PlayerJoinEvent event = new PlayerJoinEvent(player, "CanIHazGuide has joined and wants sum guide"); + PlayerJoinEvent event = new PlayerJoinEvent(player, Component.text("CanIHazGuide has joined and wants sum guide")); listener.onJoin(event); ItemStack guide = SlimefunGuide.getItem(SlimefunGuide.getDefaultMode()); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSlimefunItemInteractListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSlimefunItemInteractListener.java index cc33e3750a..ed7e3b5568 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSlimefunItemInteractListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSlimefunItemInteractListener.java @@ -30,9 +30,13 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.entity.PlayerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.not; +import static org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventFilterMatcher.hasFiredFilteredEvent; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.entity.PlayerMock; class TestSlimefunItemInteractListener { @@ -100,17 +104,17 @@ void testCannotOpenInvOfBrokenBlock() { ); server.getPluginManager().callEvent(playerInteractEvent); - server.getPluginManager().assertEventFired(PlayerInteractEvent.class, e -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(PlayerInteractEvent.class, e -> { // We cancel the event on inventory open Assertions.assertSame(e.useInteractedBlock(), Result.DENY); return true; - }); + })); // Assert our right click event fired and the block usage was not denied - server.getPluginManager().assertEventFired(PlayerRightClickEvent.class, e -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(PlayerRightClickEvent.class, e -> { Assertions.assertNotSame(e.useBlock(), Result.DENY); return true; - }); + })); // Assert we do have an inventory which would be opened // TODO: Create an event for open inventory so this isn't guess work @@ -123,10 +127,10 @@ void testCannotOpenInvOfBrokenBlock() { // Break the block BlockBreakEvent blockBreakEvent = new BlockBreakEvent(block, player); server.getPluginManager().callEvent(blockBreakEvent); - server.getPluginManager().assertEventFired(SlimefunBlockBreakEvent.class, e -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(SlimefunBlockBreakEvent.class, e -> { Assertions.assertEquals(electricFurnace.getId(), e.getSlimefunItem().getId()); return true; - }); + })); // Assert the block is queued for removal Assertions.assertTrue(Slimefun.getTickerTask().isDeletedSoon(block.getLocation())); @@ -143,17 +147,14 @@ void testCannotOpenInvOfBrokenBlock() { ); server.getPluginManager().callEvent(secondPlayerInteractEvent); - server.getPluginManager().assertEventFired(PlayerInteractEvent.class, e -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(PlayerInteractEvent.class, e -> { // We cancelled the event due to the block being removed Assertions.assertSame(e.useInteractedBlock(), Result.DENY); return true; - }); + })); // Assert our right click event was not fired due to the block being broken - Assertions.assertThrows( - AssertionError.class, - () -> server.getPluginManager().assertEventFired(PlayerRightClickEvent.class, e -> true) - ); + assertThat(server.getPluginManager(), not(hasFiredFilteredEvent(PlayerRightClickEvent.class, e -> true))); } @Test @@ -171,17 +172,17 @@ void testRightClickItem() { ); server.getPluginManager().callEvent(playerInteractEvent); - server.getPluginManager().assertEventFired(PlayerInteractEvent.class, e -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(PlayerInteractEvent.class, e -> { // Assert our interaction was not cancelled Assertions.assertNotSame(e.useItemInHand(), Result.DENY); return true; - }); + })); // Assert our right click event fired and the item usage was not denied - server.getPluginManager().assertEventFired(PlayerRightClickEvent.class, e -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(PlayerRightClickEvent.class, e -> { Assertions.assertNotSame(e.useItem(), Result.DENY); return true; - }); + })); // Assert our food level is now 18 Assertions.assertEquals(18, player.getFoodLevel()); @@ -204,17 +205,17 @@ void testRightClickInteractableBlock() { ); server.getPluginManager().callEvent(playerInteractEvent); - server.getPluginManager().assertEventFired(PlayerInteractEvent.class, e -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(PlayerInteractEvent.class, e -> { // Allow interaction of the block Assertions.assertSame(e.useInteractedBlock(), Result.ALLOW); return true; - }); + })); // Assert our right click event fired and the block usage was not denied - server.getPluginManager().assertEventFired(PlayerRightClickEvent.class, e -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(PlayerRightClickEvent.class, e -> { Assertions.assertNotSame(e.useBlock(), Result.DENY); return true; - }); + })); // Assert the message our energy connector sends Assertions.assertEquals(ChatColors.color("&7Connected: " + "&4\u2718"), player.nextMessage()); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSmithingTableListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSmithingTableListener.java index 4c02f5864b..f714920f51 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSmithingTableListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSmithingTableListener.java @@ -1,7 +1,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; import org.apache.commons.lang3.mutable.MutableObject; import org.bukkit.Material; @@ -70,6 +70,8 @@ private SmithItemEvent mockSmithingEvent(ItemStack tool, ItemStack material) { Player player = server.addPlayer(); SmithingInventory inv = Mockito.mock(SmithingInventory.class); + Mockito.when(inv.getType()).thenReturn(org.bukkit.event.inventory.InventoryType.SMITHING); + Mockito.when(inv.getSize()).thenReturn(4); // MinecraftVersion#isAtLeast always returns true during unit test, so we use the 1.20 layout here. Mockito.when(inv.getContents()).thenReturn(new ItemStack[] { new ItemStack(Material.NETHERITE_UPGRADE_SMITHING_TEMPLATE), tool, material, null }); @@ -84,6 +86,8 @@ private PrepareSmithingEvent mockPrepareSmithingEvent(ItemStack tool, ItemStack Player player = server.addPlayer(); SmithingInventory inv = Mockito.mock(SmithingInventory.class); + Mockito.when(inv.getType()).thenReturn(org.bukkit.event.inventory.InventoryType.SMITHING); + Mockito.when(inv.getSize()).thenReturn(4); MutableObject result = new MutableObject<>(new ItemStack(Material.NETHERITE_PICKAXE)); Mockito.doAnswer(invocation -> { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSoulboundListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSoulboundListener.java index cfe65281ed..72fb9bfd56 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSoulboundListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestSoulboundListener.java @@ -18,9 +18,12 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.entity.PlayerMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventFilterMatcher.hasFiredFilteredEvent; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.entity.PlayerMock; class TestSoulboundListener { @@ -49,9 +52,9 @@ void testItemDrop(boolean soulbound) { player.getInventory().setItem(6, item); player.setHealth(0); - server.getPluginManager().assertEventFired(EntityDeathEvent.class, event -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(EntityDeathEvent.class, event -> { return soulbound != event.getDrops().contains(item); - }); + })); } @ParameterizedTest @@ -71,10 +74,10 @@ void testItemDropIfItemDisabled(boolean enabled) { player.getInventory().setItem(0, item.item()); player.setHealth(0); - server.getPluginManager().assertEventFired(EntityDeathEvent.class, event -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(EntityDeathEvent.class, event -> { // If the item is enabled, we don't want it to drop. return enabled == !event.getDrops().contains(item.item()); - }); + })); Slimefun.getRegistry().getEnabledSlimefunItems().remove(soulboundItem); } @@ -89,10 +92,10 @@ void testItemRecover(boolean soulbound) { player.setHealth(0); player.respawn(); - server.getPluginManager().assertEventFired(PlayerRespawnEvent.class, event -> { + assertThat(server.getPluginManager(), hasFiredFilteredEvent(PlayerRespawnEvent.class, event -> { ItemStack stack = player.getInventory().getItem(6); return SlimefunUtils.isItemSimilar(stack, item, true) == soulbound; - }); + })); } } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestVillagerTradingListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestVillagerTradingListener.java index 4dc145ba9c..42f438d231 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestVillagerTradingListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TestVillagerTradingListener.java @@ -27,8 +27,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.misc.SyntheticEmerald; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestVillagerTradingListener { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestItemGroups.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestItemGroups.java index bdaa4a1d25..496bbd7934 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestItemGroups.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestItemGroups.java @@ -27,8 +27,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestItemGroups { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestItemHandlers.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestItemHandlers.java index 945c1082aa..ab8a608e09 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestItemHandlers.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestItemHandlers.java @@ -19,7 +19,7 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import io.github.thebusybiscuit.slimefun4.test.mocks.MockItemHandler; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestItemHandlers { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestRechargeableItems.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestRechargeableItems.java index 9dbde56faf..062611865a 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestRechargeableItems.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestRechargeableItems.java @@ -18,7 +18,7 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import io.github.thebusybiscuit.slimefun4.utils.LoreBuilder; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestRechargeableItems { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestRegistration.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestRegistration.java index 8364ca3409..f33023cdf1 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestRegistration.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestRegistration.java @@ -32,7 +32,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.setup.ResearchSetup; import io.github.thebusybiscuit.slimefun4.implementation.setup.SlimefunItemSetup; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; @TestMethodOrder(value = OrderAnnotation.class) class TestRegistration { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestSlimefunItemRegistration.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestSlimefunItemRegistration.java index 577bbd0318..4b1ec18cb1 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestSlimefunItemRegistration.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/registration/TestSlimefunItemRegistration.java @@ -17,7 +17,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.VanillaItem; import io.github.thebusybiscuit.slimefun4.test.TestUtilities; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestSlimefunItemRegistration { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TestArmorTask.java b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TestArmorTask.java index 2d53c865fa..f8446f3155 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TestArmorTask.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TestArmorTask.java @@ -28,8 +28,8 @@ import io.github.thebusybiscuit.slimefun4.test.TestUtilities; import io.github.thebusybiscuit.slimefun4.test.mocks.MockHazmatSuit; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; class TestArmorTask { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/storage/backend/TestLegacyBackend.java b/src/test/java/io/github/thebusybiscuit/slimefun4/storage/backend/TestLegacyBackend.java index 6fa492b7a0..adfe50250b 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/storage/backend/TestLegacyBackend.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/storage/backend/TestLegacyBackend.java @@ -22,8 +22,8 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; import io.github.thebusybiscuit.slimefun4.api.gps.Waypoint; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.api.researches.Research; diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/test/TestUtilities.java b/src/test/java/io/github/thebusybiscuit/slimefun4/test/TestUtilities.java index a46d933d54..017d4501a5 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/test/TestUtilities.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/test/TestUtilities.java @@ -26,8 +26,11 @@ import org.junit.jupiter.api.Assertions; import org.mockito.Mockito; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.block.BlockMock; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.block.BlockMock; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventFilterMatcher.hasFiredFilteredEvent; import io.github.bakedlibs.dough.items.CustomItemStack; import io.github.thebusybiscuit.slimefun4.api.events.SlimefunBlockPlaceEvent; import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; @@ -117,7 +120,7 @@ public static Block placeSlimefunBlock(ServerMock server, ItemStack item, World ); server.getPluginManager().callEvent(blockPlaceEvent); - server.getPluginManager().assertEventFired(SlimefunBlockPlaceEvent.class, e -> true); + assertThat(server.getPluginManager(), hasFiredFilteredEvent(SlimefunBlockPlaceEvent.class, e -> true)); return block; } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/test/mocks/InventoryViewWrapper.java b/src/test/java/io/github/thebusybiscuit/slimefun4/test/mocks/InventoryViewWrapper.java index 0b49c5ed0b..1cc1b09342 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/test/mocks/InventoryViewWrapper.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/test/mocks/InventoryViewWrapper.java @@ -1,6 +1,6 @@ package io.github.thebusybiscuit.slimefun4.test.mocks; -import be.seeseemelk.mockbukkit.inventory.InventoryViewMock; +import org.mockbukkit.mockbukkit.inventory.InventoryViewMock; import org.bukkit.entity.HumanEntity; import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.Inventory; @@ -25,21 +25,19 @@ public class InventoryViewWrapper extends InventoryViewMock { private InventoryViewWrapper(HumanEntity player, - String name, Inventory top, Inventory bottom, InventoryType type) { - super(player, name, top, bottom, type); + super(player, top, bottom, type); } @Nonnull public static InventoryViewWrapper wrap(@Nonnull InventoryView inventoryView) { HumanEntity player = inventoryView.getPlayer(); - String name = inventoryView.getTitle(); Inventory top = inventoryView.getTopInventory(); Inventory bottom = inventoryView.getBottomInventory(); InventoryType inventoryType = inventoryView.getType(); - return new InventoryViewWrapper(player, name, top, bottom, inventoryType); + return new InventoryViewWrapper(player, top, bottom, inventoryType); } @Override diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/test/presets/SlimefunItemTest.java b/src/test/java/io/github/thebusybiscuit/slimefun4/test/presets/SlimefunItemTest.java index 36218a9506..e236ec2cc4 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/test/presets/SlimefunItemTest.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/test/presets/SlimefunItemTest.java @@ -16,7 +16,7 @@ import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.block.BlockMock; +import org.mockbukkit.mockbukkit.block.BlockMock; /** * This is a convenient interface for us to use in unit test classes @@ -59,7 +59,7 @@ default void simulateRightClickBlock(Player player, T item, ItemStack heldItem, @ParametersAreNonnullByDefault default void simulateConsumption(Player player, T item) { - PlayerItemConsumeEvent event = new PlayerItemConsumeEvent(player, item.getItem().clone()); + PlayerItemConsumeEvent event = new PlayerItemConsumeEvent(player, item.getItem().clone(), EquipmentSlot.HAND); item.callItemHandler(ItemConsumptionHandler.class, handler -> handler.onConsume(event, player, event.getItem())); } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestChargeUtils.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestChargeUtils.java index 1f91b38415..1f56782d29 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestChargeUtils.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestChargeUtils.java @@ -15,7 +15,7 @@ import io.github.bakedlibs.dough.data.persistent.PersistentDataAPI; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestChargeUtils { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestFireworkUtils.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestFireworkUtils.java index a32183d663..c633b47892 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestFireworkUtils.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestFireworkUtils.java @@ -17,8 +17,8 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.WorldMock; +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.world.WorldMock; class TestFireworkUtils { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestInfiniteBlockGenerators.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestInfiniteBlockGenerators.java index 5d0d2fec68..c6e3b73e39 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestInfiniteBlockGenerators.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestInfiniteBlockGenerators.java @@ -20,9 +20,12 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.WorldMock; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventClassMatcher.hasFiredEventInstance; + +import org.mockbukkit.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.ServerMock; +import org.mockbukkit.mockbukkit.world.WorldMock; class TestInfiniteBlockGenerators { @@ -70,7 +73,7 @@ void testValidCobblestoneGenerator(BlockFace water, BlockFace lava) { Assertions.assertTrue(generator.test(block)); Assertions.assertNotNull(generator.callEvent(block)); - server.getPluginManager().assertEventFired(BlockFormEvent.class); + assertThat(server.getPluginManager(), hasFiredEventInstance(BlockFormEvent.class)); server.getPluginManager().clearEvents(); Assertions.assertEquals(generator, InfiniteBlockGenerator.findAt(block)); @@ -112,7 +115,7 @@ void testValidBasaltGenerator(BlockFace ice, BlockFace lava) { Assertions.assertTrue(generator.test(block)); Assertions.assertNotNull(generator.callEvent(block)); - server.getPluginManager().assertEventFired(BlockFormEvent.class); + assertThat(server.getPluginManager(), hasFiredEventInstance(BlockFormEvent.class)); server.getPluginManager().clearEvents(); Assertions.assertEquals(generator, InfiniteBlockGenerator.findAt(block)); @@ -153,7 +156,7 @@ void testValidStoneGenerator(BlockFace water) { Assertions.assertTrue(generator.test(block)); Assertions.assertNotNull(generator.callEvent(block)); - server.getPluginManager().assertEventFired(BlockFormEvent.class); + assertThat(server.getPluginManager(), hasFiredEventInstance(BlockFormEvent.class)); server.getPluginManager().clearEvents(); Assertions.assertEquals(generator, InfiniteBlockGenerator.findAt(block)); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestItemStackWrapper.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestItemStackWrapper.java index 76aaa5b944..de85a35649 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestItemStackWrapper.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestItemStackWrapper.java @@ -17,7 +17,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestItemStackWrapper { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestLoreComparison.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestLoreComparison.java index 7441f22502..d24e59ad11 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestLoreComparison.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestLoreComparison.java @@ -12,7 +12,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestLoreComparison { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestSoulboundItem.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestSoulboundItem.java index 391fd6c2e0..0593d54de3 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestSoulboundItem.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/TestSoulboundItem.java @@ -17,7 +17,7 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.Soulbound; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestSoulboundItem { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMap.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMap.java index 756c5044cf..13022b3f5d 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMap.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMap.java @@ -16,7 +16,7 @@ import io.github.thebusybiscuit.slimefun4.api.exceptions.BiomeMapException; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestBiomeMap { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapCompatibility.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapCompatibility.java index 6dc1c8b3c7..2738a8e1e9 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapCompatibility.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapCompatibility.java @@ -29,7 +29,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.utils.JsonUtils; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; /** * This test checks if biome maps work across multiple versions of Minecraft. diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapParser.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapParser.java index 0aa6bf9c81..b29e95bb41 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapParser.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapParser.java @@ -17,7 +17,7 @@ import io.github.thebusybiscuit.slimefun4.api.exceptions.BiomeMapException; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestBiomeMapParser { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/tags/TestSlimefunTags.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/tags/TestSlimefunTags.java index 0e9fe8e3f6..cc913ae713 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/tags/TestSlimefunTags.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/tags/TestSlimefunTags.java @@ -19,7 +19,7 @@ import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestSlimefunTags { diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/tags/TestTagParser.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/tags/TestTagParser.java index 68f3748715..029da3786c 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/tags/TestTagParser.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/tags/TestTagParser.java @@ -12,7 +12,7 @@ import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; -import be.seeseemelk.mockbukkit.MockBukkit; +import org.mockbukkit.mockbukkit.MockBukkit; class TestTagParser { From d611f0af345c6d98efb49cc6443cbc4d42422632 Mon Sep 17 00:00:00 2001 From: Intisy Date: Tue, 10 Mar 2026 22:05:55 +0100 Subject: [PATCH 7/8] Fix README and workflows for gradle migration --- .github/workflows/gradle-build.yml | 1 + .github/workflows/javadocs.yml | 1 + .github/workflows/pull-request.yml | 1 + .github/workflows/release.yml | 1 + 4 files changed, 4 insertions(+) diff --git a/.github/workflows/gradle-build.yml b/.github/workflows/gradle-build.yml index cb883ef311..a4e816a3a7 100644 --- a/.github/workflows/gradle-build.yml +++ b/.github/workflows/gradle-build.yml @@ -39,4 +39,5 @@ jobs: - name: Build with Gradle uses: gradle/actions/setup-gradle@v4 + - run: chmod +x ./gradlew - run: ./gradlew shadowJar diff --git a/.github/workflows/javadocs.yml b/.github/workflows/javadocs.yml index 37b884a73b..80512e50f5 100644 --- a/.github/workflows/javadocs.yml +++ b/.github/workflows/javadocs.yml @@ -28,4 +28,5 @@ jobs: - name: Build Javadocs uses: gradle/actions/setup-gradle@v4 + - run: chmod +x ./gradlew - run: ./gradlew javadoc diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 5121b3791e..244a69a5d1 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -38,6 +38,7 @@ jobs: - name: Build with Gradle uses: gradle/actions/setup-gradle@v4 + - run: chmod +x ./gradlew - run: ./gradlew shadowJar - name: Upload the artifact diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d2f44005e5..cd14f8e699 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,6 +43,7 @@ jobs: - name: Build with Gradle uses: gradle/actions/setup-gradle@v4 + - run: chmod +x ./gradlew - run: ./gradlew shadowJar - name: Create GitHub Release From f2a66c8e87ca8b26f6a474955bb8e5b99685115f Mon Sep 17 00:00:00 2001 From: Intisy Date: Tue, 10 Mar 2026 22:11:14 +0100 Subject: [PATCH 8/8] Update old github repository references in markdown files --- CHANGELOG.md | 2 +- CONTRIBUTING.md | 20 ++++++++++---------- README.md | 26 +++++++++++++------------- docs/adr/0001-storage-layer.md | 18 +++++++++--------- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 453eb54984..bb2a5a5f43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -328,7 +328,7 @@ https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#28 https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#27 ### **Breaking Changes (API)** -This RC brings a lot of breaking changes to the API. For more info on why we did this and what happened [please refer to our PSA](https://github.com/Slimefun/Slimefun4/pull/3139) +This RC brings a lot of breaking changes to the API. For more info on why we did this and what happened [please refer to our PSA](https://github.com/Slimefun5/Slimefun5/pull/3139) * Category has been renamed to ItemGroup. * All Category / ItemGroup variants have been relocated to `io.github.thebusybiscuit.slimefun4.api.items.groups` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6e6d01d2e8..425b35a37e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,15 +1,15 @@ # Contributing to Slimefun This document outlines various ways how you can help contribute to Slimefun and make this a bigger and better project.
-All contributions must be inline with our [Code of Conduct](https://github.com/Slimefun/Slimefun4/blob/master/.github/CODE_OF_CONDUCT.md) and [License](https://github.com/Slimefun/Slimefun4/blob/master/LICENSE). +All contributions must be inline with our [Code of Conduct](https://github.com/Slimefun5/Slimefun5/blob/master/.github/CODE_OF_CONDUCT.md) and [License](https://github.com/Slimefun5/Slimefun5/blob/master/LICENSE). Please also follow the templates for Issues and Pull Requests we provide. ## :beetle: 1. Issues: Bug Reports One of the foundations for good software is reliability. To facilitate this reliability, our community must work together to crush bugs that arise. This of course requires good information and knowledge about ongoing bugs and issues though. -You can help this project by reporting a bug on our [Issues Tracker](https://github.com/Slimefun/Slimefun4/issues).
+You can help this project by reporting a bug on our [Issues Tracker](https://github.com/Slimefun5/Slimefun5/issues).
Please adhere to the provided template and provide as much information as possible. -For more info on how to make good and helpful bug reports, check out our article on [How to report bugs](https://github.com/Slimefun/Slimefun4/wiki/How-to-report-bugs). +For more info on how to make good and helpful bug reports, check out our article on [How to report bugs](https://github.com/Slimefun5/Slimefun5/wiki/How-to-report-bugs). If you encounter an issue which has already been reported, please don't open a new one.
It would be awesome though if you could post a comment on the existing issue which explains how you were able to reproduce this yourself. @@ -17,10 +17,10 @@ The more context and information we get, the easier we can fix it. ## :hammer_and_wrench: 2. Pull Requests: Bug Fixes Bugs that have been reported need to be fixed of course.
-Any open Issue on our [Issues Tracker](https://github.com/Slimefun/Slimefun4/issues) is waiting to be fixed. +Any open Issue on our [Issues Tracker](https://github.com/Slimefun5/Slimefun5/issues) is waiting to be fixed. This is an Open-Source project and we love Pull Requests. -So if you have an idea on how to approach a known issue, feel free to make a [Pull Request](https://github.com/Slimefun/Slimefun4/pulls) which fixes this bug. +So if you have an idea on how to approach a known issue, feel free to make a [Pull Request](https://github.com/Slimefun5/Slimefun5/pulls) which fixes this bug. You can also comment on the existing Issue, proposing your idea or communicating that you wanna work on this. ## :wrench: 3. Pull Requests: Additions/Changes @@ -34,7 +34,7 @@ Suggestions which gotten enough votes will be moved to `#approved`. Therefore our `#approved` is a great place to start looking for ideas on what to add or change, since it will definitely be something a large number of people agree with. Also consider making an addon for your additions when they get too large, too abstract or too "niche". -You can check out our [Developer Guide](https://github.com/Slimefun/Slimefun4/wiki/Developer-Guide) for a guide on how to create a Slimefun addon.. +You can check out our [Developer Guide](https://github.com/Slimefun5/Slimefun5/wiki/Developer-Guide) for a guide on how to create a Slimefun addon.. ## :earth_africa: 4. Pull Requests: Translations Another great way to contribute to Slimefun is by working on translations for the project. @@ -46,7 +46,7 @@ One of our Language Moderators will review the changes and submit a Pull Request Very active community translators will have the option to become a "Language Moderator". Language Moderators are responsible for proof-reading any new translations for their designated language and correct it when they see a mistake. -For more info on how or what to translate, check out our article on [How to translate Slimefun](https://github.com/Slimefun/Slimefun4/wiki/Translating-Slimefun). +For more info on how or what to translate, check out our article on [How to translate Slimefun](https://github.com/Slimefun5/Slimefun5/wiki/Translating-Slimefun). ## :scroll: 5. Pull Requests: Wiki contributions Slimefun is a very large project and might be quite intimidating for new players. @@ -55,7 +55,7 @@ If you have played with Slimefun for a while and gotten yourself familiar with h It would help out a lot :heart: You can find a tutorial on how to contribute to our wiki right here:
-https://github.com/Slimefun/Slimefun4/wiki/Expanding-the-Wiki +https://github.com/Slimefun5/Slimefun5/wiki/Expanding-the-Wiki ## :star: 6. Pull Requests: Code Quality Slimefun uses [sonarcloud.io](https://sonarcloud.io/dashboard?id=Slimefun_Slimefun4) to monitor Code Quality. @@ -74,7 +74,7 @@ Feel free to visit our [Javadocs](https://slimefun.github.io/javadocs/Slimefun4/ #### Unit Tests Unit Tests help us test the project to work as intended in an automated manner.
-More or better Unit Tests are always good to have, so feel free to submit a Test and place it in our [src/test/java](https://github.com/Slimefun/Slimefun4/tree/master/src/test/java/io/github/thebusybiscuit/slimefun4/testing) directory +More or better Unit Tests are always good to have, so feel free to submit a Test and place it in our [src/test/java](https://github.com/Slimefun5/Slimefun5/tree/master/src/test/java/io/github/thebusybiscuit/slimefun4/testing) directory We are using [Junit 5 - Jupiter](https://github.com/junit-team/junit5/) and [MockBukkit](https://github.com/seeseemelk/MockBukkit) as our testing environment.
Every new Unit Test should have a `@DisplayName` annotation with a plain text description on what the Unit Test tests. @@ -84,7 +84,7 @@ Slimefun is written in Java and uses [Maven](https://maven.apache.org/) for comp To compile Slimefun yourself, follow these steps: 1. Clone the project via git
-`$ git clone https://github.com/Slimefun/Slimefun4/` +`$ git clone https://github.com/Slimefun5/Slimefun5/` 2. Compile the project using Maven
`$ mvn clean package` 3. Extract the compiled `Slimefun-v4.X-UNOFFICIAL.jar` from your `/target/` directory. diff --git a/README.md b/README.md index b4608c892d..b48c747778 100644 --- a/README.md +++ b/README.md @@ -7,21 +7,21 @@ We got everything from magical wands to nuclear reactors.
We feature a magical altar, an electric power grid and even item transport systems. This project originally started back **in 2013** and has grown ever since.
-It currently adds over **500 new items and recipes** to Minecraft ([Read more about the history of this project](https://github.com/Slimefun/Slimefun4/wiki/Slimefun-in-a-nutshell)). +It currently adds over **500 new items and recipes** to Minecraft ([Read more about the history of this project](https://github.com/Slimefun5/Slimefun5/wiki/Slimefun-in-a-nutshell)). -Check out the available [addons](https://github.com/Slimefun/Slimefun4/wiki/Addons) — they may have exactly what you were looking for. +Check out the available [addons](https://github.com/Slimefun5/Slimefun5/wiki/Addons) — they may have exactly what you were looking for. ### Quick navigation * **[:floppy_disk: Download](#floppy_disk-download)** * **[:framed_picture: Screenshots](#framed_picture-screenshots)** * **[:beetle: Bug Tracker](https://github.com/Slimefun5/Slimefun5/issues)** -* **[:open_book: Wiki](https://github.com/Slimefun/Slimefun4/wiki)** -* **[:interrobang: FAQ](https://github.com/Slimefun/Slimefun4/wiki/FAQ)** +* **[:open_book: Wiki](https://github.com/Slimefun5/Slimefun5/wiki)** +* **[:interrobang: FAQ](https://github.com/Slimefun5/Slimefun5/wiki/FAQ)** * **[:handshake: How to contribute](https://github.com/Slimefun5/Slimefun5/blob/stable/CONTRIBUTING.md)** ## :floppy_disk: Download Slimefun requires your Minecraft Server to be running on [Spigot](https://spigotmc.org/), [Paper](https://papermc.io/) or on any fork of these.
-(See also: [How to install Slimefun](https://github.com/Slimefun/Slimefun4/wiki/Installing-Slimefun)) +(See also: [How to install Slimefun](https://github.com/Slimefun5/Slimefun5/wiki/Installing-Slimefun)) | | This fork | | ------------------ | -------- | @@ -43,16 +43,16 @@ Here are some screenshots from the community: ## :open_book: Wiki The upstream Slimefun wiki remains a great resource for getting started:
-https://github.com/Slimefun/Slimefun4/wiki +https://github.com/Slimefun5/Slimefun5/wiki #### :star: Highlighted Articles -* [What is Slimefun?](https://github.com/Slimefun/Slimefun4/wiki/Slimefun-in-a-nutshell) -* [How to install Slimefun](https://github.com/Slimefun/Slimefun4/wiki/Installing-Slimefun) -* [Addons for Slimefun 4](https://github.com/Slimefun/Slimefun4/wiki/Addons) -* [How to create an Addon](https://github.com/Slimefun/Slimefun4/wiki/Developer-Guide) -* [Getting Started](https://github.com/Slimefun/Slimefun4/wiki/Getting-Started) -* [Frequently Asked Questions](https://github.com/Slimefun/Slimefun4/wiki/FAQ) -* [Common issues](https://github.com/Slimefun/Slimefun4/wiki/Common-Issues) +* [What is Slimefun?](https://github.com/Slimefun5/Slimefun5/wiki/Slimefun-in-a-nutshell) +* [How to install Slimefun](https://github.com/Slimefun5/Slimefun5/wiki/Installing-Slimefun) +* [Addons for Slimefun 4](https://github.com/Slimefun5/Slimefun5/wiki/Addons) +* [How to create an Addon](https://github.com/Slimefun5/Slimefun5/wiki/Developer-Guide) +* [Getting Started](https://github.com/Slimefun5/Slimefun5/wiki/Getting-Started) +* [Frequently Asked Questions](https://github.com/Slimefun5/Slimefun5/wiki/FAQ) +* [Common issues](https://github.com/Slimefun5/Slimefun5/wiki/Common-Issues) The wiki is entirely community-run, so if you find an article missing, feel free to write one and share it with others. diff --git a/docs/adr/0001-storage-layer.md b/docs/adr/0001-storage-layer.md index 0809ed04a2..7d6038e2b9 100644 --- a/docs/adr/0001-storage-layer.md +++ b/docs/adr/0001-storage-layer.md @@ -35,7 +35,7 @@ We want to create a new storage layer abstraction and implementations which will be backwards-compatible but open up new ways of storing data within Slimefun. The end end goal is we can quickly and easily support new storage backends (such as binary storage, SQL, etc.) for things like -[PlayerProfile](https://github.com/Slimefun/Slimefun4/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java), [BlockStorage](https://github.com/Slimefun/Slimefun4/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java), etc. +[PlayerProfile](https://github.com/Slimefun5/Slimefun5/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java), [BlockStorage](https://github.com/Slimefun5/Slimefun5/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java), etc. We also want to be generally more efficient in the way we save and load data. Today, we load way more than is required. @@ -56,13 +56,13 @@ as possible. There is a new interface called [`Storage`](TBD) which is what all storage backends will implement. This will have methods for loading and saving things like -[`PlayerProfile`](https://github.com/Slimefun/Slimefun4/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java) and [`BlockStorage`](https://github.com/Slimefun/Slimefun4/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java). +[`PlayerProfile`](https://github.com/Slimefun5/Slimefun5/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java) and [`BlockStorage`](https://github.com/Slimefun5/Slimefun5/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java). Then, backends will implement these (e.g. [`LegacyStorageBackend`](TBD) (today's YAML situation)) in order to support these functions. Not all storage backends are required support each data type. -e.g. SQL may not support [`BlockStorage`](https://github.com/Slimefun/Slimefun4/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java). +e.g. SQL may not support [`BlockStorage`](https://github.com/Slimefun5/Slimefun5/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java). ## Addons @@ -86,29 +86,29 @@ Phases do not (and very likely will not) be done within a single PR. They will a The current plan looks like this: -* Phase 1 - Implement legacy data backend for [`PlayerProfile`](https://github.com/Slimefun/Slimefun4/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java). +* Phase 1 - Implement legacy data backend for [`PlayerProfile`](https://github.com/Slimefun5/Slimefun5/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java). * We want to load player data using the new storage layer with the current data system. * We'll want to monitor for any possible issues and generally refine how this system should look -* Phase 2 - Implement new experimental binary backend for [`PlayerProfile`](https://github.com/Slimefun/Slimefun4/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java). +* Phase 2 - Implement new experimental binary backend for [`PlayerProfile`](https://github.com/Slimefun5/Slimefun5/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java). * Create a new backend for binary storage * Implement in an experimental capacity and allow users to opt-in * Provide a warning that this is **experimental** and there will be bugs. * Implement new metric for storage backend being used -* Phase 3 - Mark the new backend as stable for [`PlayerProfile`](https://github.com/Slimefun/Slimefun4/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java). +* Phase 3 - Mark the new backend as stable for [`PlayerProfile`](https://github.com/Slimefun5/Slimefun5/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java). * Mark it as stable and remove the warnings once we're sure things are working correctly * Create a migration path for users currently using "legacy". * Enable by default for new servers -* Phase 4 - Move [`BlockStorage`](https://github.com/Slimefun/Slimefun4/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java) to new storage layer. +* Phase 4 - Move [`BlockStorage`](https://github.com/Slimefun5/Slimefun5/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java) to new storage layer. * The big one! We're gonna tackle adding this to BlockStorage. This will probably be a large change and we'll want to be as careful as possible here. * Implement `legacy` and `binary` as experimental storage backends for BlockStorage and allow users to opt-in * Provide a warning that this is **experimental** and there will be bugs. -* Phase 5 - Mark the new storage layer as stable for [`BlockStorage`](https://github.com/Slimefun/Slimefun4/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java). +* Phase 5 - Mark the new storage layer as stable for [`BlockStorage`](https://github.com/Slimefun5/Slimefun5/blob/bbfb9734b9f549d7e82291eff041f9b666a61b63/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java). * Mark it as stable and remove the warnings once we're sure things are working correctly * Ensure migration path works here too. @@ -121,7 +121,7 @@ The current plan looks like this: ## State of work * Phase 1: In progress - * https://github.com/Slimefun/Slimefun4/pull/4065 + * https://github.com/Slimefun5/Slimefun5/pull/4065 * Phase 2: Not started * Phase 3: Not started * Phase 4: Not started