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

Fix/cargo enchants #4190

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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 @@ -21,18 +21,20 @@
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import org.bukkit.inventory.meta.ItemMeta;

/**
* The {@link ItemFilter} is a performance-optimization for our {@link CargoNet}.
* It is a snapshot of a cargo node's configuration.
*
* @author TheBusyBiscuit
* @author Vaan1310
*
* @see CargoNet
* @see CargoNetworkTask
*
*/
class ItemFilter implements Predicate<ItemStack> {
public class ItemFilter implements Predicate<ItemStack> {

/**
* Our {@link List} of items to check against, might be empty.
Expand All @@ -54,6 +56,8 @@ class ItemFilter implements Predicate<ItemStack> {
*/
private boolean checkLore;

private boolean checkEnchants;

/**
* If an {@link ItemFilter} is marked as dirty / outdated, then it will be updated
* on the next tick.
Expand Down Expand Up @@ -112,6 +116,7 @@ public void update(@Nonnull Block b) {

this.items.clear();
this.checkLore = Objects.equals(blockData.getString("filter-lore"), "true");
this.checkEnchants = Objects.equals(blockData.getString("filter-enchant"), "true");
this.rejectOnMatch = !Objects.equals(blockData.getString("filter-type"), "whitelist");

for (int slot : slots) {
Expand Down Expand Up @@ -140,6 +145,7 @@ public void update(@Nonnull Block b) {
private void clear(boolean rejectOnMatch) {
this.items.clear();
this.checkLore = false;
this.checkEnchants = false;
this.rejectOnMatch = rejectOnMatch;
}

Expand Down Expand Up @@ -188,31 +194,43 @@ public boolean test(@Nonnull ItemStack item) {
if (potentialMatches == 0) {
// If there is no match, we can safely assume the default value
return rejectOnMatch;
} else {
/*
* If there is more than one potential match, create a wrapper to save
* performance on the ItemMeta otherwise just use the item directly.
*/
ItemStack subject = potentialMatches == 1 ? item : ItemStackWrapper.wrap(item);

/*
* If there is only one match, we won't need to create a Wrapper
* and thus only perform .getItemMeta() once
*/
for (ItemStackWrapper stack : items) {
if (SlimefunUtils.isItemSimilar(subject, stack, checkLore, false)) {
/*
* The filter has found a match, we can return the opposite
* of our default value. If we exclude items, this is where we
* would return false. Otherwise, we return true.
*/
return !rejectOnMatch;
}
}
/*
* If there is more than one potential match, create a wrapper to save
* performance on the ItemMeta otherwise just use the item directly.
*/
ItemStack subject = potentialMatches == 1 ? item : ItemStackWrapper.wrap(item);

/*
* If there is only one match, we won't need to create a Wrapper
* and thus only perform .getItemMeta() once
*/
for (ItemStackWrapper stack : items) {
boolean isSimilar = SlimefunUtils.isItemSimilar(subject,stack,checkLore);

if (!isSimilar) {
continue;
}

if (!checkEnchants) {
/*
* The filter has found a match, we can return the opposite
* of our default value. If we exclude items, this is where we
* would return false. Otherwise, we return true.
*/
return !rejectOnMatch;
}

boolean areSameEnchant = SlimefunUtils.areSameEnchants(subject, stack);

if (checkEnchants && areSameEnchant) {
return !rejectOnMatch;
}

// If no particular item was matched, we fallback to our default value.
return rejectOnMatch;
}
}

// If no particular item was matched, we fallback to our default value.
return rejectOnMatch;

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.FurnaceInventory;
import org.bukkit.inventory.ItemStack;

import io.github.bakedlibs.dough.items.CustomItemStack;
Expand Down Expand Up @@ -37,6 +38,7 @@ abstract class AbstractFilterNode extends AbstractCargoNode {
protected static final int[] SLOTS = { 19, 20, 21, 28, 29, 30, 37, 38, 39 };
private static final String FILTER_TYPE = "filter-type";
private static final String FILTER_LORE = "filter-lore";
private static final String FILTER_ENCHANT = "filter-enchant";

@ParametersAreNonnullByDefault
protected AbstractFilterNode(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, @Nullable ItemStack recipeOutput) {
Expand Down Expand Up @@ -74,6 +76,7 @@ protected void onPlace(BlockPlaceEvent e) {
BlockStorage.addBlockInfo(b, "index", "0");
BlockStorage.addBlockInfo(b, FILTER_TYPE, "whitelist");
BlockStorage.addBlockInfo(b, FILTER_LORE, String.valueOf(true));
BlockStorage.addBlockInfo(b, FILTER_ENCHANT, String.valueOf(false));
BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(false));
}

Expand Down Expand Up @@ -125,6 +128,24 @@ protected void updateBlockMenu(BlockMenu menu, Block b) {
});
}

String enchants = BlockStorage.getLocationInfo(b.getLocation(), FILTER_ENCHANT);

if (!BlockStorage.hasBlockInfo(b) || enchants == null || enchants.equals(String.valueOf(true))) {
menu.replaceExistingItem(34, new CustomItemStack(Material.MAP, "&7Include Enchants: &2\u2714", "", "&e> Click to toggle whether the Enchants have to match"));
menu.addMenuClickHandler(34, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, FILTER_ENCHANT, String.valueOf(false));
updateBlockMenu(menu, b);
return false;
});
} else {
menu.replaceExistingItem(34, new CustomItemStack(Material.MAP, "&7Include Enchants: &4\u2718", "", "&e> Click to toggle whether the Enchants have to match"));
menu.addMenuClickHandler(34, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, FILTER_ENCHANT, String.valueOf(true));
updateBlockMenu(menu, b);
return false;
});
}

