Compare commits

..

22 Commits

Author SHA1 Message Date
YouHaveTrouble 38d9d5115e add github actions 2021-03-15 15:08:23 +01:00
YouHaveTrouble 2fda6ac23e Merge remote-tracking branch 'origin/master' 2021-03-15 15:06:22 +01:00
YouHaveTrouble 6a4a27e7b3 fix legacy mode event registration 2021-03-15 15:01:17 +01:00
YouHaveTrouble 42bfaa2efb version bump and update depends 2021-03-15 15:00:46 +01:00
YouHaveTrouble adbf02a4c3 Create FUNDING.yml 2021-02-21 14:12:58 +01:00
YouHaveTrouble 94d5afdb47 version bump 2021-02-02 22:37:04 +01:00
YouHaveTrouble c943455392 remove all copies of completion 2021-02-02 22:29:49 +01:00
YouHaveTrouble e823aa91aa added optional usage of protocollib for command filter 2021-01-07 19:02:38 +01:00
YouHaveTrouble eb0f53f19d version bump 2020-12-24 20:11:19 +01:00
YouHaveTrouble 103a793a63 basic velocity support 2020-12-16 05:32:29 +01:00
YouHaveTrouble 2a93f8c636 default commands no longer check permission 2020-12-15 22:10:01 +01:00
YouHaveTrouble c135815ce3 improved code readability 2020-12-15 21:05:56 +01:00
YouHaveTrouble 9254c7fc7b tab completion now fails gracefully if command is not registered (cannot block completions that are not registered) 2020-12-06 14:47:56 +01:00
YouHaveTrouble b9db85278c Merge remote-tracking branch 'origin/master' 2020-11-25 19:23:34 +01:00
YouHaveTrouble 87e59e3f2b version bump 2020-11-25 19:23:11 +01:00
YouHaveTrouble 292cac7415 prevented saving duplicate command entries 2020-11-25 19:22:51 +01:00
YouHaveTrouble 7629b580ae Update issue templates 2020-11-18 13:14:04 +01:00
YouHaveTrouble 7101d3d713 Update readme.md 2020-11-18 12:25:19 +01:00
YouHaveTrouble 6487255d04 version bump 2020-11-17 17:12:59 +01:00
YouHaveTrouble c57a58eb41 made config more clear 2020-11-17 17:05:48 +01:00
YouHaveTrouble 8fac940359 added spigot subcommand blocking system 2020-11-17 03:06:19 +01:00
YouHaveTrouble fe0b8c416d update commands on add/remove 2020-11-02 15:42:29 +01:00
27 changed files with 574 additions and 82 deletions
+12
View File
@@ -0,0 +1,12 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: YouHaveTrouble
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
+28
View File
@@ -0,0 +1,28 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: YouHaveTrouble
---
**Describe the bug**
A clear and concise description of what the bug is.
**Expected behavior**
A clear and concise description of what you expected to happen.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.
+20
View File
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: YouHaveTrouble
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
+10
View File
@@ -0,0 +1,10 @@
---
name: Other issue
about: For other issues
title: ''
labels: ''
assignees: YouHaveTrouble
---
+36
View File
@@ -0,0 +1,36 @@
name: Build CommandWhitelist Jar
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Git repo
uses: actions/checkout@v1
- name: Restore Maven cache
uses: actions/cache@v1
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Maven
run: mvn package --file pom.xml
- name: Copy artifacts
uses: actions/upload-artifact@master
with:
name: CommandWhitelist
path: target/CommandWhitelist*.jar
+13 -3
View File
@@ -6,7 +6,7 @@
<groupId>eu.endermite</groupId> <groupId>eu.endermite</groupId>
<artifactId>CommandWhitelist</artifactId> <artifactId>CommandWhitelist</artifactId>
<version>1.4.0</version> <version>1.7.2</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>CommandWhitelist</name> <name>CommandWhitelist</name>
@@ -74,13 +74,17 @@
<id>papermc</id> <id>papermc</id>
<url>https://papermc.io/repo/repository/maven-public/</url> <url>https://papermc.io/repo/repository/maven-public/</url>
</repository> </repository>
<repository>
<id>velocity</id>
<url>https://repo.velocitypowered.com/snapshots/</url>
</repository>
</repositories> </repositories>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId> <artifactId>spigot-api</artifactId>
<version>1.16.3-R0.1-SNAPSHOT</version> <version>1.16.5-R0.1-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
@@ -95,10 +99,16 @@
<version>1.16-R0.4-SNAPSHOT</version> <version>1.16-R0.4-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>com.velocitypowered</groupId>
<artifactId>velocity-api</artifactId>
<version>1.1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency> <dependency>
<groupId>com.comphenix.protocol</groupId> <groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId> <artifactId>ProtocolLib</artifactId>
<version>4.5.0</version> <version>4.6.0</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
</dependencies> </dependencies>
+1
View File
@@ -8,6 +8,7 @@ precisely what commands players can see and use.
<li>Overwrites default "no such command" message with your branding <li>Overwrites default "no such command" message with your branding
<li>Blocks tab completion on spigot and bungeecord*</li> <li>Blocks tab completion on spigot and bungeecord*</li>
<li>Blocks command execution on spigot and bungeecord</li> <li>Blocks command execution on spigot and bungeecord</li>
<li>Blocks completion and execution of specific subcommands (spigot only)</li>
</ul> </ul>
\*This only works on Waterfall and its forks \*This only works on Waterfall and its forks
@@ -2,34 +2,65 @@ package eu.endermite.commandwhitelist.api;
import eu.endermite.commandwhitelist.bungee.CommandWhitelistBungee; import eu.endermite.commandwhitelist.bungee.CommandWhitelistBungee;
import eu.endermite.commandwhitelist.spigot.CommandWhitelist; import eu.endermite.commandwhitelist.spigot.CommandWhitelist;
import net.md_5.bungee.api.connection.ProxiedPlayer; import eu.endermite.commandwhitelist.velocity.CommandWhitelistVelocity;
import org.bukkit.entity.Player;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class CommandsList { public class CommandsList {
public static List<String> getCommands(Player player) { public static List<String> getCommands(org.bukkit.entity.Player player) {
List<String> commandList = new ArrayList<>(); List<String> commandList = new ArrayList<>();
for (Map.Entry<String, List<String>> s : CommandWhitelist.getConfigCache().getPermList().entrySet()) { for (Map.Entry<String, List<String>> s : CommandWhitelist.getConfigCache().getPermList().entrySet()) {
if (player.hasPermission("commandwhitelist.commands." + s.getKey())) { if (s.getKey().equalsIgnoreCase("default"))
commandList.addAll(s.getValue());
else if (player.hasPermission("commandwhitelist.commands." + s.getKey()))
commandList.addAll(s.getValue()); commandList.addAll(s.getValue());
}
} }
return commandList; return commandList;
} }
public static List<String> getCommands(ProxiedPlayer player) { public static List<String> getCommands(net.md_5.bungee.api.connection.ProxiedPlayer player) {
List<String> commandList = new ArrayList<>(); List<String> commandList = new ArrayList<>();
for (Map.Entry<String, List<String>> s : CommandWhitelistBungee.getConfigCache().getPermList().entrySet()) { for (Map.Entry<String, List<String>> s : CommandWhitelistBungee.getConfigCache().getPermList().entrySet()) {
if (player.hasPermission("commandwhitelist.commands." + s.getKey())) { if (s.getKey().equalsIgnoreCase("default"))
commandList.addAll(s.getValue());
else if (player.hasPermission("commandwhitelist.commands." + s.getKey()))
commandList.addAll(s.getValue()); commandList.addAll(s.getValue());
} }
return commandList;
}
public static List<String> getCommands(com.velocitypowered.api.proxy.Player player) {
List<String> commandList = new ArrayList<>();
for (Map.Entry<String, List<String>> s : CommandWhitelistVelocity.getConfigCache().getPermList().entrySet()) {
if (s.getKey().equalsIgnoreCase("default"))
commandList.addAll(s.getValue());
else if (player.hasPermission("commandwhitelist.commands." + s.getKey()))
commandList.addAll(s.getValue());
} }
return commandList; return commandList;
} }
public static List<String> getSuggestions(org.bukkit.entity.Player player) {
List<String> suggestionList = new ArrayList<>();
for (Map.Entry<String, List<String>> s : CommandWhitelist.getConfigCache().getPermSubList().entrySet()) {
if (player.hasPermission("commandwhitelist.subcommands." + s.getKey()))
continue;
suggestionList.addAll(s.getValue());
}
return suggestionList;
}
public static String getLastArgument(String cmd) {
String[] parts = cmd.split(" ");
if (parts.length <= 1)
return "";
String last = "";
for (String part : parts) {
last = part;
}
return last;
}
} }
@@ -24,7 +24,6 @@ public final class CommandWhitelistBungee extends Plugin {
@Override @Override
public void onEnable() { public void onEnable() {
plugin = this; plugin = this;
getLogger().info("Running on "+ ChatColor.DARK_AQUA+getProxy().getName()); getLogger().info("Running on "+ ChatColor.DARK_AQUA+getProxy().getName());
loadConfig(); loadConfig();
@@ -40,18 +39,15 @@ public final class CommandWhitelistBungee extends Plugin {
int pluginId = 8704; int pluginId = 8704;
new BungeeMetrics(this, pluginId); new BungeeMetrics(this, pluginId);
} }
public static CommandWhitelistBungee getPlugin() { public static CommandWhitelistBungee getPlugin() {
return plugin; return plugin;
} }
public static BungeeConfigCache getConfigCache() { public static BungeeConfigCache getConfigCache() {
return configCache; return configCache;
} }
public void loadConfig() { public void loadConfig() {
try { try {
if (!getDataFolder().exists()) { if (!getDataFolder().exists()) {
@@ -81,5 +77,4 @@ public final class CommandWhitelistBungee extends Plugin {
sender.sendMessage(ChatColor.translateAlternateColorCodes('&', CommandWhitelistBungee.getConfigCache().getPrefix() + CommandWhitelistBungee.getConfigCache().getConfigReloaded())); sender.sendMessage(ChatColor.translateAlternateColorCodes('&', CommandWhitelistBungee.getConfigCache().getPrefix() + CommandWhitelistBungee.getConfigCache().getConfigReloaded()));
}); });
} }
} }
@@ -9,7 +9,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class BungeeMainCommand extends Command implements TabExecutor { public class BungeeMainCommand extends Command implements TabExecutor {
public BungeeMainCommand(String name) { public BungeeMainCommand(String name) {
@@ -14,28 +14,20 @@ public class BungeeChatEventListener implements Listener {
@EventHandler @EventHandler
public void onChatEvent(net.md_5.bungee.api.event.ChatEvent event) { public void onChatEvent(net.md_5.bungee.api.event.ChatEvent event) {
if (event.isCancelled()) if (event.isCancelled())
return; return;
if (!(event.getSender() instanceof ProxiedPlayer)) if (!(event.getSender() instanceof ProxiedPlayer))
return; return;
if (!event.isProxyCommand()) if (!event.isProxyCommand())
return; return;
ProxiedPlayer player = (ProxiedPlayer) event.getSender(); ProxiedPlayer player = (ProxiedPlayer) event.getSender();
if (player.hasPermission("commandwhitelist.bypass"))
if (player.hasPermission("commandwhitelist.bypass")) {
return; return;
}
String command = event.getMessage().toLowerCase(); String command = event.getMessage().toLowerCase();
boolean found = false; boolean found = false;
for (Map.Entry<String, List<String>> s : CommandWhitelistBungee.getConfigCache().getPermList().entrySet()) { for (Map.Entry<String, List<String>> s : CommandWhitelistBungee.getConfigCache().getPermList().entrySet()) {
if (!player.hasPermission("commandwhitelist.commands." + s.getKey())) if (!player.hasPermission("commandwhitelist.commands." + s.getKey()))
continue; continue;
for (String comm : s.getValue()) { for (String comm : s.getValue()) {
comm = comm.toLowerCase(); comm = comm.toLowerCase();
if (command.equalsIgnoreCase("/" + comm)) { if (command.equalsIgnoreCase("/" + comm)) {
@@ -13,25 +13,17 @@ public class WaterfallDefineCommandsListener implements Listener {
@EventHandler @EventHandler
public void onProxyDefineCommandsEvent(io.github.waterfallmc.waterfall.event.ProxyDefineCommandsEvent event) { public void onProxyDefineCommandsEvent(io.github.waterfallmc.waterfall.event.ProxyDefineCommandsEvent event) {
if (event.getReceiver() instanceof ProxiedPlayer) { if (event.getReceiver() instanceof ProxiedPlayer) {
ProxiedPlayer player = (ProxiedPlayer) event.getReceiver(); ProxiedPlayer player = (ProxiedPlayer) event.getReceiver();
if (player.hasPermission("commandwhitelist.bypass"))
if (player.hasPermission("commandwhitelist.bypass")) {
return; return;
}
HashMap<String, Command> commandHashMap = new HashMap<>(); HashMap<String, Command> commandHashMap = new HashMap<>();
CommandsList.getCommands(player).forEach(cmdName -> CommandsList.getCommands(player).forEach(cmdName ->
CommandWhitelistBungee.getPlugin().getProxy().getPluginManager().getCommands() CommandWhitelistBungee.getPlugin().getProxy().getPluginManager().getCommands()
.stream() .stream()
.filter(commandEntry -> cmdName.equalsIgnoreCase(commandEntry.getValue().getName())) .filter(commandEntry -> cmdName.equalsIgnoreCase(commandEntry.getValue().getName()))
.forEach(commandEntry -> commandHashMap.put(commandEntry.getKey(), commandEntry.getValue()))); .forEach(commandEntry -> commandHashMap.put(commandEntry.getKey(), commandEntry.getValue())));
event.getCommands().values().removeIf((cmd) -> !commandHashMap.containsValue(cmd)); event.getCommands().values().removeIf((cmd) -> !commandHashMap.containsValue(cmd));
} }
} }
} }
@@ -2,14 +2,13 @@ package eu.endermite.commandwhitelist.spigot;
import eu.endermite.commandwhitelist.spigot.command.MainCommand; import eu.endermite.commandwhitelist.spigot.command.MainCommand;
import eu.endermite.commandwhitelist.spigot.config.ConfigCache; import eu.endermite.commandwhitelist.spigot.config.ConfigCache;
import eu.endermite.commandwhitelist.spigot.listeners.LegacyPlayerTabChatCompleteListener; import eu.endermite.commandwhitelist.spigot.listeners.*;
import eu.endermite.commandwhitelist.spigot.listeners.PlayerCommandPreProcessListener;
import eu.endermite.commandwhitelist.spigot.listeners.PlayerCommandSendListener;
import eu.endermite.commandwhitelist.spigot.metrics.BukkitMetrics; import eu.endermite.commandwhitelist.spigot.metrics.BukkitMetrics;
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.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
public class CommandWhitelist extends JavaPlugin { public class CommandWhitelist extends JavaPlugin {
@@ -27,12 +26,20 @@ public class CommandWhitelist extends JavaPlugin {
reloadPluginConfig(); reloadPluginConfig();
getServer().getPluginManager().registerEvents(new PlayerCommandPreProcessListener(), this); Plugin protocollib = getServer().getPluginManager().getPlugin("ProtocolLib");
if (!isLegacy) { if (!isLegacy) {
if (!getConfigCache().isUseProtocolLib() || protocollib == null || !protocollib.isEnabled()) {
getServer().getPluginManager().registerEvents(new PlayerCommandPreProcessListener(), this);
getServer().getPluginManager().registerEvents(new PlayerCommandSendListener(), this); getServer().getPluginManager().registerEvents(new PlayerCommandSendListener(), this);
} else {
PacketCommandSendListener.protocol(this);
getLogger().info(ChatColor.AQUA+"Using ProtocolLib for command filter!");
}
getServer().getPluginManager().registerEvents(new TabCompleteBlockerListener(), this);
} else { } else {
getLogger().info(ChatColor.AQUA+"Running in legacy mode..."); getLogger().info(ChatColor.AQUA+"Running in legacy mode...");
if (getServer().getPluginManager().getPlugin("ProtocolLib") != null) { if (protocollib != null) {
LegacyPlayerTabChatCompleteListener.protocol(this); LegacyPlayerTabChatCompleteListener.protocol(this);
} else { } else {
getLogger().info(ChatColor.YELLOW+"ProtocolLib is required for tab completion blocking!"); getLogger().info(ChatColor.YELLOW+"ProtocolLib is required for tab completion blocking!");
@@ -58,7 +58,6 @@ public class MainCommand implements TabExecutor {
} else { } else {
sender.sendMessage("/cw remove <group> <command>"); sender.sendMessage("/cw remove <group> <command>");
} }
} else { } else {
sender.sendMessage(ChatColor.translateAlternateColorCodes('&', CommandWhitelist.getConfigCache().getPrefix() + CommandWhitelist.getConfigCache().getNoSubCommand())); sender.sendMessage(ChatColor.translateAlternateColorCodes('&', CommandWhitelist.getConfigCache().getPrefix() + CommandWhitelist.getConfigCache().getNoSubCommand()));
} }
@@ -69,6 +68,7 @@ public class MainCommand implements TabExecutor {
} }
if (sender.hasPermission("commandwhitelist.admin")) { if (sender.hasPermission("commandwhitelist.admin")) {
sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&9/cw add <group> <command> &b- Add command to group")); sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&9/cw add <group> <command> &b- Add command to group"));
sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&9/cw remove <group> <command> &b- Remove command from a group"));
} }
} }
return true; return true;
@@ -1,7 +1,9 @@
package eu.endermite.commandwhitelist.spigot.config; package eu.endermite.commandwhitelist.spigot.config;
import eu.endermite.commandwhitelist.spigot.CommandWhitelist; import eu.endermite.commandwhitelist.spigot.CommandWhitelist;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -11,38 +13,57 @@ public class ConfigCache {
private FileConfiguration config; private FileConfiguration config;
private HashMap<String, List<String>> permList = new HashMap<>(); private HashMap<String, List<String>> permList = new HashMap<>();
private HashMap<String, List<String>> permSubList = new HashMap<>();
private final String prefix, commandDenied, noPermission, noSubCommand, configReloaded, whitelistedCommand, private final String prefix, commandDenied, noPermission, noSubCommand, configReloaded, whitelistedCommand,
removedWhitelistedCommand, noSuchGroup; removedWhitelistedCommand, noSuchGroup, subCommandDenied;
private final List<String> commandDeniedList; private final List<String> commandDeniedList;
private boolean useProtocolLib;
public ConfigCache(FileConfiguration config) { public ConfigCache(FileConfiguration config) {
this.config = config; this.config = config;
prefix = config.getString("messages.prefix"); prefix = config.getString("messages.prefix", "");
commandDenied = config.getString("messages.command-denied", null); commandDenied = config.getString("messages.command-denied", null);
commandDeniedList = config.getStringList("messages.command-denied"); commandDeniedList = config.getStringList("messages.command-denied");
noPermission = config.getString("messages.no-permission"); subCommandDenied = config.getString("messages.subcommand-denied", "You cannot use this subcommand");
noSubCommand = config.getString("messages.no-such-subcommand"); noPermission = config.getString("messages.no-permission", "&cYou don't have permission to do this.");
configReloaded = config.getString("messages.config-reloaded"); noSubCommand = config.getString("messages.no-such-subcommand", "&cNo subcommand by that name.");
configReloaded = config.getString("messages.config-reloaded", "&eConfiguration reloaded.");
whitelistedCommand = config.getString("messages.added-to-whitelist", "&eWhitelisted command &6%s &efor permission &6%s"); whitelistedCommand = config.getString("messages.added-to-whitelist", "&eWhitelisted command &6%s &efor permission &6%s");
removedWhitelistedCommand = config.getString("messages.removed-from-whitelist", "&eRemoved command &6%s &efrom permission &6%s"); removedWhitelistedCommand = config.getString("messages.removed-from-whitelist", "&eRemoved command &6%s &efrom permission &6%s");
noSuchGroup = config.getString("messages.group-doesnt-exist", "&cGroup %s doesn't exist"); noSuchGroup = config.getString("messages.group-doesnt-exist", "&cGroup %s doesn't exist");
useProtocolLib = config.getBoolean("use-protocollib-to-detect-commands", false);
Set<String> perms = config.getConfigurationSection("commands").getKeys(false); Set<String> perms = config.getConfigurationSection("commands").getKeys(false);
for (String s : perms) { for (String s : perms) {
this.permList.put(s, config.getStringList("commands."+s)); this.permList.put(s, config.getStringList("commands."+s));
} }
Set<String> subperms = config.getConfigurationSection("tabcompletions").getKeys(false);
for (String s : subperms) {
this.permSubList.put(s, config.getStringList("tabcompletions."+s));
}
} }
public HashMap<String, List<String>> getPermList() { public HashMap<String, List<String>> getPermList() {
return permList; return permList;
} }
public HashMap<String, List<String>> getPermSubList() {
return permSubList;
}
public boolean addCommand(String command, String group) { public boolean addCommand(String command, String group) {
try { try {
if (this.permList.get(group).contains(command)) {
return true;
}
this.permList.get(group).add(command); this.permList.get(group).add(command);
this.config.set("commands."+group, permList.get(group)); this.config.set("commands."+group, permList.get(group));
config.save(CommandWhitelist.getPlugin().getDataFolder()+"/config.yml"); config.save(CommandWhitelist.getPlugin().getDataFolder()+"/config.yml");
for (Player player : Bukkit.getOnlinePlayers()) {
player.updateCommands();
}
return true; return true;
} catch (Exception e) { } catch (Exception e) {
return false; return false;
@@ -53,6 +74,9 @@ public class ConfigCache {
this.permList.get(group).remove(command); this.permList.get(group).remove(command);
this.config.set("commands."+group, permList.get(group)); this.config.set("commands."+group, permList.get(group));
config.save(CommandWhitelist.getPlugin().getDataFolder()+"/config.yml"); config.save(CommandWhitelist.getPlugin().getDataFolder()+"/config.yml");
for (Player player : Bukkit.getOnlinePlayers()) {
player.updateCommands();
}
return true; return true;
} catch (Exception e) { } catch (Exception e) {
return false; return false;
@@ -75,4 +99,10 @@ public class ConfigCache {
public String getNoSuchGroup() { public String getNoSuchGroup() {
return noSuchGroup; return noSuchGroup;
} }
public String getSubCommandDenied() {
return subCommandDenied;
}
public boolean isUseProtocolLib() {
return useProtocolLib;
}
} }
@@ -25,12 +25,10 @@ public class LegacyPlayerTabChatCompleteListener {
protocolManager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.HIGHEST, PacketType.Play.Server.TAB_COMPLETE) { protocolManager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.HIGHEST, PacketType.Play.Server.TAB_COMPLETE) {
@Override @Override
public void onPacketSending(PacketEvent event) { public void onPacketSending(PacketEvent event) {
try { try {
Player player = event.getPlayer(); Player player = event.getPlayer();
if (player.hasPermission("commandwhitelist.bypass")) { if (player.hasPermission("commandwhitelist.bypass"))
return; return;
}
PacketContainer packet = event.getPacket(); PacketContainer packet = event.getPacket();
String[] message = packet.getSpecificModifier(String[].class).read(0); String[] message = packet.getSpecificModifier(String[].class).read(0);
List<String> commandList = CommandsList.getCommands(player); List<String> commandList = CommandsList.getCommands(player);
@@ -44,18 +42,14 @@ public class LegacyPlayerTabChatCompleteListener {
} }
} }
} }
String[] toWrite = new String[components]; String[] toWrite = new String[components];
int counter = 0; int counter = 0;
for (String cmd : finalList) { for (String cmd : finalList) {
toWrite[counter++] = cmd; toWrite[counter++] = cmd;
} }
packet.getSpecificModifier(String[].class).write(0, toWrite); packet.getSpecificModifier(String[].class).write(0, toWrite);
} catch (Exception ignored) {} } catch (Exception ignored) {}
} }
}); });
} }
} }
@@ -0,0 +1,68 @@
package eu.endermite.commandwhitelist.spigot.listeners;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import eu.endermite.commandwhitelist.api.CommandsList;
import eu.endermite.commandwhitelist.api.RandomStuff;
import eu.endermite.commandwhitelist.spigot.CommandWhitelist;
import eu.endermite.commandwhitelist.spigot.config.ConfigCache;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.List;
import java.util.Map;
public class PacketCommandSendListener {
public static void protocol(CommandWhitelist plugin) {
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
commandExecListener(protocolManager, plugin);
}
public static void commandExecListener(ProtocolManager protocolManager, Plugin plugin) {
protocolManager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.HIGHEST, PacketType.Play.Client.CHAT) {
@Override
public void onPacketReceiving(PacketEvent event) {
PacketContainer packet = event.getPacket();
String string = packet.getStrings().read(0);
if (!string.startsWith("/"))
return;
Player player = event.getPlayer();
if (player.hasPermission("commandwhitelist.bypass"))
return;
String cmd = string.replace("/", "");
String[] split = cmd.split("\\s+");
String command = split[0].toLowerCase();
for (Map.Entry<String, List<String>> s : CommandWhitelist.getConfigCache().getPermList().entrySet()) {
if (!player.hasPermission("commandwhitelist.commands." + s.getKey()))
continue;
for (String comm : s.getValue()) {
comm = comm.toLowerCase();
if (command.equalsIgnoreCase(comm) || command.startsWith(comm + " ")) {
List<String> bannedSubCommands = CommandsList.getSuggestions(player);
for (String bannedSubCommand : bannedSubCommands) {
if (cmd.startsWith(bannedSubCommand)) {
event.setCancelled(true);
ConfigCache config = CommandWhitelist.getConfigCache();
player.sendMessage(ChatColor.translateAlternateColorCodes('&', config.getPrefix() + RandomStuff.getMessage(config.getCommandDeniedList(), config.getSubCommandDenied())));
return;
}
}
return;
}
}
}
event.setCancelled(true);
ConfigCache config = CommandWhitelist.getConfigCache();
player.sendMessage(ChatColor.translateAlternateColorCodes('&', config.getPrefix() + RandomStuff.getMessage(config.getCommandDeniedList(), config.getCommandDenied())));
}
});
}
}
@@ -1,5 +1,6 @@
package eu.endermite.commandwhitelist.spigot.listeners; package eu.endermite.commandwhitelist.spigot.listeners;
import eu.endermite.commandwhitelist.api.CommandsList;
import eu.endermite.commandwhitelist.api.RandomStuff; import eu.endermite.commandwhitelist.api.RandomStuff;
import eu.endermite.commandwhitelist.spigot.CommandWhitelist; import eu.endermite.commandwhitelist.spigot.CommandWhitelist;
import eu.endermite.commandwhitelist.spigot.config.ConfigCache; import eu.endermite.commandwhitelist.spigot.config.ConfigCache;
@@ -8,37 +9,38 @@ import org.bukkit.entity.Player;
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 java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class PlayerCommandPreProcessListener implements Listener { public class PlayerCommandPreProcessListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
public void PlayerCommandSendEvent(org.bukkit.event.player.PlayerCommandPreprocessEvent event) { public void PlayerCommandSendEvent(org.bukkit.event.player.PlayerCommandPreprocessEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
if (player.hasPermission("commandwhitelist.bypass")) if (player.hasPermission("commandwhitelist.bypass"))
return; return;
String command = event.getMessage().toLowerCase(); String command = event.getMessage().toLowerCase();
for (Map.Entry<String, List<String>> s : CommandWhitelist.getConfigCache().getPermList().entrySet()) { for (Map.Entry<String, List<String>> s : CommandWhitelist.getConfigCache().getPermList().entrySet()) {
if (!player.hasPermission("commandwhitelist.commands." + s.getKey())) if (!player.hasPermission("commandwhitelist.commands." + s.getKey()))
continue; continue;
for (String comm : s.getValue()) { for (String comm : s.getValue()) {
comm = comm.toLowerCase(); comm = comm.toLowerCase();
if (command.equalsIgnoreCase("/" + comm)) if (command.equalsIgnoreCase("/" + comm) || command.startsWith("/" + comm + " ")) {
String rawCmd = event.getMessage();
List<String> bannedSubCommands = CommandsList.getSuggestions(player);
for (String bannedSubCommand : bannedSubCommands) {
if (rawCmd.startsWith("/"+bannedSubCommand)) {
event.setCancelled(true);
ConfigCache config = CommandWhitelist.getConfigCache();
player.sendMessage(ChatColor.translateAlternateColorCodes('&', config.getPrefix() + RandomStuff.getMessage(config.getCommandDeniedList(), config.getSubCommandDenied())));
return; return;
else if (command.startsWith("/" + comm + " ")) { }
}
return; return;
} }
} }
} }
event.setCancelled(true); event.setCancelled(true);
ConfigCache config = CommandWhitelist.getConfigCache(); ConfigCache config = CommandWhitelist.getConfigCache();
player.sendMessage(ChatColor.translateAlternateColorCodes('&', CommandWhitelist.getConfigCache().getPrefix() + RandomStuff.getMessage(config.getCommandDeniedList(), config.getCommandDenied()))); player.sendMessage(ChatColor.translateAlternateColorCodes('&', config.getPrefix() + RandomStuff.getMessage(config.getCommandDeniedList(), config.getCommandDenied())));
} }
} }
@@ -8,21 +8,12 @@ import org.bukkit.event.Listener;
import java.util.*; import java.util.*;
public class PlayerCommandSendListener implements Listener { public class PlayerCommandSendListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
public void PlayerCommandSendEvent(org.bukkit.event.player.PlayerCommandSendEvent event) { public void PlayerCommandSendEvent(org.bukkit.event.player.PlayerCommandSendEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
if (player.hasPermission("commandwhitelist.bypass"))
if (player.hasPermission("commandwhitelist.bypass")) {
return; return;
}
List<String> commandList = CommandsList.getCommands(player); List<String> commandList = CommandsList.getCommands(player);
event.getCommands().removeIf((cmd) -> !commandList.contains(cmd)); event.getCommands().removeIf((cmd) -> !commandList.contains(cmd));
} }
} }
@@ -0,0 +1,33 @@
package eu.endermite.commandwhitelist.spigot.listeners;
import eu.endermite.commandwhitelist.api.CommandsList;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import java.util.List;
public class TabCompleteBlockerListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onCommandTabComplete(org.bukkit.event.server.TabCompleteEvent event) {
if (!(event.getSender() instanceof Player))
return;
Player player = (Player) event.getSender();
String buffer = event.getBuffer();
String cmd = buffer.replace(CommandsList.getLastArgument(buffer), "");
List<String> blockedCommands = CommandsList.getSuggestions(player);
List<String> suggestions = event.getCompletions();
for (String s : blockedCommands) {
String slast = CommandsList.getLastArgument(s);
String scommand = s.replace(slast, "");
cmd = cmd.replace(CommandsList.getLastArgument(cmd), "");
if (cmd.startsWith("/" + scommand)) {
try {
while (suggestions.contains(slast))
suggestions.remove(slast);
} catch (Exception ignored) {}
}
}
event.setCompletions(suggestions);
}
}
@@ -0,0 +1,112 @@
package eu.endermite.commandwhitelist.velocity;
import com.moandjiezana.toml.Toml;
import com.velocitypowered.api.command.CommandMeta;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.command.CommandExecuteEvent;
import com.velocitypowered.api.event.command.PlayerAvailableCommandsEvent;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyServer;
import eu.endermite.commandwhitelist.api.CommandsList;
import eu.endermite.commandwhitelist.velocity.command.VelocityMainCommand;
import eu.endermite.commandwhitelist.velocity.config.VelocityConfigCache;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.text.Component;
import org.slf4j.Logger;
import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
public class CommandWhitelistVelocity {
private static CommandWhitelistVelocity plugin;
private static ProxyServer server;
private static VelocityConfigCache configCache;
private static Path folder;
@Inject
public CommandWhitelistVelocity(ProxyServer server, Logger logger, @DataDirectory final Path folder) {
CommandWhitelistVelocity.server = server;
CommandWhitelistVelocity.folder = folder;
CommandWhitelistVelocity.plugin = this;
}
private static Toml loadConfig(Path path) {
File folder = path.toFile();
File file = new File(folder, "config.toml");
if (!file.getParentFile().exists())
file.getParentFile().mkdirs();
if (!file.exists()) {
try (InputStream input = CommandWhitelistVelocity.class.getResourceAsStream("/" + file.getName())) {
if (input != null) {
Files.copy(input, file.toPath());
} else {
file.createNewFile();
}
} catch (IOException exception) {
exception.printStackTrace();
return null;
}
}
return new Toml().read(file);
}
private static void reloadConfig() {
configCache = new VelocityConfigCache(loadConfig(folder));
}
public static void reloadConfig(CommandSource source) {
server.getScheduler().buildTask(plugin, () -> {
reloadConfig();
source.sendMessage(Identity.nil(), Component.text(getConfigCache().getConfigReloaded()));
}).schedule();
}
@Subscribe
public void onProxyInitialization(ProxyInitializeEvent event) {
reloadConfig();
CommandMeta commandMeta = server.getCommandManager().metaBuilder("vcw").build();
server.getCommandManager().register(commandMeta, new VelocityMainCommand());
}
@Subscribe
public void onUserCommandSendEvent(PlayerAvailableCommandsEvent event) {
if (event.getPlayer().hasPermission("commandwhitelist.bypass"))
return;
List<String> allowedCommands = CommandsList.getCommands(event.getPlayer());
event.getRootNode().getChildren().removeIf((commandNode) ->
server.getCommandManager().hasCommand(commandNode.getName())
&& !allowedCommands.contains(commandNode.getName())
);
}
@Subscribe
public void onUserCommandExecuteEvent(com.velocitypowered.api.event.command.CommandExecuteEvent event) {
if (!(event.getCommandSource() instanceof Player))
return;
Player player = (Player) event.getCommandSource();
if (player.hasPermission("commandwhitelist.bypass"))
return;
List<String> allowedCommands = CommandsList.getCommands(player);
String command = event.getCommand().split(" ")[0];
if (server.getCommandManager().hasCommand(command)
&& !allowedCommands.contains(command))
event.setResult(CommandExecuteEvent.CommandResult.forwardToServer());
}
public static VelocityConfigCache getConfigCache() {
return configCache;
}
}
@@ -0,0 +1,48 @@
package eu.endermite.commandwhitelist.velocity.command;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.command.SimpleCommand;
import eu.endermite.commandwhitelist.velocity.CommandWhitelistVelocity;
import net.kyori.adventure.text.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
public class VelocityMainCommand implements SimpleCommand {
@Override
public void execute(final Invocation invocation) {
CommandSource source = invocation.source();
String[] args = invocation.arguments();
if (args.length > 0) {
if (args.length == 1 && args[0].equalsIgnoreCase("reload")) {
if (source.hasPermission("commandwhitelist.reload")) {
CommandWhitelistVelocity.reloadConfig(source);
} else {
source.sendMessage(Component.text(CommandWhitelistVelocity.getConfigCache().getNoPermission()));
}
}
} else {
source.sendMessage(Component.text("&bCommand Whitelist by YouHaveTrouble".replaceAll("&", "§")));
if (source.hasPermission("commandwhitelist.reload")) {
source.sendMessage(Component.text("&9/vcw reload &b- Reload velocity plugin configuration".replaceAll("&", "§")));
}
}
}
@Override
public CompletableFuture<List<String>> suggestAsync(Invocation invocation) {
CommandSource source = invocation.source();
String[] args = invocation.arguments();
return CompletableFuture.supplyAsync(() -> {
List<String> suggestions = new ArrayList<>();
if (args.length == 1) {
if (source.hasPermission("commandwhitelist.reload") && "reload".startsWith(args[0]))
suggestions.add("reload");
}
return suggestions;
});
}
}
@@ -0,0 +1,38 @@
package eu.endermite.commandwhitelist.velocity.config;
import com.moandjiezana.toml.Toml;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class VelocityConfigCache {
private HashMap<String, List<String>> permList = new HashMap<>();
private final String noPermission, noSubCommand, configReloaded;
public VelocityConfigCache(Toml config) {
Toml messages = config.getTable("messages");
noPermission = messages.getString("no-permission", "&cYou don't have permission to do this.");
noSubCommand = messages.getString("no-such-subcommand", "&cNo subcommand by that name.");
configReloaded = messages.getString("config-reloaded", "&eConfiguration reloaded.");
Toml groups = config.getTable("commands");
for (Map.Entry<String, Object> set : groups.entrySet()) {
this.permList.put(set.getKey(), (List<String>) set.getValue());
}
}
public HashMap<String, List<String>> getPermList() {
return permList;
}
public String getNoPermission() {
return noPermission.replaceAll("&", "§");
}
public String getNoSubCommand() {return noSubCommand.replaceAll("&", "§");}
public String getConfigReloaded() {return configReloaded.replaceAll("&", "§");}
}
+1 -3
View File
@@ -13,9 +13,7 @@ commands:
# Permissions that control what commands players can use # Permissions that control what commands players can use
# you can add unlimited amount of whitelists # you can add unlimited amount of whitelists
# commandwhitelist.commands.default # this will be automatically given to players by default
# this will NOT be automatically given to players by default!
# you have to give this permission to default droup by yourself as there is no automatic way to do it for a plugin
default: default:
- glist - glist
- server - server
+24
View File
@@ -0,0 +1,24 @@
# This is velocity version of the config.
[messages]
prefix="CommandWhitelist > "
command-denied="No such command."
subcommand-denied="You cannot use this subcommand"
no-permission="&cYou don't have permission to do this."
no-such-subcommand="&cNo subcommand by that name."
config-reloaded="&eConfiguration reloaded."
added-to-whitelist="&eWhitelisted command &6%s &efor permission &6%s"
removed-from-whitelist="&eRemoved command &6%s &efrom permission &6%s"
group-doesnt-exist="&cGroup doesn't exist or error occured"
# Permissions that control what commands players can use
# you can add unlimited amount of whitelists
[commands]
# this will be automatically given to players by default
default= [
"velocity",
"server",
]
# commandwhitelist.commands.example
example= [
"example"
]
+13 -1
View File
@@ -1,6 +1,7 @@
messages: messages:
prefix: "CommandWhitelist > " prefix: "CommandWhitelist > "
command-denied: "No such command." command-denied: "No such command."
subcommand-denied: "You cannot use this subcommand"
no-permission: "&cYou don't have permission to do this." no-permission: "&cYou don't have permission to do this."
no-such-subcommand: "&cNo subcommand by that name." no-such-subcommand: "&cNo subcommand by that name."
config-reloaded: "&eConfiguration reloaded." config-reloaded: "&eConfiguration reloaded."
@@ -8,11 +9,15 @@ messages:
removed-from-whitelist: "&eRemoved command &6%s &efrom permission &6%s" removed-from-whitelist: "&eRemoved command &6%s &efrom permission &6%s"
group-doesnt-exist: "&cGroup doesn't exist or error occured" group-doesnt-exist: "&cGroup doesn't exist or error occured"
# To cover the 1% of plugins that don't register their commands and/or aliases properly.
# Do not enable if you don't have issues with aliased commands.
# This requires server restart to take effect.
use-protocollib-to-detect-commands: false
commands: commands:
# Permissions that control what commands players can use # Permissions that control what commands players can use
# you can add unlimited amount of whitelists # you can add unlimited amount of whitelists
# commandwhitelist.commands.default
# this will be automatically given to players by default # this will be automatically given to players by default
default: default:
- help - help
@@ -31,3 +36,10 @@ commands:
# commandwhitelist.commands.example # commandwhitelist.commands.example
example: example:
- example - example
tabcompletions:
# This one is working as a blacklist. Player will not be able
# to see/use listed subcommands unless they have specified permission
# commandwhitelist.subcommands.example
example:
- help about
+9
View File
@@ -0,0 +1,9 @@
{
"id":"commandwhitelist",
"name":"CommandWhitelist",
"version":"${project.version}",
"description":"Control what commands players can use",
"authors":["YouHaveTrouble"],
"dependencies":[],
"main":"eu.endermite.commandwhitelist.velocity.CommandWhitelistVelocity"
}