diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..ab963d8 --- /dev/null +++ b/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6dd29b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +bin/ \ No newline at end of file diff --git a/.project b/.project new file mode 100644 index 0000000..2c9cd87 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + Antidrop+ + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..3a21537 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/config.yml b/config.yml new file mode 100644 index 0000000..8c58491 --- /dev/null +++ b/config.yml @@ -0,0 +1,69 @@ +# -------------------------------- +# Antidrop+ v1.0.0 config file +# Created by despawningbone +# -------------------------------- + +# Filter options +Filter: + # Blacklist types of block that you do not want being filtered. + # Please use Bukkit's Material list name. + # Use a colon after the item name to indicate the damage value if needed. + Filter-Blacklist: + #- EXAMPLE_MATERIAL + - + + # Maximum amount of filters that a player can have. + # Set to -1 for infinite (not recommended). + Max-amount: 5 + + # Here you can set which click type to be blocked by the filter. + # Click types can be found in this link: + # https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/inventory/ClickType.html + Filter-click-type: + - CONTROL_DROP + - DROP + - SHIFT_LEFT + - SHIFT_RIGHT + - DOUBLE_CLICK + + # Here you can set which type of checks in the filter you want to disable. + # Available checks: Name, Lore, Exact, Type, Damage. + Disable-filter-check: + #- Exact + - + +#Slot Lock options +SlotLock: + # Maximum amount of slots to be locked. + # Set to -1 for infinite. + Max-amount: -1 + + # Allow Hotbar to be slot locked? + Hotbar-slotlock: true + + # Allow armor slots to be locked? + Armor-slotlock: false + +# Use permissions? +# If not, every command will be available to all players (except reload), +# and all bypasses (and reload) will only be available to OPs. +Use-permissions: true + +# Here you can set the antidrop filter and slot lock messages' cooldown +# Measured in ticks (1 second = 20 ticks in optimal conditiions) +Antidrop-message-cooldown: 100 + +# Some servers might encounter the glowing of the GUI indicators not showing up. +# It is most likely caused by plugin interference. +# If that happens, turn this off. +Glow: true + +# Allow player with permission adp.death.keepfilter/ado.death.keepslot (or OPs if config Use-permissions is disabled) +# To keep their antidrop locked items even after death? +Death-AntiDrop: false + +# Use economy? Vault API required. +Eco: + Use: false + Filter-fee: 20000.0 + SlotLock-fee: 10000.0 diff --git a/plugin.yml b/plugin.yml new file mode 100644 index 0000000..0061912 --- /dev/null +++ b/plugin.yml @@ -0,0 +1,13 @@ +name: AntiDropPlus +description: A plugin that avoids accidental drops and related item loss. +version: 1.0.0 +author: despawningbone + +main: me.despawningbone.antidrop.ADMain +softdepend: [Vault] + +commands: + antidrop: + description: opens a GUI for the configuration of antidrop. + usage: / [filter/lockslot] + aliases: [nodrop, adp] \ No newline at end of file diff --git a/src/me/despawningbone/antidrop/ADCommandMain.java b/src/me/despawningbone/antidrop/ADCommandMain.java new file mode 100644 index 0000000..119010b --- /dev/null +++ b/src/me/despawningbone/antidrop/ADCommandMain.java @@ -0,0 +1,192 @@ +package me.despawningbone.antidrop; + +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; + +public class ADCommandMain implements CommandExecutor { + + private ADMain plugin; + + public ADCommandMain(ADMain instance) { + plugin = instance; + } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { + if(args.length > 0 && args[0].equalsIgnoreCase("reload")) { + if((ConfigHandler.usePerms && sender.hasPermission("adp.reload")) || (!ConfigHandler.usePerms && sender.isOp())) { + if(ConfigHandler.getConfigValues()) { + sender.sendMessage(ADMain.prefix + ChatColor.BLUE + "Antidrop+ has been reloaded."); + } else { + sender.sendMessage(ADMain.prefix + ChatColor.DARK_RED + "There is a missing dependency. Disabled Antidrop+."); + } + } else { + sender.sendMessage(ADMain.prefix + ChatColor.RED + "You do not have permission."); + } + return true; + } + if (sender instanceof Player) { + Player player = (Player) sender; + if (args.length <= 0){ + sender.sendMessage(ADMain.prefix + ChatColor.RED + "Unknown arguments. Do /antidrop help for more info."); + } else if(args[0].equalsIgnoreCase("lockslot")) { + if((ConfigHandler.usePerms && player.hasPermission("adp.lockslot")) || !ConfigHandler.usePerms) { + if(ConfigHandler.eco && GUIHandler.slotParam.containsKey(player.getUniqueId()) && !GUIHandler.slotParam.get(player.getUniqueId()).isEmpty()) { + List buffer = new ArrayList(GUIHandler.slotParam.get(player.getUniqueId())); + ADListener.slotsBuffer.put(player.getUniqueId(), buffer); + } + boolean bypassmax = (ConfigHandler.usePerms && sender.hasPermission("adp.bypass.slotmax")) || (!ConfigHandler.usePerms && sender.isOp()); + if(!bypassmax && GUIHandler.slotParam.containsKey(player.getUniqueId()) && GUIHandler.slotParam.get(player.getUniqueId()).size() >= ConfigHandler.slotMax ) { + player.sendMessage(ADMain.prefix + ChatColor.RED + "You have reached the slot limit of " + ConfigHandler.slotMax + "."); + } else { + GUIHandler.OpenSlotLockGUI(player); + } + } else { + sender.sendMessage(ADMain.prefix + ChatColor.RED + "You do not have permission."); + } + } else if(args[0].equalsIgnoreCase("filter")) { + if((ConfigHandler.usePerms && player.hasPermission("adp.filter")) || !ConfigHandler.usePerms) { + ItemStack item = player.getItemInHand(); + boolean bypass = (ConfigHandler.usePerms && sender.hasPermission("adp.bypass.filterblacklist")) || (!ConfigHandler.usePerms && sender.isOp()); + if(item.getType() != Material.AIR) { + if(!bypass && (ConfigHandler.filterBlacklist.containsKey(item.getType()) && (ConfigHandler.filterBlacklist.get(item.getType()) == -1 || ConfigHandler.filterBlacklist.get(item.getType()) == item.getDurability()))) { + player.sendMessage(ADMain.prefix + ChatColor.RED + "Sorry, but you cannot filter this item."); + } else { + boolean bypassmax = (ConfigHandler.usePerms && sender.hasPermission("adp.bypass.filtermax")) || (!ConfigHandler.usePerms && sender.isOp()); + if(!bypassmax && (GUIHandler.filterParam.containsKey(player.getUniqueId()) && GUIHandler.filterParam.get(player.getUniqueId()).size() >= ConfigHandler.filterMax)) { + player.sendMessage(ADMain.prefix + ChatColor.RED + "You have reached the filter limit of " + ConfigHandler.filterMax + "!"); + } else { + GUIHandler.OpenFilterGUI(item, player); + } + } + } else { + player.sendMessage(ADMain.prefix + ChatColor.RED + "Please hold a item to filter!"); + } + } else { + sender.sendMessage(ADMain.prefix + ChatColor.RED + "You do not have permission."); + } + } else if(args[0].equalsIgnoreCase("filterlist")) { + if((ConfigHandler.usePerms && player.hasPermission("adp.filter")) || !ConfigHandler.usePerms) { + String header = ChatColor.GRAY + (ChatColor.STRIKETHROUGH + "------------------") + ChatColor.GOLD + "AntiDrop+ Filter List" + ChatColor.GRAY + ChatColor.STRIKETHROUGH + "------------------"; + String nofilter = ADMain.prefix + ChatColor.RED + "You currently have no filters set."; + if(args.length > 1) { + if((ConfigHandler.usePerms && player.hasPermission("adp.others.filterlist")) || (!ConfigHandler.usePerms && player.isOp())) { + String playername = args[1]; + Player otherPlayer = Bukkit.getServer().getPlayer(playername); + if(otherPlayer != null) { + player = otherPlayer; + int length = 57 - player.getName().length() - 14; + String repeat = ChatColor.GRAY + (ChatColor.STRIKETHROUGH + (StringUtils.repeat("-", (int) Math.floor(length / 2)))); + String lastletter = (length % 2) == 0 ? "" : "-"; + header = repeat + ChatColor.GOLD + player.getName() + "'s Filter List" + repeat + lastletter; + nofilter = nofilter.replace("You", player.getName()); + } else { + sender.sendMessage(ADMain.prefix + ChatColor.RED + "Unknown player."); + return true; + } + } else { + sender.sendMessage(ADMain.prefix + ChatColor.RED + "You do not have permission."); + return true; + } + } + //async? + if(GUIHandler.filterParam.containsKey(player.getUniqueId()) && !GUIHandler.filterParam.get(player.getUniqueId()).isEmpty()) { + List>> filterlist = GUIHandler.filterParam.get(player.getUniqueId()); + sender.sendMessage(header); + for(int i = 0; i < filterlist.size(); i++) { + List> filter = filterlist.get(i); + sender.sendMessage(ChatColor.GOLD + String.valueOf(i + 1) + ":"); + for(int i2 = 0; i2 < filter.size(); i2++) { + Entry val = filter.get(i2); + if(val.getKey().equals("Exact")) { + String config = val.getValue().toString().replaceAll("\n", "\n\u00A73"); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName() + " {\"text\":\"\u00A76 Exact: \u00A77(Hover me!)\",\"hoverEvent\":{\"action\":\"show_text\",\"value\":\"\u00A73" + config + "\"}}"); + } else if(val.getKey().equals("Lore")){ + sender.sendMessage(ChatColor.GOLD + " " + val.getKey() + ":"); + @SuppressWarnings("unchecked") + List lore = (List) val.getValue(); + for(int i3 = 0; i3 < lore.size(); i3++) { + sender.sendMessage(ChatColor.GOLD + " - " + ChatColor.GRAY + lore.get(i3)); + } + } else { + sender.sendMessage(ChatColor.GOLD + " " + val.getKey() + ": " + ChatColor.GRAY + val.getValue()); + } + } + } + sender.sendMessage(ChatColor.GRAY + (ChatColor.STRIKETHROUGH + "-----------------------------------------------------")); + } else { + sender.sendMessage(nofilter); + } + } else { + sender.sendMessage(ADMain.prefix + ChatColor.RED + "You do not have permission."); + } + } else if(args[0].equalsIgnoreCase("remove")) { + if((ConfigHandler.usePerms && player.hasPermission("adp.filter")) || !ConfigHandler.usePerms) { + if(GUIHandler.filterParam.containsKey(player.getUniqueId()) && !GUIHandler.filterParam.get(player.getUniqueId()).isEmpty()) { + if(args.length > 1) { + int filtID = 0; + try { + filtID = Integer.parseInt(args[1]) - 1; + } catch (NumberFormatException e) { + player.sendMessage(ADMain.prefix + ChatColor.RED + "Please enter a valid integer."); + return true; + } + List>> filterList = GUIHandler.filterParam.get(player.getUniqueId()); + if(filtID >= 0 && filtID < filterList.size()) { + filterList.remove(filtID); + GUIHandler.filterParam.put(player.getUniqueId(), filterList); + player.sendMessage(ADMain.prefix + ChatColor.YELLOW + "Successfully removed filter #" + (filtID + 1) + "."); + plugin.serialize(GUIHandler.filterParam, "FilterData.bin"); + } else { + player.sendMessage(ADMain.prefix + ChatColor.RED + "The integer inputted is out of range."); + } + } else { + player.sendMessage(ADMain.prefix + ChatColor.RED + "Please input the filter's ID. You can see it in /antidrop filterlist."); + } + } else { + player.sendMessage(ADMain.prefix + ChatColor.RED + "You currently have no filters set."); + } + } else { + sender.sendMessage(ADMain.prefix + ChatColor.RED + "You do not have permission."); + } + } else if(args[0].equalsIgnoreCase("help")) { + sender.sendMessage(ChatColor.GRAY + (ChatColor.STRIKETHROUGH + "--------------------") + ChatColor.GOLD + "AntiDrop+ Help" + ChatColor.GRAY + ChatColor.STRIKETHROUGH + "---------------------"); + sender.sendMessage(ChatColor.DARK_AQUA + "Alias:" + ChatColor.DARK_GRAY + " /adp, /nodrop"); + if((ConfigHandler.usePerms && player.hasPermission("adp.lockslot")) || !ConfigHandler.usePerms) { + sender.sendMessage(ChatColor.GOLD + "/antidrop lockslot" + ChatColor.GRAY + " - " + ChatColor.BLUE + "Opens the slot lock GUI."); + } + if((ConfigHandler.usePerms && player.hasPermission("adp.filter")) || !ConfigHandler.usePerms) { + sender.sendMessage(ChatColor.GOLD + "/antidrop filter" + ChatColor.GRAY + " - " + ChatColor.BLUE + "Opens the filter GUI."); + sender.sendMessage(ChatColor.GOLD + "/antidrop filterlist" + ChatColor.GRAY + " - " + ChatColor.BLUE + "Lists the filters you currently have."); + sender.sendMessage(ChatColor.GOLD + "/antidrop remove " + ChatColor.GRAY + " - " + ChatColor.BLUE + "Removes a filter."); + } + if(sender.hasPermission("adp.reload")) { + sender.sendMessage(ChatColor.GOLD + "/antidrop reload" + ChatColor.GRAY + " - " + ChatColor.BLUE + "Reloads the config."); + } + sender.sendMessage(ChatColor.GOLD + "/antidrop about" + ChatColor.GRAY + " - " + ChatColor.BLUE + "Displays the about page."); + } else if(args[0].equalsIgnoreCase("about")) { + sender.sendMessage(ChatColor.BLUE + "Antidrop+" + ChatColor.DARK_GRAY + " Version: " + ChatColor.GOLD + plugin.getDescription().getVersion()); + sender.sendMessage(ChatColor.GOLD + "Made by " + ChatColor.DARK_BLUE + "despawningbone"); + } else { + sender.sendMessage(ADMain.prefix + ChatColor.RED + "Unknown arguments. Do /antidrop help for more info."); + } + } else { + sender.sendMessage(ChatColor.RED + "This is a player only command."); + } + return true; + } + +} \ No newline at end of file diff --git a/src/me/despawningbone/antidrop/ADListener.java b/src/me/despawningbone/antidrop/ADListener.java new file mode 100644 index 0000000..2306274 --- /dev/null +++ b/src/me/despawningbone/antidrop/ADListener.java @@ -0,0 +1,472 @@ +package me.despawningbone.antidrop; + +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import me.despawningbone.antidrop.utils.Timer; + +public class ADListener implements Listener { + + private ADMain plugin; + + public ADListener(ADMain instance) { + plugin = instance; + } + + public static HashMap> slotsBuffer = new HashMap>(); + + public static List cooldown = new ArrayList(); + + private HashMap>> toBeKeeped = new HashMap>>(); //will reset if player didnt respawn in time + + public void sendCooldownMessage(Player player, String msg) { + if(!cooldown.contains(player.getUniqueId())) { + player.sendMessage(msg); + cooldown.add(player.getUniqueId()); + Timer.cooldown(player); + } + } + + @EventHandler + public void onPlayerDropItem(PlayerDropItemEvent event) { + Player player = event.getPlayer(); + if(player.getGameMode() != GameMode.CREATIVE) { + if((ConfigHandler.usePerms && player.hasPermission("adp.filter")) || !ConfigHandler.usePerms) { + boolean cancel = filterCheckStart(player, event.getItemDrop().getItemStack()); //filter check + if(cancel) { + event.setCancelled(true); + sendCooldownMessage(player, ADMain.prefix + ChatColor.BLUE + "Item is in the filter list! You will not be able to drop items the filtered list until you remove it with /antidrop remove."); + return; + } + } + if((ConfigHandler.usePerms && player.hasPermission("adp.lockslot")) || !ConfigHandler.usePerms) { + //SlotLock check + if(runSlotCheck(player, player.getInventory().getHeldItemSlot())) { + event.setCancelled(true); + sendCooldownMessage(player, ADMain.prefix + ChatColor.BLUE + "Slot is locked! If you want to unlock it, do /antidrop lockslot and click on the slot you want to unlock."); + return; + } + } + } + } + + //checks run in async? + private boolean filterCheckStart(Player player, ItemStack item) { + final List ret = new ArrayList(Arrays.asList(false)); + ExecutorService executor = Executors.newFixedThreadPool(1); + executor.execute(new Runnable() { + @Override + public void run() { + if(GUIHandler.filterParam.containsKey(player.getUniqueId())) { + for(int i = 0; i < GUIHandler.filterParam.get(player.getUniqueId()).size(); i++) { + List> filter = GUIHandler.filterParam.get(player.getUniqueId()).get(i); + boolean success = runFilterCheck(filter, item); + if(success) { + ret.set(0, true); + } + } + } + } + }); + executor.shutdown(); + try { + executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + return ret.get(0); + } + private boolean runFilterCheck(List> filter, ItemStack item) { + for(int i = 0; i < filter.size(); i++) { + String checkType = filter.get(i).getKey(); + Object value = filter.get(i).getValue(); + if(checkType.equals("Exact")) { + YamlConfiguration check = new YamlConfiguration(); + YamlConfiguration toCheck = new YamlConfiguration(); + try { + check.loadFromString((String) value); + } catch (InvalidConfigurationException e) { + e.printStackTrace(); return false; + } + ItemStack itoCheck = item.clone(); itoCheck.setAmount(1); + toCheck.set("i", itoCheck); + if(!toCheck.saveToString().equals(check.saveToString())){ return false; } + } else { + if(checkType.equals("Name")) { + if(!(item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().equals(value))) return false; + } + if(checkType.equals("Lore")) { + if(!(item.getItemMeta().hasLore() && item.getItemMeta().getLore().equals(value))) return false; + } + if(checkType.equals("Type")) { + if(!item.getType().equals(value)) return false; + } + if(checkType.equals("Damage")) { + if(item.getDurability() != (short) value) return false; + } + } + } + return true; + } + + private boolean runSlotCheck(Player player, int slot) { + //SlotLock check + if(GUIHandler.slotParam.containsKey(player.getUniqueId())) { + if(GUIHandler.slotParam.containsKey(player.getUniqueId()) && !GUIHandler.slotParam.get(player.getUniqueId()).isEmpty()) { + List slotlist = GUIHandler.slotParam.get(player.getUniqueId()); + for(int i = 0; i < slotlist.size(); i++) { + if(slotlist.get(i) == slot) { + return true; + } + } + } + } + return false; + } + + //TODO check if works, update spigot + + @EventHandler + public void onPlayerDeath(PlayerDeathEvent event) { + System.out.println(event.getKeepInventory()); + if(ConfigHandler.deathKeepEnable && !event.getKeepInventory()) { + Player player = event.getEntity(); + + if((ConfigHandler.usePerms && player.hasPermission("adp.death.keepfilter")) || (!ConfigHandler.usePerms && player.isOp())) { + System.out.println("deathfil1"); + if(GUIHandler.filterParam.containsKey(player.getUniqueId()) && !GUIHandler.filterParam.get(player.getUniqueId()).isEmpty()) { + System.out.println("deathfil2"); + List items = event.getDrops(); + ExecutorService executor = Executors.newFixedThreadPool(1); + executor.execute(new Runnable() { + @Override + public void run() { + System.out.println("deathfil3"); + //HashMap + HashMap invVal = new HashMap(); + List name = new ArrayList(); + List> lore = new ArrayList>(); + List damage = new ArrayList(); + List type = new ArrayList(); + for(int i = 0; i < items.size(); i++) { + System.out.println("deathfilloop1"); + ItemStack item = items.get(i); + name.add((item.hasItemMeta() && item.getItemMeta().hasDisplayName()) ? item.getItemMeta().getDisplayName() : null); + lore.add((item.hasItemMeta() && item.getItemMeta().hasLore()) ? item.getItemMeta().getLore() : null); + damage.add(item.getDurability()); + type.add(item.getType()); + } + invVal.put("Name", name); invVal.put("Lore", lore); invVal.put("Damage", damage); invVal.put("Type", type); + List>> filters = GUIHandler.filterParam.get(player.getUniqueId()); + for(int i = 0; i < filters.size(); i++) { + System.out.println("deathfilloop2:1"); + HashMap times = new HashMap(); + List> filter = filters.get(i); + for(int i2 = 0; i2 < filter.size(); i2++) { + System.out.println("deathfilloop2:2"); + Entry check = filter.get(i2); + String checkType = check.getKey(); + if(checkType.equals("Exact")) { + System.out.println("deathfiltodo"); + } else { + System.out.println("deathfilcheck"); + @SuppressWarnings("unchecked") + List list = new ArrayList((List) invVal.get(checkType)); //ClassCastException? + Object val = check.getValue(); + if(list.contains(val)) { + int index = list.indexOf(val); + for(int i3 = 0; index >= 0; i3++) { + times.put(index + i3, times.containsKey(index) ? times.get(index) + 1 : 1); + System.out.println("Index: " + (index + i3)); + list.remove(index); + index = list.indexOf(val); + } + } + } + } + if(times.values().contains(filter.size())) { + System.out.println("deathfil4"); + List cloneval = new ArrayList(times.values()); + List clonekey = new ArrayList(times.keySet()); + int mapIndex = cloneval.indexOf(filter.size()); + for(int i2 = 0; mapIndex >= 0; i2++) { + System.out.println("MapIndex:" + mapIndex + i2); + System.out.println("Index: " + clonekey.get(mapIndex + i2)); + ItemStack item = items.get(clonekey.get(mapIndex + i2)); //check if it is key actually corresponds to value + System.out.println(item); + int slot = player.getInventory().first(item); + Entry entry = new AbstractMap.SimpleEntry(slot, item); + player.getInventory().clear(slot); //check if it will still appear as a drop or not + items.remove(item); + if(toBeKeeped.containsKey(player.getUniqueId())) { + toBeKeeped.get(player.getUniqueId()).add(entry); + } else { + toBeKeeped.put(player.getUniqueId(), new ArrayList>(Arrays.asList(entry))); + } + cloneval.remove(mapIndex); + mapIndex = cloneval.indexOf(filter.size()); + } + } + } + } + }); + executor.shutdown(); + try { + executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + if((ConfigHandler.usePerms && player.hasPermission("adp.death.keepslot")) || (!ConfigHandler.usePerms && player.isOp())) { + if(GUIHandler.slotParam.containsKey(player.getUniqueId()) && !GUIHandler.slotParam.get(player.getUniqueId()).isEmpty()) { + List items = event.getDrops(); + List slots = GUIHandler.slotParam.get(player.getUniqueId()); + for(int i = 0; i < slots.size(); i++) { + ItemStack item = player.getInventory().getItem(slots.get(i)); + items.remove(item); + Entry entry = new AbstractMap.SimpleEntry(slots.get(i), item); + if(toBeKeeped.containsKey(player.getUniqueId())) { + toBeKeeped.get(player.getUniqueId()).add(entry); + } else { + toBeKeeped.put(player.getUniqueId(), new ArrayList>(Arrays.asList(entry))); + } + } + } + } + } + } + + @EventHandler + public void onPlayerRespawn(PlayerRespawnEvent event) { + Player player = event.getPlayer(); + if(toBeKeeped.containsKey(player.getUniqueId()) && !toBeKeeped.get(player.getUniqueId()).isEmpty()) { + List> playerKeep = toBeKeeped.get(player.getUniqueId()); + for(int i = 0; i < playerKeep.size(); i++) { + Entry entry = playerKeep.get(i); + player.getInventory().setItem(entry.getKey(), entry.getValue()); + } + } + } + + @EventHandler + public void onInventoryClose(InventoryCloseEvent event) { + Inventory inv = event.getInventory(); + Player player = (Player) event.getPlayer(); + String sslotLock = ChatColor.GREEN + "Antidrop lock slot"; + if(inv.getName().equals(sslotLock)) { //SlotLock GUI + if(GUIHandler.slotParam.containsKey(player.getUniqueId()) && !GUIHandler.slotParam.get(player.getUniqueId()).isEmpty()) { + if(ConfigHandler.eco && ConfigHandler.slotFee > 0) { + if(!((ConfigHandler.usePerms && event.getPlayer().hasPermission("adp.bypass.payment")) || (!ConfigHandler.usePerms && event.getPlayer().isOp()))) { + List slots = GUIHandler.slotParam.get(player.getUniqueId()); + double money = 0; + if(slotsBuffer.containsKey(player.getUniqueId())) { + money = ConfigHandler.slotFee * (slots.size() - slotsBuffer.get(player.getUniqueId()).size()); + } else { + money = ConfigHandler.slotFee * slots.size(); + } + if(ADMain.getMoney(player) >= money) { + if(money > 0) { + ADMain.econ.withdrawPlayer(player, money); + player.sendMessage(ADMain.prefix + ChatColor.YELLOW + "$" + money + ChatColor.GREEN + " has been taken from your account."); + } + } else { + if(slotsBuffer.containsKey(player.getUniqueId())) { + GUIHandler.slotParam.put(player.getUniqueId(), slotsBuffer.get(player.getUniqueId())); + } else { + GUIHandler.slotParam.remove(player.getUniqueId()); + } + player.sendMessage(ADMain.prefix + ChatColor.RED + "You do not have enough money to perform the slot locks."); + } + } + if(slotsBuffer.containsKey(player.getUniqueId())) { + slotsBuffer.remove(player.getUniqueId()); + } + } + plugin.serialize(GUIHandler.slotParam, "SlotData.bin"); + } + } + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent event) { + if(event.getWhoClicked().getGameMode() != GameMode.CREATIVE) { + if(event.getClickedInventory() != null) { + if(event.getClickedInventory().equals(((Player) event.getWhoClicked()).getInventory())) { + Player player = (Player) event.getWhoClicked(); + if((ConfigHandler.usePerms && player.hasPermission("adp.filter")) || !ConfigHandler.usePerms) { + //Filter check + if(ConfigHandler.clickCheck.contains(event.getClick())) { //number key? + boolean cancel = filterCheckStart(player, event.getCurrentItem()); + if(cancel) { + event.setCancelled(true); + sendCooldownMessage(player, ADMain.prefix + ChatColor.BLUE + "Item is in the filter list! You will not be able to remove the items in the filtered list from inventory until you remove it with /antidrop remove."); + return; + } + } + } + if((ConfigHandler.usePerms && player.hasPermission("adp.lockslot")) || !ConfigHandler.usePerms) { + //SlotLock check + if(runSlotCheck(player, event.getSlot())) { + event.setCancelled(true); + sendCooldownMessage(player, ADMain.prefix + ChatColor.BLUE + "Slot is locked! If you want to unlock it, do /antidrop lockslot and click on the slot you want to unlock."); + return; + } + } + } + + Inventory inv = event.getInventory(); + String sslotLock = ChatColor.GREEN + "Antidrop lock slot"; + if(inv.getName().equals(sslotLock)) { //SlotLock GUI + if(event.getClickedInventory().getName().equals(sslotLock)) { + Player player = (Player) event.getWhoClicked(); + if(event.getCurrentItem() != null && event.getCurrentItem().getType() != Material.AIR) { + int slot = event.getSlot(); + if(slot > 35) { slot -= 36; } else slot += 9; + if(event.getCurrentItem().equals(GUIHandler.locked)) { + event.getInventory().setItem(event.getSlot(), player.getInventory().getItem(slot)); + GUIHandler.slotParam.get(player.getUniqueId()).remove((Object) slot); + } else { + boolean bypassmax = (ConfigHandler.usePerms && player.hasPermission("adp.bypass.slotmax")) || (!ConfigHandler.usePerms && player.isOp()); + if(GUIHandler.slotParam.containsKey(player.getUniqueId()) && !GUIHandler.slotParam.get(player.getUniqueId()).isEmpty()) { + if(bypassmax || !(GUIHandler.slotParam.get(player.getUniqueId()).size() >= ConfigHandler.slotMax)) { + event.getInventory().setItem(event.getSlot(), GUIHandler.locked); + if(!GUIHandler.slotParam.get(player.getUniqueId()).contains(slot)) { + GUIHandler.slotParam.get(player.getUniqueId()).add(slot); + } + } else { + player.sendMessage(ADMain.prefix + ChatColor.RED + "You have reached the slot limit of " + ConfigHandler.slotMax + "."); + } + } else { + event.getInventory().setItem(event.getSlot(), GUIHandler.locked); + GUIHandler.slotParam.put(player.getUniqueId(), new ArrayList(Arrays.asList(slot))); + } + } + } + } + event.setCancelled(true); + } + + String sfilter = ChatColor.BLUE + "AntiDrop Filter"; + if(inv.getName().equals(sfilter)) { //Filter GUI + if(event.getClickedInventory().getName().equals(sfilter)) { + if(event.getCurrentItem() != null) { + ItemStack currentItem = event.getCurrentItem(); + for(Map.Entry entry : GUIHandler.checks.entrySet()) { + if(currentItem.equals(entry.getValue())) { + inv.setItem(event.getSlot(), GUIHandler.checkOffs.get(entry.getKey())); + } else if(currentItem.equals(GUIHandler.checkOffs.get(entry.getKey()))) { + inv.setItem(event.getSlot(), entry.getValue()); + } + } + + if(event.getCurrentItem().equals(GUIHandler.submit)) { + Player player = (Player)event.getWhoClicked(); + ItemStack main = inv.getItem(13); + List> filter = new ArrayList>(); + if(inv.contains(GUIHandler.checks.get("Exact"))) { + YamlConfiguration config = new YamlConfiguration(); + ItemStack itemFilt = main.clone(); itemFilt.setAmount(1); + config.set("i", itemFilt); + Entry entry = new AbstractMap.SimpleEntry("Exact", config.saveToString()); + filter.add(entry); + } else { + if(inv.contains(GUIHandler.checks.get("Name"))) { + if(main.getItemMeta().hasDisplayName()) { + Entry entry = new AbstractMap.SimpleEntry("Name", main.getItemMeta().getDisplayName()); + filter.add(entry); + } else { + player.sendMessage(ADMain.prefix + ChatColor.RED + "Chosen item has no name. Skipping name check..."); + } + } + if(inv.contains(GUIHandler.checks.get("Lore"))) { + if(main.getItemMeta().hasLore()) { + Entry entry = new AbstractMap.SimpleEntry("Lore", main.getItemMeta().getLore()); + filter.add(entry); + } else { + player.sendMessage(ADMain.prefix + ChatColor.RED + "Chosen item has no lore. Skipping lore check..."); + } + } + if(inv.contains(GUIHandler.checks.get("Type"))) { + Entry entry = new AbstractMap.SimpleEntry("Type", main.getType()); + filter.add(entry); + } + if(inv.contains(GUIHandler.checks.get("Damage"))) { + Entry entry = new AbstractMap.SimpleEntry("Damage", main.getDurability()); + filter.add(entry); + } + } + if(!filter.isEmpty()) { + player.closeInventory(); + boolean useEco = false; + if(ConfigHandler.eco && ConfigHandler.filterFee > 0) { + if(!((ConfigHandler.usePerms && player.hasPermission("adp.bypass.payment")) || (!ConfigHandler.usePerms && player.isOp()))) { + if(ADMain.getMoney(player) >= ConfigHandler.filterFee) { + useEco = true; + } else { + player.sendMessage(ADMain.prefix + ChatColor.RED + "You have insufficient funds."); + event.setCancelled(true); + return; + } + } + } + boolean success = false; + if(GUIHandler.filterParam.containsKey(player.getUniqueId()) && !GUIHandler.filterParam.get(player.getUniqueId()).isEmpty()) { + if(GUIHandler.filterParam.get(player.getUniqueId()).contains(filter)) { + player.sendMessage(ADMain.prefix + ChatColor.RED + "This filter already exists."); + } else { + GUIHandler.filterParam.get(player.getUniqueId()).add(filter); + success = true; + } + } else { + List>> filterList = new ArrayList>>(Arrays.asList(filter)); + GUIHandler.filterParam.put(player.getUniqueId(), filterList); + success = true; + } + if(success) { + plugin.serialize(GUIHandler.filterParam, "FilterData.bin"); + if(useEco) { + ADMain.econ.withdrawPlayer(player, ConfigHandler.filterFee); + player.sendMessage(ADMain.prefix + ChatColor.YELLOW + "$" + ConfigHandler.filterFee + ChatColor.GREEN + " has been taken from your account."); + } + player.sendMessage(ADMain.prefix + ChatColor.GREEN + "Successfully added the filter!"); + } + } else { + player.sendMessage(ADMain.prefix + "Please choose at least one check first!"); + } + } + } + } + event.setCancelled(true); + } + } + } + } +} diff --git a/src/me/despawningbone/antidrop/ADMain.java b/src/me/despawningbone/antidrop/ADMain.java new file mode 100644 index 0000000..615ee6d --- /dev/null +++ b/src/me/despawningbone/antidrop/ADMain.java @@ -0,0 +1,134 @@ +package me.despawningbone.antidrop; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; +import java.util.UUID; +import java.util.logging.Logger; +import java.io.File; + +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.java.JavaPlugin; + +import me.despawningbone.antidrop.utils.Glow; +import net.md_5.bungee.api.ChatColor; +import net.milkbowl.vault.economy.Economy; + +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; + +public class ADMain extends JavaPlugin { + public static Logger log; + public ADCommandMain ADCM = new ADCommandMain(this); + public ADListener listener = new ADListener(this); + public static String prefix = ChatColor.translateAlternateColorCodes('&', "&8[&3AntiDrop+&8]&r "); + public static Economy econ; + + String[] commandMainAliases = {"nodrop", "adp"}; + + @SuppressWarnings("unchecked") + @Override + public void onEnable() { + log = getLogger(); + new ConfigHandler(this); + ConfigHandler.getConfigValues(); + getCommand("antidrop").setExecutor(ADCM); + getCommand("antidrop").setAliases(Arrays.asList(commandMainAliases)); + getServer().getPluginManager().registerEvents(listener, this); + if(new File(this.getDataFolder() + File.separator + "FilterData.bin").exists()) { + Object filterobj = deserialize("FilterData.bin"); + Object slotobj = deserialize("SlotData.bin"); + if(filterobj != null) { + GUIHandler.filterParam = (HashMap>>>) filterobj; + } + if(slotobj != null) { + GUIHandler.slotParam = (HashMap>) slotobj; + } + } + log.info("Antidrop+ v" + getDescription().getVersion() + " by despawningbone has been enabled!"); + } + + @Override + public void onDisable() { + serialize(GUIHandler.filterParam, "FilterData.bin"); + serialize(GUIHandler.slotParam, "SlotData.bin"); + log.info("Disabled Antidrop+ v" + getDescription().getVersion() + "."); + } + + public Object deserialize(String file) { + Object obj = null; + try { + FileInputStream in = new FileInputStream(this.getDataFolder() + File.separator + file); + ObjectInputStream ois = new ObjectInputStream(in); + obj = ois.readObject(); + ois.close(); + } catch (Exception e) { + log.severe("Problem deserializing data from file: " + e); + return null; + } + return obj; + } + + public void serialize(Object obj, String file) { + File folder = this.getDataFolder(); + new Thread(new Runnable() { + @Override + public void run() { + try { + FileOutputStream out = new FileOutputStream(folder + File.separator + file); + ObjectOutputStream oos = new ObjectOutputStream(out); + oos.writeObject(obj); + oos.flush(); + oos.close(); + } catch (Exception e) { + log.severe("Problem serializing data to file: " + e); + } + return; + } + }).start(); + } + + public static Enchantment getGlow() { + try { + Field f = Enchantment.class.getDeclaredField("acceptingNew"); + f.setAccessible(true); + f.set(null, true); + } + catch (Exception e) { + e.printStackTrace(); + } + Glow glow = null; + try { + glow = new Glow(100); + if(!Arrays.asList(Enchantment.values()).contains(glow)) { + Enchantment.registerEnchantment(glow); + } + } + catch (Exception e){ + e.printStackTrace(); + } + return glow; + } + + public boolean setupEconomy() { + if (getServer().getPluginManager().getPlugin("Vault") == null) { + return false; + } + RegisteredServiceProvider rsp = getServer().getServicesManager().getRegistration(Economy.class); + if (rsp == null) { + return false; + } + econ = rsp.getProvider(); + return econ != null; + } + public static double getMoney(Player p) { + double m = econ.getBalance(p); + return m; + } +} diff --git a/src/me/despawningbone/antidrop/ConfigHandler.java b/src/me/despawningbone/antidrop/ConfigHandler.java new file mode 100644 index 0000000..ffefa0a --- /dev/null +++ b/src/me/despawningbone/antidrop/ConfigHandler.java @@ -0,0 +1,115 @@ +package me.despawningbone.antidrop; + +import java.io.File; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.bukkit.event.inventory.ClickType; +import org.bukkit.Material; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +public class ConfigHandler { + + private static ADMain plugin; + private static FileConfiguration config; + + static boolean hotbarSl, usePerms, eco; + static List clickCheck = new ArrayList(); + static int filterMax, slotMax; + static List disableCheck = new ArrayList(); + static HashMap filterBlacklist = new HashMap(); + static double filterFee, slotFee; + static boolean deathKeepEnable; + public static int cooldownTicks; + public static boolean glow; + + public ConfigHandler(ADMain instance) { + plugin = instance; + createFiles(); + } + + public static void createFiles() { + File configFile = new File(plugin.getDataFolder() + File.separator + + "config.yml"); + if (!configFile.exists()) { + ADMain.log.info("Cannot find config.yml, Generating now...."); + plugin.saveDefaultConfig(); + ADMain.log.info("Config generated!"); + } + } + + public static boolean getConfigValues() { + plugin.reloadConfig(); + config = plugin.getConfig(); + YamlConfiguration defcfg = YamlConfiguration.loadConfiguration(new InputStreamReader(plugin.getResource("config.yml"))); + if(!defcfg.getKeys(true).equals(config.getKeys(true))) { + ADMain.log.warning("Config File's keys are not the same."); + ADMain.log.warning("This can mean that your configuration file is corrupted or was tempered with wrongly."); + ADMain.log.warning("Please reset or remove the config file in order for it to work properly."); + } + usePerms = config.getBoolean("Use-permissions"); + eco = config.getBoolean("Eco.Use"); + if(eco) { + if (!plugin.setupEconomy()) { + ADMain.log.severe("Disabling due to no Vault dependency found!"); + plugin.getServer().getPluginManager().disablePlugin(plugin); + return false; + } + slotFee = config.getDouble("Eco.SlotLock-fee"); + filterFee = config.getDouble("Eco.Filter-fee"); + } + deathKeepEnable = config.getBoolean("Death-AntiDrop"); + glow = config.getBoolean("Glow"); + if(glow) { + GUIHandler.glow = ADMain.getGlow(); + } + hotbarSl = config.getBoolean("SlotLock.Hotbar-slotlock"); + //TODO armor slotlock + slotMax = config.getInt("SlotLock.Max-amount"); + if(slotMax == -1) { slotMax = Integer.MAX_VALUE; } + filterMax = config.getInt("Filter.Max-amount"); + if(filterMax == -1) { filterMax = Integer.MAX_VALUE; } + disableCheck = config.getStringList("Filter.Disable-filter-check"); + GUIHandler.initItems(); + cooldownTicks = config.getInt("Antidrop-message-cooldown"); + filterBlacklist = new HashMap(); + List sFilterBlackList = config.getStringList("Filter.Filter-Blacklist"); + if(!sFilterBlackList.isEmpty()) { + for (int i = 0; i < sFilterBlackList.size(); i++) { + String item = sFilterBlackList.get(i); + String itemname = null; String dv = null; + boolean nodv = false; + try { + itemname = item.split(":")[0]; + dv = item.split(":")[1]; + } catch (ArrayIndexOutOfBoundsException e) { + itemname = item; + nodv = true; + } + itemname = itemname.toUpperCase(); + Material material = Material.getMaterial(itemname); + if(nodv) { + filterBlacklist.put(material, (short) -1); + } else { + filterBlacklist.put(material, Short.parseShort(dv)); + } + } + } + clickCheck = new ArrayList(); + List sClickCheck = config.getStringList("Filter.Filter-click-type"); + if(!sClickCheck.isEmpty()) { + for (int i = 0; i < sClickCheck.size(); i++) { + try { + clickCheck.add(ClickType.valueOf(sClickCheck.get(i))); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } + } + } + return true; + } + +} diff --git a/src/me/despawningbone/antidrop/GUIHandler.java b/src/me/despawningbone/antidrop/GUIHandler.java new file mode 100644 index 0000000..9a3f421 --- /dev/null +++ b/src/me/despawningbone/antidrop/GUIHandler.java @@ -0,0 +1,143 @@ +package me.despawningbone.antidrop; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public class GUIHandler { + + public static HashMap checks = new HashMap(); + public static HashMap checkOffs = new HashMap(); + public static ItemStack locked; + public static ItemStack submit; + //Player -> List of filters(List of things to be filtered by this filter(Entry of filter types and values())) + public static HashMap>>> filterParam = new HashMap>>>(); + public static HashMap> slotParam = new HashMap>(); + + public static Enchantment glow = null; + + public static void initItems() { //known bug: any items thats same as the checking items is gonna break the system in some ways //probably will not fix + new Thread(new Runnable() { + @Override + public void run() { + locked = new ItemStack(Material.STAINED_GLASS_PANE); + locked.setDurability((short) 14); + locked = setItemValue(locked, ChatColor.RED + "Locked", Arrays.asList(ChatColor.GRAY + "Any Items in this slot will be locked", ChatColor.GRAY + "and will not be able to be moved", ChatColor.GRAY + "or dropped until you unlocked it."), ConfigHandler.glow); + + submit = setItemValue(new ItemStack(Material.SLIME_BALL, 1), ChatColor.GREEN + "Submit", null, ConfigHandler.glow); + + ItemStack checkBase = new ItemStack(Material.WOOL, 1); + checkBase.setDurability((short) 5); + checks = new HashMap(); + checks.put("Name", setItemValue(checkBase, ChatColor.AQUA + "Name check", Arrays.asList(ChatColor.DARK_BLUE + "The filter will prevent the dropping of any", ChatColor.DARK_BLUE + "items with the same name in your inventory."), ConfigHandler.glow)); + checks.put("Lore", setItemValue(checkBase, ChatColor.AQUA + "Lore check", Arrays.asList(ChatColor.DARK_BLUE + "The filter will prevent the dropping of any", ChatColor.DARK_BLUE + "items with the same lore in your inventory."), ConfigHandler.glow)); + checks.put("Exact", setItemValue(checkBase, ChatColor.AQUA + "Exact Item", Arrays.asList(ChatColor.DARK_BLUE + "The filter will prevent the dropping of any items", ChatColor.DARK_BLUE + "that is exactly the same in your inventory", + ChatColor.DARK_BLUE + "Great for items with custom properties like books and banners.", + ChatColor.DARK_BLUE + "Note: Item amount is ignored."), ConfigHandler.glow)); + checks.put("Type", setItemValue(checkBase, ChatColor.AQUA + "Type check", Arrays.asList(ChatColor.DARK_BLUE + "The filter will prevent the dropping of any items", ChatColor.DARK_BLUE + "that is the same material in your inventory."), ConfigHandler.glow)); + checks.put("Damage", setItemValue(checkBase, ChatColor.AQUA + "Damage check", Arrays.asList(ChatColor.DARK_BLUE + "The filter will prevent the dropping of any", ChatColor.DARK_BLUE + "items with the same damage value in your inventory.", + ChatColor.DARK_BLUE + "Useful for if you want to keep items", + ChatColor.DARK_BLUE + "like specific color of wool only."), ConfigHandler.glow)); + if(!ConfigHandler.disableCheck.isEmpty()) { + for(int i = 0; i < ConfigHandler.disableCheck.size(); i++) { + checks.remove(ConfigHandler.disableCheck.get(i)); + } + } + checkOffs = new HashMap(); + short dura = 14; + for (Map.Entry entry : checks.entrySet()) { + checkOffs.put(entry.getKey(), toOff(entry.getValue(), dura, ConfigHandler.glow)); + } + } + }).start(); + } + + private static ItemStack toOff(ItemStack item, short dura, boolean removeench) { + ItemStack itemOff = item.clone(); + if(removeench) { + itemOff.removeEnchantment(glow); + } + itemOff.setDurability(dura); + return itemOff; + } + + private static ItemStack setItemValue(ItemStack item, String name, List lore, boolean addench) { + ItemStack i = item.clone(); + ItemMeta meta = i.getItemMeta(); + meta.setDisplayName(name); + if(lore != null) { + meta.setLore(lore); + } + if(addench) { + meta.addEnchant(glow, 1, true); + } + i.setItemMeta(meta); + return i; + } + + public static void OpenFilterGUI(ItemStack item, Player player) { + Inventory filterinv = Bukkit.createInventory(null, 45, ChatColor.BLUE + "AntiDrop Filter"); + for(int i = 0; i < checkOffs.size(); i++) { + Object[] val = checkOffs.values().toArray(); + filterinv.setItem(centralize(checkOffs.size()).get(i), (ItemStack) val[i]); + } + filterinv.setItem(13, item); + filterinv.setItem(40, submit); + player.openInventory(filterinv); + } + + public static List centralize(int num) { + if(num == 5) { return Arrays.asList(29, 30, 31, 32, 33); } + else if(num == 4) { return Arrays.asList(29, 30, 32, 33); } + else if(num == 3) { return Arrays.asList(30, 31, 32); } + else if(num == 2) { return Arrays.asList(30, 32); } + else if(num == 1) { return Arrays.asList(31); } + else throw new IllegalArgumentException("Invalid number!"); + } + + public static void OpenSlotLockGUI(Player player) { + int slots = 27; + if(ConfigHandler.hotbarSl) { + slots = 45; + } + Inventory slinv = Bukkit.createInventory(null, slots, ChatColor.GREEN + "Antidrop lock slot"); + List iteminv = new ArrayList(Arrays.asList(player.getInventory().getContents())); + List hotbar = new ArrayList(); + hotbar.addAll(iteminv.subList(0, 9)); + iteminv.subList(0, 9).clear(); + List maininv = iteminv; + if(ConfigHandler.hotbarSl) { + maininv.addAll(Collections.nCopies(9, new ItemStack(Material.AIR))); + maininv.addAll(hotbar); + } + slinv.setContents(maininv.toArray(new ItemStack[maininv.size()])); //TODO apparently breaks in 1.12 + if(!slotParam.isEmpty() && slotParam.containsKey(player.getUniqueId()) && !slotParam.get(player.getUniqueId()).isEmpty()) { + List lockList = slotParam.get(player.getUniqueId()); + for(int i = 0; i < lockList.size(); i++) { + int slot = lockList.get(i); + if(slot < 9) { + slot += 36; + } else { + slot -= 9; + } + slinv.setItem(slot, GUIHandler.locked); + } + } + player.openInventory(slinv); + } + +} diff --git a/src/me/despawningbone/antidrop/utils/Glow.java b/src/me/despawningbone/antidrop/utils/Glow.java new file mode 100644 index 0000000..bf79d98 --- /dev/null +++ b/src/me/despawningbone/antidrop/utils/Glow.java @@ -0,0 +1,48 @@ +package me.despawningbone.antidrop.utils; + +import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentTarget; +import org.bukkit.inventory.ItemStack; + +public class Glow extends Enchantment { + public Glow( int id ) + { + super(id); + } + + @Override + public boolean canEnchantItem(ItemStack item) + { + return true; + } + + @Override + public boolean conflictsWith(Enchantment other) + { + return false; + } + + @Override + public EnchantmentTarget getItemTarget() + { + return null; + } + + @Override + public int getMaxLevel() + { + return 10; + } + + @Override + public String getName() + { + return "Glow"; + } + + @Override + public int getStartLevel() + { + return 1; + } +} diff --git a/src/me/despawningbone/antidrop/utils/Timer.java b/src/me/despawningbone/antidrop/utils/Timer.java new file mode 100644 index 0000000..2c61bfe --- /dev/null +++ b/src/me/despawningbone/antidrop/utils/Timer.java @@ -0,0 +1,20 @@ +package me.despawningbone.antidrop.utils; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitTask; + +import me.despawningbone.antidrop.ConfigHandler; +import me.despawningbone.antidrop.ADListener; + +public class Timer { + public static BukkitTask cooldown(Player player) { + BukkitTask taskid = Bukkit.getServer().getScheduler().runTaskLaterAsynchronously(Bukkit.getPluginManager().getPlugin("AntiDropPlus"), new Runnable() { + @Override + public void run() { + ADListener.cooldown.remove(player.getUniqueId()); + } + }, ConfigHandler.cooldownTicks); + return taskid; + } +} \ No newline at end of file