Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于若干issue的修复 #991

Merged
merged 2 commits into from
Dec 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -425,8 +425,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);
Expand All @@ -443,7 +444,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);
}
Expand All @@ -467,7 +469,7 @@ public void getBlockDataAsync(Location l, IAsyncReadCallback<SlimefunBlockData>
* @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));
}

/**
Expand Down Expand Up @@ -1270,6 +1272,17 @@ 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 {
// jump to origin getChunkDataCache and call getChunk() to trigger chunkLoad
return getChunkDataCache(loc.getChunk(), createOnNotExists);
}
}

private void deleteChunkAndBlockDataDirectly(String cKey) {
var req = new RecordKey(DataScope.BLOCK_RECORD);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ 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) {
if (lKey == null || lKey.isEmpty()) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
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;
Expand All @@ -29,7 +31,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) {
Expand Down Expand Up @@ -65,6 +67,12 @@ public Optional<EntityType> 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();
}
Expand All @@ -80,38 +88,56 @@ public Optional<EntityType> 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<String> lore = meta.getLore();

for (int i = 0; i < lore.size(); i++) {
String currentLine = lore.get(i);
if (currentLine.contains("<Type>") || currentLine.contains("<类型>")) {
String typeName = ChatUtils.humanize(type.name());
String typeName = type == null ? "空" : ChatUtils.humanize(type.name());
lore.set(i, currentLine.replace("<Type>", typeName).replace("<类型>", typeName));
break;
}
}

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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -15,6 +16,7 @@
import io.papermc.lib.PaperLib;
import java.util.Optional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
import org.bukkit.block.Block;
Expand Down Expand Up @@ -49,26 +51,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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
Expand Down Expand Up @@ -38,14 +40,19 @@ public SmeltersPickaxe(ItemGroup itemGroup, SlimefunItemStack item, RecipeType r
if (SlimefunTag.SMELTERS_PICKAXE_BLOCKS.isTagged(b.getType())
&& !StorageCacheUtils.hasBlock(b.getLocation())) {
Collection<ItemStack> blockDrops = b.getDrops(tool);

List<ItemStack> itemDrops = new ArrayList<>();
for (ItemStack drop : blockDrops) {
if (drop != null && !drop.getType().isAir()) {
smelt(b, drop, fortune);
drops.add(drop);
itemDrops.add(drop);
}
}

// stop blockListener from dropping origin drops
e.setDropItems(false);
// drop smelted manually
for (ItemStack itemDrop : itemDrops) {
b.getWorld().dropItemNaturally(b.getLocation(), itemDrop);
}
damageItem(e.getPlayer(), tool);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,18 +202,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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,14 @@ public void onDamage(PlayerDeathEvent e) {
}

// There shouldn't even be any items in there, but let's be extra safe!
Map<Integer, ItemStack> existingItems = soulbound.get(p.getUniqueId());

if (existingItems == null) {
soulbound.put(p.getUniqueId(), items);
} else {
existingItems.putAll(items);
}
// Map<Integer, ItemStack> existingItems = soulbound.get(p.getUniqueId());
// fix issue #964 dupe using soulbound
//
// if (existingItems == null) {
// } else {
// existingItems.putAll(items);
// }
soulbound.put(p.getUniqueId(), items);

// Remove soulbound items from our drops
e.getDrops().removeIf(itemStack -> SlimefunUtils.isSoulbound(itemStack, p.getWorld()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -38,4 +39,17 @@ 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);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -328,18 +328,22 @@ 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<DistinctiveItem> 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<DistinctiveItem> optionalDistinctive = getDistinctiveItem(id);
if (optionalDistinctive.isPresent()) {
ItemMeta sfItemMeta = sfitem.getItemMeta();
return optionalDistinctive.get().canStack(sfItemMeta, itemMeta);
}
}
return true;
}
return id.equals(sfItemStack.getItemId());
}
Expand Down Expand Up @@ -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<DistinctiveItem> optionalDistinctive = getDistinctiveItem(id);
if (optionalDistinctive.isPresent()) {
return optionalDistinctive.get().canStack(possibleSfItemMeta, itemMeta);
}

// to fix issue #976
var match = id.equals(possibleItemId);

if (match) {
Optional<DistinctiveItem> 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(
Expand Down
Loading