From 5cf02687c9d9804d950817178393ba31d3c982ad Mon Sep 17 00:00:00 2001 From: m1919810 Date: Sun, 29 Dec 2024 19:48:19 +0800 Subject: [PATCH] commit fix --- .../controller/BlockDataController.java | 20 ++++++-- .../slimefun4/storage/util/LocationUtils.java | 3 ++ .../api/items/SlimefunItemStack.java | 28 +++++----- .../items/blocks/AbstractMonsterSpawner.java | 51 ++++++++++++++----- .../items/tools/PickaxeOfContainment.java | 22 +++++--- .../items/tools/SmeltersPickaxe.java | 3 +- .../listeners/BackpackListener.java | 8 ++- .../listeners/SoulboundListener.java | 14 ++--- .../listeners/crafting/AnvilListener.java | 12 +++++ .../slimefun4/utils/SlimefunUtils.java | 42 ++++++++------- 10 files changed, 136 insertions(+), 67 deletions(-) diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataController.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataController.java index 8a8be2c2ca..80060c0c4c 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataController.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataController.java @@ -220,8 +220,9 @@ public SlimefunBlockData getBlockData(Location l) { return getBlockDataFromCache(l); } - var chunk = l.getChunk(); - var chunkData = getChunkDataCache(chunk, false); + //var chunk = l.getChunk(); + //fix issue #935 + var chunkData = getChunkDataCache(l, false); var lKey = LocationUtils.getLocKey(l); if (chunkData != null) { var re = chunkData.getBlockCacheInternal(lKey); @@ -238,7 +239,8 @@ public SlimefunBlockData getBlockData(Location l) { var re = result.isEmpty() ? null : new SlimefunBlockData(l, result.get(0).get(FieldKey.SLIMEFUN_ID)); if (re != null) { - chunkData = getChunkDataCache(chunk, true); + //fix issue #935 + chunkData = getChunkDataCache(l, true); chunkData.addBlockCacheInternal(re, false); re = chunkData.getBlockCacheInternal(lKey); } @@ -262,7 +264,7 @@ public void getBlockDataAsync(Location l, IAsyncReadCallback * @return {@link SlimefunBlockData} */ public SlimefunBlockData getBlockDataFromCache(Location l) { - return getBlockDataFromCache(LocationUtils.getChunkKey(l.getChunk()), LocationUtils.getLocKey(l)); + return getBlockDataFromCache(LocationUtils.getChunkKey(l), LocationUtils.getLocKey(l)); } /** @@ -745,6 +747,16 @@ private SlimefunChunkData getChunkDataCache(Chunk chunk, boolean createOnNotExis }) : loadedChunk.get(LocationUtils.getChunkKey(chunk)); } + //fix issue 935: auto chunk load when using loc.getChunk(),if chunk data is already loaded into cache, we generate keyString using location,instead of loc.getChunk + private SlimefunChunkData getChunkDataCache(Location loc, boolean createOnNotExists) { + var re= loadedChunk.get(LocationUtils.getChunkKey(loc)); + if(re!=null){ + return re; + }else{ + //这里不要检测createOnNotExist 容易出事 + return getChunkDataCache(loc.getChunk(),createOnNotExists); + } + } private void deleteChunkAndBlockDataDirectly(String cKey) { var req = new RecordKey(DataScope.BLOCK_RECORD); 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 1c01ea947d..c24e606975 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 @@ -14,6 +14,9 @@ public static String getLocKey(Location l) { public static String getChunkKey(Chunk chunk) { return chunk.getWorld().getName() + ";" + chunk.getX() + ":" + chunk.getZ(); } + public static String getChunkKey(Location loc) { + return loc.getWorld().getName() + ";" + (loc.getBlockX()>>4) + ":" + (loc.getBlockZ()>>4); + } public static Location toLocation(String lKey) { var strArr = lKey.split(";"); 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 e6df6506c9..fb4d46f889 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 @@ -46,13 +46,9 @@ public class SlimefunItemStack extends ItemStack { private boolean locked = false; private String texture = null; - public SlimefunItemStack(@Nonnull String id, @Nonnull ItemStack item) { + public SlimefunItemStack(@Nonnull String id, @Nonnull ItemStack item, @Nonnull Consumer consumer) { super(item.getType(), item.getAmount()); - if (item.hasItemMeta()) { - setItemMeta(item.getItemMeta()); - } - Validate.notNull(id, "The Item id must never be null!"); Validate.isTrue( id.equals(id.toUpperCase(Locale.ROOT)), "Slimefun Item Ids must be uppercase! (e.g. 'MY_ITEM_ID')"); @@ -64,20 +60,17 @@ public SlimefunItemStack(@Nonnull String id, @Nonnull ItemStack item) { this.id = id; - ItemMeta meta = getItemMeta(); + ItemMeta meta = item.hasItemMeta()?item.getItemMeta(): getItemMeta(); Slimefun.getItemDataService().setItemData(meta, id); Slimefun.getItemTextureService().setTexture(meta, id); + consumer.accept(meta); setItemMeta(meta); } - - public SlimefunItemStack(@Nonnull String id, @Nonnull ItemStack item, @Nonnull Consumer consumer) { - this(id, item); - - ItemMeta im = getItemMeta(); - consumer.accept(im); - setItemMeta(im); + private static final Consumer DEFAULT_CONSUMER=(itemMeta -> {}); + public SlimefunItemStack(@Nonnull String id, @Nonnull ItemStack item) { + this(id, item,DEFAULT_CONSUMER); } public SlimefunItemStack(@Nonnull String id, @Nonnull Material type, @Nonnull Consumer consumer) { @@ -316,10 +309,15 @@ public void lock() { "The provided texture for Item \"" + id + "\" does not seem to be a valid texture String!"); } } - + //fix issue 988 : addon menu can't open propertly due to cast error in 1.21+paper @Override public ItemStack clone() { - return new SlimefunItemStack(id, this); + //return new SlimefunItemStack(id, this); + ItemStack stack=super.clone(); + if(stack instanceof SlimefunItemStack sfitem){ + sfitem.locked=false; + } + return stack; } @Override diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/AbstractMonsterSpawner.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/AbstractMonsterSpawner.java index f0157ccfe6..108c115da1 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/AbstractMonsterSpawner.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/AbstractMonsterSpawner.java @@ -4,14 +4,17 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.core.attributes.DistinctiveItem; import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; import java.util.List; import java.util.Locale; import java.util.Optional; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; import org.apache.commons.lang.Validate; import org.bukkit.ChatColor; +import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.CreatureSpawner; import org.bukkit.entity.EntityType; @@ -29,7 +32,7 @@ * @see RepairedSpawner * */ -public abstract class AbstractMonsterSpawner extends SlimefunItem { +public abstract class AbstractMonsterSpawner extends SlimefunItem implements DistinctiveItem { @ParametersAreNonnullByDefault AbstractMonsterSpawner(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { @@ -65,6 +68,13 @@ public Optional getEntityType(@Nonnull ItemStack item) { return Optional.of(type); } } + if(meta instanceof BlockStateMeta blockStateMeta){ + if(blockStateMeta.hasBlockState()&& blockStateMeta.getBlockState() instanceof CreatureSpawner spawner){ + EntityType type=spawner.getSpawnedType(); + if(type!=null) + return Optional.of(type); + } + } return Optional.empty(); } @@ -80,30 +90,32 @@ public Optional getEntityType(@Nonnull ItemStack item) { * @return An {@link ItemStack} for this {@link SlimefunItem} holding that {@link EntityType} */ @Nonnull - public ItemStack getItemForEntityType(@Nonnull EntityType type) { - Validate.notNull(type, "The EntityType cannot be null"); + public ItemStack getItemForEntityType(@Nullable EntityType type) { + //Validate.notNull(type, "The EntityType cannot be null"); ItemStack item = getItem().clone(); ItemMeta meta = item.getItemMeta(); + //fix: you can't set null type or a not-spawnable type, for example ,player + if(type!=null&&type.isSpawnable()) { - // Fixes #2583 - Proper NBT handling of Spawners - if (meta instanceof BlockStateMeta stateMeta) { - BlockState state = stateMeta.getBlockState(); + // Fixes #2583 - Proper NBT handling of Spawners + if (meta instanceof BlockStateMeta stateMeta) { + BlockState state = stateMeta.getBlockState(); - if (state instanceof CreatureSpawner spawner) { - spawner.setSpawnedType(type); - } + if (state instanceof CreatureSpawner spawner) { + spawner.setSpawnedType(type); + } - stateMeta.setBlockState(state); + stateMeta.setBlockState(state); + } } - // Setting the lore to indicate the Type visually List lore = meta.getLore(); for (int i = 0; i < lore.size(); i++) { String currentLine = lore.get(i); if (currentLine.contains("") || currentLine.contains("<类型>")) { - String typeName = ChatUtils.humanize(type.name()); + String typeName = type==null?"空" :ChatUtils.humanize(type.name()); lore.set(i, currentLine.replace("", typeName).replace("<类型>", typeName)); break; } @@ -111,7 +123,20 @@ public ItemStack getItemForEntityType(@Nonnull EntityType type) { meta.setLore(lore); item.setItemMeta(meta); - return item; } + //to fix the bug of stacking two BROKEN_SPAWNER/REINFORCED_SPAWNER containing different EntityType using cargo or machine + public boolean canStack(@Nonnull ItemMeta itemMetaOne, @Nonnull ItemMeta itemMetaTwo){ + if(itemMetaOne instanceof BlockStateMeta blockStateMeta1&& itemMetaTwo instanceof BlockStateMeta blockStateMeta2){ + if(blockStateMeta1.hasBlockState()&&blockStateMeta2.hasBlockState()){ + //BlockState.equals do not compare these data + if(blockStateMeta1.getBlockState() instanceof CreatureSpawner spawner1&& blockStateMeta2.getBlockState() instanceof CreatureSpawner spawner2){ + return spawner1.getSpawnedType()==spawner2.getSpawnedType(); + } + }else{ + return blockStateMeta1.hasBlockState()==blockStateMeta2.hasBlockState(); + } + } + return false; + } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PickaxeOfContainment.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PickaxeOfContainment.java index 2531282c64..65e79b1e30 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PickaxeOfContainment.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PickaxeOfContainment.java @@ -3,6 +3,7 @@ import com.xzavier0722.mc.plugin.slimefun4.storage.util.StorageCacheUtils; import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.ItemSpawnReason; +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler; @@ -14,6 +15,7 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.papermc.lib.PaperLib; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; import org.bukkit.Material; import org.bukkit.block.Block; @@ -48,26 +50,32 @@ public PickaxeOfContainment( if (b.getType() == Material.SPAWNER) { ItemStack spawner = breakSpawner(b); - SlimefunUtils.spawnItem( - b.getLocation(), spawner, ItemSpawnReason.BROKEN_SPAWNER_DROP, true, e.getPlayer()); + if(spawner!=null){ + SlimefunUtils.spawnItem( + b.getLocation(), spawner, ItemSpawnReason.BROKEN_SPAWNER_DROP, true, e.getPlayer()); - e.setExpToDrop(0); - e.setDropItems(false); + e.setExpToDrop(0); + e.setDropItems(false); + } } }; } - private @Nonnull ItemStack breakSpawner(@Nonnull Block b) { + private @Nullable ItemStack breakSpawner(@Nonnull Block b) { AbstractMonsterSpawner spawner; /* If the spawner's BlockStorage has BlockInfo, then it's not a vanilla spawner and should not give a broken spawner but a repaired one instead. */ - if (StorageCacheUtils.hasBlock(b.getLocation())) { + SlimefunItem item=StorageCacheUtils.getSfItem(b.getLocation()); + if (item instanceof RepairedSpawner) { spawner = (AbstractMonsterSpawner) SlimefunItems.REPAIRED_SPAWNER.getItem(); - } else { + } else if (item ==null) { spawner = (AbstractMonsterSpawner) SlimefunItems.BROKEN_SPAWNER.getItem(); + }else{ + //do not drop anything when mining other addon's spawner-material machine + return null; } BlockState state = PaperLib.getBlockState(b, false).getState(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/SmeltersPickaxe.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/SmeltersPickaxe.java index 64bcfac346..34add06b0c 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/SmeltersPickaxe.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/SmeltersPickaxe.java @@ -45,7 +45,8 @@ public SmeltersPickaxe(ItemGroup itemGroup, SlimefunItemStack item, RecipeType r drops.add(drop); } } - + //fix issue #967 + e.setDropItems(false); damageItem(e.getPlayer(), tool); } }; 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 77bbd088ee..917c1d412e 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 @@ -10,9 +10,12 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler; import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.SlimefunBackpack; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; @@ -183,18 +186,19 @@ private void openBackpack(Player p, ItemStack item, PlayerProfile profile, int s // Check if someone else is currently viewing this backpack if (!backpacks.containsValue(item)) { SoundEffect.BACKPACK_OPEN_SOUND.playAt(p.getLocation(), SoundCategory.PLAYERS); - PlayerBackpack.getAsync( item, backpack -> { + //fix the issue #978 dupe with fast-click backpack + backpack.open(p); backpacks.put(p.getUniqueId(), item); invSnapshot.put( backpack.getUniqueId(), InvStorageUtils.getInvSnapshot( backpack.getInventory().getContents())); - backpack.open(p); }, true); + } else { Slimefun.getLocalization().sendMessage(p, "backpack.already-open", true); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SoulboundListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SoulboundListener.java index f144956e95..54b9d71f48 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SoulboundListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SoulboundListener.java @@ -45,13 +45,15 @@ public void onDamage(PlayerDeathEvent e) { } // There shouldn't even be any items in there, but let's be extra safe! - Map existingItems = soulbound.get(p.getUniqueId()); +// Map existingItems = soulbound.get(p.getUniqueId()); + //fix issue #964 dupe using soulbound +// +// if (existingItems == null) { +// } else { +// existingItems.putAll(items); +// } + soulbound.put(p.getUniqueId(), items); - if (existingItems == null) { - soulbound.put(p.getUniqueId(), items); - } else { - existingItems.putAll(items); - } // Remove soulbound items from our drops e.getDrops().removeIf(itemStack -> SlimefunUtils.isSoulbound(itemStack, p.getWorld())); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/crafting/AnvilListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/crafting/AnvilListener.java index 8d5247cac0..b498b96a0b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/crafting/AnvilListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/crafting/AnvilListener.java @@ -9,6 +9,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.inventory.PrepareAnvilEvent; import org.bukkit.inventory.ItemStack; /** @@ -38,4 +39,15 @@ public void onAnvil(InventoryClickEvent e) { } } } + @EventHandler(ignoreCancelled = true) + public void onAnvilCraft(PrepareAnvilEvent e){ + //fix issue #958 + if(e.getInventory().getType() == InventoryType.ANVIL&&e.getInventory().getSize()>=2){ + ItemStack item1 = e.getInventory().getContents()[0]; + ItemStack item2 = e.getInventory().getContents()[1]; + if (hasUnallowedItems(item1, item2)) { + e.setResult(null); + } + } + } } 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 4a9f0aeeb3..e79211dfaa 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java @@ -328,20 +328,24 @@ public static boolean isItemSimilar( String id = Slimefun.getItemDataService().getItemData(itemMeta).orElse(null); if (id != null) { - if (checkDistinctiveItem) { - /* - * PR #3417 - * - * Some items can't rely on just IDs matching and will implement Distinctive Item - * in which case we want to use the method provided to compare - */ - Optional optionalDistinctive = getDistinctiveItem(id); - if (optionalDistinctive.isPresent()) { - ItemMeta sfItemMeta = sfitem.getItemMeta(); - return optionalDistinctive.get().canStack(sfItemMeta, itemMeta); + //to fix issue #976 + if(id.equals(sfItemStack.getItemId())) { + if (checkDistinctiveItem) { + /* + * PR #3417 + * + * Some items can't rely on just IDs matching and will implement Distinctive Item + * in which case we want to use the method provided to compare + */ + Optional optionalDistinctive = getDistinctiveItem(id); + if (optionalDistinctive.isPresent()) { + ItemMeta sfItemMeta = sfitem.getItemMeta(); + return optionalDistinctive.get().canStack(sfItemMeta, itemMeta); + } } + return true; } - return id.equals(sfItemStack.getItemId()); + return false; } ItemMetaSnapshot meta = ((SlimefunItemStack) sfitem).getItemMetaSnapshot(); @@ -369,15 +373,15 @@ public static boolean isItemSimilar( * Some items can't rely on just IDs matching and will implement Distinctive Item * in which case we want to use the method provided to compare */ - Optional optionalDistinctive = getDistinctiveItem(id); - if (optionalDistinctive.isPresent()) { - return optionalDistinctive.get().canStack(possibleSfItemMeta, itemMeta); - } - + //to fix issue #976 var match = id.equals(possibleItemId); - + if(match) { + Optional optionalDistinctive = getDistinctiveItem(id); + if (optionalDistinctive.isPresent()) { + return optionalDistinctive.get().canStack(possibleSfItemMeta, itemMeta); + } + } Debug.log(TestCase.CARGO_INPUT_TESTING, " Use Item ID match: {}", match); - return match; } else { Debug.log(