/* * This file is part of NucleusFramework for Bukkit, licensed under the MIT License (MIT). * * Copyright (c) JCThePants (www.jcwhatever.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.jcwhatever.nucleus.views.anvil; import com.jcwhatever.nucleus.Nucleus; import com.jcwhatever.nucleus.events.anvil.AnvilEnchantItemEvent; import com.jcwhatever.nucleus.events.anvil.AnvilRenameItemEvent; import com.jcwhatever.nucleus.events.anvil.AnvilRepairItemEvent; import com.jcwhatever.nucleus.internal.NucLang; import com.jcwhatever.nucleus.managed.language.Localizable; import com.jcwhatever.nucleus.managed.scheduler.Scheduler; import com.jcwhatever.nucleus.utils.items.ItemFilter; import com.jcwhatever.nucleus.utils.items.ItemStackUtils; import com.jcwhatever.nucleus.views.View; import com.jcwhatever.nucleus.views.ViewCloseReason; import com.jcwhatever.nucleus.views.ViewOpenReason; import com.jcwhatever.nucleus.views.ViewSession; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Entity; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; import javax.annotation.Nullable; import java.util.Map; import java.util.WeakHashMap; /** * Represents an anvil that can allow or disallow items. */ public class FilteredAnvilView extends AnvilView { @Localizable static final String _NOT_REPAIRABLE = "{RED}Not repairable here."; private static AnvilEventListener _eventListener; private static Map<Entity, ViewSession> _anvilMap = new WeakHashMap<>(20); private final ItemFilter _filterManager; /** * Constructor. * * @param plugin The owning plugin. * @param itemFilter The item filter manager. */ public FilteredAnvilView(Plugin plugin, @Nullable ItemFilter itemFilter) { super(plugin); _filterManager = itemFilter; if (_eventListener != null) return; _eventListener = new AnvilEventListener(); Bukkit.getPluginManager().registerEvents(_eventListener, Nucleus.getPlugin()); } @Nullable public ItemFilter getItemFilter() { return _filterManager; } @Override protected boolean openView(ViewOpenReason reason) { if (super.openView(reason)) { _anvilMap.put(getPlayer(), getViewSession()); return true; } return false; } @Override protected void onClose(ViewCloseReason reason) { super.onClose(reason); _anvilMap.remove(getPlayer()); } /** * Invoked to get the craft deny message. */ protected String getDenyMessage() { return NucLang.get(getPlugin(), _NOT_REPAIRABLE).toString(); } /** * Anvil event listener. */ static class AnvilEventListener implements Listener { @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) private void onAnvilRepair(AnvilRepairItemEvent event) { if (!isValid(event.getPlayer(), event.getItem())) { event.setCancelled(true); } } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) private void onAnvilEnchant(AnvilEnchantItemEvent event) { if (!isValid(event.getPlayer(), event.getItem())) { event.setCancelled(true); } } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) private void onAnvilItemRename(AnvilRenameItemEvent event) { if (!isValid(event.getPlayer(), event.getItem())) { event.setCancelled(true); } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) private void onAnvilClick(InventoryClickEvent event) { if (event.getView().getType() != InventoryType.ANVIL) return; final FilteredAnvilView view = getAnvil(event.getWhoClicked()); if (view == null) return; ItemFilter filter = view.getItemFilter(); if (filter == null) return; if (!event.getView().getTopInventory().equals(event.getClickedInventory())) return; ItemStack input = event.getView().getTopInventory().getItem(0); if (input == null || input.getType() == Material.AIR) return; if (!filter.isValid(input)) { final InventoryView invView = event.getView(); if (invView != null) { Scheduler.runTaskLater(Nucleus.getPlugin(), 2, new Runnable() { @Override public void run() { ItemStack output = invView.getTopInventory().getItem(2); if (output == null || output.getType() == Material.AIR) return; ItemStackUtils.setLore(output, view.getDenyMessage()); invView.setItem(2, output.clone()); } }); } } } @Nullable private FilteredAnvilView getAnvil(HumanEntity entity) { if (!(entity instanceof Player)) return null; Player player = (Player)entity; ViewSession session = _anvilMap.get(player); if (session == null) return null; View current = session.getCurrent(); if (current == null) return null; if (!(current instanceof FilteredAnvilView)) return null; return (FilteredAnvilView)current; } private boolean isValid(Player p, ItemStack repaired) { FilteredAnvilView view = getAnvil(p); if (view == null) return true; ItemFilter filter = view.getItemFilter(); return filter == null || filter.isValid(repaired); } } }