addChannelSelector(b, menu, 41, 42, 43);
markDirty(loc);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/
public class AdvancedCargoOutputNode extends AbstractFilterNode {

private static final int[] BORDER = { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 22, 23, 24, 26, 27, 31, 32, 33, 34, 35, 36, 40, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 };
private static final int[] BORDER = { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 22, 23, 24, 26, 27, 31, 32, 33, 35, 36, 40, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 };

@ParametersAreNonnullByDefault
public AdvancedCargoOutputNode(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

public class CargoInputNode extends AbstractFilterNode {

private static final int[] BORDER = { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 22, 23, 26, 27, 31, 32, 33, 34, 35, 36, 40, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 };
private static final int[] BORDER = { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 22, 23, 26, 27, 31, 32, 33, 35, 36, 40, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 };

private static final String ROUND_ROBIN_MODE = "round-robin";
private static final String SMART_FILL_MODE = "smart-fill";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,24 @@
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.Map;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;

import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
Expand All @@ -26,6 +30,7 @@
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;

import io.github.bakedlibs.dough.common.CommonPatterns;
import io.github.bakedlibs.dough.items.ItemMetaSnapshot;
Expand Down Expand Up @@ -331,6 +336,7 @@ public static boolean isItemSimilar(@Nullable ItemStack item, @Nullable ItemStac
*
* @return True if the given {@link ItemStack}s are similar under the given constraints
*/
private static HashMap<Material, ItemMeta> defaultItemMetas = new HashMap<>();
public static boolean isItemSimilar(@Nullable ItemStack item, @Nullable ItemStack sfitem, boolean checkLore, boolean checkAmount, boolean checkDistinction) {
if (item == null) {
return sfitem == null;
Expand Down Expand Up @@ -380,7 +386,7 @@ public static boolean isItemSimilar(@Nullable ItemStack item, @Nullable ItemStac

ItemMetaSnapshot meta = ((SlimefunItemStack) sfitem).getItemMetaSnapshot();
return equalsItemMeta(itemMeta, meta, checkLore);
} else if (sfitem instanceof ItemStackWrapper && sfitem.hasItemMeta()) {
} else if (sfitem instanceof ItemStackWrapper) {
Debug.log(TestCase.CARGO_INPUT_TESTING, " is wrapper");
/*
* Cargo optimization (PR #3258)
Expand All @@ -389,9 +395,22 @@ public static boolean isItemSimilar(@Nullable ItemStack item, @Nullable ItemStac
* so let's try to do an ID comparison before meta comparison
*/
Debug.log(TestCase.CARGO_INPUT_TESTING, " sfitem is ItemStackWrapper - possible SF Item: {}", sfitem);
ItemMeta possibleSfItemMeta;
String id = null;
if (sfitem.hasItemMeta()) {
possibleSfItemMeta = sfitem.getItemMeta();
id = Slimefun.getItemDataService().getItemData(itemMeta).orElse(null);
} else {
Material type = sfitem.getType();
possibleSfItemMeta = defaultItemMetas.get(type);

if (possibleSfItemMeta == null) {
possibleSfItemMeta = Bukkit.getItemFactory().getItemMeta(sfitem.getType());
defaultItemMetas.put(type, possibleSfItemMeta);
}
}


ItemMeta possibleSfItemMeta = sfitem.getItemMeta();
String id = Slimefun.getItemDataService().getItemData(itemMeta).orElse(null);
String possibleItemId = Slimefun.getItemDataService().getItemData(possibleSfItemMeta).orElse(null);
// Prioritize SlimefunItem id comparison over ItemMeta comparison
if (id != null && id.equals(possibleItemId)) {
Expand Down Expand Up @@ -424,6 +443,44 @@ public static boolean isItemSimilar(@Nullable ItemStack item, @Nullable ItemStac
}
}

public static boolean areSameEnchants(ItemStack first, ItemStack second) {

if (!first.hasItemMeta() && !second.hasItemMeta()) {
return true;
}

if (!first.hasItemMeta() || !second.hasItemMeta() ) {
return false;
}

ItemMeta firstM = first.getItemMeta();
ItemMeta secondM = second.getItemMeta();

boolean frstEnchant = firstM instanceof EnchantmentStorageMeta;
boolean sndEnchant = secondM instanceof EnchantmentStorageMeta;

if (frstEnchant != sndEnchant) {
return false;
}

if (!frstEnchant) {
return true;
}

/*
if (!(firstM instanceof EnchantmentStorageMeta || secondM instanceof EnchantmentStorageMeta)) {
return true;
}*/

EnchantmentStorageMeta stEnch = (EnchantmentStorageMeta) firstM;
EnchantmentStorageMeta ndEnch = (EnchantmentStorageMeta) secondM;

Map<Enchantment, Integer> enchantsFirst = stEnch.getStoredEnchants();
Map<Enchantment, Integer> enchantsSecond = ndEnch.getStoredEnchants();

return enchantsFirst.equals(enchantsSecond);
}

private static @Nonnull Optional<DistinctiveItem> getDistinctiveItem(@Nonnull String id) {
SlimefunItem slimefunItem = SlimefunItem.getById(id);
if (slimefunItem instanceof DistinctiveItem distinctive) {
Expand Down Expand Up @@ -459,6 +516,7 @@ private static boolean equalsItemMeta(@Nonnull ItemMeta itemMeta, @Nonnull ItemM
}

private static boolean equalsItemMeta(@Nonnull ItemMeta itemMeta, @Nonnull ItemMeta sfitemMeta, boolean checkLore) {

if (itemMeta.hasDisplayName() != sfitemMeta.hasDisplayName()) {
return false;
} else if (itemMeta.hasDisplayName() && sfitemMeta.hasDisplayName() && !itemMeta.getDisplayName().equals(sfitemMeta.getDisplayName())) {
Expand Down