mirror of
https://github.com/RayzsYT/ProAntiTab.git
synced 2026-11-09 02:45:30 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b53678764a | ||
|
|
1f7743d089 | ||
|
|
a60b6896f7 | ||
|
|
34c33df136 | ||
|
|
ef63674b0c | ||
|
|
130af1547d | ||
|
|
cdb17c1ea8 | ||
|
|
8f4f4b6438 | ||
|
|
3a0fc6e579 | ||
|
|
e0747a5101 | ||
|
|
5741dab763 | ||
|
|
5d7a8bb4c5 | ||
|
|
786b2fa560 | ||
|
|
5cf51052d2 | ||
|
|
22eaecb17f | ||
|
|
816354bb92 | ||
|
|
2fc6d96bd9 | ||
|
|
3f472b0bf5 | ||
|
|
41417893be | ||
|
|
64a7b80ec5 | ||
|
|
65f136f2b8 | ||
|
|
618bee5e9b |
No files matched your search
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>de.rayzs.pat</groupId>
|
||||
<artifactId>ProAntiTab</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<version>2.5.1</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
|
||||
@@ -335,8 +335,11 @@ public class Storage {
|
||||
|
||||
public static final AllowGroupOverrulingSection ALLOW_GROUP_OVERRULING = new AllowGroupOverrulingSection();
|
||||
public static final AutoLowercaseCommandsSection AUTO_LOWERCASE_COMMANDS = new AutoLowercaseCommandsSection();
|
||||
public static final TurnBlacklistToWhitelistSection TURN_BLACKLIST_TO_WHITELIST = new TurnBlacklistToWhitelistSection();
|
||||
public static final BlockNamespaceCommandsSection BLOCK_NAMESPACE_COMMANDS = new BlockNamespaceCommandsSection();
|
||||
public static final HandleThroughProxySection HANDLE_THROUGH_PROXY = new HandleThroughProxySection();
|
||||
public static final HidePluginChannelsSection HIDE_PLUGIN_CHANNELS = new HidePluginChannelsSection();
|
||||
public static final TabCompletionForNotExistingCommandsSection TAB_COMPLETION_FOR_NOT_EXISTING_COMMANDS = new TabCompletionForNotExistingCommandsSection();
|
||||
public static final InjectionFailedSection INJECTION_FAILED = new InjectionFailedSection();
|
||||
public static final PatchExploitSection PATCH_EXPLOITS = new PatchExploitSection();
|
||||
public static final CustomBrandSection CUSTOM_BRAND = new CustomBrandSection();
|
||||
@@ -348,7 +351,6 @@ public class Storage {
|
||||
public static final ForwardLuckPermsChangesSection FORWARD_LUCK_PERMS_CHANGES_SECTION = new ForwardLuckPermsChangesSection();
|
||||
public static final CustomProtocolPingSection CUSTOM_PROTOCOL_PING = new CustomProtocolPingSection();
|
||||
public static final CustomUnknownCommandSection CUSTOM_UNKNOWN_COMMAND = new CustomUnknownCommandSection();
|
||||
public static final TurnBlacklistToWhitelistSection TURN_BLACKLIST_TO_WHITELIST = new TurnBlacklistToWhitelistSection();
|
||||
public static final BaseCommandCaseSensitiveSection BASE_COMMAND_CASE_SENSITIVE = new BaseCommandCaseSensitiveSection();
|
||||
public static final UpdateGroupsPerWorldSection UPDATE_GROUPS_PER_WORLD = new UpdateGroupsPerWorldSection();
|
||||
public static final UpdateGroupsPerServerSection UPDATE_GROUPS_PER_SERVER = new UpdateGroupsPerServerSection();
|
||||
|
||||
+9
-1
@@ -1,6 +1,7 @@
|
||||
package de.rayzs.pat.api.storage.config.settings;
|
||||
|
||||
import de.rayzs.pat.api.storage.storages.ConfigStorage;
|
||||
import de.rayzs.pat.plugin.logger.Logger;
|
||||
import de.rayzs.pat.utils.configuration.helper.*;
|
||||
import de.rayzs.pat.api.storage.Storage;
|
||||
import java.util.Collections;
|
||||
@@ -18,8 +19,15 @@ public class CustomUnknownCommandSection extends ConfigStorage {
|
||||
public void load() {
|
||||
super.load();
|
||||
|
||||
if(Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) return;
|
||||
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) return;
|
||||
|
||||
|
||||
ENABLED = new ConfigSectionHelper<Boolean>(this, "enabled", true).getOrSet();
|
||||
MESSAGE = new MultipleMessagesHelper(this, "message", Collections.singletonList("&cThis command does not exist!"));
|
||||
|
||||
|
||||
if (ENABLED && Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED) {
|
||||
Logger.warning("It's not recommended to use the 'custom-unknown-command' feature when you are already using ProAntiTab in WHITELIST mode! Since in this mode, all commands except the once you specifically allow, are blocked anyway. So instead, change the 'blocked' message to your desired message. It has the same effect.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package de.rayzs.pat.api.storage.config.settings;
|
||||
|
||||
import de.rayzs.pat.api.storage.storages.ConfigStorage;
|
||||
import de.rayzs.pat.utils.configuration.helper.ConfigSectionHelper;
|
||||
import de.rayzs.pat.utils.configuration.helper.MultipleMessagesHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class HidePluginChannelsSection extends ConfigStorage {
|
||||
|
||||
public boolean ENABLED;
|
||||
public MultipleMessagesHelper WHITELISTED_CHANNELS;
|
||||
|
||||
private final HashSet<String> REGISTER_CHANNELS = new HashSet<>(
|
||||
Arrays.asList("register", "unregister", "minecraft:register", "minecraft:unregister")
|
||||
);
|
||||
|
||||
public HidePluginChannelsSection() {
|
||||
super("plugin-channels-hider");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
super.load();
|
||||
ENABLED = new ConfigSectionHelper<Boolean>(this, "enabled", false).getOrSet();
|
||||
WHITELISTED_CHANNELS = new MultipleMessagesHelper(this, "whitelisted-channels", Arrays.asList(
|
||||
"minecraft:brand",
|
||||
"bungeecord:main",
|
||||
"velocity:main"
|
||||
));
|
||||
}
|
||||
|
||||
public boolean isRegisterChannel(final String channelId) {
|
||||
return REGISTER_CHANNELS.contains(channelId);
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package de.rayzs.pat.api.storage.config.settings;
|
||||
|
||||
import de.rayzs.pat.api.storage.storages.ConfigStorage;
|
||||
import de.rayzs.pat.utils.Reflection;
|
||||
import de.rayzs.pat.utils.configuration.helper.ConfigSectionHelper;
|
||||
|
||||
public class TabCompletionForNotExistingCommandsSection extends ConfigStorage {
|
||||
|
||||
public boolean ENABLED;
|
||||
|
||||
public TabCompletionForNotExistingCommandsSection() {
|
||||
super("tab-completion-for-not-existing-commands");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
super.load();
|
||||
if (!Reflection.isProxyServer()) return;
|
||||
|
||||
ENABLED = new ConfigSectionHelper<Boolean>(this, null, false).getOrSet();
|
||||
}
|
||||
}
|
||||
@@ -45,9 +45,9 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class BukkitLoader extends JavaPlugin implements PluginLoader {
|
||||
|
||||
private static List<String> commands = new ArrayList<>(),
|
||||
allowedCommands = new ArrayList<>(),
|
||||
disallowedCommands = new ArrayList<>();
|
||||
private static List<String> allCommands = new ArrayList<>(),
|
||||
allowedCommands = new ArrayList<>(),
|
||||
disallowedCommands = new ArrayList<>();
|
||||
|
||||
private static Plugin plugin;
|
||||
private static java.util.logging.Logger logger;
|
||||
@@ -55,6 +55,7 @@ public class BukkitLoader extends JavaPlugin implements PluginLoader {
|
||||
private final CommandsCache commandsCache = new CommandsCache();
|
||||
private final List<String> offlinePlayerNames = new ArrayList<>();
|
||||
|
||||
private HashSet<String> registeredCommands = new HashSet<>();
|
||||
private Map<String, Command> commandsMap = null;
|
||||
|
||||
private BukkitAntiTabListener bukkitAntiTabListener = null;
|
||||
@@ -235,9 +236,7 @@ public class BukkitLoader extends JavaPlugin implements PluginLoader {
|
||||
if (commandsMap == null)
|
||||
return false;
|
||||
|
||||
loadAllCommands();
|
||||
|
||||
return getAllCommands().contains(command);
|
||||
return registeredCommands.contains(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -355,12 +354,10 @@ public class BukkitLoader extends JavaPlugin implements PluginLoader {
|
||||
}
|
||||
|
||||
public static List<String> getAllCommands() {
|
||||
return new ArrayList<>(commands);
|
||||
return allCommands;
|
||||
}
|
||||
|
||||
public static List<String> getAllowedCommands() {
|
||||
return new ArrayList<>(allowedCommands);
|
||||
}
|
||||
public static List<String> getAllowedCommands() { return allowedCommands; }
|
||||
|
||||
public static List<String> getDisallowedCommands() {
|
||||
return disallowedCommands;
|
||||
@@ -442,50 +439,47 @@ public class BukkitLoader extends JavaPlugin implements PluginLoader {
|
||||
}
|
||||
|
||||
private void loadAllCommands() {
|
||||
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) return;
|
||||
|
||||
if (lastCommandsLoad != -1 && System.currentTimeMillis() - lastCommandsLoad < 1000)
|
||||
return;
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
final HashSet<String> tmpCommands = new HashSet<>(Bukkit.getHelpMap().getHelpTopics().stream()
|
||||
.map(topic -> {
|
||||
String name = topic.getName();
|
||||
|
||||
if (commandsMap == null) {
|
||||
result.addAll(
|
||||
Bukkit.getHelpMap().getHelpTopics().stream()
|
||||
.map(topic -> {
|
||||
String name = topic.getName();
|
||||
if (name.startsWith("/"))
|
||||
name = name.substring(1);
|
||||
|
||||
if (name.startsWith("/"))
|
||||
name = name.substring(1);
|
||||
|
||||
return name;
|
||||
}).toList()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
return name;
|
||||
}).toList());
|
||||
|
||||
commandsMap.entrySet().forEach(entry -> {
|
||||
String key = entry.getKey();
|
||||
Command command = entry.getValue();
|
||||
final String key = entry.getKey();
|
||||
final Command command = entry.getValue();
|
||||
|
||||
result.add(key);
|
||||
tmpCommands.add(key);
|
||||
|
||||
if (!command.getAliases().isEmpty()) {
|
||||
result.addAll(command.getAliases());
|
||||
tmpCommands.addAll(command.getAliases());
|
||||
}
|
||||
});
|
||||
|
||||
boolean turn = Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED;
|
||||
List<String> allowedCommands = new ArrayList<>(result).stream().filter(command -> {
|
||||
boolean contains = Storage.Blacklist.getBlacklist().getCommands().contains(command);
|
||||
final boolean turn = Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED;
|
||||
final List<String> tmpAllowedCommands = tmpCommands.stream().filter(command -> {
|
||||
final boolean contains = Storage.Blacklist.getBlacklist().getCommands().contains(command);
|
||||
return turn == contains;
|
||||
}).toList();
|
||||
|
||||
final List<String> tmpDisallowedCommands = tmpCommands.stream().filter(command ->
|
||||
!allowedCommands.contains(command)
|
||||
).toList();
|
||||
|
||||
lastCommandsLoad = System.currentTimeMillis();
|
||||
|
||||
BukkitLoader.commands = result;
|
||||
BukkitLoader.allowedCommands = allowedCommands;
|
||||
BukkitLoader.disallowedCommands = commands.stream().filter(command -> !allowedCommands.contains(command)).toList();
|
||||
registeredCommands = tmpCommands;
|
||||
allowedCommands = tmpAllowedCommands;
|
||||
disallowedCommands = tmpDisallowedCommands;
|
||||
}
|
||||
|
||||
public static Plugin getPlugin() {
|
||||
|
||||
@@ -42,7 +42,7 @@ import java.util.*;
|
||||
|
||||
@Plugin(name = "ProAntiTab",
|
||||
id = "proantitab",
|
||||
version = "2.4.3",
|
||||
version = "2.5.1",
|
||||
authors = "Rayzs_YT",
|
||||
description = "Hides more than just your plugins.",
|
||||
url = "https://www.rayzs.de/products/proantitab/page",
|
||||
|
||||
@@ -24,16 +24,17 @@ public class BukkitAntiTabListener implements Listener {
|
||||
|
||||
@EventHandler (priority = EventPriority.LOWEST)
|
||||
public void onPlayerCommandSend(PlayerCommandSendEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
final CommandSender sender = CommandSender.from(player);
|
||||
final UUID uuid = player.getUniqueId();
|
||||
final boolean isOperator = player.isOp();
|
||||
|
||||
|
||||
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
final CommandSender sender = CommandSender.from(player);
|
||||
final UUID uuid = player.getUniqueId();
|
||||
final boolean isOperator = player.isOp();
|
||||
|
||||
if (player.isOp()) {
|
||||
if (!knownOperators.contains(uuid)) {
|
||||
knownOperators.add(uuid);
|
||||
|
||||
@@ -40,14 +40,8 @@ public class BukkitBlockCommandListener implements Listener {
|
||||
if (PermissionUtil.hasBypassPermission(sender, isOperator))
|
||||
return;
|
||||
|
||||
/* Removed since not necessary and only takes up unnecessary performance.
|
||||
|
||||
if (Storage.getLoader().doesCommandExist(command))
|
||||
return;
|
||||
*/
|
||||
|
||||
if (Bukkit.getHelpMap().getHelpTopic(rawCommand) != null)
|
||||
return;
|
||||
|
||||
event.setCancelled(true);
|
||||
MessageTranslator.send(player, Storage.ConfigSections.Settings.CUSTOM_UNKNOWN_COMMAND.MESSAGE, "%command%", command, "%world%", world.getName());
|
||||
|
||||
+18
-1
@@ -3,9 +3,11 @@ package de.rayzs.pat.plugin.listeners.velocity;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.command.CommandExecuteEvent;
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import de.rayzs.pat.plugin.logger.Logger;
|
||||
import de.rayzs.pat.plugin.system.communication.Communicator;
|
||||
import de.rayzs.pat.api.event.events.ExecuteCommandEvent;
|
||||
import de.rayzs.pat.plugin.system.subargument.SubArgument;
|
||||
import de.rayzs.pat.plugin.system.subargument.argument.Arguments;
|
||||
import de.rayzs.pat.utils.group.Group;
|
||||
import de.rayzs.pat.utils.group.GroupManager;
|
||||
import de.rayzs.pat.utils.message.MessageTranslator;
|
||||
@@ -139,7 +141,6 @@ public class VelocityBlockCommandListener {
|
||||
|
||||
|
||||
if (!allowed) {
|
||||
|
||||
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(
|
||||
sender,
|
||||
event.getCommand(),
|
||||
@@ -190,6 +191,22 @@ public class VelocityBlockCommandListener {
|
||||
);
|
||||
|
||||
if (executeCommandEvent.isBlocked()) {
|
||||
|
||||
/*
|
||||
if (event.getCommand().toLowerCase().contains("discord")) {
|
||||
Logger.info("Blocked for " + player.getUsername() + " (" + command + " -> " + event.getCommand() + ")");
|
||||
Logger.info("Groups: " + (groups.isEmpty() ? "None" : String.join(", ", groups.stream().map(Group::getGroupName).toList())));
|
||||
Logger.info("Server: " + serverName + " (" + sender.getServerName() + ")");
|
||||
Arguments argument = SubArgument.get().getPlayerArgument(sender);
|
||||
|
||||
if (argument != null) {
|
||||
Logger.info("Chat Arguments: " + String.join(", ", argument.CHAT_ARGUMENTS.getAllInputs()));
|
||||
Logger.info("Tab Arguments: " + String.join(", ", argument.TAB_ARGUMENTS.getAllInputs()));
|
||||
} else Logger.info("Arguments: /");
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
event.setResult(CommandExecuteEvent.CommandResult.denied());
|
||||
|
||||
MessageTranslator.send(
|
||||
|
||||
@@ -5,6 +5,10 @@ import de.rayzs.pat.plugin.packetanalyzer.bukkit.handlers.LegacyPacketHandler;
|
||||
import de.rayzs.pat.plugin.packetanalyzer.bukkit.handlers.ModernCommandsNodeHandler;
|
||||
import de.rayzs.pat.plugin.packetanalyzer.bukkit.handlers.ModernPacketHandler;
|
||||
import de.rayzs.pat.utils.permission.PermissionUtil;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import de.rayzs.pat.api.storage.Storage;
|
||||
import de.rayzs.pat.utils.ExpireCache;
|
||||
@@ -16,6 +20,7 @@ import org.bukkit.entity.Player;
|
||||
import io.netty.channel.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class BukkitPacketAnalyzer {
|
||||
|
||||
@@ -49,7 +54,7 @@ public class BukkitPacketAnalyzer {
|
||||
}
|
||||
|
||||
public static boolean inject(Player player) {
|
||||
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED)
|
||||
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED && !Storage.ConfigSections.Settings.HIDE_PLUGIN_CHANNELS.ENABLED)
|
||||
return true;
|
||||
|
||||
try {
|
||||
@@ -81,6 +86,11 @@ public class BukkitPacketAnalyzer {
|
||||
return success;
|
||||
|
||||
} catch (NoSuchFieldException noSuchFieldException) {
|
||||
|
||||
if (!Storage.ConfigSections.Settings.INJECTION_FAILED.ENABLED) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Logger.warning("Failed to inject into " + player.getName() + " and kicked the player as result, to avoid any security risks.");
|
||||
Logger.warning("You can read more about it here: https://www.rayzs.de/products/proantitab/pkafi");
|
||||
Logger.warning("Error details: " + noSuchFieldException.getMessage());
|
||||
@@ -110,7 +120,7 @@ public class BukkitPacketAnalyzer {
|
||||
}
|
||||
|
||||
public static void uninject(Channel channel) {
|
||||
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED)
|
||||
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED && !Storage.ConfigSections.Settings.HIDE_PLUGIN_CHANNELS.ENABLED)
|
||||
return;
|
||||
|
||||
if (channel != null) {
|
||||
@@ -151,13 +161,30 @@ public class BukkitPacketAnalyzer {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext channel, Object packetObj) {
|
||||
try {
|
||||
if (packetObj.getClass() == null || Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
|
||||
if (packetObj.getClass() == null) {
|
||||
super.channelRead(channel, packetObj);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String packetName = packetObj.getClass().getSimpleName();
|
||||
|
||||
if (Storage.ConfigSections.Settings.HIDE_PLUGIN_CHANNELS.ENABLED && packetName.equalsIgnoreCase("ServerboundCustomPayloadPacket")) {
|
||||
final Object newPacketObj = handlePluginChannelPacket(packetObj);
|
||||
|
||||
if (newPacketObj != null)
|
||||
super.channelRead(channel, newPacketObj);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
|
||||
super.channelRead(channel, packetObj);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!packetName.equals("PacketPlayInTabComplete") && !packetName.equals("ServerboundCommandSuggestionPacket")) {
|
||||
super.channelRead(channel, packetObj);
|
||||
return;
|
||||
@@ -177,13 +204,30 @@ public class BukkitPacketAnalyzer {
|
||||
@Override
|
||||
public void write(ChannelHandlerContext channel, Object packetObj, ChannelPromise promise) {
|
||||
try {
|
||||
|
||||
if(packetObj.getClass() == null || Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
|
||||
if(packetObj.getClass() == null) {
|
||||
super.write(channel, packetObj, promise);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final String packetName = packetObj.getClass().getSimpleName();
|
||||
|
||||
if (Storage.ConfigSections.Settings.HIDE_PLUGIN_CHANNELS.ENABLED && packetName.equalsIgnoreCase("ClientboundCustomPayloadPacket")) {
|
||||
final Object newPacketObj = handlePluginChannelPacket(packetObj);
|
||||
|
||||
if (newPacketObj != null)
|
||||
super.write(channel, newPacketObj, promise);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
|
||||
super.write(channel, packetObj, promise);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final boolean isCommandsPacket = packetName.equals("ClientboundCommandsPacket");
|
||||
final boolean isTabCompletePacket = packetName.equals("PacketPlayOutTabComplete") || packetName.equals("ClientboundCommandSuggestionsPacket");
|
||||
|
||||
@@ -234,5 +278,75 @@ public class BukkitPacketAnalyzer {
|
||||
|
||||
return this.operatorStatus;
|
||||
}
|
||||
|
||||
|
||||
private Object handlePluginChannelPacket(Object packet) throws NoSuchFieldException, IllegalAccessException {
|
||||
final Field payloadField = packet.getClass().getDeclaredField("payload");
|
||||
payloadField.setAccessible(true);
|
||||
|
||||
final Object payloadObj = payloadField.get(packet);
|
||||
Field channelField;
|
||||
|
||||
try {
|
||||
channelField = payloadObj.getClass().getDeclaredField("id");
|
||||
} catch (NoSuchFieldException noSuchFieldException) {
|
||||
return packet;
|
||||
}
|
||||
|
||||
channelField.setAccessible(true);
|
||||
|
||||
final Object channelIdObj = channelField.get(payloadObj);
|
||||
final String channelId = channelIdObj.toString();
|
||||
channelField.setAccessible(false);
|
||||
|
||||
|
||||
if (!Storage.ConfigSections.Settings.HIDE_PLUGIN_CHANNELS.isRegisterChannel(channelId)) {
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
||||
final Field dataField = payloadObj.getClass().getDeclaredField("data");
|
||||
dataField.setAccessible(true);
|
||||
|
||||
final byte[] data = (byte[]) dataField.get(payloadObj);
|
||||
dataField.setAccessible(true);
|
||||
|
||||
final String dataStr = new String(data, StandardCharsets.UTF_8);
|
||||
final String[] channels = dataStr.split("\u0000");
|
||||
|
||||
final List<String> filteredChannels = new ArrayList<>(Arrays.asList(channels));
|
||||
final AtomicBoolean changedAnything = new AtomicBoolean(false);
|
||||
|
||||
filteredChannels.removeIf(channel -> {
|
||||
if (!Storage.ConfigSections.Settings.HIDE_PLUGIN_CHANNELS.WHITELISTED_CHANNELS.getLines().contains(channel)) {
|
||||
changedAnything.set(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (!changedAnything.get()) {
|
||||
return packet;
|
||||
}
|
||||
|
||||
try {
|
||||
final Class<?> customPayloadClass = packet.getClass().getConstructors()[0].getParameterTypes()[0];
|
||||
final Class<?> discardPayloadClass = payloadObj.getClass();
|
||||
|
||||
final Constructor<?> discardPayloadConstr = discardPayloadClass.getConstructor(channelIdObj.getClass(), byte[].class);
|
||||
final Object newDiscardPayloadObj = discardPayloadConstr.newInstance(
|
||||
channelIdObj,
|
||||
String.join("\u0000", filteredChannels).getBytes()
|
||||
);
|
||||
|
||||
final Constructor<?> newPacketConstr = packet.getClass().getConstructor(customPayloadClass);
|
||||
return newPacketConstr.newInstance(newDiscardPayloadObj);
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
package de.rayzs.pat.plugin.packetanalyzer.proxy;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import com.mojang.brigadier.tree.CommandNode;
|
||||
|
||||
@@ -146,16 +148,17 @@ public class BungeePacketAnalyzer {
|
||||
|
||||
final boolean ignore = PermissionUtil.hasBypassPermission(sender, false) || Storage.Blacklist.isDisabledServer(serverName);
|
||||
|
||||
ProxyCommandNodeHelper helper = new ProxyCommandNodeHelper<CommandNode>(commands.getRoot());
|
||||
|
||||
List<String> commandsAsString = new ArrayList<>(PROXY_COMMANDS);
|
||||
final ProxyCommandNodeHelper helper = new ProxyCommandNodeHelper<CommandNode>(commands.getRoot());
|
||||
final List<String> commandsAsString = new ArrayList<>(PROXY_COMMANDS);
|
||||
commandsAsString.addAll(helper.getChildrenNames());
|
||||
|
||||
final List<Group> groups = ignore
|
||||
? Collections.emptyList()
|
||||
: GroupManager.getPlayerGroups(sender, false);
|
||||
|
||||
HashSet<String> playerCommands = new HashSet<>();
|
||||
|
||||
if (!ignore) {
|
||||
final List<Group> groups = GroupManager.getPlayerGroups(sender, false);
|
||||
|
||||
final Map<String, CommandsCache> cache = Storage.getLoader().getPerServerCommandsCacheMap();
|
||||
if (!cache.containsKey(serverName)) {
|
||||
cache.put(serverName, new CommandsCache());
|
||||
@@ -216,6 +219,14 @@ public class BungeePacketAnalyzer {
|
||||
}
|
||||
}
|
||||
|
||||
if (Storage.ConfigSections.Settings.TAB_COMPLETION_FOR_NOT_EXISTING_COMMANDS.ENABLED) {
|
||||
for (Group group : groups) {
|
||||
for (String groupCommands : group.getAllCommands(serverName)) {
|
||||
helper.add(groupCommands, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignore) {
|
||||
SubArgument.get().getCommandNodeHandler().handleCommandNode(helper, SubArgument.get().getPlayerArgument(sender));
|
||||
}
|
||||
@@ -240,6 +251,7 @@ public class BungeePacketAnalyzer {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class PacketDecoder extends MessageToMessageDecoder<PacketWrapper> {
|
||||
|
||||
private final ProxiedPlayer player;
|
||||
@@ -262,6 +274,31 @@ public class BungeePacketAnalyzer {
|
||||
|
||||
if (CustomServerBrand.get().isEnabled() && CustomServerBrand.get().isBrandTag(pluginMessage.getTag())) {
|
||||
return;
|
||||
} else if (Storage.ConfigSections.Settings.HIDE_PLUGIN_CHANNELS.ENABLED) {
|
||||
final String channelId = pluginMessage.getTag();
|
||||
|
||||
if (Storage.ConfigSections.Settings.HIDE_PLUGIN_CHANNELS.isRegisterChannel(channelId)) {
|
||||
final String dataStr = new String(pluginMessage.getData(), StandardCharsets.UTF_8);
|
||||
final String[] channels = dataStr.split("\u0000");
|
||||
|
||||
final List<String> filteredChannels = new ArrayList<>(Arrays.asList(channels));
|
||||
final AtomicBoolean changedAnything = new AtomicBoolean(false);
|
||||
|
||||
filteredChannels.removeIf(channel -> {
|
||||
if (!Storage.ConfigSections.Settings.HIDE_PLUGIN_CHANNELS.WHITELISTED_CHANNELS.getLines().contains(channel)) {
|
||||
changedAnything.set(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (changedAnything.get()) {
|
||||
pluginMessage.setData(String.join("\u0000", filteredChannels).getBytes());
|
||||
player.unsafe().sendPacket(pluginMessage);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (wrapper.packet instanceof Commands response) {
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
package de.rayzs.pat.plugin.packetanalyzer.proxy;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import com.mojang.brigadier.suggestion.SuggestionProvider;
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.*;
|
||||
import com.velocitypowered.proxy.protocol.packet.chat.session.UnsignedPlayerCommandPacket;
|
||||
|
||||
import de.rayzs.pat.plugin.system.serverbrand.CustomServerBrand;
|
||||
@@ -32,6 +31,8 @@ import de.rayzs.pat.utils.message.MessageTranslator;
|
||||
import de.rayzs.pat.utils.node.ProxyCommandNodeHelper;
|
||||
import de.rayzs.pat.utils.permission.PermissionUtil;
|
||||
import de.rayzs.pat.utils.sender.CommandSender;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
@@ -206,6 +207,18 @@ public class VelocityPacketAnalyzer {
|
||||
return !playerCommands.contains(str);
|
||||
});
|
||||
|
||||
if (Storage.ConfigSections.Settings.TAB_COMPLETION_FOR_NOT_EXISTING_COMMANDS.ENABLED) {
|
||||
for (Group group : groups) {
|
||||
for (String groupServerName : group.getBlacklistServerNames(serverName)) {
|
||||
if (Storage.isServer(groupServerName, serverName)) {
|
||||
for (String groupCommands : group.getAllCommands(groupServerName)) {
|
||||
helper.add(groupCommands, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Storage.ConfigSections.Settings.CUSTOM_VERSION.ALWAYS_TAB_COMPLETABLE) {
|
||||
Storage.ConfigSections.Settings.CUSTOM_VERSION.COMMANDS.getLines().forEach(input -> helper.add(input, false));
|
||||
}
|
||||
@@ -217,6 +230,37 @@ public class VelocityPacketAnalyzer {
|
||||
SubArgument.get().getCommandNodeHandler().handleCommandNode(helper, SubArgument.get().getPlayerArgument(sender));
|
||||
}
|
||||
|
||||
private static void handlePluginMessageChannelsPacket(final PluginMessagePacket packet) {
|
||||
final String channelId = packet.getChannel();
|
||||
|
||||
if (Storage.ConfigSections.Settings.HIDE_PLUGIN_CHANNELS.isRegisterChannel(channelId)) {
|
||||
final ByteBuf buf = packet.content();
|
||||
final byte[] data = new byte[buf.readableBytes()];
|
||||
buf.getBytes(buf.readerIndex(), data);
|
||||
|
||||
final String dataStr = new String(data, StandardCharsets.UTF_8);
|
||||
final String[] channels = dataStr.split("\u0000");
|
||||
|
||||
final List<String> filteredChannels = new ArrayList<>(Arrays.asList(channels));
|
||||
final AtomicBoolean changedAnything = new AtomicBoolean(false);
|
||||
|
||||
filteredChannels.removeIf(channel -> {
|
||||
if (!Storage.ConfigSections.Settings.HIDE_PLUGIN_CHANNELS.WHITELISTED_CHANNELS.getLines().contains(channel)) {
|
||||
changedAnything.set(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (changedAnything.get()) {
|
||||
final ByteBuf newBuf = Unpooled.wrappedBuffer(String.join("\u0000", filteredChannels).getBytes());
|
||||
packet.replace(newBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class PacketDecoder extends ChannelDuplexHandler {
|
||||
|
||||
private final Player player;
|
||||
@@ -253,6 +297,10 @@ public class VelocityPacketAnalyzer {
|
||||
}
|
||||
}
|
||||
|
||||
if (packet instanceof PluginMessagePacket pluginMessagePacket && Storage.ConfigSections.Settings.HIDE_PLUGIN_CHANNELS.ENABLED) {
|
||||
handlePluginMessageChannelsPacket(pluginMessagePacket);
|
||||
}
|
||||
|
||||
if (packet instanceof UnsignedPlayerCommandPacket unsignedPlayerCommandPacket) {
|
||||
if (!VelocityBlockCommandListener.handleCommand(player, unsignedPlayerCommandPacket.getCommand()).getResult().isAllowed())
|
||||
return;
|
||||
@@ -282,11 +330,13 @@ public class VelocityPacketAnalyzer {
|
||||
MinecraftPacket packet = (MinecraftPacket) msg;
|
||||
|
||||
if (packet instanceof PluginMessagePacket pluginMessagePacket) {
|
||||
if(CustomServerBrand.get().isEnabled() && CustomServerBrand.get().isBrandTag(pluginMessagePacket.getChannel()) && !player.getCurrentServer().isPresent()) {
|
||||
if (CustomServerBrand.get().isEnabled() && CustomServerBrand.get().isBrandTag(pluginMessagePacket.getChannel()) && !player.getCurrentServer().isPresent()) {
|
||||
final PacketUtils.BrandManipulate brandManipulatePacket = CustomServerBrand.get().createBrandPacket(player);
|
||||
|
||||
super.write(ctx, new PluginMessagePacket(pluginMessagePacket.getChannel(), brandManipulatePacket.getByteBuf()), promise);
|
||||
return;
|
||||
} else if (Storage.ConfigSections.Settings.HIDE_PLUGIN_CHANNELS.ENABLED) {
|
||||
handlePluginMessageChannelsPacket(pluginMessagePacket);
|
||||
}
|
||||
|
||||
} else if (packet instanceof TabCompleteResponsePacket response) {
|
||||
|
||||
+2
@@ -98,6 +98,8 @@ public class CommandNodeHandler extends SubArgumentHandler {
|
||||
break;
|
||||
}
|
||||
|
||||
if (input == null) continue;
|
||||
|
||||
final Storage.Blacklist.BlockType type = Storage.Blacklist.BlockTypeFetcher.getType(input);
|
||||
if (type == Storage.Blacklist.BlockType.CHAT) {
|
||||
continue;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package de.rayzs.pat.plugin.system.subargument.handler.impl;
|
||||
|
||||
import de.rayzs.pat.api.storage.Storage;
|
||||
import de.rayzs.pat.plugin.logger.Logger;
|
||||
import de.rayzs.pat.plugin.system.subargument.handler.SubArgumentHandler;
|
||||
import de.rayzs.pat.plugin.system.subargument.SubArgument;
|
||||
import de.rayzs.pat.utils.StringUtils;
|
||||
@@ -67,6 +68,16 @@ public class ExecuteHandler extends SubArgumentHandler {
|
||||
listed = !turn;
|
||||
}
|
||||
|
||||
/*
|
||||
final boolean blocked = turn != listed;
|
||||
if (blocked && command.contains("discord")) {
|
||||
Logger.info("Yes, sub-argument was blocked! (" + sender.getName() + ", " + command + ")");
|
||||
Logger.info("-> " + turn + ", " + listed + ", " + negated);
|
||||
}
|
||||
|
||||
return blocked;
|
||||
*/
|
||||
|
||||
return turn != listed;
|
||||
}
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ public class CommandsCache {
|
||||
String command = filteredCommands.get(i);
|
||||
localFilteredCommands.add(command);
|
||||
} catch (IndexOutOfBoundsException indexOutOfBoundsException) {
|
||||
Logger.warning("Array is out of bounds " + i + "/" + max + "! " + indexOutOfBoundsException.getMessage());
|
||||
//Logger.warning("Array is out of bounds " + i + "/" + max + "! " + indexOutOfBoundsException.getMessage());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,21 +6,21 @@ import java.util.*;
|
||||
|
||||
public class MultipleMessagesHelper implements Serializable {
|
||||
|
||||
private final ArrayList<String> lines;
|
||||
private final List<String> lines;
|
||||
|
||||
public MultipleMessagesHelper(ConfigStorage config, String path, List<String> input) {
|
||||
ConfigSectionHelper<ArrayList<String>> sectionHelper = new ConfigSectionHelper<>(config, path, input);
|
||||
final ConfigSectionHelper<ArrayList<String>> sectionHelper = new ConfigSectionHelper<>(config, path, input);
|
||||
final Object resultObj = sectionHelper.getOrSet();
|
||||
|
||||
if(!sectionHelper.exist()) {
|
||||
lines = new ArrayList<>(input);
|
||||
sectionHelper.set(lines);
|
||||
if (resultObj instanceof List list) {
|
||||
lines = (List<String>) list;
|
||||
return;
|
||||
}
|
||||
|
||||
lines = sectionHelper.get();
|
||||
lines = input;
|
||||
}
|
||||
|
||||
public ArrayList<String> getLines() {
|
||||
public List<String> getLines() {
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
@@ -209,8 +209,9 @@ public class LuckPermsHook {
|
||||
private static boolean isRelevantPermission(Node node) {
|
||||
final String key = node.getKey();
|
||||
|
||||
return key.startsWith("group.")
|
||||
return key.equals("*")
|
||||
|| key.startsWith("group.")
|
||||
|| key.startsWith("proantitab.")
|
||||
|| key.equals("*");
|
||||
|| key.startsWith("-proantitab.");
|
||||
}
|
||||
}
|
||||
@@ -92,12 +92,29 @@ public class PermissionUtil {
|
||||
}
|
||||
|
||||
public static void setPermission(UUID uuid, String permission, boolean permitted) {
|
||||
PermissionMap permissionMap;
|
||||
PermissionMap permissionMap = MAP.get(uuid);
|
||||
|
||||
if(!MAP.containsKey(uuid)) {
|
||||
if(permissionMap == null) {
|
||||
permissionMap = new PermissionMap(uuid);
|
||||
MAP.put(uuid, permissionMap);
|
||||
} else permissionMap = MAP.get(uuid);
|
||||
}
|
||||
|
||||
|
||||
final boolean isNegatedPermission = permission.charAt(0) == '-';
|
||||
|
||||
// Ignore because set permission is negated.
|
||||
if (!isNegatedPermission && permissionMap.isPermitted("-" + permission)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNegatedPermission) {
|
||||
final String nonNegatedPermission = permission.substring(1);
|
||||
|
||||
if (permissionMap.isPermitted(nonNegatedPermission)) {
|
||||
permissionMap.setState(nonNegatedPermission, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
permissionMap.setState(permission, permitted);
|
||||
}
|
||||
@@ -169,7 +186,9 @@ public class PermissionUtil {
|
||||
}
|
||||
}
|
||||
|
||||
return permissionMap.isPermitted("*") || permissionMap.isPermitted("proantitab.*") || permissionMap.isPermitted("proantitab." + permission);
|
||||
return permissionMap.isPermitted("*")
|
||||
|| permissionMap.isPermitted("proantitab.*")
|
||||
|| permissionMap.isPermitted("proantitab." + permission);
|
||||
}
|
||||
|
||||
public static boolean hasBypassPermission(Object targetObj, final boolean isOperator) {
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Hides more than just your plugins.
|
||||
website: https://www.rayzs.de/products/proantitab/page
|
||||
|
||||
author: Rayzs_YT
|
||||
version: 2.4.3
|
||||
version: 2.5.1
|
||||
main: de.rayzs.pat.plugin.BungeeLoader
|
||||
|
||||
softDepends: [LuckPerms, PAPIProxyBridge]
|
||||
@@ -101,6 +101,28 @@ update-groups-per-world: false
|
||||
# of the player accordingly.
|
||||
auto-forward-luckperms-changes: false
|
||||
|
||||
|
||||
# This option here works as a whitelist and hides certain plugins channels
|
||||
# from the user, if they are not supposed to be able to register for any
|
||||
# of the non-mentioned plugin channels below. This prevents modern plugin
|
||||
# spoofing attempts that are now trying to find plugins via their plugin
|
||||
# channel.
|
||||
#
|
||||
# (!) Warning:
|
||||
# Currently only works on standalone Spigot servers >=1.20
|
||||
# and proxies like Bungeecord/Velocity. It's also not
|
||||
# recommended to enable this feature, unless you know
|
||||
# what plugin channels are and which may be needed
|
||||
# for your server, in case your server supports a specific
|
||||
# minecraft client that relies on plugin channels for identification!
|
||||
plugin-channels-hider:
|
||||
enabled: false
|
||||
|
||||
whitelisted-channels:
|
||||
- "minecraft:brand"
|
||||
- "bungeecord:main"
|
||||
- "velocity:main"
|
||||
|
||||
# Here you can customize the server version that is displayed on a ping. (The text at the player-count)
|
||||
# (!) Warning: It's required to use Paper or Purpur to use this feature!
|
||||
# (!) Supported server versions: 1.12.2 - latest
|
||||
|
||||
@@ -64,11 +64,37 @@ allow-group-overruling: false
|
||||
# lpv (...) permission set proantitab.group.<group> server=<server>
|
||||
update-groups-per-server: false
|
||||
|
||||
# If you whitelist a command using PAT that does not exist, it would still
|
||||
# make the command tab-completable, even though it doesn't exist.
|
||||
# (!) WARNING: Only works with PAT groups!
|
||||
tab-completion-for-not-existing-commands: false
|
||||
|
||||
# Enabling this forwards the notification message to the backend
|
||||
# server so it will be displayed there as well. (Only in console)
|
||||
forward-console-notification-alerts: false
|
||||
|
||||
|
||||
# This option here works as a whitelist and hides certain plugins channels
|
||||
# from the user, if they are not supposed to be able to register for any
|
||||
# of the non-mentioned plugin channels below. This prevents modern plugin
|
||||
# spoofing attempts that are now trying to find plugins via their plugin
|
||||
# channel.
|
||||
#
|
||||
# (!) Warning:
|
||||
# Currently only works on standalone Spigot servers >=1.20
|
||||
# and proxies like Bungeecord/Velocity. It's also not
|
||||
# recommended to enable this feature, unless you know
|
||||
# what plugin channels are and which may be needed
|
||||
# for your server, in case your server supports a specific
|
||||
# minecraft client that relies on plugin channels for identification!
|
||||
plugin-channels-hider:
|
||||
enabled: false
|
||||
|
||||
whitelisted-channels:
|
||||
- "minecraft:brand"
|
||||
- "bungeecord:main"
|
||||
- "velocity:main"
|
||||
|
||||
# Here you can customize the server version that is displayed on a ping. (The text at the player-count)
|
||||
custom-protocol-ping:
|
||||
enabled: true
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Hides more than just your plugins.
|
||||
website: https://www.rayzs.de/products/proantitab/page
|
||||
|
||||
author: Rayzs_YT
|
||||
version: 2.4.3
|
||||
version: 2.5.1
|
||||
api-version: 1.13
|
||||
folia-supported: true
|
||||
main: de.rayzs.pat.plugin.BukkitLoader
|
||||
|
||||
Reference in new issue
Block a user