diff --git a/.github/workflows/pr-checker.yml b/.github/workflows/pr-checker.yml index 0a91e9c360..926218ab4d 100644 --- a/.github/workflows/pr-checker.yml +++ b/.github/workflows/pr-checker.yml @@ -31,20 +31,11 @@ jobs: java-version: ${{ vars.JAVA_CI_VERSION }} java-package: jdk architecture: x64 - - - name: Cache Maven packages - uses: actions/cache@v3 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 + cache: 'maven' - name: Codestyle Check run: mvn -s .mvn/settings.xml -B spotless:check compile --errors - - name: Build with Maven - run: mvn -s .mvn/settings.xml package --errors - # Setup for the preview build - name: Environment Setup id: env-setup @@ -54,7 +45,10 @@ 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/5.0-SNAPSHOT<\/version>/$JAR_VERSION<\/version>/g" pom.xml + sed -i "s/UNOFFICIAL<\/version>/$JAR_VERSION<\/version>/g" pom.xml + + - name: Build with Maven + run: mvn -s .mvn/settings.xml package --errors - name: Upload the artifact uses: actions/upload-artifact@v3 diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 6e75e593d8..9e89223c9b 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -14,5 +14,5 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -wrapperVersion=3.3.1 -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip +wrapperVersion=3.3.2 +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip diff --git a/README.md b/README.md index d536670ee2..ca8289dc01 100644 --- a/README.md +++ b/README.md @@ -75,8 +75,8 @@ Slimefun 4 可以在[鬼斩构建站](https://builds.guizhanss.com)页面中** ## :computer: 如何编译 要编译 Slimefun4,你必须先安装 [Git](https://git-scm.com/) 然后 `git clone https://github.com/SlimefunGuguProject/Slimefun4.git` -最后如果你是 Windows 系统: `.\mvnw.cmd -s .mvn/settings.xml package` -如果你是类 Unix 系统: `.\mvnw -s .mvn/settings.xml package` +最后如果你是 Windows 系统: `.\mvnw.cmd package` +如果你是类 Unix 系统: `.\mvnw package` ## :framed_picture: 截图 diff --git a/pom.xml b/pom.xml index 40dc0a8cd8..990556b610 100644 --- a/pom.xml +++ b/pom.xml @@ -207,7 +207,7 @@ com.rudikershaw.gitbuildhook git-build-hook-maven-plugin - 3.4.1 + 3.5.0 .git-hooks/pre-commit @@ -369,7 +369,7 @@ me.clip placeholderapi - 2.11.5 + 2.11.6 provided diff --git a/src/main/java/city/norain/slimefun4/SlimefunExtended.java b/src/main/java/city/norain/slimefun4/SlimefunExtended.java index 330d09fe83..c9436e2796 100644 --- a/src/main/java/city/norain/slimefun4/SlimefunExtended.java +++ b/src/main/java/city/norain/slimefun4/SlimefunExtended.java @@ -2,6 +2,8 @@ import city.norain.slimefun4.compatibillty.VersionedEvent; import city.norain.slimefun4.listener.SlimefunMigrateListener; +import io.github.bakedlibs.dough.versions.MinecraftVersion; +import io.github.bakedlibs.dough.versions.UnknownServerVersionException; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import java.util.logging.Level; import javax.annotation.Nonnull; @@ -13,6 +15,9 @@ public final class SlimefunExtended { @Getter private static boolean databaseDebugMode = false; + @Getter + private static MinecraftVersion minecraftVersion; + private static void checkDebug() { if ("true".equals(System.getProperty("slimefun.database.debug"))) { databaseDebugMode = true; @@ -20,6 +25,13 @@ private static void checkDebug() { } public static boolean checkEnvironment(@Nonnull Slimefun sf) { + try { + minecraftVersion = MinecraftVersion.of(sf.getServer()); + } catch (UnknownServerVersionException e) { + sf.getLogger().log(Level.WARNING, "无法识别你正在使用的服务端版本 :("); + return false; + } + if (EnvironmentChecker.checkHybridServer()) { sf.getLogger().log(Level.WARNING, "#######################################################"); sf.getLogger().log(Level.WARNING, ""); diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/util/LocationUtils.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/util/LocationUtils.java index db03bc4585..1c01ea947d 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/util/LocationUtils.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/util/LocationUtils.java @@ -1,5 +1,6 @@ package com.xzavier0722.mc.plugin.slimefun4.storage.util; +import city.norain.slimefun4.SlimefunExtended; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.Location; @@ -39,7 +40,11 @@ public static boolean isSameLoc(Location l1, Location l2) { public static Chunk toChunk(World w, String cKey) { var loc = cKey.split(";")[1].split(":"); - return w.getChunkAt(Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), false); + if (SlimefunExtended.getMinecraftVersion().isAtLeast(1, 19, 4)) { + return w.getChunkAt(Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), false); + } else { + return w.getChunkAt(Integer.parseInt(loc[0]), Integer.parseInt(loc[1])); + } } public static boolean isSameWorld(World w1, World w2) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java index b22cb3324a..1aac0d5d02 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java @@ -115,9 +115,8 @@ public List getAllItemGroups() { */ public @Nonnull List getDisabledSlimefunItems() { List allItems = new ArrayList<>(getAllSlimefunItems()); - List enabledItems = getEnabledSlimefunItems(); - allItems.removeAll(enabledItems); - return allItems; + return new ArrayList<>( + allItems.stream().filter(SlimefunItem::isDisabled).toList()); } /** 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 9ae25d5493..1198b6a17f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java @@ -88,6 +88,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.CraftingTableListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.GrindstoneListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.SmithingTableListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting.VanillaCrafterListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.entity.BeeListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.entity.EntityInteractionListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.entity.FireworksListener; @@ -708,6 +709,7 @@ private void registerListeners() { new BeeWingsListener(this, (BeeWings) SlimefunItems.BEE_WINGS.getItem()); new PiglinListener(this); new SmithingTableListener(this); + new VanillaCrafterListener(this); new JoinListener(this); // Item-specific Listeners 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 51cdf70103..7dc91df32c 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java @@ -1008,8 +1008,8 @@ private SlimefunItems() {} public static final SlimefunItemStack LAVA_CRYSTAL = new SlimefunItemStack("LAVA_CRYSTAL", HeadTexture.LAVA_CRYSTAL, "&4岩浆水晶"); public static final SlimefunItemStack SALT = new SlimefunItemStack("SALT", Material.SUGAR, "&r盐"); - public static final SlimefunItemStack CHEESE = new SlimefunItemStack("CHEESE", HeadTexture.CHEESE, "&r黄油"); - public static final SlimefunItemStack BUTTER = new SlimefunItemStack("BUTTER", HeadTexture.BUTTER, "&r奶酪"); + public static final SlimefunItemStack CHEESE = new SlimefunItemStack("CHEESE", HeadTexture.CHEESE, "&r奶酪"); + public static final SlimefunItemStack BUTTER = new SlimefunItemStack("BUTTER", HeadTexture.BUTTER, "&r黄油"); public static final SlimefunItemStack DUCT_TAPE = new SlimefunItemStack("DUCT_TAPE", HeadTexture.DUCT_TAPE, "&8强力胶布", "", "&r可以用这个在自动铁砧里", "&r修复物品"); public static final SlimefunItemStack HEAVY_CREAM = diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BackpackListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BackpackListener.java index 6107a9ad10..77bbd088ee 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BackpackListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BackpackListener.java @@ -160,6 +160,10 @@ private void openBackpack(Player p, ItemStack item, PlayerProfile profile, int s Slimefun.getLocalization().sendMessage(p, "backpack.not-original-item", true); return; } + if (item.getAmount() > 1) { + Slimefun.getLocalization().sendMessage(p, "backpack.no-stack", true); + return; + } PlayerBackpack.bindItem( item, Slimefun.getDatabaseManager() diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java index 6a2efb809a..1a3f7d5c49 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java @@ -176,11 +176,11 @@ public void onBlockBreak(BlockBreakEvent e) { var heldItem = e.getPlayer().getInventory().getItemInMainHand(); var block = e.getBlock(); var blockData = StorageCacheUtils.getBlock(block.getLocation()); + var sfItem = blockData == null ? null : SlimefunItem.getById(blockData.getSfId()); // If there is a Slimefun Block here, call our BreakEvent and, if cancelled, cancel this event // and return if (blockData != null) { - var sfItem = SlimefunItem.getById(blockData.getSfId()); SlimefunBlockBreakEvent breakEvent = new SlimefunBlockBreakEvent(e.getPlayer(), heldItem, e.getBlock(), sfItem); Bukkit.getPluginManager().callEvent(breakEvent); @@ -204,7 +204,7 @@ public void onBlockBreak(BlockBreakEvent e) { checkForSensitiveBlockAbove(e.getPlayer(), e.getBlock(), heldItem); if (blockData == null || blockData.isPendingRemove()) { - dropItems(e, drops); + dropItems(e, heldItem, block, sfItem, drops); return; } @@ -223,7 +223,7 @@ public void onBlockBreak(BlockBreakEvent e) { return; } e.setDropItems(true); - dropItems(e, drops); + dropItems(e, heldItem, block, sfItem, drops); }, true); return; @@ -233,7 +233,7 @@ public void onBlockBreak(BlockBreakEvent e) { if (e.isCancelled()) { blockData.setPendingRemove(false); } - dropItems(e, drops); + dropItems(e, heldItem, block, sfItem, drops); // Checks for vanilla sensitive blocks everywhere // checkForSensitiveBlocks(e.getBlock(), 0, e.isDropItems()); @@ -271,12 +271,13 @@ private void callBlockHandler(BlockBreakEvent e, ItemStack item, List } @ParametersAreNonnullByDefault - private void dropItems(BlockBreakEvent e, List drops) { + private void dropItems( + BlockBreakEvent e, ItemStack item, Block block, @Nullable SlimefunItem sfBlock, List drops) { if (!drops.isEmpty()) { // TODO: properly support loading inventories within unit tests if (!Slimefun.instance().isUnitTest()) { // Notify plugins like CoreProtect - Slimefun.getProtectionManager().logAction(e.getPlayer(), e.getBlock(), Interaction.BREAK_BLOCK); + Slimefun.getProtectionManager().logAction(e.getPlayer(), block, Interaction.BREAK_BLOCK); } // Fixes #2560 @@ -284,14 +285,18 @@ private void dropItems(BlockBreakEvent e, List drops) { // Disable normal block drops e.setDropItems(false); + // Fixes #4051 + if (sfBlock == null) { + block.breakNaturally(item); + } + + // The list only contains other drops, not those from the block itself, so we still need to handle those for (ItemStack drop : drops) { // Prevent null or air from being dropped if (drop != null && drop.getType() != Material.AIR) { if (e.getPlayer().getGameMode() != GameMode.CREATIVE || Slimefun.getCfg().getBoolean("options.drop-block-creative")) { - e.getBlock() - .getWorld() - .dropItemNaturally(e.getBlock().getLocation(), drop); + block.getWorld().dropItemNaturally(block.getLocation(), drop); } } } @@ -330,7 +335,7 @@ private void checkForSensitiveBlockAbove(Player player, Block block, ItemStack i sfItem.callItemHandler( BlockBreakHandler.class, handler -> handler.onPlayerBreak(dummyEvent, item, drops)); controller.removeBlock(loc); - dropItems(dummyEvent, drops); + dropItems(dummyEvent, item, block, sfItem, drops); } else { blockData.setPendingRemove(true); controller.loadBlockDataAsync(blockData, new IAsyncReadCallback<>() { @@ -344,7 +349,7 @@ public void onResult(SlimefunBlockData result) { sfItem.callItemHandler( BlockBreakHandler.class, handler -> handler.onPlayerBreak(dummyEvent, item, drops)); controller.removeBlock(loc); - dropItems(dummyEvent, drops); + dropItems(dummyEvent, item, block, sfItem, drops); } }); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/crafting/SlimefunCraftingListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/crafting/SlimefunCraftingListener.java index 861acb2f5b..1354df4a4c 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/crafting/SlimefunCraftingListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/crafting/SlimefunCraftingListener.java @@ -31,4 +31,17 @@ default boolean isUnallowed(@Nullable ItemStack item) { default boolean isUnallowed(@Nullable SlimefunItem item) { return item != null && !(item instanceof VanillaItem) && !item.isDisabled(); } + + default boolean isCraftingUnallowed(@Nullable ItemStack item) { + if (item == null) { + return false; + } + + SlimefunItem sfItem = SlimefunItem.getByItem(item); + return isCraftingUnallowed(sfItem); + } + + default boolean isCraftingUnallowed(@Nullable SlimefunItem item) { + return item != null && !item.isUseableInWorkbench(); + } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/crafting/VanillaCrafterListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/crafting/VanillaCrafterListener.java new file mode 100644 index 0000000000..0b1b7f278a --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/crafting/VanillaCrafterListener.java @@ -0,0 +1,58 @@ +package io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting; + +import city.norain.slimefun4.SlimefunExtended; +import city.norain.slimefun4.compatibillty.VersionedEvent; +import io.github.bakedlibs.dough.versions.MinecraftVersion; +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; +import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; +import javax.annotation.Nonnull; +import org.bukkit.block.Crafter; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; + +public class VanillaCrafterListener implements SlimefunCraftingListener { + public VanillaCrafterListener(@Nonnull Slimefun plugin) { + if (SlimefunExtended.getMinecraftVersion().isAtLeast(MinecraftVersion.parse("1.20.3"))) + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler(ignoreCancelled = true) + public void onCrafter(InventoryClickEvent e) { + Inventory clickedInventory = e.getClickedInventory(); + Inventory topInventory = VersionedEvent.getTopInventory(e); + + if (clickedInventory != null + && topInventory.getType() == InventoryType.CRAFTER + && topInventory.getHolder() instanceof Crafter + && e.getWhoClicked() instanceof Player player) { + + if (e.getAction() == InventoryAction.HOTBAR_SWAP) { + e.setCancelled(true); + return; + } + + if (clickedInventory.getType() == InventoryType.CRAFTER) { + e.setCancelled(isCraftingUnallowed(SlimefunItem.getByItem(e.getCursor()))); + } else { + e.setCancelled(isCraftingUnallowed(SlimefunItem.getByItem(e.getCurrentItem()))); + } + + if (e.getResult() == Event.Result.DENY) { + Slimefun.getLocalization().sendMessage((Player) e.getWhoClicked(), "crafter.not-working", true); + } + } + } + + @EventHandler + public void hopperOnCrafter(InventoryMoveItemEvent e) { + if (e.getDestination().getType() == InventoryType.CRAFTER && isCraftingUnallowed(e.getItem())) { + e.setCancelled(true); + } + } +} 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 339a22c3c2..4a9f0aeeb3 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java @@ -1,5 +1,6 @@ package io.github.thebusybiscuit.slimefun4.utils; +import city.norain.slimefun4.SlimefunExtended; import io.github.bakedlibs.dough.common.CommonPatterns; import io.github.bakedlibs.dough.items.ItemMetaSnapshot; import io.github.bakedlibs.dough.skins.PlayerHead; @@ -501,8 +502,20 @@ private static boolean equalsItemMeta( } } - if (itemMeta instanceof PotionMeta && sfitemMeta instanceof PotionMeta) { - return ((PotionMeta) itemMeta).getBasePotionType().equals(((PotionMeta) sfitemMeta).getBasePotionType()); + if (itemMeta instanceof PotionMeta potionMeta && sfitemMeta instanceof PotionMeta sfPotionMeta) { + if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_20_5)) { + if (!potionMeta.hasBasePotionType() && !sfPotionMeta.hasBasePotionType()) { + return true; + } + + return potionMeta.hasBasePotionType() + && sfPotionMeta.hasBasePotionType() + && potionMeta.getBasePotionType().equals(sfPotionMeta.getBasePotionType()); + } else if (SlimefunExtended.getMinecraftVersion().isAtLeast(1, 20, 2)) { + return potionMeta.getBasePotionType().equals(sfPotionMeta.getBasePotionType()); + } else { + return potionMeta.getBasePotionData().equals(sfPotionMeta.getBasePotionData()); + } } Debug.log(TestCase.CARGO_INPUT_TESTING, " All meta checked."); diff --git a/src/main/resources/languages/en/messages.yml b/src/main/resources/languages/en/messages.yml index bf5909ba79..ae12c15a81 100644 --- a/src/main/resources/languages/en/messages.yml +++ b/src/main/resources/languages/en/messages.yml @@ -363,6 +363,9 @@ workbench: cauldron: no-discoloring: '&4You cannot discolor Slimefun Armor' +crafter: + not-working: '&4You cannot use a Slimefun item in crafter!' + gps: deathpoint: '&4Deathpoint &7%date%' status-online: 'ONLINE' diff --git a/src/main/resources/languages/zh-CN/messages.yml b/src/main/resources/languages/zh-CN/messages.yml index 3c0ffda805..caecb56fc7 100644 --- a/src/main/resources/languages/zh-CN/messages.yml +++ b/src/main/resources/languages/zh-CN/messages.yml @@ -350,6 +350,8 @@ workbench: not-enhanced: '&4你不能在普通的工作台上使用 Slimefun 物品' cauldron: no-discoloring: '&4你不能用炼药锅洗去 Slimefun 物品的颜色' +crafter: + not-working: '&4你不能在合成机上用 Slimefun 物品合成' gps: deathpoint: '&4死亡点 &7%date%' status-online: '在线'