Skip to content

Commit

Permalink
Various fixes and improvements
Browse files Browse the repository at this point in the history
- CustomBlockRegistry no longer throws an exception when breaking a custom block
- Commands registered through CommandManager will now be unregistered when the plugin that registered them is disabled
- InventoryGUI now cancels InventoryDragEvents which are in non-open slots in the GUI
- ItemUtils now has a utility method to clone an inventory (cannot be opened, but supports other operations)
  • Loading branch information
boxbeam committed Aug 3, 2020
1 parent 9f1110e commit ba4da05
Show file tree
Hide file tree
Showing 6 changed files with 300 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/redempt/redlib/blockdata/CustomBlockRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ public <T extends CustomBlock> void onBreak(DataBlockDestroyEvent e) {
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> {
List<Item> drops = new ArrayList<>();
drops.add(e.getBlock().getWorld().dropItemNaturally(e.getBlock().getLocation(), item));
Event event = (Event) NMSHelper.getClass("BlockDropItemEvent").getInstance(e.getBlock(), state, e.getPlayer(), drops).getObject();
Event event = (Event) NMSHelper.getClass("org.bukkit.event.block.BlockDropItemEvent").getInstance(e.getBlock(), state, e.getPlayer(), drops).getObject();
Bukkit.getPluginManager().callEvent(event);
if (((Cancellable) event).isCancelled()) {
drops.get(0).remove();
Expand Down
37 changes: 27 additions & 10 deletions src/redempt/redlib/commandmanager/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@
import org.bukkit.command.CommandSender;
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.entity.Player;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.TabCompleteEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import redempt.redlib.RedLib;
import redempt.redlib.commandmanager.exceptions.CommandParseException;
import redempt.redlib.commandmanager.exceptions.MissingHookException;
import redempt.redlib.misc.EventListener;
import redempt.redlib.region.MultiRegion;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -54,7 +55,7 @@ public class Command {
}));
}

private Plugin plugin;
protected Plugin plugin;
private CommandArgument[] args;
private ContextProvider<?>[] contextProviders;
private ContextProvider<?>[] asserters;
Expand Down Expand Up @@ -313,9 +314,9 @@ private boolean assertAll(CommandSender sender) {
public void register(String prefix, Object... listeners) {
Field field;
try {
field = Bukkit.getServer().getClass().getDeclaredField("commandMap");
field = Bukkit.getPluginManager().getClass().getDeclaredField("commandMap");
field.setAccessible(true);
SimpleCommandMap map = (SimpleCommandMap) field.get(Bukkit.getServer());
SimpleCommandMap map = (SimpleCommandMap) field.get(Bukkit.getPluginManager());
org.bukkit.command.Command cmd = new org.bukkit.command.Command(names[0], help == null ? "None" : help, "", Arrays.stream(names).skip(1).collect(Collectors.toList())) {

@Override
Expand All @@ -330,7 +331,26 @@ public List<String> tabComplete(CommandSender sender, String alias, String[] arg
}

};
Class<?> clazz = map.getClass();
while (!clazz.getSimpleName().equals("SimpleCommandMap")) {
clazz = clazz.getSuperclass();
}
Field mapField = clazz.getDeclaredField("knownCommands");
mapField.setAccessible(true);
Map<String, org.bukkit.command.Command> knownCommands = (Map<String, org.bukkit.command.Command>) mapField.get(map);
map.register(prefix, cmd);
if (plugin == null) {
plugin = JavaPlugin.getProvidingPlugin(Class.forName(new Exception().getStackTrace()[1].getClassName()));
}
new EventListener<>(RedLib.getInstance(), PluginDisableEvent.class, e -> {
if (e.getPlugin().equals(plugin)) {
try {
Arrays.stream(names).forEach(knownCommands::remove);
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
loop:
for (Object listener : listeners) {
for (Method method : listener.getClass().getDeclaredMethods()) {
Expand Down Expand Up @@ -435,9 +455,6 @@ protected List<String> tab(CommandSender sender, String[] args) {
}

protected boolean execute(CommandSender sender, String[] args) {
if (plugin != null && !plugin.isEnabled()) {
return true;
}
if (permission != null && !sender.hasPermission(permission)) {
sender.sendMessage(msg("noPermission").replace("%permission%", permission));
return true;
Expand Down
15 changes: 14 additions & 1 deletion src/redempt/redlib/commandmanager/CommandCollection.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import java.util.stream.Collectors;

import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;

/**
* Represents a collection of commands which can be mass-registered. Can contain any amount of commands, including 0
Expand All @@ -28,7 +30,18 @@ public CommandCollection(List<Command> commands) {
*/
public void register(String prefix, Object... listeners) {
mergeBaseCommands();
commands.stream().forEach(c -> c.register(prefix, listeners));
Plugin plugin = null;
try {
Class<?> clazz = Class.forName(new Exception().getStackTrace()[1].getClassName());
plugin = JavaPlugin.getProvidingPlugin(clazz);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Plugin fplugin = plugin;
commands.stream().forEach(c -> {
c.plugin = fplugin;
c.register(prefix, listeners);
});
}

private void mergeBaseCommands() {
Expand Down
12 changes: 8 additions & 4 deletions src/redempt/redlib/inventorygui/InventoryGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.*;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;

Expand Down Expand Up @@ -317,6 +314,13 @@ public void clear() {
buttons.clear();
}

@EventHandler
public void onDrag(InventoryDragEvent e) {
if (e.getRawSlots().stream().anyMatch(s -> e.getView().getInventory(s).equals(inventory) && !openSlots.contains(s))) {
e.setCancelled(true);
}
}

@EventHandler
public void onClick(InventoryClickEvent e) {
if (!inventory.equals(e.getView().getTopInventory())) {
Expand Down
27 changes: 23 additions & 4 deletions src/redempt/redlib/itemutils/ItemUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@
import java.util.List;
import java.util.UUID;

import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeModifier;
import org.bukkit.attribute.AttributeModifier.Operation;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.*;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;

Expand Down Expand Up @@ -423,4 +424,22 @@ public static boolean compare(ItemStack first, ItemStack second) {
return true;
}

/**
* Creates a mock inventory clone of the given inventory. Do not try to open this inventory for players,
* it will throw an error.
* @param inv The inventory to clone
* @return A mock clone inventory
*/
public static Inventory cloneInventory(Inventory inv) {
ItemStack[] contents = new ItemStack[inv.getSize()];
for (int i = 0; i < inv.getSize(); i++) {
ItemStack item = inv.getItem(i);
if (item == null) {
continue;
}
contents[i] = item.clone();
}
return new MockInventory(contents, inv.getHolder(), inv.getType());
}

}
Loading

0 comments on commit ba4da05

Please sign in to comment.