Reduce permission check calls in PlayerCommandSendEvent (#3026)

This reduces permissions checks by only checking each command once, not checking each command for each alias.

The impact of this is a near-tenfold reduction in permission checks during this listener, which should slightly improve performance when using LuckPerms (and provide significant improvements on older inefficient permissions plugins).
This commit is contained in:
md678685 2020-02-22 10:02:53 +00:00 committed by GitHub
parent 8069370b8c
commit 0bafbc3184
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -48,6 +48,24 @@ public class EssentialsPlayerListener implements Listener {
this.ess = parent; this.ess = parent;
} }
private static boolean isEntityPickupEvent() {
try {
Class.forName("org.bukkit.event.entity.EntityPickupItemEvent");
return true;
} catch (ClassNotFoundException ignored) {
return false;
}
}
private static boolean isCommandSendEvent() {
try {
Class.forName("org.bukkit.event.player.PlayerCommandSendEvent");
return true;
} catch (ClassNotFoundException ignored) {
return false;
}
}
public void registerEvents() { public void registerEvents() {
ess.getServer().getPluginManager().registerEvents(this, ess); ess.getServer().getPluginManager().registerEvents(this, ess);
@ -156,7 +174,7 @@ public class EssentialsPlayerListener implements Listener {
.replace("{PLAYER}", player.getDisplayName()) .replace("{PLAYER}", player.getDisplayName())
.replace("{USERNAME}", player.getName()) .replace("{USERNAME}", player.getName())
.replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size())); .replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size()));
event.setQuitMessage(msg.isEmpty() ? null : msg); event.setQuitMessage(msg.isEmpty() ? null : msg);
} }
@ -258,9 +276,9 @@ public class EssentialsPlayerListener implements Listener {
//NOOP //NOOP
} else if (ess.getSettings().isCustomJoinMessage()) { } else if (ess.getSettings().isCustomJoinMessage()) {
String msg = ess.getSettings().getCustomJoinMessage() String msg = ess.getSettings().getCustomJoinMessage()
.replace("{PLAYER}", player.getDisplayName()).replace("{USERNAME}", player.getName()) .replace("{PLAYER}", player.getDisplayName()).replace("{USERNAME}", player.getName())
.replace("{UNIQUE}", NumberFormat.getInstance().format(ess.getUserMap().getUniqueUsers())) .replace("{UNIQUE}", NumberFormat.getInstance().format(ess.getUserMap().getUniqueUsers()))
.replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size())); .replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size()));
if (!msg.isEmpty()) { if (!msg.isEmpty()) {
ess.getServer().broadcastMessage(msg); ess.getServer().broadcastMessage(msg);
} }
@ -312,7 +330,7 @@ public class EssentialsPlayerListener implements Listener {
user.setGodModeEnabled(false); user.setGodModeEnabled(false);
ess.getLogger().log(Level.INFO, "Set god mode to false for {0} because they had it enabled without permission.", user.getName()); ess.getLogger().log(Level.INFO, "Set god mode to false for {0} because they had it enabled without permission.", user.getName());
} }
user.setConfirmingClearCommand(null); user.setConfirmingClearCommand(null);
user.getConfirmingPayments().clear(); user.getConfirmingPayments().clear();
@ -477,7 +495,7 @@ public class EssentialsPlayerListener implements Listener {
LOGGER.info(tl("mutedUserSpeaks", player.getName(), event.getMessage())); LOGGER.info(tl("mutedUserSpeaks", player.getName(), event.getMessage()));
return; return;
} }
boolean broadcast = true; // whether to broadcast the updated activity boolean broadcast = true; // whether to broadcast the updated activity
boolean update = true; // Only modified when the command is afk boolean update = true; // Only modified when the command is afk
@ -496,16 +514,16 @@ public class EssentialsPlayerListener implements Listener {
} }
if (ess.getSettings().isCommandCooldownsEnabled() && pluginCommand != null if (ess.getSettings().isCommandCooldownsEnabled() && pluginCommand != null
&& !user.isAuthorized("essentials.commandcooldowns.bypass")) { && !user.isAuthorized("essentials.commandcooldowns.bypass")) {
int argStartIndex = event.getMessage().indexOf(" "); int argStartIndex = event.getMessage().indexOf(" ");
String args = argStartIndex == -1 ? "" // No arguments present String args = argStartIndex == -1 ? "" // No arguments present
: " " + event.getMessage().substring(argStartIndex); // arguments start at argStartIndex; substring from there. : " " + event.getMessage().substring(argStartIndex); // arguments start at argStartIndex; substring from there.
String fullCommand = pluginCommand.getName() + args; String fullCommand = pluginCommand.getName() + args;
// Used to determine whether a user already has an existing cooldown // Used to determine whether a user already has an existing cooldown
// If so, no need to check for (and write) new ones. // If so, no need to check for (and write) new ones.
boolean cooldownFound = false; boolean cooldownFound = false;
// Iterate over a copy of getCommandCooldowns in case of concurrent modifications // Iterate over a copy of getCommandCooldowns in case of concurrent modifications
for (Entry<Pattern, Long> entry : new HashMap<>(user.getCommandCooldowns()).entrySet()) { for (Entry<Pattern, Long> entry : new HashMap<>(user.getCommandCooldowns()).entrySet()) {
// Remove any expired cooldowns // Remove any expired cooldowns
@ -543,8 +561,8 @@ public class EssentialsPlayerListener implements Listener {
final User user = ess.getUser(event.getPlayer()); final User user = ess.getUser(event.getPlayer());
if (user.getBase().getGameMode() != GameMode.CREATIVE if (user.getBase().getGameMode() != GameMode.CREATIVE
// COMPAT: String compare for 1.7.10 // COMPAT: String compare for 1.7.10
&& !user.getBase().getGameMode().name().equals("SPECTATOR") && !user.getBase().getGameMode().name().equals("SPECTATOR")
&& !user.isAuthorized("essentials.fly")) { && !user.isAuthorized("essentials.fly")) {
user.getBase().setFallDistance(0f); user.getBase().setFallDistance(0f);
user.getBase().setAllowFlight(false); user.getBase().setAllowFlight(false);
} }
@ -730,9 +748,9 @@ public class EssentialsPlayerListener implements Listener {
} }
} else if (clickedInventory != null && clickedInventory.getType() == InventoryType.PLAYER) { } else if (clickedInventory != null && clickedInventory.getType() == InventoryType.PLAYER) {
if (ess.getSettings().isDirectHatAllowed() && event.getClick() == ClickType.LEFT && event.getSlot() == 39 if (ess.getSettings().isDirectHatAllowed() && event.getClick() == ClickType.LEFT && event.getSlot() == 39
&& event.getCursor().getType() != Material.AIR && event.getCursor().getType().getMaxDurability() == 0 && event.getCursor().getType() != Material.AIR && event.getCursor().getType().getMaxDurability() == 0
&& !MaterialUtil.isSkull(event.getCursor().getType()) && !MaterialUtil.isSkull(event.getCursor().getType())
&& ess.getUser(event.getWhoClicked()).isAuthorized("essentials.hat") && !ess.getUser(event.getWhoClicked()).isAuthorized("essentials.hat.prevent-type." + event.getCursor().getType().name().toLowerCase())) { && ess.getUser(event.getWhoClicked()).isAuthorized("essentials.hat") && !ess.getUser(event.getWhoClicked()).isAuthorized("essentials.hat.prevent-type." + event.getCursor().getType().name().toLowerCase())) {
event.setCancelled(true); event.setCancelled(true);
final PlayerInventory inv = (PlayerInventory) clickedInventory; final PlayerInventory inv = (PlayerInventory) clickedInventory;
final ItemStack head = inv.getHelmet(); final ItemStack head = inv.getHelmet();
@ -788,24 +806,6 @@ public class EssentialsPlayerListener implements Listener {
user.updateActivityOnInteract(true); user.updateActivityOnInteract(true);
} }
private static boolean isEntityPickupEvent() {
try {
Class.forName("org.bukkit.event.entity.EntityPickupItemEvent");
return true;
} catch (ClassNotFoundException ignored) {
return false;
}
}
private static boolean isCommandSendEvent() {
try {
Class.forName("org.bukkit.event.player.PlayerCommandSendEvent");
return true;
} catch (ClassNotFoundException ignored) {
return false;
}
}
private final class PickupListenerPre1_12 implements Listener { private final class PickupListenerPre1_12 implements Listener {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerPickupItem(final org.bukkit.event.player.PlayerPickupItemEvent event) { public void onPlayerPickupItem(final org.bukkit.event.player.PlayerPickupItemEvent event) {
@ -833,30 +833,40 @@ public class EssentialsPlayerListener implements Listener {
public void onCommandSend(final PlayerCommandSendEvent event) { public void onCommandSend(final PlayerCommandSendEvent event) {
User user = ess.getUser(event.getPlayer()); User user = ess.getUser(event.getPlayer());
ArrayList<String> removedCmds = new ArrayList<>(event.getCommands()); Set<PluginCommand> checked = new HashSet<>();
Set<PluginCommand> toRemove = new HashSet<>();
event.getCommands().removeIf(str -> shouldHideFromUser(str, user)); event.getCommands().removeIf(label -> {
if (isEssentialsCommand(label)) {
PluginCommand command = ess.getServer().getPluginCommand(label);
if (!checked.contains(command)) {
checked.add(command);
if (!user.isAuthorized(command.getName().equals("r") ? "essentials.msg" : "essentials." + command.getName())) {
toRemove.add(command);
}
}
return toRemove.contains(command);
}
return false;
});
if (ess.getSettings().isDebug()) { if (ess.getSettings().isDebug()) {
removedCmds.removeAll(event.getCommands()); ess.getLogger().info("Removed commands: " + toRemove.toString());
ess.getLogger().info("Removed commands: " + removedCmds.toString());
} }
} }
/** /**
* Returns true if all of the following are true: * Returns true if all of the following are true:
* - The command is a plugin command * - The command is a plugin command
* - The plugin command is from Essentials * - The plugin command is from Essentials
* - There is no known alternative OR the alternative is overridden by Essentials * - There is no known alternative OR the alternative is overridden by Essentials
* - The user is not allowed to perform the given Essentials command
*/ */
private boolean shouldHideFromUser(String commandLabel, User user) { private boolean isEssentialsCommand(String label) {
PluginCommand command = ess.getServer().getPluginCommand(commandLabel); PluginCommand command = ess.getServer().getPluginCommand(label);
return command != null return command != null
&& command.getPlugin() == ess && command.getPlugin() == ess
&& (ess.getSettings().isCommandOverridden(commandLabel) || (ess.getAlternativeCommandsHandler().getAlternative(commandLabel) == null)) && (ess.getSettings().isCommandOverridden(label) || (ess.getAlternativeCommandsHandler().getAlternative(label) == null));
&& !user.isAuthorized(command.getName().equals("r") ? "essentials.msg" : "essentials." + command.getName());
} }
} }
} }