API refactoring

This commit is contained in:
filoghost 2020-07-04 17:19:57 +02:00
parent f0aa5347ee
commit 41fcd9540d
73 changed files with 1765 additions and 1670 deletions

View File

@ -20,8 +20,8 @@ import org.bukkit.entity.Player;
public interface ClickHandler { public interface ClickHandler {
/** /**
* @param player the player that clicked on the icon * @param player the player that clicked on the inventory
* @return true if the menu should be closed right after, false otherwise * @return true if the inventory should be closed, false otherwise
*/ */
ClickResult onClick(Player player); ClickResult onClick(Player player);

View File

@ -16,7 +16,6 @@ package me.filoghost.chestcommands.api;
public enum ClickResult { public enum ClickResult {
DEFAULT,
KEEP_OPEN, KEEP_OPEN,
CLOSE CLOSE

View File

@ -0,0 +1,20 @@
package me.filoghost.chestcommands.api;
import org.bukkit.entity.Player;
public interface ClickableIcon extends Icon {
void setClickHandler(ClickHandler clickHandler);
ClickHandler getClickHandler();
@Override
default ClickResult onClick(ItemInventory itemInventory, Player clicker) {
if (getClickHandler() != null) {
return getClickHandler().onClick(clicker);
} else {
return ClickResult.KEEP_OPEN;
}
}
}

View File

@ -14,20 +14,19 @@
*/ */
package me.filoghost.chestcommands.api; package me.filoghost.chestcommands.api;
import java.util.List; import me.filoghost.chestcommands.api.internal.BackendAPI;
import java.util.Map;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.DyeColor; import org.bukkit.DyeColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.banner.Pattern; import org.bukkit.block.banner.Pattern;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import me.filoghost.chestcommands.api.internal.BackendAPI; import java.util.List;
import java.util.Map;
public interface ConfigurableIcon extends Icon { public interface ConfigurableIcon extends ClickableIcon {
public static ConfigurableIcon create(Material material) { static ConfigurableIcon create(Material material) {
return BackendAPI.getImplementation().createConfigurableIcon(material); return BackendAPI.getImplementation().createConfigurableIcon(material);
} }
@ -65,11 +64,11 @@ public interface ConfigurableIcon extends Icon {
Map<Enchantment, Integer> getEnchantments(); Map<Enchantment, Integer> getEnchantments();
void addEnchantment(Enchantment ench); void addEnchantment(Enchantment enchantment);
void addEnchantment(Enchantment ench, Integer level); void addEnchantment(Enchantment enchantment, Integer level);
void removeEnchantment(Enchantment ench); void removeEnchantment(Enchantment enchantment);
Color getLeatherColor(); Color getLeatherColor();
@ -87,10 +86,6 @@ public interface ConfigurableIcon extends Icon {
void setBannerPatterns(List<Pattern> bannerPatterns); void setBannerPatterns(List<Pattern> bannerPatterns);
void setCloseOnClick(boolean closeOnClick); void setPlaceholdersEnabled(boolean enabled);
void setClickHandler(ClickHandler clickHandler);
ClickHandler getClickHandler();
} }

View File

@ -15,13 +15,12 @@
package me.filoghost.chestcommands.api; package me.filoghost.chestcommands.api;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
public interface Icon { public interface Icon {
ItemStack createItemStack(Player viewer); ItemStack render(Player viewer);
boolean onClick(Inventory inventory, Player clicker); ClickResult onClick(ItemInventory itemInventory, Player clicker);
} }

View File

@ -14,19 +14,19 @@
*/ */
package me.filoghost.chestcommands.api; package me.filoghost.chestcommands.api;
import org.bukkit.entity.Player;
import me.filoghost.chestcommands.api.internal.BackendAPI; import me.filoghost.chestcommands.api.internal.BackendAPI;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
public interface IconMenu { public interface IconMenu {
public static IconMenu create(String title, int rowCount) { static IconMenu create(Plugin owner, String title, int rowCount) {
return BackendAPI.getImplementation().createIconMenu(title, rowCount); return BackendAPI.getImplementation().createIconMenu(owner, title, rowCount);
} }
void setIcon(int x, int y, Icon icon); void setIcon(int row, int column, Icon icon);
Icon getIcon(int x, int y); Icon getIcon(int row, int column);
String getTitle(); String getTitle();
@ -34,6 +34,12 @@ public interface IconMenu {
int getColumnCount(); int getColumnCount();
void open(Player player); /**
* Opens a view of the current menu configuration.
* Updating the menu doesn't automatically update all the views.
*
* @param player the player to which the menu will be displayed
*/
ItemInventory open(Player player);
} }

View File

@ -0,0 +1,7 @@
package me.filoghost.chestcommands.api;
public interface ItemInventory {
void refresh();
}

View File

@ -14,14 +14,17 @@
*/ */
package me.filoghost.chestcommands.api; package me.filoghost.chestcommands.api;
import me.filoghost.chestcommands.api.internal.BackendAPI;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import me.filoghost.chestcommands.api.internal.BackendAPI; public interface StaticIcon extends ClickableIcon {
public interface StaticIcon extends Icon { static StaticIcon create(ItemStack itemStack) {
return BackendAPI.getImplementation().createStaticIcon(itemStack);
public static StaticIcon create(ItemStack itemStack, boolean closeOnClick) {
return BackendAPI.getImplementation().createStaticIcon(itemStack, closeOnClick);
} }
ItemStack getItemStack();
void setItemStack(ItemStack itemStack);
} }

View File

@ -14,13 +14,13 @@
*/ */
package me.filoghost.chestcommands.api.internal; package me.filoghost.chestcommands.api.internal;
import me.filoghost.chestcommands.api.ConfigurableIcon;
import me.filoghost.chestcommands.api.IconMenu;
import me.filoghost.chestcommands.api.StaticIcon;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import me.filoghost.chestcommands.api.IconMenu;
import me.filoghost.chestcommands.api.StaticIcon;
import me.filoghost.chestcommands.api.ConfigurableIcon;
public abstract class BackendAPI { public abstract class BackendAPI {
@ -42,12 +42,10 @@ public abstract class BackendAPI {
public abstract boolean openPluginMenu(Player player, String yamlFile); public abstract boolean openPluginMenu(Player player, String yamlFile);
public abstract IconMenu createIconMenu(String title, int rows); public abstract IconMenu createIconMenu(Plugin owner, String title, int rows);
public abstract ConfigurableIcon createConfigurableIcon(Material material); public abstract ConfigurableIcon createConfigurableIcon(Material material);
public abstract StaticIcon createStaticIcon(ItemStack itemStack, boolean closeOnClick); public abstract StaticIcon createStaticIcon(ItemStack itemStack);
} }

View File

@ -14,6 +14,8 @@
*/ */
package me.filoghost.chestcommands; package me.filoghost.chestcommands;
import me.filoghost.chestcommands.api.impl.DefaultBackendAPI;
import me.filoghost.chestcommands.api.internal.BackendAPI;
import me.filoghost.chestcommands.command.CommandHandler; import me.filoghost.chestcommands.command.CommandHandler;
import me.filoghost.chestcommands.command.framework.CommandFramework; import me.filoghost.chestcommands.command.framework.CommandFramework;
import me.filoghost.chestcommands.config.ConfigLoader; import me.filoghost.chestcommands.config.ConfigLoader;
@ -77,6 +79,7 @@ public class ChestCommands extends JavaPlugin {
instance = this; instance = this;
Log.setLogger(getLogger()); Log.setLogger(getLogger());
BackendAPI.setImplementation(new DefaultBackendAPI());
configManager = new ConfigManager(getDataFolder().toPath()); configManager = new ConfigManager(getDataFolder().toPath());
menuManager = new MenuManager(); menuManager = new MenuManager();
@ -185,7 +188,7 @@ public class ChestCommands extends JavaPlugin {
public static void closeAllMenus() { public static void closeAllMenus() {
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
if (MenuManager.getOpenMenu(player) != null) { if (MenuManager.getOpenMenuInventory(player) != null) {
player.closeInventory(); player.closeInventory();
} }
} }

View File

@ -24,14 +24,14 @@ public abstract class Action {
this.errorMessage = errorMessage; this.errorMessage = errorMessage;
} }
public void execute(Player player) { public final void execute(Player player) {
if (errorMessage != null) { if (errorMessage != null) {
player.sendMessage(errorMessage); player.sendMessage(errorMessage);
} else { } else {
executeInner(player); execute0(player);
} }
} }
protected abstract void executeInner(Player player); protected abstract void execute0(Player player);
} }

View File

@ -29,7 +29,7 @@ public class BroadcastAction extends Action {
} }
@Override @Override
protected void executeInner(Player player) { protected void execute0(Player player) {
Bukkit.broadcastMessage(message.getValue(player)); Bukkit.broadcastMessage(message.getValue(player));
} }

View File

@ -28,7 +28,7 @@ public class ChangeServerAction extends Action {
} }
@Override @Override
protected void executeInner(Player player) { protected void execute0(Player player) {
BungeeCordHook.connect(player, targetServer.getValue(player)); BungeeCordHook.connect(player, targetServer.getValue(player));
} }

View File

@ -28,7 +28,7 @@ public class ConsoleCommandAction extends Action {
} }
@Override @Override
protected void executeInner(Player player) { protected void execute0(Player player) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command.getValue(player)); Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command.getValue(player));
} }

View File

@ -48,7 +48,7 @@ public class DragonBarAction extends Action {
} }
@Override @Override
protected void executeInner(Player player) { protected void execute0(Player player) {
if (BarAPIHook.INSTANCE.isEnabled()) { if (BarAPIHook.INSTANCE.isEnabled()) {
BarAPIHook.setMessage(player, message.getValue(player), seconds); BarAPIHook.setMessage(player, message.getValue(player), seconds);
} }

View File

@ -35,7 +35,7 @@ public class GiveItemAction extends Action {
} }
@Override @Override
protected void executeInner(Player player) { protected void execute0(Player player) {
player.getInventory().addItem(itemToGive.clone()); player.getInventory().addItem(itemToGive.clone());
} }

View File

@ -34,7 +34,7 @@ public class GiveMoneyAction extends Action {
} }
@Override @Override
protected void executeInner(Player player) { protected void execute0(Player player) {
if (VaultEconomyHook.INSTANCE.isEnabled()) { if (VaultEconomyHook.INSTANCE.isEnabled()) {
VaultEconomyHook.giveMoney(player, moneyToGive); VaultEconomyHook.giveMoney(player, moneyToGive);
} else { } else {

View File

@ -27,7 +27,7 @@ public class OpCommandAction extends Action {
} }
@Override @Override
protected void executeInner(Player player) { protected void execute0(Player player) {
if (player.isOp()) { if (player.isOp()) {
player.chat("/" + command.getValue(player)); player.chat("/" + command.getValue(player));
} else { } else {

View File

@ -14,14 +14,13 @@
*/ */
package me.filoghost.chestcommands.action; package me.filoghost.chestcommands.action;
import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.menu.InternalIconMenu;
import me.filoghost.chestcommands.variable.RelativeString;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.menu.AdvancedIconMenu;
import me.filoghost.chestcommands.variable.RelativeString;
public class OpenMenuAction extends Action { public class OpenMenuAction extends Action {
private final RelativeString targetMenu; private final RelativeString targetMenu;
@ -31,8 +30,8 @@ public class OpenMenuAction extends Action {
} }
@Override @Override
protected void executeInner(final Player player) { protected void execute0(final Player player) {
final AdvancedIconMenu menu = ChestCommands.getInstance().getMenuManager().getMenuByFileName(targetMenu.getValue(player)); final InternalIconMenu menu = ChestCommands.getInstance().getMenuManager().getMenuByFileName(targetMenu.getValue(player));
if (menu != null) { if (menu != null) {
/* /*

View File

@ -62,7 +62,7 @@ public class PlaySoundAction extends Action {
} }
@Override @Override
protected void executeInner(Player player) { protected void execute0(Player player) {
player.playSound(player.getLocation(), sound, volume, pitch); player.playSound(player.getLocation(), sound, volume, pitch);
} }

View File

@ -27,7 +27,7 @@ public class PlayerCommandAction extends Action {
} }
@Override @Override
protected void executeInner(Player player) { protected void execute0(Player player) {
player.chat('/' + command.getValue(player)); player.chat('/' + command.getValue(player));
} }

View File

@ -28,7 +28,7 @@ public class SendMessageAction extends Action {
} }
@Override @Override
protected void executeInner(Player player) { protected void execute0(Player player) {
player.sendMessage(message.getValue(player)); player.sendMessage(message.getValue(player));
} }

View File

@ -0,0 +1,26 @@
package me.filoghost.chestcommands.api.impl;
import me.filoghost.chestcommands.api.ClickHandler;
import me.filoghost.chestcommands.api.ConfigurableIcon;
import me.filoghost.chestcommands.icon.BaseConfigurableIcon;
import org.bukkit.Material;
public class APIConfigurableIcon extends BaseConfigurableIcon implements ConfigurableIcon {
private ClickHandler clickHandler;
public APIConfigurableIcon(Material material) {
super(material);
}
@Override
public void setClickHandler(ClickHandler clickHandler) {
this.clickHandler = clickHandler;
}
@Override
public ClickHandler getClickHandler() {
return clickHandler;
}
}

View File

@ -14,16 +14,20 @@
*/ */
package me.filoghost.chestcommands.api.impl; package me.filoghost.chestcommands.api.impl;
import me.filoghost.chestcommands.api.Icon;
import me.filoghost.chestcommands.api.IconMenu;
import me.filoghost.chestcommands.menu.BaseIconMenu; import me.filoghost.chestcommands.menu.BaseIconMenu;
import org.bukkit.plugin.Plugin;
public class IconMenuImpl extends BaseIconMenu<Icon> implements IconMenu { public class APIIconMenu extends BaseIconMenu {
private final Plugin owner;
public IconMenuImpl(String title, int rows) { public APIIconMenu(Plugin owner, String title, int rows) {
super(title, rows); super(title, rows);
this.owner = owner;
} }
public Plugin getOwner() {
return owner;
}
} }

View File

@ -0,0 +1,42 @@
package me.filoghost.chestcommands.api.impl;
import me.filoghost.chestcommands.api.ClickHandler;
import me.filoghost.chestcommands.api.StaticIcon;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class APIStaticIcon implements StaticIcon {
private ItemStack itemStack;
private ClickHandler clickHandler;
public APIStaticIcon(ItemStack itemStack) {
this.itemStack = itemStack;
}
@Override
public ItemStack getItemStack() {
return itemStack;
}
@Override
public void setItemStack(ItemStack itemStack) {
this.itemStack = itemStack;
}
@Override
public ClickHandler getClickHandler() {
return clickHandler;
}
@Override
public void setClickHandler(ClickHandler clickHandler) {
this.clickHandler = clickHandler;
}
@Override
public ItemStack render(Player viewer) {
return itemStack;
}
}

View File

@ -14,19 +14,18 @@
*/ */
package me.filoghost.chestcommands.api.impl; package me.filoghost.chestcommands.api.impl;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import me.filoghost.chestcommands.ChestCommands; import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.api.ConfigurableIcon; import me.filoghost.chestcommands.api.ConfigurableIcon;
import me.filoghost.chestcommands.api.IconMenu; import me.filoghost.chestcommands.api.IconMenu;
import me.filoghost.chestcommands.api.StaticIcon; import me.filoghost.chestcommands.api.StaticIcon;
import me.filoghost.chestcommands.api.internal.BackendAPI; import me.filoghost.chestcommands.api.internal.BackendAPI;
import me.filoghost.chestcommands.menu.AdvancedIconMenu; import me.filoghost.chestcommands.menu.InternalIconMenu;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
public class BackendAPIImpl extends BackendAPI { public class DefaultBackendAPI extends BackendAPI {
@Override @Override
public boolean isPluginMenu(String yamlFile) { public boolean isPluginMenu(String yamlFile) {
@ -35,7 +34,7 @@ public class BackendAPIImpl extends BackendAPI {
@Override @Override
public boolean openPluginMenu(Player player, String yamlFile) { public boolean openPluginMenu(Player player, String yamlFile) {
AdvancedIconMenu menu = ChestCommands.getInstance().getMenuManager().getMenuByFileName(yamlFile); InternalIconMenu menu = ChestCommands.getInstance().getMenuManager().getMenuByFileName(yamlFile);
if (menu != null) { if (menu != null) {
menu.open(player); menu.open(player);
@ -47,31 +46,17 @@ public class BackendAPIImpl extends BackendAPI {
@Override @Override
public ConfigurableIcon createConfigurableIcon(Material material) { public ConfigurableIcon createConfigurableIcon(Material material) {
return new ConfigurableIconImpl(material); return new APIConfigurableIcon(material);
} }
@Override @Override
public IconMenu createIconMenu(String title, int rows) { public IconMenu createIconMenu(Plugin owner, String title, int rows) {
return new IconMenuImpl(title, rows); return new APIIconMenu(owner, title, rows);
} }
@Override @Override
public StaticIcon createStaticIcon(ItemStack itemStack, boolean closeOnClick) { public StaticIcon createStaticIcon(ItemStack itemStack) {
ItemStack itemStackCopy = itemStack.clone(); return new APIStaticIcon(itemStack);
return new StaticIcon() {
@Override
public ItemStack createItemStack(Player viewer) {
return itemStackCopy;
}
@Override
public boolean onClick(Inventory inventory, Player clicker) {
return closeOnClick;
}
};
} }
} }

View File

@ -14,20 +14,19 @@
*/ */
package me.filoghost.chestcommands.command; package me.filoghost.chestcommands.command;
import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.Permissions;
import me.filoghost.chestcommands.command.framework.CommandFramework;
import me.filoghost.chestcommands.command.framework.CommandValidate;
import me.filoghost.chestcommands.menu.InternalIconMenu;
import me.filoghost.chestcommands.menu.MenuManager;
import me.filoghost.chestcommands.util.collection.ErrorCollector;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.Permissions;
import me.filoghost.chestcommands.command.framework.CommandFramework;
import me.filoghost.chestcommands.command.framework.CommandValidate;
import me.filoghost.chestcommands.menu.AdvancedIconMenu;
import me.filoghost.chestcommands.menu.MenuManager;
import me.filoghost.chestcommands.util.collection.ErrorCollector;
public class CommandHandler extends CommandFramework { public class CommandHandler extends CommandFramework {
private final MenuManager menuManager; private final MenuManager menuManager;
@ -101,7 +100,7 @@ public class CommandHandler extends CommandFramework {
CommandValidate.notNull(target, "That player is not online."); CommandValidate.notNull(target, "That player is not online.");
String menuName = args[1].toLowerCase().endsWith(".yml") ? args[1] : args[1] + ".yml"; String menuName = args[1].toLowerCase().endsWith(".yml") ? args[1] : args[1] + ".yml";
AdvancedIconMenu menu = menuManager.getMenuByFileName(menuName); InternalIconMenu menu = menuManager.getMenuByFileName(menuName);
CommandValidate.notNull(menu, "The menu \"" + menuName + "\" was not found."); CommandValidate.notNull(menu, "The menu \"" + menuName + "\" was not found.");
if (!sender.hasPermission(menu.getOpenPermission())) { if (!sender.hasPermission(menu.getOpenPermission())) {

View File

@ -12,11 +12,10 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package me.filoghost.chestcommands.api.impl; package me.filoghost.chestcommands.icon;
import me.filoghost.chestcommands.api.ClickHandler; import me.filoghost.chestcommands.api.Icon;
import me.filoghost.chestcommands.api.ClickResult; import me.filoghost.chestcommands.parsing.icon.IconSettingsNode;
import me.filoghost.chestcommands.api.ConfigurableIcon;
import me.filoghost.chestcommands.util.Log; import me.filoghost.chestcommands.util.Log;
import me.filoghost.chestcommands.util.Preconditions; import me.filoghost.chestcommands.util.Preconditions;
import me.filoghost.chestcommands.util.collection.CollectionUtils; import me.filoghost.chestcommands.util.collection.CollectionUtils;
@ -30,7 +29,6 @@ import org.bukkit.Material;
import org.bukkit.block.banner.Pattern; import org.bukkit.block.banner.Pattern;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BannerMeta; import org.bukkit.inventory.meta.BannerMeta;
@ -43,9 +41,8 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
public class ConfigurableIconImpl implements ConfigurableIcon { public abstract class BaseConfigurableIcon implements Icon {
private Material material; private Material material;
private int amount; private int amount;
@ -59,74 +56,70 @@ public class ConfigurableIconImpl implements ConfigurableIcon {
private RelativeString skullOwner; private RelativeString skullOwner;
private DyeColor bannerColor; private DyeColor bannerColor;
private List<Pattern> bannerPatterns; private List<Pattern> bannerPatterns;
private boolean placeholdersEnabled;
protected boolean closeOnClick; protected ItemStack cachedRendering; // Cache the rendered item when there are no variables and values haven't changed
private ClickHandler clickHandler;
private ItemStack cachedItem; // When there are no variables, we don't recreate the item public BaseConfigurableIcon(Material material) {
public ConfigurableIconImpl(Material material) {
Preconditions.checkArgumentNotAir(material, "material"); Preconditions.checkArgumentNotAir(material, "material");
this.material = material; this.material = material;
this.amount = 1; this.amount = 1;
this.closeOnClick = true;
} }
public boolean hasVariables() { protected boolean shouldCacheRendering() {
return (name != null && name.hasVariables()) if (placeholdersEnabled) {
|| (lore != null && lore.hasVariables()) return false;
|| (skullOwner != null && skullOwner.hasVariables()); }
return (name == null || !name.hasVariables())
&& (lore == null || !lore.hasVariables())
&& (skullOwner == null || !skullOwner.hasVariables());
} }
@Override
public void setMaterial(Material material) { public void setMaterial(Material material) {
Preconditions.checkArgumentNotAir(material, "material"); Preconditions.checkArgumentNotAir(material, "material");
this.material = material; this.material = material;
cachedRendering = null;
} }
@Override
public Material getMaterial() { public Material getMaterial() {
return material; return material;
} }
@Override
public void setAmount(int amount) { public void setAmount(int amount) {
Preconditions.checkArgument(amount >= 1, "Amount must 1 or greater"); Preconditions.checkArgument(amount >= 1, "Amount must 1 or greater");
this.amount = Math.min(amount, 127); this.amount = Math.min(amount, 127);
cachedRendering = null;
} }
@Override
public int getAmount() { public int getAmount() {
return amount; return amount;
} }
@Override
public void setDurability(short durability) { public void setDurability(short durability) {
Preconditions.checkArgument(durability >= 0, "Durability must not be negative"); Preconditions.checkArgument(durability >= 0, "Durability must not be negative");
this.durability = durability; this.durability = durability;
cachedRendering = null;
} }
@Override
public short getDurability() { public short getDurability() {
return durability; return durability;
} }
@Override
public void setNBTData(String nbtData) { public void setNBTData(String nbtData) {
this.nbtData = nbtData; this.nbtData = nbtData;
cachedRendering = null;
} }
@Override
public String getNBTData() { public String getNBTData() {
return nbtData; return nbtData;
} }
@Override
public void setName(String name) { public void setName(String name) {
this.name = RelativeString.of(name); this.name = RelativeString.of(name);
cachedRendering = null;
} }
@Override
public boolean hasName() { public boolean hasName() {
return name != null; return name != null;
} }
@ -139,28 +132,25 @@ public class ConfigurableIconImpl implements ConfigurableIcon {
} }
} }
@Override
public void setLore(String... lore) { public void setLore(String... lore) {
if (lore != null) { if (lore != null) {
setLore(Arrays.asList(lore)); setLore(Arrays.asList(lore));
} }
} }
@Override
public void setLore(List<String> lore) { public void setLore(List<String> lore) {
if (!CollectionUtils.isNullOrEmpty(lore)) { if (!CollectionUtils.isNullOrEmpty(lore)) {
this.lore = new RelativeStringList(lore); this.lore = new RelativeStringList(lore);
} else { } else {
this.lore = null; this.lore = null;
} }
cachedRendering = null;
} }
@Override
public boolean hasLore() { public boolean hasLore() {
return lore != null; return lore != null;
} }
@Override
public List<String> getLore() { public List<String> getLore() {
if (lore != null) { if (lore != null) {
return new ArrayList<>(lore.getRawValue()); return new ArrayList<>(lore.getRawValue());
@ -169,48 +159,44 @@ public class ConfigurableIconImpl implements ConfigurableIcon {
} }
} }
@Override
public void setEnchantments(Map<Enchantment, Integer> enchantments) { public void setEnchantments(Map<Enchantment, Integer> enchantments) {
this.enchantments = CollectionUtils.nullableCopy(enchantments); this.enchantments = CollectionUtils.nullableCopy(enchantments);
cachedRendering = null;
} }
@Override
public Map<Enchantment, Integer> getEnchantments() { public Map<Enchantment, Integer> getEnchantments() {
return CollectionUtils.nullableCopy(enchantments); return CollectionUtils.nullableCopy(enchantments);
} }
@Override public void addEnchantment(Enchantment enchantment) {
public void addEnchantment(Enchantment ench) { addEnchantment(enchantment, 1);
addEnchantment(ench, 1);
} }
@Override public void addEnchantment(Enchantment enchantment, Integer level) {
public void addEnchantment(Enchantment ench, Integer level) {
if (enchantments == null) { if (enchantments == null) {
enchantments = new HashMap<>(); enchantments = new HashMap<>();
} }
enchantments.put(ench, level); enchantments.put(enchantment, level);
cachedRendering = null;
} }
@Override public void removeEnchantment(Enchantment enchantment) {
public void removeEnchantment(Enchantment ench) {
if (enchantments == null) { if (enchantments == null) {
return; return;
} }
enchantments.remove(ench); enchantments.remove(enchantment);
cachedRendering = null;
} }
@Override
public Color getLeatherColor() { public Color getLeatherColor() {
return leatherColor; return leatherColor;
} }
@Override
public void setLeatherColor(Color leatherColor) { public void setLeatherColor(Color leatherColor) {
this.leatherColor = leatherColor; this.leatherColor = leatherColor;
cachedRendering = null;
} }
@Override
public String getSkullOwner() { public String getSkullOwner() {
if (skullOwner != null) { if (skullOwner != null) {
return skullOwner.getRawValue(); return skullOwner.getRawValue();
@ -219,50 +205,41 @@ public class ConfigurableIconImpl implements ConfigurableIcon {
} }
} }
@Override
public void setSkullOwner(String skullOwner) { public void setSkullOwner(String skullOwner) {
this.skullOwner = RelativeString.of(skullOwner); this.skullOwner = RelativeString.of(skullOwner);
cachedRendering = null;
} }
@Override
public DyeColor getBannerColor() { public DyeColor getBannerColor() {
return bannerColor; return bannerColor;
} }
@Override
public void setBannerColor(DyeColor bannerColor) { public void setBannerColor(DyeColor bannerColor) {
this.bannerColor = bannerColor; this.bannerColor = bannerColor;
cachedRendering = null;
} }
@Override
public List<Pattern> getBannerPatterns() { public List<Pattern> getBannerPatterns() {
return CollectionUtils.nullableCopy(bannerPatterns); return CollectionUtils.nullableCopy(bannerPatterns);
} }
@Override
public void setBannerPatterns(List<Pattern> bannerPatterns) { public void setBannerPatterns(List<Pattern> bannerPatterns) {
this.bannerPatterns = CollectionUtils.nullableCopy(bannerPatterns); this.bannerPatterns = CollectionUtils.nullableCopy(bannerPatterns);
cachedRendering = null;
} }
@Override public void setPlaceholdersEnabled(boolean placeholdersEnabled) {
public void setCloseOnClick(boolean closeOnClick) { this.placeholdersEnabled = placeholdersEnabled;
this.closeOnClick = closeOnClick; cachedRendering = null;
} }
@Override public String renderName(Player viewer) {
public void setClickHandler(ClickHandler clickHandler) {
this.clickHandler = clickHandler;
}
@Override
public ClickHandler getClickHandler() {
return clickHandler;
}
public String calculateName(Player viewer) {
if (!hasName()) { if (!hasName()) {
return null; return null;
} }
if (!placeholdersEnabled) {
return name.getRawValue();
}
String name = this.name.getValue(viewer); String name = this.name.getValue(viewer);
@ -274,21 +251,23 @@ public class ConfigurableIconImpl implements ConfigurableIcon {
} }
} }
public List<String> calculateLore(Player viewer) { public List<String> renderLore(Player viewer) {
if (hasLore()) { if (!hasLore()) {
return lore.getValue(viewer);
} else {
return null; return null;
} }
if (!placeholdersEnabled) {
return lore.getRawValue();
}
return lore.getValue(viewer);
} }
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public ItemStack createItemStack(Player viewer) { public ItemStack render(Player viewer) {
if (shouldCacheRendering() && cachedRendering != null) {
if (!this.hasVariables() && cachedItem != null) { // Performance: return a cached item
// Performance: return a static item return cachedRendering;
return cachedItem;
} }
ItemStack itemStack = new ItemStack(material, amount, durability); ItemStack itemStack = new ItemStack(material, amount, durability);
@ -300,18 +279,18 @@ public class ConfigurableIconImpl implements ConfigurableIcon {
Bukkit.getUnsafe().modifyItemStack(itemStack, nbtData); Bukkit.getUnsafe().modifyItemStack(itemStack, nbtData);
} catch (Throwable t) { } catch (Throwable t) {
this.nbtData = null; this.nbtData = null;
Log.warning("Could not apply NBT-DATA to an item.", t); Log.warning("Could not apply NBT data to an item.", t);
} }
} }
// Then apply data from config nodes, overwriting NBT data if there are confliting values // Then apply data from config nodes, overwriting NBT data if there are conflicting values
ItemMeta itemMeta = itemStack.getItemMeta(); ItemMeta itemMeta = itemStack.getItemMeta();
if (hasName()) { if (hasName()) {
itemMeta.setDisplayName(calculateName(viewer)); itemMeta.setDisplayName(renderName(viewer));
} }
if (hasLore()) { if (hasLore()) {
itemMeta.setLore(calculateLore(viewer)); itemMeta.setLore(renderLore(viewer));
} }
if (leatherColor != null && itemMeta instanceof LeatherArmorMeta) { if (leatherColor != null && itemMeta instanceof LeatherArmorMeta) {
@ -323,9 +302,11 @@ public class ConfigurableIconImpl implements ConfigurableIcon {
((SkullMeta) itemMeta).setOwner(skullOwner); ((SkullMeta) itemMeta).setOwner(skullOwner);
} }
if (bannerColor != null && itemMeta instanceof BannerMeta) { if (itemMeta instanceof BannerMeta) {
BannerMeta bannerMeta = (BannerMeta) itemMeta; BannerMeta bannerMeta = (BannerMeta) itemMeta;
if (bannerColor != null) {
bannerMeta.setBaseColor(bannerColor); bannerMeta.setBaseColor(bannerColor);
}
if (bannerPatterns != null) { if (bannerPatterns != null) {
((BannerMeta) itemMeta).setPatterns(bannerPatterns); ((BannerMeta) itemMeta).setPatterns(bannerPatterns);
} }
@ -339,34 +320,16 @@ public class ConfigurableIconImpl implements ConfigurableIcon {
itemStack.setItemMeta(itemMeta); itemStack.setItemMeta(itemMeta);
if (enchantments != null) { if (enchantments != null) {
for (Entry<Enchantment, Integer> entry : enchantments.entrySet()) { enchantments.forEach(itemStack::addUnsafeEnchantment);
itemStack.addUnsafeEnchantment(entry.getKey(), entry.getValue());
}
} }
if (!this.hasVariables()) { if (shouldCacheRendering()) {
// If there are no variables, cache the item // If there are no variables, cache the item
cachedItem = itemStack; cachedRendering = itemStack;
} }
return itemStack; return itemStack;
} }
@Override
public boolean onClick(Inventory inventory, Player clicker) {
if (clickHandler == null) {
return closeOnClick;
}
ClickResult result = clickHandler.onClick(clicker);
switch (result) {
case CLOSE:
return true;
case KEEP_OPEN:
return false;
default:
return closeOnClick;
}
}
} }

View File

@ -12,25 +12,28 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package me.filoghost.chestcommands.menu.icon; package me.filoghost.chestcommands.icon;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import me.filoghost.chestcommands.action.Action; import me.filoghost.chestcommands.action.Action;
import me.filoghost.chestcommands.action.OpenMenuAction; import me.filoghost.chestcommands.action.OpenMenuAction;
import me.filoghost.chestcommands.api.impl.ConfigurableIconImpl; import me.filoghost.chestcommands.api.ClickResult;
import me.filoghost.chestcommands.menu.AdvancedIconMenu; import me.filoghost.chestcommands.api.ItemInventory;
import me.filoghost.chestcommands.menu.BaseIconMenu; import me.filoghost.chestcommands.icon.requirement.PermissionChecker;
import me.filoghost.chestcommands.menu.MenuManager; import me.filoghost.chestcommands.icon.requirement.RequiredExpLevel;
import me.filoghost.chestcommands.icon.requirement.RequiredItem;
import me.filoghost.chestcommands.icon.requirement.RequiredItems;
import me.filoghost.chestcommands.icon.requirement.RequiredMoney;
import me.filoghost.chestcommands.icon.requirement.Requirement;
import me.filoghost.chestcommands.util.Preconditions;
import me.filoghost.chestcommands.util.collection.CollectionUtils; import me.filoghost.chestcommands.util.collection.CollectionUtils;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
public class AdvancedIcon extends ConfigurableIconImpl { import java.util.List;
public class InternalConfigurableIcon extends BaseConfigurableIcon implements RefreshableIcon {
private PermissionChecker viewPermission; private PermissionChecker viewPermission;
@ -40,8 +43,12 @@ public class AdvancedIcon extends ConfigurableIconImpl {
private RequiredItems requiredItems; private RequiredItems requiredItems;
private List<Action> clickActions; private List<Action> clickActions;
public AdvancedIcon(Material material) { private ClickResult clickResult;
public InternalConfigurableIcon(Material material) {
super(material); super(material);
setPlaceholdersEnabled(true);
this.clickResult = ClickResult.CLOSE;
} }
public boolean canViewIcon(Player player) { public boolean canViewIcon(Player player) {
@ -94,52 +101,37 @@ public class AdvancedIcon extends ConfigurableIconImpl {
@Override @Override
public ItemStack createItemStack(Player viewer) { public ItemStack render(Player viewer) {
if (canViewIcon(viewer)) { if (canViewIcon(viewer)) {
return super.createItemStack(viewer); return super.render(viewer);
} else { } else {
return null; return null;
} }
} }
public ItemStack refreshItemStack(Player viewer, ItemStack currentItemStack) {
if (!hasViewPermission() && !hasVariables()) {
// Icon is not dynamic, no need to refresh
return currentItemStack;
}
if (!canViewIcon(viewer)) {
// Player can't view the icon
return null;
}
if (currentItemStack == null) {
// Create item from scratch
return createItemStack(viewer);
} else {
// Performance: only update name and lore
ItemMeta meta = currentItemStack.getItemMeta();
meta.setDisplayName(calculateName(viewer));
meta.setLore(calculateLore(viewer));
currentItemStack.setItemMeta(meta);
return currentItemStack;
}
}
@Override @Override
public boolean onClick(Inventory inventory, Player player) { protected boolean shouldCacheRendering() {
return super.shouldCacheRendering() && !hasViewPermission();
}
public void setClickResult(ClickResult clickResult) {
Preconditions.notNull(clickResult, "clickResult");
this.clickResult = clickResult;
}
@Override
public ClickResult onClick(ItemInventory itemInventory, Player player) {
// Check all the requirements // Check all the requirements
boolean hasAllRequirements = Requirement.hasAll(player, clickPermission, requiredMoney, requiredExpLevel, requiredItems); boolean hasAllRequirements = Requirement.hasAll(player, clickPermission, requiredMoney, requiredExpLevel, requiredItems);
if (!hasAllRequirements) { if (!hasAllRequirements) {
return closeOnClick; return clickResult;
} }
// If all requirements are satisfied, take their cost // If all requirements are satisfied, take their cost
boolean takenAllCosts = Requirement.takeAllCosts(player, clickPermission, requiredMoney, requiredExpLevel, requiredItems); boolean takenAllCosts = Requirement.takeAllCosts(player, clickPermission, requiredMoney, requiredExpLevel, requiredItems);
if (!takenAllCosts) { if (!takenAllCosts) {
return closeOnClick; return clickResult;
} }
boolean hasOpenMenuAction = false; boolean hasOpenMenuAction = false;
@ -155,18 +147,39 @@ public class AdvancedIcon extends ConfigurableIconImpl {
} }
// Update the menu after taking requirement costs and executing all actions // Update the menu after taking requirement costs and executing all actions
BaseIconMenu<?> menu = MenuManager.getOpenMenu(inventory); itemInventory.refresh();
if (menu instanceof AdvancedIconMenu) {
((AdvancedIconMenu) menu).refresh(player, inventory);
}
// Force menu to stay open if actions open another menu // Force menu to stay open if actions open another menu
if (hasOpenMenuAction) { if (hasOpenMenuAction) {
return false; return ClickResult.KEEP_OPEN;
} else { } else {
return closeOnClick; return clickResult;
} }
} }
@Override
public ItemStack updateRendering(Player viewer, ItemStack currentRendering) {
if (currentRendering != null && shouldCacheRendering()) {
// Internal icons do not change, no need to update if the item is already rendered
return currentRendering;
}
if (!canViewIcon(viewer)) {
// Hide the current item
return null;
}
if (currentRendering == null) {
// Render item normally
return render(viewer);
} else {
// Internal icons are loaded and then never change, we can safely update only name and lore (for performance)
ItemMeta meta = currentRendering.getItemMeta();
meta.setDisplayName(renderName(viewer));
meta.setLore(renderLore(viewer));
currentRendering.setItemMeta(meta);
return currentRendering;
}
}
} }

View File

@ -0,0 +1,10 @@
package me.filoghost.chestcommands.icon;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public interface RefreshableIcon {
ItemStack updateRendering(Player viewer, ItemStack currentRendering);
}

View File

@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package me.filoghost.chestcommands.menu.icon; package me.filoghost.chestcommands.icon.requirement;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;

View File

@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package me.filoghost.chestcommands.menu.icon; package me.filoghost.chestcommands.icon.requirement;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;

View File

@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package me.filoghost.chestcommands.menu.icon; package me.filoghost.chestcommands.icon.requirement;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;

View File

@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package me.filoghost.chestcommands.menu.icon; package me.filoghost.chestcommands.icon.requirement;
import java.util.List; import java.util.List;

View File

@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package me.filoghost.chestcommands.menu.icon; package me.filoghost.chestcommands.icon.requirement;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;

View File

@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package me.filoghost.chestcommands.menu.icon; package me.filoghost.chestcommands.icon.requirement;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;

View File

@ -0,0 +1,72 @@
package me.filoghost.chestcommands.inventory;
import me.filoghost.chestcommands.api.ClickResult;
import me.filoghost.chestcommands.api.Icon;
import me.filoghost.chestcommands.api.ItemInventory;
import me.filoghost.chestcommands.icon.RefreshableIcon;
import me.filoghost.chestcommands.menu.BaseIconMenu;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
/**
* Represents a particular view of a menu.
*/
public class DefaultItemInventory implements ItemInventory {
private final BaseIconMenu menu;
private final InventoryGrid bukkitInventory;
private final Player viewer;
public DefaultItemInventory(BaseIconMenu menu, Player viewer) {
this.menu = menu;
this.viewer = viewer;
this.bukkitInventory = new InventoryGrid(new MenuInventoryHolder(this), menu.getRowCount(), menu.getTitle());
refresh();
}
public BaseIconMenu getMenu() {
return menu;
}
@Override
public void refresh() {
for (int i = 0; i < menu.getIcons().getSize(); i++) {
Icon icon = menu.getIcons().getByIndex(i);
if (icon == null) {
bukkitInventory.setByIndex(i, null);
} else if (icon instanceof RefreshableIcon) {
ItemStack newItemStack = ((RefreshableIcon) icon).updateRendering(viewer, bukkitInventory.getByIndex(i));
bukkitInventory.setByIndex(i, newItemStack);
} else {
bukkitInventory.setByIndex(i, icon.render(viewer));
}
}
}
public void open(Player viewer) {
viewer.openInventory(bukkitInventory.getInventory());
}
public SlotClickHandler getSlotClickHandler(int slot, Player clicker) {
if (slot < 0 || slot >= bukkitInventory.getSize()) {
return null;
}
Icon icon = menu.getIcons().getByIndex(slot);
if (icon == null) {
return null;
}
return () -> icon.onClick(this, clicker);
}
@FunctionalInterface
public interface SlotClickHandler {
ClickResult onClick();
}
}

View File

@ -0,0 +1,31 @@
package me.filoghost.chestcommands.inventory;
import me.filoghost.chestcommands.util.collection.Grid;
import org.bukkit.Bukkit;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
public class InventoryGrid extends Grid<ItemStack> {
private final Inventory inventory;
public InventoryGrid(MenuInventoryHolder inventoryHolder, int rows, String title) {
super(rows, 9);
this.inventory = Bukkit.createInventory(inventoryHolder, getSize(), title);
}
public Inventory getInventory() {
return inventory;
}
@Override
protected ItemStack getByIndex0(int ordinalIndex) {
return inventory.getItem(ordinalIndex);
}
@Override
protected void setByIndex0(int ordinalIndex, ItemStack element) {
inventory.setItem(ordinalIndex, element);
}
}

View File

@ -12,25 +12,20 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package me.filoghost.chestcommands.menu.inventory; package me.filoghost.chestcommands.inventory;
import me.filoghost.chestcommands.util.Preconditions;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.InventoryHolder;
import me.filoghost.chestcommands.menu.BaseIconMenu;
import me.filoghost.chestcommands.util.Preconditions;
/**
* This class links an IconMenu with an Inventory, via InventoryHolder.
*/
public class MenuInventoryHolder implements InventoryHolder { public class MenuInventoryHolder implements InventoryHolder {
private final BaseIconMenu<?> iconMenu; private final DefaultItemInventory menuInventory;
public MenuInventoryHolder(BaseIconMenu<?> iconMenu) { public MenuInventoryHolder(DefaultItemInventory menuInventory) {
Preconditions.notNull(iconMenu, "iconMenu"); Preconditions.notNull(menuInventory, "menuInventory");
this.iconMenu = iconMenu; this.menuInventory = menuInventory;
} }
@Override @Override
@ -44,8 +39,7 @@ public class MenuInventoryHolder implements InventoryHolder {
return Bukkit.createInventory(null, 9); return Bukkit.createInventory(null, 9);
} }
public BaseIconMenu<?> getIconMenu() { public DefaultItemInventory getMenuInventory() {
return iconMenu; return menuInventory;
} }
} }

View File

@ -14,14 +14,13 @@
*/ */
package me.filoghost.chestcommands.listener; package me.filoghost.chestcommands.listener;
import me.filoghost.chestcommands.menu.InternalIconMenu;
import me.filoghost.chestcommands.menu.MenuManager;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import me.filoghost.chestcommands.menu.AdvancedIconMenu;
import me.filoghost.chestcommands.menu.MenuManager;
public class CommandListener implements Listener { public class CommandListener implements Listener {
private final MenuManager menuManager; private final MenuManager menuManager;
@ -38,7 +37,7 @@ public class CommandListener implements Listener {
return; return;
} }
AdvancedIconMenu menu = menuManager.getMenuByCommand(command); InternalIconMenu menu = menuManager.getMenuByCommand(command);
if (menu == null) { if (menu == null) {
return; return;

View File

@ -14,9 +14,11 @@
*/ */
package me.filoghost.chestcommands.listener; package me.filoghost.chestcommands.listener;
import java.util.HashMap; import me.filoghost.chestcommands.ChestCommands;
import java.util.Map; import me.filoghost.chestcommands.api.ClickResult;
import me.filoghost.chestcommands.inventory.DefaultItemInventory.SlotClickHandler;
import me.filoghost.chestcommands.menu.MenuManager;
import me.filoghost.chestcommands.inventory.DefaultItemInventory;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -25,22 +27,19 @@ import org.bukkit.event.Listener;
import org.bukkit.event.block.Action; import org.bukkit.event.block.Action;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import me.filoghost.chestcommands.ChestCommands; import java.util.Map;
import me.filoghost.chestcommands.api.Icon; import java.util.WeakHashMap;
import me.filoghost.chestcommands.menu.BaseIconMenu;
import me.filoghost.chestcommands.menu.MenuManager;
public class InventoryListener implements Listener { public class InventoryListener implements Listener {
private static final Map<Player, Long> antiClickSpam = new HashMap<>();
private final MenuManager menuManager; private final MenuManager menuManager;
private final Map<Player, Long> antiClickSpam;
public InventoryListener(MenuManager menuManager) { public InventoryListener(MenuManager menuManager) {
this.menuManager = menuManager; this.menuManager = menuManager;
this.antiClickSpam = new WeakHashMap<>();
} }
@ -62,25 +61,20 @@ public class InventoryListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = false) @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = false)
public void onLateInventoryClick(InventoryClickEvent event) { public void onLateInventoryClick(InventoryClickEvent event) {
Inventory inventory = event.getInventory(); Inventory inventory = event.getInventory();
BaseIconMenu<?> menu = MenuManager.getOpenMenu(inventory); DefaultItemInventory menuInventory = MenuManager.getOpenMenuInventory(inventory);
if (menu == null) { if (menuInventory == null) {
return; return;
} }
// Make sure the event is still cancelled (in case another plugin wrongly uncancels it) // Cancel the event again just in case a plugin un-cancels it
event.setCancelled(true); event.setCancelled(true);
int slot = event.getRawSlot(); int slot = event.getRawSlot();
if (slot < 0 || slot >= menu.getSize()) {
return;
}
Icon icon = menu.getIconAtSlot(slot);
if (icon == null || event.getInventory().getItem(slot) == null) {
return;
}
Player clicker = (Player) event.getWhoClicked(); Player clicker = (Player) event.getWhoClicked();
SlotClickHandler slotClickHandler = menuInventory.getSlotClickHandler(slot, clicker);
if (slotClickHandler == null) {
return;
}
Long cooldownUntil = antiClickSpam.get(clicker); Long cooldownUntil = antiClickSpam.get(clicker);
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
@ -96,17 +90,12 @@ public class InventoryListener implements Listener {
// Only handle the click AFTER the event has finished // Only handle the click AFTER the event has finished
Bukkit.getScheduler().runTask(ChestCommands.getInstance(), () -> { Bukkit.getScheduler().runTask(ChestCommands.getInstance(), () -> {
boolean close = icon.onClick(inventory, clicker); ClickResult result = slotClickHandler.onClick();
if (close) { if (result == ClickResult.CLOSE) {
clicker.closeInventory(); clicker.closeInventory();
} }
}); });
} }
@EventHandler
public void onQuit(PlayerQuitEvent event) {
antiClickSpam.remove(event.getPlayer());
}
} }

View File

@ -14,6 +14,10 @@
*/ */
package me.filoghost.chestcommands.listener; package me.filoghost.chestcommands.listener;
import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.Permissions;
import me.filoghost.chestcommands.menu.InternalIconMenu;
import me.filoghost.chestcommands.menu.MenuManager;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.block.Sign; import org.bukkit.block.Sign;
@ -25,11 +29,6 @@ import org.bukkit.event.block.Action;
import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.Permissions;
import me.filoghost.chestcommands.menu.AdvancedIconMenu;
import me.filoghost.chestcommands.menu.MenuManager;
public class SignListener implements Listener { public class SignListener implements Listener {
private static final int HEADER_LINE = 0; private static final int HEADER_LINE = 0;
@ -65,7 +64,7 @@ public class SignListener implements Listener {
} }
String menuFileName = addYamlExtension(sign.getLine(FILENAME_LINE).trim()); String menuFileName = addYamlExtension(sign.getLine(FILENAME_LINE).trim());
AdvancedIconMenu menu = menuManager.getMenuByFileName(menuFileName); InternalIconMenu menu = menuManager.getMenuByFileName(menuFileName);
if (menu == null) { if (menu == null) {
event.getPlayer().sendMessage(ChestCommands.getLang().menu_not_found); event.getPlayer().sendMessage(ChestCommands.getLang().menu_not_found);
@ -88,7 +87,7 @@ public class SignListener implements Listener {
menuFileName = addYamlExtension(menuFileName); menuFileName = addYamlExtension(menuFileName);
AdvancedIconMenu iconMenu = menuManager.getMenuByFileName(menuFileName); InternalIconMenu iconMenu = menuManager.getMenuByFileName(menuFileName);
if (iconMenu == null) { if (iconMenu == null) {
event.setCancelled(true); event.setCancelled(true);
event.getPlayer().sendMessage(ChatColor.RED + "Menu \"" + menuFileName + "\" was not found."); event.getPlayer().sendMessage(ChatColor.RED + "Menu \"" + menuFileName + "\" was not found.");

View File

@ -14,82 +14,63 @@
*/ */
package me.filoghost.chestcommands.menu; package me.filoghost.chestcommands.menu;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import me.filoghost.chestcommands.api.Icon; import me.filoghost.chestcommands.api.Icon;
import me.filoghost.chestcommands.menu.inventory.Grid; import me.filoghost.chestcommands.api.IconMenu;
import me.filoghost.chestcommands.menu.inventory.MenuInventoryHolder; import me.filoghost.chestcommands.api.ItemInventory;
import me.filoghost.chestcommands.inventory.DefaultItemInventory;
import me.filoghost.chestcommands.util.Preconditions; import me.filoghost.chestcommands.util.Preconditions;
import me.filoghost.chestcommands.util.collection.ArrayGrid;
import me.filoghost.chestcommands.util.collection.Grid;
import org.bukkit.entity.Player;
public class BaseIconMenu<T extends Icon> { public abstract class BaseIconMenu implements IconMenu {
protected final String title; protected final String title;
protected final Grid<T> inventoryGrid; protected final Grid<Icon> icons;
public BaseIconMenu(String title, int rows) { public BaseIconMenu(String title, int rows) {
this.title = title; this.title = title;
this.inventoryGrid = new Grid<>(rows, 9); this.icons = new ArrayGrid<>(rows, 9);
} }
public void setIcon(int x, int y, T icon) { @Override
inventoryGrid.setElement(x, y, icon); public void setIcon(int row, int column, Icon icon) {
icons.set(row, column, icon);
} }
public T getIcon(int x, int y) { @Override
return inventoryGrid.getElement(x, y); public Icon getIcon(int row, int column) {
} return icons.get(row, column);
public T getIconAtSlot(int slot) {
return inventoryGrid.getElementAtIndex(slot);
} }
@Override
public int getRowCount() { public int getRowCount() {
return inventoryGrid.getRows(); return icons.getRows();
} }
@Override
public int getColumnCount() { public int getColumnCount() {
return inventoryGrid.getColumns(); return icons.getColumns();
}
public int getSize() {
return inventoryGrid.getSize();
} }
@Override
public String getTitle() { public String getTitle() {
return title; return title;
} }
public Grid<Icon> getIcons() {
public void open(Player player) { return icons;
Preconditions.notNull(player, "player");
Inventory inventory = Bukkit.createInventory(new MenuInventoryHolder(this), getSize(), title);
for (int i = 0; i < inventoryGrid.getSize(); i++) {
T icon = inventoryGrid.getElementAtIndex(i);
if (icon == null) {
continue;
}
ItemStack itemStack = icon.createItemStack(player);
if (itemStack == null) {
continue;
}
inventory.setItem(i, itemStack);
}
player.openInventory(inventory);
} }
@Override @Override
public String toString() { public ItemInventory open(Player player) {
return "IconMenu [title=" + title + ", icons=" + inventoryGrid + "]"; Preconditions.notNull(player, "player");
DefaultItemInventory menuInventory = new DefaultItemInventory(this, player);
menuInventory.open(player);
return menuInventory;
} }
} }

View File

@ -14,20 +14,17 @@
*/ */
package me.filoghost.chestcommands.menu; package me.filoghost.chestcommands.menu;
import java.util.List;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import me.filoghost.chestcommands.ChestCommands; import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.Permissions; import me.filoghost.chestcommands.Permissions;
import me.filoghost.chestcommands.action.Action; import me.filoghost.chestcommands.action.Action;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.api.ItemInventory;
import me.filoghost.chestcommands.util.collection.CollectionUtils; import me.filoghost.chestcommands.util.collection.CollectionUtils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class AdvancedIconMenu extends BaseIconMenu<AdvancedIcon> { import java.util.List;
public class InternalIconMenu extends BaseIconMenu {
private final String fileName; private final String fileName;
private final String openPermission; private final String openPermission;
@ -35,7 +32,7 @@ public class AdvancedIconMenu extends BaseIconMenu<AdvancedIcon> {
private List<Action> openActions; private List<Action> openActions;
private int refreshTicks; private int refreshTicks;
public AdvancedIconMenu(String title, int rows, String fileName) { public InternalIconMenu(String title, int rows, String fileName) {
super(title, rows); super(title, rows);
this.fileName = fileName; this.fileName = fileName;
this.openPermission = Permissions.OPEN_MENU_BASE + fileName; this.openPermission = Permissions.OPEN_MENU_BASE + fileName;
@ -62,14 +59,14 @@ public class AdvancedIconMenu extends BaseIconMenu<AdvancedIcon> {
} }
@Override @Override
public void open(Player player) { public ItemInventory open(Player player) {
if (openActions != null) { if (openActions != null) {
for (Action openAction : openActions) { for (Action openAction : openActions) {
openAction.execute(player); openAction.execute(player);
} }
} }
super.open(player); return super.open(player);
} }
public void openCheckingPermission(Player player) { public void openCheckingPermission(Player player) {
@ -80,19 +77,6 @@ public class AdvancedIconMenu extends BaseIconMenu<AdvancedIcon> {
} }
} }
public void refresh(Player player, Inventory inventory) {
for (int i = 0; i < inventoryGrid.getSize(); i++) {
AdvancedIcon icon = inventoryGrid.getElementAtIndex(i);
if (icon == null) {
continue;
}
ItemStack newItemStack = icon.refreshItemStack(player, inventory.getItem(i));
inventory.setItem(i, newItemStack);
}
}
public void sendNoOpenPermissionMessage(CommandSender sender) { public void sendNoOpenPermissionMessage(CommandSender sender) {
String noPermMessage = ChestCommands.getLang().no_open_permission; String noPermMessage = ChestCommands.getLang().no_open_permission;
if (noPermMessage != null && !noPermMessage.isEmpty()) { if (noPermMessage != null && !noPermMessage.isEmpty()) {

View File

@ -14,8 +14,9 @@
*/ */
package me.filoghost.chestcommands.menu; package me.filoghost.chestcommands.menu;
import me.filoghost.chestcommands.inventory.DefaultItemInventory;
import me.filoghost.chestcommands.inventory.MenuInventoryHolder;
import me.filoghost.chestcommands.parsing.menu.LoadedMenu; import me.filoghost.chestcommands.parsing.menu.LoadedMenu;
import me.filoghost.chestcommands.menu.inventory.MenuInventoryHolder;
import me.filoghost.chestcommands.parsing.menu.OpenTrigger; import me.filoghost.chestcommands.parsing.menu.OpenTrigger;
import me.filoghost.chestcommands.util.collection.CaseInsensitiveMap; import me.filoghost.chestcommands.util.collection.CaseInsensitiveMap;
import me.filoghost.chestcommands.util.collection.ErrorCollector; import me.filoghost.chestcommands.util.collection.ErrorCollector;
@ -32,9 +33,9 @@ import java.util.Map;
public class MenuManager { public class MenuManager {
private static Map<String, AdvancedIconMenu> menusByFile; private static Map<String, InternalIconMenu> menusByFile;
private static Map<String, AdvancedIconMenu> menusByCommand; private static Map<String, InternalIconMenu> menusByCommand;
private static Map<OpenTrigger, AdvancedIconMenu> menusByOpenTrigger; private static Map<OpenTrigger, InternalIconMenu> menusByOpenTrigger;
public MenuManager() { public MenuManager() {
menusByFile = new CaseInsensitiveMap<>(); menusByFile = new CaseInsensitiveMap<>();
@ -48,12 +49,12 @@ public class MenuManager {
menusByOpenTrigger.clear(); menusByOpenTrigger.clear();
} }
public AdvancedIconMenu getMenuByFileName(String fileName) { public InternalIconMenu getMenuByFileName(String fileName) {
return menusByFile.get(fileName); return menusByFile.get(fileName);
} }
public void registerMenu(LoadedMenu loadedMenu, ErrorCollector errorCollector) { public void registerMenu(LoadedMenu loadedMenu, ErrorCollector errorCollector) {
AdvancedIconMenu menu = loadedMenu.getMenu(); InternalIconMenu menu = loadedMenu.getMenu();
if (menusByFile.containsKey(loadedMenu.getFileName())) { if (menusByFile.containsKey(loadedMenu.getFileName())) {
errorCollector.addError("Two menus have the same file name \"" + loadedMenu.getFileName() + "\". " errorCollector.addError("Two menus have the same file name \"" + loadedMenu.getFileName() + "\". "
@ -86,7 +87,7 @@ public class MenuManager {
}); });
} }
public AdvancedIconMenu getMenuByCommand(String command) { public InternalIconMenu getMenuByCommand(String command) {
return menusByCommand.get(command); return menusByCommand.get(command);
} }
@ -98,43 +99,25 @@ public class MenuManager {
return getMenuInventoryHolder(inventory) != null; return getMenuInventoryHolder(inventory) != null;
} }
public static BaseIconMenu<?> getOpenMenu(Player player) { public static DefaultItemInventory getOpenMenuInventory(Player player) {
MenuView menuView = getOpenMenuView(player);
if (menuView != null) {
return menuView.getMenu();
} else {
return null;
}
}
public static BaseIconMenu<?> getOpenMenu(Inventory inventory) {
MenuView menuView = getOpenMenuView(inventory);
if (menuView != null) {
return menuView.getMenu();
} else {
return null;
}
}
public static MenuView getOpenMenuView(Player player) {
InventoryView view = player.getOpenInventory(); InventoryView view = player.getOpenInventory();
if (view == null) { if (view == null) {
return null; return null;
} }
MenuView openMenuView = getOpenMenuView(view.getTopInventory()); DefaultItemInventory menuInventory = getOpenMenuInventory(view.getTopInventory());
if (openMenuView == null) { if (menuInventory == null) {
openMenuView = getOpenMenuView(view.getBottomInventory()); menuInventory = getOpenMenuInventory(view.getBottomInventory());
} }
return openMenuView; return menuInventory;
} }
public static MenuView getOpenMenuView(Inventory inventory) { public static DefaultItemInventory getOpenMenuInventory(Inventory inventory) {
MenuInventoryHolder inventoryHolder = getMenuInventoryHolder(inventory); MenuInventoryHolder inventoryHolder = getMenuInventoryHolder(inventory);
if (inventoryHolder != null) { if (inventoryHolder != null) {
return new MenuView(inventoryHolder.getIconMenu(), inventory); return inventoryHolder.getMenuInventory();
} else { } else {
return null; return null;
} }

View File

@ -1,37 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package me.filoghost.chestcommands.menu;
import org.bukkit.inventory.Inventory;
public class MenuView {
private final BaseIconMenu<?> menu;
private final Inventory inventory;
public MenuView(BaseIconMenu<?> menu, Inventory inventory) {
this.menu = menu;
this.inventory = inventory;
}
public BaseIconMenu<?> getMenu() {
return menu;
}
public Inventory getInventory() {
return inventory;
}
}

View File

@ -14,10 +14,10 @@
*/ */
package me.filoghost.chestcommands.parsing.icon; package me.filoghost.chestcommands.parsing.icon;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
public interface ApplicableIconAttribute extends IconAttribute { public interface ApplicableIconAttribute extends IconAttribute {
void apply(AdvancedIcon icon); void apply(InternalConfigurableIcon icon);
} }

View File

@ -16,7 +16,7 @@ package me.filoghost.chestcommands.parsing.icon;
import me.filoghost.chestcommands.config.ConfigSection; import me.filoghost.chestcommands.config.ConfigSection;
import me.filoghost.chestcommands.config.ConfigValueException; import me.filoghost.chestcommands.config.ConfigValueException;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.ParseException; import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.attributes.ActionsAttribute; import me.filoghost.chestcommands.parsing.icon.attributes.ActionsAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.AmountAttribute; import me.filoghost.chestcommands.parsing.icon.attributes.AmountAttribute;
@ -38,8 +38,8 @@ import me.filoghost.chestcommands.parsing.icon.attributes.PriceAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.RequiredItemsAttribute; import me.filoghost.chestcommands.parsing.icon.attributes.RequiredItemsAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.SkullOwnerAttribute; import me.filoghost.chestcommands.parsing.icon.attributes.SkullOwnerAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.ViewPermissionAttribute; import me.filoghost.chestcommands.parsing.icon.attributes.ViewPermissionAttribute;
import me.filoghost.chestcommands.util.collection.ErrorCollector;
import me.filoghost.chestcommands.util.Preconditions; import me.filoghost.chestcommands.util.Preconditions;
import me.filoghost.chestcommands.util.collection.ErrorCollector;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -118,7 +118,7 @@ public class IconSettings {
applicableAttributes.add(iconAttribute); applicableAttributes.add(iconAttribute);
} }
public void applyAttributesTo(AdvancedIcon icon) { public void applyAttributesTo(InternalConfigurableIcon icon) {
if (materialAttribute != null) { if (materialAttribute != null) {
materialAttribute.apply(icon); materialAttribute.apply(icon);
} }

View File

@ -15,7 +15,7 @@
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.action.Action; import me.filoghost.chestcommands.action.Action;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.ActionParser; import me.filoghost.chestcommands.parsing.ActionParser;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector; import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
@ -40,7 +40,7 @@ public class ActionsAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setClickActions(actions); icon.setClickActions(actions);
} }

View File

@ -14,7 +14,7 @@
*/ */
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.ParseException; import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector; import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
@ -31,7 +31,7 @@ public class AmountAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setAmount(amount); icon.setAmount(amount);
} }

View File

@ -14,7 +14,7 @@
*/ */
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.ItemMetaParser; import me.filoghost.chestcommands.parsing.ItemMetaParser;
import me.filoghost.chestcommands.parsing.ParseException; import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
@ -30,7 +30,7 @@ public class BannerColorAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setBannerColor(dyeColor); icon.setBannerColor(dyeColor);
} }

View File

@ -14,7 +14,7 @@
*/ */
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.ItemMetaParser; import me.filoghost.chestcommands.parsing.ItemMetaParser;
import me.filoghost.chestcommands.parsing.ParseException; import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
@ -47,7 +47,7 @@ public class BannerPatternsAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setBannerPatterns(patterns); icon.setBannerPatterns(patterns);
} }

View File

@ -14,7 +14,7 @@
*/ */
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector; import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
@ -27,7 +27,7 @@ public class ClickPermissionAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setClickPermission(clickPermission); icon.setClickPermission(clickPermission);
} }

View File

@ -14,7 +14,7 @@
*/ */
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector; import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
@ -27,7 +27,7 @@ public class ClickPermissionMessageAttribute implements ApplicableIconAttribute
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setNoClickPermissionMessage(clickPermissionMessage); icon.setNoClickPermissionMessage(clickPermissionMessage);
} }

View File

@ -14,7 +14,7 @@
*/ */
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector; import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
@ -27,7 +27,7 @@ public class DurabilityAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setDurability(durability); icon.setDurability(durability);
} }

View File

@ -14,7 +14,7 @@
*/ */
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.EnchantmentParser; import me.filoghost.chestcommands.parsing.EnchantmentParser;
import me.filoghost.chestcommands.parsing.ParseException; import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
@ -47,7 +47,7 @@ public class EnchantmentsAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setEnchantments(enchantments); icon.setEnchantments(enchantments);
} }

View File

@ -14,7 +14,7 @@
*/ */
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.ParseException; import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector; import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
@ -31,7 +31,7 @@ public class ExpLevelsAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setRequiredExpLevel(expLevels); icon.setRequiredExpLevel(expLevels);
} }

View File

@ -14,21 +14,26 @@
*/ */
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.api.ClickResult;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector; import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
public class KeepOpenAttribute implements ApplicableIconAttribute { public class KeepOpenAttribute implements ApplicableIconAttribute {
private final boolean keepOpen; private final ClickResult clickResult;
public KeepOpenAttribute(boolean keepOpen, AttributeErrorCollector attributeErrorCollector) { public KeepOpenAttribute(boolean keepOpen, AttributeErrorCollector attributeErrorCollector) {
this.keepOpen = keepOpen; if (keepOpen) {
this.clickResult = ClickResult.KEEP_OPEN;
} else {
this.clickResult = ClickResult.CLOSE;
}
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setCloseOnClick(!keepOpen); icon.setClickResult(clickResult);
} }
} }

View File

@ -14,7 +14,7 @@
*/ */
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.ItemMetaParser; import me.filoghost.chestcommands.parsing.ItemMetaParser;
import me.filoghost.chestcommands.parsing.ParseException; import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
@ -30,7 +30,7 @@ public class LeatherColorAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setLeatherColor(color); icon.setLeatherColor(color);
} }

View File

@ -15,7 +15,7 @@
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.ChestCommands; import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector; import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
import me.filoghost.chestcommands.util.Colors; import me.filoghost.chestcommands.util.Colors;
@ -31,7 +31,7 @@ public class LoreAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setLore(lore); icon.setLore(lore);
} }

View File

@ -14,7 +14,7 @@
*/ */
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.ParseException; import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector; import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
@ -38,7 +38,7 @@ public class MaterialAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setMaterial(material); icon.setMaterial(material);
} }

View File

@ -14,7 +14,7 @@
*/ */
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.ParseException; import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector; import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
@ -37,7 +37,7 @@ public class NBTDataAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setNBTData(nbtData); icon.setNBTData(nbtData);
} }

View File

@ -15,7 +15,7 @@
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.ChestCommands; import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector; import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
import me.filoghost.chestcommands.util.Colors; import me.filoghost.chestcommands.util.Colors;
@ -29,7 +29,7 @@ public class NameAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setName(name); icon.setName(name);
} }

View File

@ -14,7 +14,7 @@
*/ */
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.ParseException; import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector; import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
@ -31,7 +31,7 @@ public class PriceAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setRequiredMoney(price); icon.setRequiredMoney(price);
} }

View File

@ -14,8 +14,8 @@
*/ */
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.menu.icon.RequiredItem; import me.filoghost.chestcommands.icon.requirement.RequiredItem;
import me.filoghost.chestcommands.parsing.ItemStackParser; import me.filoghost.chestcommands.parsing.ItemStackParser;
import me.filoghost.chestcommands.parsing.ParseException; import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
@ -46,7 +46,7 @@ public class RequiredItemsAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setRequiredItems(requiredItems); icon.setRequiredItems(requiredItems);
} }

View File

@ -14,7 +14,7 @@
*/ */
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector; import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
@ -27,7 +27,7 @@ public class SkullOwnerAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setSkullOwner(skullOwner); icon.setSkullOwner(skullOwner);
} }

View File

@ -14,7 +14,7 @@
*/ */
package me.filoghost.chestcommands.parsing.icon.attributes; package me.filoghost.chestcommands.parsing.icon.attributes;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector; import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
@ -27,7 +27,7 @@ public class ViewPermissionAttribute implements ApplicableIconAttribute {
} }
@Override @Override
public void apply(AdvancedIcon icon) { public void apply(InternalConfigurableIcon icon) {
icon.setViewPermission(viewPermission); icon.setViewPermission(viewPermission);
} }

View File

@ -1,24 +1,24 @@
package me.filoghost.chestcommands.parsing.menu; package me.filoghost.chestcommands.parsing.menu;
import me.filoghost.chestcommands.menu.AdvancedIconMenu; import me.filoghost.chestcommands.menu.InternalIconMenu;
import java.util.List; import java.util.List;
public class LoadedMenu { public class LoadedMenu {
private final AdvancedIconMenu menu; private final InternalIconMenu menu;
private final String fileName; private final String fileName;
private final List<String> triggerCommands; private final List<String> triggerCommands;
private final OpenTrigger openTrigger; private final OpenTrigger openTrigger;
public LoadedMenu(AdvancedIconMenu menu, String fileName, List<String> triggerCommands, OpenTrigger openTrigger) { public LoadedMenu(InternalIconMenu menu, String fileName, List<String> triggerCommands, OpenTrigger openTrigger) {
this.menu = menu; this.menu = menu;
this.fileName = fileName; this.fileName = fileName;
this.triggerCommands = triggerCommands; this.triggerCommands = triggerCommands;
this.openTrigger = openTrigger; this.openTrigger = openTrigger;
} }
public AdvancedIconMenu getMenu() { public InternalIconMenu getMenu() {
return menu; return menu;
} }

View File

@ -18,16 +18,16 @@ import me.filoghost.chestcommands.action.Action;
import me.filoghost.chestcommands.config.Config; import me.filoghost.chestcommands.config.Config;
import me.filoghost.chestcommands.config.ConfigSection; import me.filoghost.chestcommands.config.ConfigSection;
import me.filoghost.chestcommands.config.ConfigValueException; import me.filoghost.chestcommands.config.ConfigValueException;
import me.filoghost.chestcommands.menu.AdvancedIconMenu; import me.filoghost.chestcommands.menu.InternalIconMenu;
import me.filoghost.chestcommands.menu.icon.AdvancedIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.ActionParser; import me.filoghost.chestcommands.parsing.ActionParser;
import me.filoghost.chestcommands.parsing.ErrorFormat; import me.filoghost.chestcommands.parsing.ErrorFormat;
import me.filoghost.chestcommands.parsing.ItemStackParser; import me.filoghost.chestcommands.parsing.ItemStackParser;
import me.filoghost.chestcommands.parsing.ParseException; import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.IconSettingsNode;
import me.filoghost.chestcommands.parsing.icon.IconSettings; import me.filoghost.chestcommands.parsing.icon.IconSettings;
import me.filoghost.chestcommands.util.collection.ErrorCollector; import me.filoghost.chestcommands.parsing.icon.IconSettingsNode;
import me.filoghost.chestcommands.util.Colors; import me.filoghost.chestcommands.util.Colors;
import me.filoghost.chestcommands.util.collection.ErrorCollector;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
@ -41,7 +41,7 @@ public class MenuParser {
MenuSettings menuSettings = loadMenuSettings(menuConfig, errorCollector); MenuSettings menuSettings = loadMenuSettings(menuConfig, errorCollector);
List<IconSettings> iconSettingsList = loadIconSettingsList(menuConfig, errorCollector); List<IconSettings> iconSettingsList = loadIconSettingsList(menuConfig, errorCollector);
AdvancedIconMenu iconMenu = new AdvancedIconMenu(menuSettings.getTitle(), menuSettings.getRows(), menuConfig.getFileName()); InternalIconMenu iconMenu = new InternalIconMenu(menuSettings.getTitle(), menuSettings.getRows(), menuConfig.getFileName());
for (IconSettings iconSettings : iconSettingsList) { for (IconSettings iconSettings : iconSettingsList) {
try { try {
@ -58,7 +58,7 @@ public class MenuParser {
} }
private static void addIconToMenu(AdvancedIconMenu iconMenu, IconSettings iconSettings, ErrorCollector errorCollector) throws IconAddException { private static void addIconToMenu(InternalIconMenu iconMenu, IconSettings iconSettings, ErrorCollector errorCollector) throws IconAddException {
if (iconSettings.getPositionX() == null) { if (iconSettings.getPositionX() == null) {
throw new IconAddException(ErrorFormat.missingAttribute(iconSettings, IconSettingsNode.POSITION_X)); throw new IconAddException(ErrorFormat.missingAttribute(iconSettings, IconSettingsNode.POSITION_X));
} }
@ -67,19 +67,19 @@ public class MenuParser {
throw new IconAddException(ErrorFormat.missingAttribute(iconSettings, IconSettingsNode.POSITION_Y)); throw new IconAddException(ErrorFormat.missingAttribute(iconSettings, IconSettingsNode.POSITION_Y));
} }
int actualX = iconSettings.getPositionX().getPosition() - 1; int row = iconSettings.getPositionY().getPosition() - 1;
int actualY = iconSettings.getPositionY().getPosition() - 1; int column = iconSettings.getPositionX().getPosition() - 1;
if (actualX < 0 || actualX >= iconMenu.getColumnCount()) { if (row < 0 || row >= iconMenu.getRowCount()) {
throw new IconAddException(ErrorFormat.invalidAttribute(iconSettings, IconSettingsNode.POSITION_X,
"it must be between 1 and " + iconMenu.getColumnCount()));
}
if (actualY < 0 || actualY >= iconMenu.getRowCount()) {
throw new IconAddException(ErrorFormat.invalidAttribute(iconSettings, IconSettingsNode.POSITION_Y, throw new IconAddException(ErrorFormat.invalidAttribute(iconSettings, IconSettingsNode.POSITION_Y,
"it must be between 1 and " + iconMenu.getRowCount())); "it must be between 1 and " + iconMenu.getRowCount()));
} }
if (column < 0 || column >= iconMenu.getColumnCount()) {
throw new IconAddException(ErrorFormat.invalidAttribute(iconSettings, IconSettingsNode.POSITION_X,
"it must be between 1 and " + iconMenu.getColumnCount()));
}
if (iconMenu.getIcon(actualX, actualY) != null) { if (iconMenu.getIcon(row, column) != null) {
throw new IconAddException(ErrorFormat.iconError(iconSettings, throw new IconAddException(ErrorFormat.iconError(iconSettings,
"is overriding another icon with the same position")); "is overriding another icon with the same position"));
} }
@ -88,9 +88,9 @@ public class MenuParser {
errorCollector.addError(ErrorFormat.missingAttribute(iconSettings, IconSettingsNode.MATERIAL)); errorCollector.addError(ErrorFormat.missingAttribute(iconSettings, IconSettingsNode.MATERIAL));
} }
AdvancedIcon icon = new AdvancedIcon(Material.BEDROCK); InternalConfigurableIcon icon = new InternalConfigurableIcon(Material.BEDROCK);
iconSettings.applyAttributesTo(icon); iconSettings.applyAttributesTo(icon);
iconMenu.setIcon(actualX, actualY, icon); iconMenu.setIcon(row, column, icon);
} }

View File

@ -14,13 +14,12 @@
*/ */
package me.filoghost.chestcommands.task; package me.filoghost.chestcommands.task;
import me.filoghost.chestcommands.inventory.DefaultItemInventory;
import me.filoghost.chestcommands.menu.InternalIconMenu;
import me.filoghost.chestcommands.menu.MenuManager;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import me.filoghost.chestcommands.menu.AdvancedIconMenu;
import me.filoghost.chestcommands.menu.MenuManager;
import me.filoghost.chestcommands.menu.MenuView;
public class RefreshMenusTask implements Runnable { public class RefreshMenusTask implements Runnable {
private long elapsedTenths; private long elapsedTenths;
@ -28,19 +27,16 @@ public class RefreshMenusTask implements Runnable {
@Override @Override
public void run() { public void run() {
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
MenuView openMenuView = MenuManager.getOpenMenuView(player); DefaultItemInventory itemInventory = MenuManager.getOpenMenuInventory(player);
if (openMenuView == null) {
return; if (itemInventory == null || !(itemInventory.getMenu() instanceof InternalIconMenu)) {
continue;
} }
if (!(openMenuView.getMenu() instanceof AdvancedIconMenu)) { int refreshTicks = ((InternalIconMenu) itemInventory.getMenu()).getRefreshTicks();
return;
}
AdvancedIconMenu iconMenu = (AdvancedIconMenu) openMenuView.getMenu(); if (refreshTicks > 0 && elapsedTenths % refreshTicks == 0) {
itemInventory.refresh();
if (elapsedTenths % iconMenu.getRefreshTicks() == 0) {
iconMenu.refresh(player, openMenuView.getInventory());
} }
} }

View File

@ -1,7 +1,5 @@
package me.filoghost.chestcommands.util; package me.filoghost.chestcommands.util;
import org.bukkit.Material;
public class Utils { public class Utils {
public static boolean isClassLoaded(String name) { public static boolean isClassLoaded(String name) {

View File

@ -0,0 +1,23 @@
package me.filoghost.chestcommands.util.collection;
public class ArrayGrid<T> extends Grid<T> {
private final T[] elements;
@SuppressWarnings("unchecked")
public ArrayGrid(int rows, int columns) {
super(rows, columns);
this.elements = (T[]) new Object[getSize()];
}
@Override
protected T getByIndex0(int ordinalIndex) {
return elements[ordinalIndex];
}
@Override
protected void setByIndex0(int ordinalIndex, T element) {
elements[ordinalIndex] = element;
}
}

View File

@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package me.filoghost.chestcommands.menu.inventory; package me.filoghost.chestcommands.util.collection;
import me.filoghost.chestcommands.util.Preconditions; import me.filoghost.chestcommands.util.Preconditions;
@ -32,37 +32,44 @@ import me.filoghost.chestcommands.util.Preconditions;
* v +--------------------------------------------+ * v +--------------------------------------------+
* *
*/ */
public class Grid<T> { public abstract class Grid<T> {
private final int rows, columns; private final int rows, columns, size;
private final T[] elements;
@SuppressWarnings("unchecked")
public Grid(int rows, int columns) { public Grid(int rows, int columns) {
this.rows = rows; this.rows = rows;
this.columns = columns; this.columns = columns;
elements = (T[]) new Object[rows * columns]; this.size = rows * columns;
} }
public void setElement(int x, int y, T element) { public final void set(int row, int column, T element) {
elements[getOrdinalIndex(x, y)] = element; setByIndex(toOrdinalIndex(row, column), element);
} }
public T getElement(int x, int y) { public final T get(int row, int column) {
return getElementAtIndex(getOrdinalIndex(x, y)); return getByIndex(toOrdinalIndex(row, column));
} }
public T getElementAtIndex(int ordinalIndex) { public final T getByIndex(int ordinalIndex) {
Preconditions.checkIndex(ordinalIndex, getSize(), "ordinalIndex"); Preconditions.checkIndex(ordinalIndex, getSize(), "ordinalIndex");
return elements[ordinalIndex]; return getByIndex0(ordinalIndex);
} }
private int getOrdinalIndex(int x, int y) { protected abstract T getByIndex0(int ordinalIndex);
Preconditions.checkIndex(x, getColumns(), "x");
Preconditions.checkIndex(y, getRows(), "y");
int ordinalIndex = y * getColumns() + x; public final void setByIndex(int ordinalIndex, T element) {
Preconditions.checkIndex(ordinalIndex, getSize(), "ordinalIndex");
setByIndex0(ordinalIndex, element);
}
protected abstract void setByIndex0(int ordinalIndex, T element);
private int toOrdinalIndex(int row, int column) {
Preconditions.checkIndex(row, getRows(), "row");
Preconditions.checkIndex(column, getColumns(), "column");
int ordinalIndex = row * getColumns() + column;
Preconditions.checkIndex(ordinalIndex, getSize(), "ordinalIndex"); Preconditions.checkIndex(ordinalIndex, getSize(), "ordinalIndex");
return ordinalIndex; return ordinalIndex;
} }
@ -76,7 +83,7 @@ public class Grid<T> {
} }
public int getSize() { public int getSize() {
return elements.length; return size;
} }
} }