Compare commits

...
171 Commits
Author SHA1 Message Date
RayzsYT a453d7999e Changed warning for disable-sync 2025-02-26 19:56:41 +01:00
RayzsYT 07aad19fec Added "about" to custom-version feature 2025-02-26 19:46:38 +01:00
RayzsYT 1c4213da64 Integrated "disable sync" option 2025-02-25 16:37:50 +01:00
RayzsYT 5d27e7ee9a Update version 2025-02-25 16:28:06 +01:00
RayzsYT 3805d433f9 Add "disable sync" option 2025-02-25 16:21:58 +01:00
RayzsYT 4d66b8e540 Update libraries 2025-02-11 00:51:58 +01:00
RayzsYT 9aae436e13 Minor change 2025-02-11 00:51:42 +01:00
RayzsYT 406cec7683 Removed debug messages 2025-02-10 20:36:44 +01:00
RayzsYT 9360f5d6e4 Fix issue with no tab-completion for some sub-arguments if base is the same 2025-02-10 20:32:09 +01:00
RayzsYT 8446537b3b Remove : commands from default list 2025-02-10 16:42:04 +01:00
RayzsYT d5ed2242c0 Modified custom-plugins and custom-features default list a bit 2025-02-10 16:40:24 +01:00
RayzsYT 88dc1887f5 Outcommented code snip 2025-02-10 15:09:35 +01:00
RayzsYT 9177b3005b Improve detection performance 2025-02-10 15:09:23 +01:00
RayzsYT 6940bfb291 Add alwaysTabable option 2025-02-10 14:28:45 +01:00
RayzsYT 11f8900140 Fix -1 brand value issue 2025-02-10 02:54:22 +01:00
RayzsYT 8fd9eb0d2e Fixed wrong permission display 2025-02-10 01:34:09 +01:00
RayzsYT c2a4507697 Added small warning to description 2025-02-10 01:25:55 +01:00
RayzsYT a934eb24f7 Tiny code cleanup 2025-02-09 23:54:10 +01:00
RayzsYT 6d0535819b Tiny changes 2025-02-05 03:53:31 +01:00
RayzsYT 6e5f7cc980 Attempt to add Skript support 2025-02-05 02:04:35 +01:00
RayzsYT f6e77c04fa Refactored the code a bit 2025-02-04 20:38:40 +01:00
RayzsYT f9a133a1ed Improve Per-Group command execution 2025-01-30 23:37:24 +01:00
RayzsYT faa67160d0 Fix Folia support 2025-01-30 21:32:30 +01:00
RayzsYT 79e17de03b Fix Folia 1.21.1 support 2024-12-22 22:20:01 +01:00
RayzsYT 7c67f8d9e4 Add PlaceholderAPI support for ProtocolPing 2024-12-22 21:37:31 +01:00
RayzsYT 62639961d2 Fixed wrong section-target name 2024-12-22 00:09:46 +01:00
RayzsYT 8fe56347fc Fixed duplicating config.yml file bug 2024-12-22 00:07:28 +01:00
RayzsYT 38b622b9dc Integrated AutoUpdateConfig option 2024-12-21 19:40:10 +01:00
RayzsYT dadd9724eb Add AutoUpdateConfig option 2024-12-21 19:23:33 +01:00
RayzsYT ad8406f4a2 Add timeout method 2024-12-21 19:13:51 +01:00
RayzsYT 2f0ee0c278 Remove debug message 2024-11-10 20:56:28 +01:00
RayzsYT 6c48c979d7 Added containsIgnoreCase method 2024-11-10 20:31:00 +01:00
RayzsYT 74dab5fb09 Added usage of new containsIgnoreCase from ArrayUtils.java 2024-11-10 20:30:50 +01:00
RayzsYT b8faadc9ba Added unchanged playerInput variable (rawPlayerInput) 2024-11-10 20:20:53 +01:00
RayzsYT b8964bc843 Changed description of example 2024-11-10 17:22:53 +01:00
RayzsYT 1b8e69da9d Remove String colorcode replacement 2024-11-10 17:18:49 +01:00
RayzsYT 1a5de85eb9 Replace String 2024-11-10 17:17:56 +01:00
RayzsYT 918c901850 Fix actionbar <1.16 issue 2024-11-10 17:11:40 +01:00
RayzsYT 7104b885d5 Add getVersionPackageName method 2024-11-10 17:11:24 +01:00
RayzsYT 73d8d70661 Remove <hint> if no arguments exist 2024-11-10 16:45:46 +01:00
RayzsYT 53ce663032 Expanded description 2024-11-10 16:32:43 +01:00
RayzsYT b3d842cac2 Modified text replacements 2024-11-10 16:32:34 +01:00
RayzsYT 75089456b2 Changed values in example 2024-11-10 15:54:47 +01:00
RayzsYT 4744ae0037 Minor version-detection change 2024-11-10 15:51:32 +01:00
RayzsYT af1e285f8c Change description and fixed double console command execution 2024-11-10 15:48:20 +01:00
RayzsYT a75a71b6e7 Changed description 2024-11-10 15:38:27 +01:00
RayzsYT 7128f7cd74 Add actionbar 2024-11-10 15:32:46 +01:00
RayzsYT f5191580cf Improve Action system 2024-11-10 15:20:50 +01:00
RayzsYT fdef5b45b0 Removed unused import 2024-11-10 05:50:55 +01:00
RayzsYT 82a2fb1513 Add %player% variable to sendTitle method & removed old executeActions method 2024-11-10 05:50:08 +01:00
RayzsYT 7b627dd1b1 Add %player% variable to sendTitle method 2024-11-10 05:49:49 +01:00
RayzsYT d247850218 Fixed wrong description 2024-11-10 05:46:43 +01:00
RayzsYT c9d91d1d16 Made title more configurable 2024-11-10 05:39:01 +01:00
RayzsYT 4173e11105 Replace %player% placeholder in executeConsoleCommand method 2024-11-10 05:34:03 +01:00
RayzsYT 42d5b0b201 Add uuid to executeConsoleCommand parameters and adjust PlaceholderAPI replacements 2024-11-10 05:29:02 +01:00
RayzsYT 1baa12e007 Add uuid to executeConsoleCommand parameters 2024-11-10 05:28:48 +01:00
RayzsYT 3e99cb44b2 Add uuid 2024-11-10 05:28:12 +01:00
RayzsYT 2ecafd5c6c Add effect action 2024-11-10 05:19:39 +01:00
RayzsYT ef8b8d619a Add giveEffect method 2024-11-10 05:15:43 +01:00
RayzsYT 0f88b3f799 Add example to playSound method 2024-11-10 05:09:44 +01:00
RayzsYT 39301e8622 Adjust new customizable actions 2024-11-10 04:54:20 +01:00
RayzsYT cf77cae518 Added customizable actions 2024-11-10 04:52:21 +01:00
RayzsYT f37bdf4c07 Added methods 2024-11-10 04:52:05 +01:00
RayzsYT f7d44f4085 Added more versions just in case 2024-11-10 02:56:24 +01:00
RayzsYT 285c8125bd Updated version 2024-11-09 21:48:47 +01:00
RayzsYT 7c38083e64 Fixed possible ModificationException 2024-11-09 21:48:01 +01:00
RayzsYT b8dde730f5 Fixed player-variables issues 2024-11-09 21:47:20 +01:00
RayzsYT cce9722a66 Add replaceLast method 2024-11-09 21:46:46 +01:00
Alihan Olgun e63836bd11 Fixed exception when using <1.13 server with Handle-Through-Proxy enabled 2024-11-07 11:13:24 +01:00
RayzsYT 1afd93d296 Change variable name 2024-11-07 00:36:42 +01:00
RayzsYT cb44ae50ff Swap boolean-checks 2024-11-07 00:29:59 +01:00
RayzsYT 6ce5c8caaf Fixed full tab-completion issue when completion is empty 2024-11-07 00:27:43 +01:00
RayzsYT d5b53aecfa Removed %rmc_online_player% from executable commands filter 2024-11-06 23:53:23 +01:00
RayzsYT cc1bb4ec34 Added placeholder to remove player-names only 2024-11-06 23:49:01 +01:00
RayzsYT be9027fa82 Added full per-server sub-arguments support 2024-11-06 23:37:43 +01:00
RayzsYT 247b3a1ffd Improved Velocity commands-detection 2024-11-04 23:00:19 +01:00
RayzsYT 356454c66d Add sub-argument feature 2024-11-04 21:26:14 +01:00
RayzsYT c11cb20917 Add sub-argument feature 2024-11-04 21:13:32 +01:00
RayzsYT 84a7fbafae Fix accidentally blocking custom-plugins & custom-version feature 2024-11-03 22:04:56 +01:00
RayzsYT f5acc445e7 Improved isOlder method 2024-11-03 21:58:52 +01:00
RayzsYT 38142da87e Fix name 2024-11-03 21:47:12 +01:00
RayzsYT 4ea2f5cb33 Add method to load custom-responses.yml 2024-11-03 21:45:33 +01:00
RayzsYT 8001e5aa8d Add base- and sub-command placeholders 2024-11-03 21:42:26 +01:00
RayzsYT 5b4c45dbcc Add sub-args initialization 2024-11-03 21:38:42 +01:00
RayzsYT fa62e0fae6 Change import package 2024-11-03 21:38:19 +01:00
RayzsYT 06e0030f63 Change package 2024-11-03 21:38:11 +01:00
RayzsYT 8441481d10 Add sub-argument 2024-11-03 21:36:08 +01:00
RayzsYT 6782635202 Changed response message to new one 2024-11-03 20:52:58 +01:00
RayzsYT d061b8967b Changed response message to new one 2024-11-03 20:52:40 +01:00
RayzsYT 4881fa3c66 Adjusted file with "subargument" message 2024-11-03 20:51:21 +01:00
RayzsYT 8e8643bf06 Changed variable names & add subarguments message 2024-11-03 20:50:59 +01:00
RayzsYT 18ee04a979 Changed output 2024-11-03 20:41:53 +01:00
RayzsYT 0394aaedf4 Update version 2024-11-03 20:40:28 +01:00
RayzsYT 3c62d3c1b9 Update version 2024-11-03 20:40:12 +01:00
RayzsYT 94eff2bf6d Add new configuration-file 2024-11-03 20:39:22 +01:00
RayzsYT 1f7e6cd77a Fix exception on <1.21 servers 2024-10-31 20:38:40 +01:00
RayzsYT 34cba027f9 Even more improved server-based commands 2024-10-31 20:30:39 +01:00
RayzsYT db42fc1295 Updated version 2024-10-31 20:00:53 +01:00
RayzsYT 5270a432e9 Improve per-server functionality (same server-endings) 2024-10-31 19:56:25 +01:00
RayzsYT ab052d62b5 Minor code improvement 2024-10-31 12:55:21 +01:00
RayzsYT a878944b33 Updated version name 2024-10-27 13:04:34 +01:00
RayzsYT cb349e8abb Fixed CustomServerBrand issues with Folia 2024-10-27 13:02:25 +01:00
RayzsYT 95963b59b8 Fixed Folia server version detection error 2024-10-27 02:26:13 +02:00
RayzsYT ce1a326f5b Removed debug message 2024-10-26 22:01:23 +02:00
RayzsYT aef3c3edfc Fixed issue with PacketInjector on Folia servers 2024-10-26 22:01:09 +02:00
RayzsYT 4332f677f9 Fixed subargs-tabcompletion issue for custom-version & custom-plugins feature 2024-10-26 20:47:49 +02:00
RayzsYT 298e98b06d Removed sending empty messages 2024-10-24 23:08:16 +02:00
RayzsYT c419444481 Fixed Pattern-issue with * 2024-10-20 03:36:42 +02:00
RayzsYT 3206a616b9 Change event call-methods 2024-10-19 20:45:46 +02:00
RayzsYT 3fd9328842 Update Version 2024-10-19 20:31:36 +02:00
RayzsYT e39939598b Implemented ServerPlayersChangeEvent & fixed minor CustomServerBrand issue 2024-10-19 20:29:10 +02:00
RayzsYT cc02837035 Change event call-methods 2024-10-19 20:22:29 +02:00
RayzsYT 0c8b50b32f Change event call-methods 2024-10-19 20:22:04 +02:00
RayzsYT b5833c05b2 Change event call-methods 2024-10-19 20:21:41 +02:00
RayzsYT 810ed9982c Implemented ServerPlayersChangeEvent 2024-10-19 19:59:42 +02:00
RayzsYT cc470740af Add Event 2024-10-19 19:59:21 +02:00
RayzsYT ed8d5e0cf3 Nothing 2024-10-19 18:34:35 +02:00
RayzsYT 161eafeea7 Fix ConcurrentModificationException ( Credits: xii69/ProAntiTab@8491e3eb30 ) 2024-10-19 18:33:55 +02:00
RayzsYT b4c54101c9 Nothing. Just test ([Test](https://github.com/RayzsYT/ProAntiTab)) 2024-10-19 18:23:47 +02:00
RayzsYT 729b1ccf8d Remove debug message 2024-10-13 14:13:06 +02:00
RayzsYT 3f14a091ec Fix Folia Support 2024-10-10 00:12:49 +02:00
RayzsYT 8282a0147b Fixed Issue With SignedVelocity 2024-10-10 00:07:42 +02:00
RayzsYT b4628443d4 Change Description 2024-10-09 22:40:38 +02:00
RayzsYT 60516283e2 Modify PatchExploit Integration 2024-10-08 22:44:21 +02:00
RayzsYT b3e622d652 Add Check 2024-10-08 22:31:55 +02:00
RayzsYT 1ee5623a80 Reposition 2024-10-08 22:21:53 +02:00
RayzsYT 419d1ae508 Update Version 2024-10-08 22:19:54 +02:00
RayzsYT a9eaa531e7 Update 2024-10-08 22:19:27 +02:00
RayzsYT ff7e3cd444 Update 2024-10-08 22:18:19 +02:00
RayzsYT abb4c5404f Implement PatchExploit 2024-10-08 22:10:02 +02:00
RayzsYT c804ec51bd Add PatchExploit Section 2024-10-08 22:09:51 +02:00
RayzsYT cc025c52b1 Add Methods 2024-10-08 22:09:36 +02:00
RayzsYT c29bab0e84 Add Method 2024-10-08 22:09:25 +02:00
RayzsYT ab74e04a53 Add New Section 2024-10-08 22:09:13 +02:00
RayzsYT 8713aafc27 Add Methods 2024-10-08 22:09:03 +02:00
RayzsYT 60e3188990 Fix 1.21.1 Meteor Exploit 2024-10-08 21:29:35 +02:00
RayzsYT 97abf3834b Update Version 2024-10-08 21:29:21 +02:00
RayzsYT 7126808d04 Implemented VersionComparer 2024-10-06 03:39:42 +02:00
RayzsYT e3c04135cc Add 2024-10-06 03:38:52 +02:00
RayzsYT c70aeefc44 Modify 2024-09-29 15:40:02 +02:00
RayzsYT 3e21d1730c Change 2024-09-29 15:10:26 +02:00
RayzsYT 903139631d New Event 2024-09-29 15:05:32 +02:00
RayzsYT 3ac2a580b1 Change Method 2024-09-29 14:26:50 +02:00
RayzsYT e83dc9484f Fix CustomBrand -1 Value 2024-09-28 22:43:17 +02:00
RayzsYT e908b8699a Fix CustomBrand -1 Value 2024-09-28 22:35:46 +02:00
RayzsYT 92e1795266 Update Version 2024-09-28 19:51:14 +02:00
RayzsYT 2b6f59bc5a Fix ViaVersion Incompatibility 2024-09-27 02:05:07 +02:00
RayzsYT 33081fa953 Remove Loophole 2024-09-18 21:38:35 +02:00
RayzsYT 552d97d5f4 Add Perms-Command 2024-09-18 03:15:02 +02:00
RayzsYT b633f8728d Implement PermsCheck Messages 2024-09-18 03:12:25 +02:00
RayzsYT 73f8d464b4 Change Output 2024-09-18 03:12:09 +02:00
RayzsYT e546dad6f3 Change %target% -> %player% 2024-09-18 03:06:47 +02:00
RayzsYT fce7a83d98 Add PermsCheck Section 2024-09-18 03:04:45 +02:00
RayzsYT e422af5cb1 Fix Folia Support 2024-09-18 02:43:18 +02:00
RayzsYT 171106c495 Add Message 2024-09-18 02:28:22 +02:00
RayzsYT 400f4d0d55 Implement Folia-Support 2024-09-18 02:23:34 +02:00
RayzsYT c48f42c421 Add Async 2024-09-18 02:14:34 +02:00
RayzsYT cd56526c01 Add Folia Support 2024-09-18 02:05:29 +02:00
RayzsYT ed4690f23c Change Description 2024-09-04 18:27:05 +02:00
RayzsYT aef18508aa Clean Imports 2024-08-23 23:52:44 +02:00
RayzsYT ebf07fc9e1 Update PAT-Event API 2024-08-23 23:48:25 +02:00
RayzsYT 2b1f03ddb7 Change senderUUID -> senderObj 2024-08-23 22:06:39 +02:00
RayzsYT 516003398d Simplified Instance-Creation 2024-08-23 03:10:27 +02:00
RayzsYT dbae642d40 Add Events 2024-08-23 02:09:42 +02:00
RayzsYT fcf84628a2 Fix 1.21 Tab-Completion Bug 2024-08-23 01:30:55 +02:00
RayzsYT ac93e5c904 Improve PAT-Event API Integration 2024-08-22 22:14:18 +02:00
RayzsYT e6e3c5a9dd Add UpdatePluginEvent 2024-08-22 20:14:49 +02:00
RayzsYT 594972b17a Improve 1.21 Support 2024-08-22 18:14:35 +02:00
RayzsYT b6903a109b Implement PAT-Event API 2024-08-21 02:13:25 +02:00
RayzsYT 0837f9d75d Implement PAT-Event API 2024-08-21 01:49:18 +02:00
RayzsYT f928a94b83 Implement PAT-Event API 2024-08-20 23:14:39 +02:00
91 changed files with 2953 additions and 273 deletions

No files matched your search

+25 -5
View File
@@ -6,7 +6,7 @@
<groupId>de.rayzs.pat</groupId>
<artifactId>ProAntiTab</artifactId>
<version>1.8.0</version>
<version>1.9.2</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
@@ -72,10 +72,30 @@
<url>https://repo.william278.net/papiproxybridge</url>
</repository>
<repository>
<id>skript-releases</id>
<name>Skript Repository</name>
<url>https://repo.skriptlang.org/releases</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.skriptlang</groupId>
<artifactId>Skript</artifactId>
<version>2.10.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>dev.folia</groupId>
<artifactId>folia-api</artifactId>
<version>1.20.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
@@ -213,28 +233,28 @@
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.15.0</version>
<version>4.18.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.17.0</version>
<version>4.18.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-api</artifactId>
<version>4.3.2</version>
<version>4.3.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-bungeecord</artifactId>
<version>4.3.2</version>
<version>4.3.3</version>
<scope>compile</scope>
</dependency>
@@ -1,5 +1,7 @@
package de.rayzs.pat.api.brand;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.PacketUtils;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.api.brand.impl.*;
@@ -12,4 +14,11 @@ public class CustomServerBrand {
public static void refreshTask() { SERVER_BRAND.initializeTask(); }
public static void preparePlayer(Object playerObj) { SERVER_BRAND.preparePlayer(playerObj); }
public static void sendBrandToPlayer(Object playerObj) { SERVER_BRAND.send(playerObj); }
public static PacketUtils.BrandManipulate createBrandPacket(Object playerObj) { return SERVER_BRAND.createPacket(playerObj); }
public static boolean isEnabled() { return Storage.ConfigSections.Settings.CUSTOM_BRAND.ENABLED; }
public static boolean isBrandTag(String tag) {
return tag.equals("MC|Brand") || tag.equals("minecraft:brand");
}
}
@@ -1,7 +1,10 @@
package de.rayzs.pat.api.brand;
import de.rayzs.pat.utils.PacketUtils;
public interface ServerBrand {
void preparePlayer(Object playerObj);
void send(Object playerObj);
PacketUtils.BrandManipulate createPacket(Object playerObj);
void initializeTask();
}
@@ -5,6 +5,8 @@ import de.rayzs.pat.utils.message.MessageTranslator;
import java.util.concurrent.atomic.AtomicInteger;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.BukkitLoader;
import de.rayzs.pat.utils.scheduler.PATScheduler;
import de.rayzs.pat.utils.scheduler.PATSchedulerTask;
import io.netty.channel.Channel;
import de.rayzs.pat.api.brand.*;
import org.bukkit.entity.Player;
@@ -19,7 +21,7 @@ public class BukkitServerBrand implements ServerBrand {
private static final List<Player> MODIFIED_BRAND_PLAYERS = new ArrayList<>();
private static final Server SERVER = Bukkit.getServer();
private static String BRAND = Storage.ConfigSections.Settings.CUSTOM_BRAND.BRANDS.getLines().get(0);
private static int TASK = -1;
private static PATSchedulerTask TASK;
private static boolean INITIALIZED = false;
private static Class<?> brandPayloadClass, clientBoundCustomPacketPayloadPacketClass, customPacketPayloadPacketClass;
@@ -48,9 +50,9 @@ public class BukkitServerBrand implements ServerBrand {
exception.printStackTrace();
}
if(TASK != -1) {
Bukkit.getScheduler().cancelTask(TASK);
TASK = -1;
if(TASK != null && TASK.isActive()) {
TASK.cancelTask();
TASK = null;
MODIFIED_BRAND_PLAYERS.clear();
}
@@ -58,12 +60,14 @@ public class BukkitServerBrand implements ServerBrand {
if(Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY == -1) {
BRAND = Storage.ConfigSections.Settings.CUSTOM_BRAND.BRANDS.getLines().get(0) + "§r";
TASK = Bukkit.getScheduler().scheduleAsyncRepeatingTask(BukkitLoader.getPlugin(), () -> {
PATScheduler.createAsyncScheduler(() -> {
Bukkit.getOnlinePlayers().forEach(this::send);
}, 1, Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY);
}, 1, 1);
} else {
AtomicInteger animationState = new AtomicInteger(0);
TASK = Bukkit.getScheduler().scheduleAsyncRepeatingTask(BukkitLoader.getPlugin(), () -> {
TASK = PATScheduler.createAsyncScheduler(() -> {
if (animationState.getAndIncrement() >= Storage.ConfigSections.Settings.CUSTOM_BRAND.BRANDS.getLines().size() - 1)
animationState.set(0);
BRAND = Storage.ConfigSections.Settings.CUSTOM_BRAND.BRANDS.getLines().get(animationState.get()) + "§r";
@@ -115,6 +119,11 @@ public class BukkitServerBrand implements ServerBrand {
}
}
@Override
public PacketUtils.BrandManipulate createPacket(Object playerObj) {
return null;
}
private boolean isModified(Player player) {
if(!Storage.ConfigSections.Settings.CUSTOM_BRAND.ENABLED || Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1) return false;
return MODIFIED_BRAND_PLAYERS.contains(player);
@@ -57,4 +57,17 @@ public class BungeeServerBrand implements ServerBrand {
String brand = player.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_13 ? "minecraft:brand" : "MC|Brand";
player.sendData(brand, serverBrand.getBytes());
}
@Override
public PacketUtils.BrandManipulate createPacket(Object playerObj) {
if (!(playerObj instanceof ProxiedPlayer) || !Storage.ConfigSections.Settings.CUSTOM_BRAND.ENABLED) return null;
ProxiedPlayer player = (ProxiedPlayer) playerObj;
String serverName = "", playerName = player.getName(), customBrand;
Server server = player.getServer();
if(server != null) serverName = server.getInfo().getName();
customBrand = BRAND.replace("%player%", playerName).replace("%server%", serverName);
return new PacketUtils.BrandManipulate(customBrand);
}
}
@@ -80,4 +80,25 @@ public class VelocityServerBrand implements ServerBrand {
exception.printStackTrace();
}
}
@Override
public PacketUtils.BrandManipulate createPacket(Object playerObj) {
if (!(playerObj instanceof Player) || !Storage.ConfigSections.Settings.CUSTOM_BRAND.ENABLED) return null;
try {
Player player = (Player) playerObj;
String serverName = "", playerName = player.getUsername(), customBrand;
Optional<ServerConnection> serverConnection = player.getCurrentServer();
if(serverConnection.isPresent()) serverName = serverConnection.get().getServerInfo().getName();
customBrand = BRAND.replace("%player%", playerName).replace("%server%", serverName).replace("%ping%", String.valueOf(player.getPing()));
return new PacketUtils.BrandManipulate(customBrand, false);
} catch (Exception exception) {
exception.printStackTrace();
}
return null;
}
}
@@ -1,12 +1,12 @@
package de.rayzs.pat.api.communication;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.BukkitLoader;
import de.rayzs.pat.utils.scheduler.*;
import org.bukkit.Bukkit;
public class BackendUpdater {
private static int TASK = -1;
private static PATSchedulerTask TASK;
public static void handle() {
if(isRunning() || !shouldRun() || !Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) return;
@@ -14,23 +14,22 @@ public class BackendUpdater {
}
public static boolean isRunning() {
return TASK != -1;
return TASK != null && TASK.isActive();
}
public static void start() {
if(TASK != -1) return;
if(isRunning()) return;
TASK = Bukkit.getScheduler().scheduleSyncRepeatingTask(BukkitLoader.getPlugin(), () -> {
if(shouldRun()) Communicator.sendRequest();
TASK = PATScheduler.createScheduler(() -> {
if (shouldRun()) Communicator.sendRequest();
else stop();
}, 5, 20);
}
public static void stop() {
if(TASK == -1) return;
Bukkit.getScheduler().cancelTask(TASK);
TASK = -1;
if(TASK == null || !TASK.isActive()) return;
TASK.cancelTask();
TASK = null;
}
private static boolean shouldRun() {
@@ -2,6 +2,7 @@ package de.rayzs.pat.api.communication;
import de.rayzs.pat.api.communication.client.ClientInfo;
import de.rayzs.pat.api.communication.client.impl.*;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.api.storage.blacklist.impl.*;
import de.rayzs.pat.api.communication.impl.*;
@@ -100,6 +101,8 @@ public class Communicator {
}
public static void syncData(String serverId) {
if (Storage.ConfigSections.Settings.DISABLE_SYNC.DISABLED) return;
LAST_DATA_UPDATE = System.currentTimeMillis();
ClientInfo clientInfo;
if(serverId == null) {
@@ -149,6 +152,8 @@ public class Communicator {
bundle = new CommunicationPackets.PacketBundle(Storage.TOKEN, serverId, commandsPacket, groupsPacket);
clientInfo.sendBytes(CommunicationPackets.convertToBytes(bundle));
PATEventHandler.callSentSyncEvents(bundle, serverName);
}
public static void sendRequest() {
@@ -1,5 +1,6 @@
package de.rayzs.pat.api.communication.impl;
import de.rayzs.pat.utils.scheduler.PATScheduler;
import org.bukkit.plugin.messaging.PluginMessageListener;
import de.rayzs.pat.utils.CommunicationPackets;
import de.rayzs.pat.plugin.BukkitLoader;
@@ -29,7 +30,7 @@ public class BukkitClient implements Client, PluginMessageListener {
Object packetObj = CommunicationPackets.buildFromBytes(bytes);
if(!CommunicationPackets.isPacket(packetObj)) return;
Bukkit.getScheduler().scheduleSyncDelayedTask(BukkitLoader.getPlugin(), () -> Communicator.receiveInformation("proxy", packetObj));
PATScheduler.createScheduler(() -> Communicator.receiveInformation("proxy", packetObj));
} catch (Throwable throwable) { throwable.printStackTrace(); }
}
}
@@ -1,14 +1,12 @@
package de.rayzs.pat.api.event;
import java.util.UUID;
public abstract class PATEvent<T> {
private final UUID senderUniqueId;
private final Object senderObj;
private boolean cancelled = false;
public PATEvent(UUID senderUniqueId) {
this.senderUniqueId = senderUniqueId;
public PATEvent(Object senderObj) {
this.senderObj = senderObj;
}
public abstract void handle(T t);
@@ -16,9 +14,8 @@ public abstract class PATEvent<T> {
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
public UUID getSenderUniqueId() {
return senderUniqueId;
public Object getSenderObj() {
return senderObj;
}
public boolean isCancelled() {
@@ -1,14 +1,16 @@
package de.rayzs.pat.api.event;
import de.rayzs.pat.api.event.events.*;
import de.rayzs.pat.utils.CommunicationPackets;
import java.util.*;
public class PATEventHandler {
private static List<PATEvent> EVENTS = new ArrayList<>();
public static ExecuteCommandEvent call(UUID senderUniqueId, String command, boolean blocked) {
ExecuteCommandEvent event = EmptyEvent.createEmptyExecuteCommandEvent(senderUniqueId, command, blocked);
public static ExecuteCommandEvent callExecuteCommandEvents(Object senderObj, String command, boolean blocked) {
ExecuteCommandEvent event = EmptyEvent.createEmptyExecuteCommandEvent(senderObj, command, blocked);
for (PATEvent patEvent : EVENTS) {
if(patEvent instanceof ExecuteCommandEvent) {
@@ -20,8 +22,8 @@ public class PATEventHandler {
return event;
}
public static FilteredSuggestionEvent call(UUID senderUniqueId, List<String> suggestions) {
FilteredSuggestionEvent event = EmptyEvent.createEmptyFilteredSuggestionEvent(senderUniqueId, suggestions);
public static FilteredSuggestionEvent callFilteredSuggestionEvents(Object senderObj, List<String> suggestions) {
FilteredSuggestionEvent event = EmptyEvent.createEmptyFilteredSuggestionEvent(senderObj, suggestions);
for (PATEvent patEvent : EVENTS) {
if(patEvent instanceof FilteredSuggestionEvent) {
@@ -33,8 +35,8 @@ public class PATEventHandler {
return event;
}
public static FilteredTabCompletionEvent call(UUID senderUniqueId, String cursor, List<String> completion) {
FilteredTabCompletionEvent event = EmptyEvent.createEmptyFilteredTabCompletion(senderUniqueId, cursor, completion);
public static FilteredTabCompletionEvent callFilteredTabCompletionEvents(Object senderObj, String cursor, List<String> completion) {
FilteredTabCompletionEvent event = EmptyEvent.createEmptyFilteredTabCompletion(senderObj, cursor, completion);
for (PATEvent patEvent : EVENTS) {
if(patEvent instanceof FilteredTabCompletionEvent) {
@@ -46,6 +48,71 @@ public class PATEventHandler {
return event;
}
public static ServerPlayersChangeEvent callServerPlayersChangeEvents(Object senderObj, ServerPlayersChangeEvent.Type type) {
ServerPlayersChangeEvent event = EmptyEvent.createEmptyServerPlayersChangeEvent(senderObj, type);
for (PATEvent patEvent : EVENTS) {
if(patEvent instanceof ServerPlayersChangeEvent) {
ServerPlayersChangeEvent serverPlayersChangeEvent = (ServerPlayersChangeEvent) patEvent;
serverPlayersChangeEvent.handle(event);
}
}
return event;
}
public static UpdatePluginEvent callUpdatePluginEvents() {
UpdatePluginEvent event = EmptyEvent.createEmptyUpdatePluginEvent();
for (PATEvent patEvent : EVENTS) {
if(patEvent instanceof UpdatePluginEvent) {
UpdatePluginEvent updatePluginEvent = (UpdatePluginEvent) patEvent;
updatePluginEvent.handle(event);
}
}
return event;
}
public static UpdatePlayerCommandsEvent callUpdatePlayerCommandsEvents(Object playerObj, List<String> commands, boolean serverBased) {
UpdatePlayerCommandsEvent event = EmptyEvent.createEmptyUpdatePlayerCommandsEvent(playerObj, commands, serverBased);
for (PATEvent patEvent : EVENTS) {
if(patEvent instanceof UpdatePlayerCommandsEvent) {
UpdatePlayerCommandsEvent updatePlayerCommandsEvent = (UpdatePlayerCommandsEvent) patEvent;
updatePlayerCommandsEvent.handle(event);
}
}
return event;
}
public static SentSyncEvent callSentSyncEvents(CommunicationPackets.PacketBundle packetBundle, String serverName) {
SentSyncEvent event = EmptyEvent.createEmptySentSyncEvent(packetBundle, serverName);
for (PATEvent patEvent : EVENTS) {
if(patEvent instanceof SentSyncEvent) {
SentSyncEvent sentSyncEvent = (SentSyncEvent) patEvent;
sentSyncEvent.handle(event);
}
}
return event;
}
public static ReceiveSyncEvent callReceiveSyncEvents(CommunicationPackets.PacketBundle packetBundle) {
ReceiveSyncEvent event = EmptyEvent.createEmptyReceiveSyncEvent(packetBundle);
for (PATEvent patEvent : EVENTS) {
if(patEvent instanceof ReceiveSyncEvent) {
ReceiveSyncEvent proxySyncEvent = (ReceiveSyncEvent) patEvent;
proxySyncEvent.handle(event);
}
}
return event;
}
public static void register(PATEvent event) {
EVENTS.add(event);
}
@@ -56,8 +123,53 @@ public class PATEventHandler {
public static class EmptyEvent {
public static ExecuteCommandEvent createEmptyExecuteCommandEvent(UUID senderUniqueId, String command, boolean blocked) {
return new ExecuteCommandEvent(senderUniqueId, command, blocked) {
public static ServerPlayersChangeEvent createEmptyServerPlayersChangeEvent(Object senderObj, ServerPlayersChangeEvent.Type type) {
return new ServerPlayersChangeEvent(senderObj, type) {
@Override
public void handle(ServerPlayersChangeEvent event) {
}
};
}
public static SentSyncEvent createEmptySentSyncEvent(CommunicationPackets.PacketBundle packetBundle, String serverName) {
return new SentSyncEvent(null, packetBundle, serverName) {
@Override
public void handle(SentSyncEvent event) {
}
};
}
public static ReceiveSyncEvent createEmptyReceiveSyncEvent(CommunicationPackets.PacketBundle packetBundle) {
return new ReceiveSyncEvent(null, packetBundle) {
@Override
public void handle(ReceiveSyncEvent event) {
}
};
}
public static UpdatePlayerCommandsEvent createEmptyUpdatePlayerCommandsEvent(Object playerObj, List<String> commands, boolean serverBased) {
return new UpdatePlayerCommandsEvent(playerObj, commands, serverBased) {
@Override
public void handle(UpdatePlayerCommandsEvent event) {
}
};
}
public static UpdatePluginEvent createEmptyUpdatePluginEvent() {
return new UpdatePluginEvent(null) {
@Override
public void handle(UpdatePluginEvent event) {
}
};
}
public static ExecuteCommandEvent createEmptyExecuteCommandEvent(Object senderObj, String command, boolean blocked) {
return new ExecuteCommandEvent(senderObj, command, blocked) {
@Override
public void handle(ExecuteCommandEvent event) {
@@ -65,8 +177,8 @@ public class PATEventHandler {
};
}
public static FilteredSuggestionEvent createEmptyFilteredSuggestionEvent(UUID senderUniqueId, List<String> suggestions) {
return new FilteredSuggestionEvent(senderUniqueId, suggestions) {
public static FilteredSuggestionEvent createEmptyFilteredSuggestionEvent(Object senderObj, List<String> suggestions) {
return new FilteredSuggestionEvent(senderObj, suggestions) {
@Override
public void handle(FilteredSuggestionEvent event) {
@@ -74,8 +186,8 @@ public class PATEventHandler {
};
}
public static FilteredTabCompletionEvent createEmptyFilteredTabCompletion(UUID senderUniqueId, String cursor, List<String> completion) {
return new FilteredTabCompletionEvent(senderUniqueId, cursor, completion) {
public static FilteredTabCompletionEvent createEmptyFilteredTabCompletion(Object senderObj, String cursor, List<String> completion) {
return new FilteredTabCompletionEvent(senderObj, cursor, completion) {
@Override
public void handle(FilteredTabCompletionEvent event) {
@@ -1,7 +1,6 @@
package de.rayzs.pat.api.event.events;
import de.rayzs.pat.api.event.PATEvent;
import java.util.UUID;
public abstract class ExecuteCommandEvent extends PATEvent<ExecuteCommandEvent> {
@@ -14,8 +13,8 @@ public abstract class ExecuteCommandEvent extends PATEvent<ExecuteCommandEvent>
this.command = null;
}
public ExecuteCommandEvent(UUID senderUniqueId, String command, boolean blocked) {
super(senderUniqueId);
public ExecuteCommandEvent(Object senderObj, String command, boolean blocked) {
super(senderObj);
this.blocked = blocked;
this.command = command;
}
@@ -24,11 +23,6 @@ public abstract class ExecuteCommandEvent extends PATEvent<ExecuteCommandEvent>
return command;
}
@Override
public UUID getSenderUniqueId() {
return super.getSenderUniqueId();
}
public boolean isBlocked() {
return blocked;
}
@@ -12,8 +12,8 @@ public abstract class FilteredSuggestionEvent extends PATEvent<FilteredSuggestio
this.suggestions = null;
}
public FilteredSuggestionEvent(UUID senderUniqueId, List<String> suggestions) {
super(senderUniqueId);
public FilteredSuggestionEvent(Object senderObj, List<String> suggestions) {
super(senderObj);
this.suggestions = suggestions;
}
@@ -21,11 +21,6 @@ public abstract class FilteredSuggestionEvent extends PATEvent<FilteredSuggestio
return suggestions;
}
@Override
public UUID getSenderUniqueId() {
return super.getSenderUniqueId();
}
public void setSuggestions(List<String> suggestions) {
this.suggestions = suggestions;
}
@@ -14,8 +14,8 @@ public abstract class FilteredTabCompletionEvent extends PATEvent<FilteredTabCom
this.completion = null;
}
public FilteredTabCompletionEvent(UUID senderUniqueId, String cursor, List<String> completion) {
super(senderUniqueId);
public FilteredTabCompletionEvent(Object senderObj, String cursor, List<String> completion) {
super(senderObj);
this.cursor = cursor;
this.completion = completion;
}
@@ -30,11 +30,6 @@ public abstract class FilteredTabCompletionEvent extends PATEvent<FilteredTabCom
return completion;
}
@Override
public UUID getSenderUniqueId() {
return super.getSenderUniqueId();
}
public void setCompletion(List<String> completion) {
this.completion = completion;
}
@@ -0,0 +1,23 @@
package de.rayzs.pat.api.event.events;
import de.rayzs.pat.utils.CommunicationPackets;
import de.rayzs.pat.api.event.PATEvent;
public abstract class ReceiveSyncEvent extends PATEvent<ReceiveSyncEvent> {
private final CommunicationPackets.PacketBundle packetBundle;
public ReceiveSyncEvent() {
super(null);
this.packetBundle = null;
}
public ReceiveSyncEvent(Object senderObj, CommunicationPackets.PacketBundle packetBundle) {
super(senderObj);
this.packetBundle = packetBundle;
}
public CommunicationPackets.PacketBundle getPacketBundle() {
return packetBundle;
}
}
@@ -0,0 +1,30 @@
package de.rayzs.pat.api.event.events;
import de.rayzs.pat.utils.CommunicationPackets;
import de.rayzs.pat.api.event.PATEvent;
public abstract class SentSyncEvent extends PATEvent<SentSyncEvent> {
private final CommunicationPackets.PacketBundle packetBundle;
private final String serverName;
public SentSyncEvent() {
super(null);
this.packetBundle = null;
this.serverName = null;
}
public SentSyncEvent(Object senderObj, CommunicationPackets.PacketBundle packetBundle, String serverName) {
super(senderObj);
this.packetBundle = packetBundle;
this.serverName = serverName;
}
public String getServerName() {
return serverName;
}
public CommunicationPackets.PacketBundle getPacketBundle() {
return packetBundle;
}
}
@@ -0,0 +1,20 @@
package de.rayzs.pat.api.event.events;
import de.rayzs.pat.api.event.PATEvent;
public abstract class ServerPlayersChangeEvent extends PATEvent<ServerPlayersChangeEvent> {
private final Type type;
public ServerPlayersChangeEvent(Object senderObj, Type type) {
super(senderObj);
this.type = type;
}
public ServerPlayersChangeEvent() {
super(null);
this.type = Type.UNKNOWN;
}
public enum Type { JOINED, LEFT, UNKNOWN }
}
@@ -0,0 +1,28 @@
package de.rayzs.pat.api.event.events;
import de.rayzs.pat.api.event.PATEvent;
import java.util.List;
public abstract class UpdatePlayerCommandsEvent extends PATEvent<UpdatePlayerCommandsEvent> {
private List<String> commands;
private boolean serverBased;
public UpdatePlayerCommandsEvent() {
super(null);;
}
public UpdatePlayerCommandsEvent(Object senderObj, List<String> commands, boolean serverBased) {
super(senderObj);
this.commands = commands;
this.serverBased = serverBased;
}
public List<String> getCommands() {
return commands;
}
public boolean isServerBased() {
return serverBased;
}
}
@@ -0,0 +1,14 @@
package de.rayzs.pat.api.event.events;
import de.rayzs.pat.api.event.PATEvent;
public abstract class UpdatePluginEvent extends PATEvent<UpdatePluginEvent> {
public UpdatePluginEvent() {
super(null);;
}
public UpdatePluginEvent(Object senderObj) {
super(senderObj);
}
}
@@ -0,0 +1,43 @@
package de.rayzs.pat.api.event.events.bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
public abstract class ExecuteCommandEvent extends Event implements Cancellable {
private final String command;
private boolean blocked;
public ExecuteCommandEvent() {
this.blocked = false;
this.command = null;
}
public ExecuteCommandEvent(Player player, String command, boolean blocked) {
this.blocked = blocked;
this.command = command;
}
public String getCommand() {
return command;
}
public boolean isBlocked() {
return blocked;
}
public void setBlocked(boolean blocked) {
this.blocked = blocked;
}
@Override
public boolean isCancelled() {
return blocked;
}
@Override
public void setCancelled(boolean cancel) {
this.blocked = cancel;
}
}
@@ -0,0 +1,26 @@
package de.rayzs.pat.api.event.events.bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import java.util.List;
public abstract class FilteredSuggestionEvent extends Event {
private List<String> suggestions;
public FilteredSuggestionEvent() {
this.suggestions = null;
}
public FilteredSuggestionEvent(Player player, List<String> suggestions) {
this.suggestions = suggestions;
}
public List<String> getSuggestions() {
return suggestions;
}
public void setSuggestions(List<String> suggestions) {
this.suggestions = suggestions;
}
}
@@ -0,0 +1,35 @@
package de.rayzs.pat.api.event.events.bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import java.util.List;
public abstract class FilteredTabCompletionEvent extends Event {
private String cursor;
private List<String> completion;
public FilteredTabCompletionEvent() {
this.cursor = null;
this.completion = null;
}
public FilteredTabCompletionEvent(Player player, String cursor, List<String> completion) {
this.cursor = cursor;
this.completion = completion;
}
public abstract void handle(FilteredTabCompletionEvent event);
public String getCursor() {
return cursor;
}
public List<String> getCompletion() {
return completion;
}
public void setCompletion(List<String> completion) {
this.completion = completion;
}
}
@@ -4,7 +4,9 @@ import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.api.netty.bukkit.handlers.*;
import java.util.concurrent.ConcurrentHashMap;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.ExpireCache;
import de.rayzs.pat.utils.Reflection;
import java.util.concurrent.TimeUnit;
import org.bukkit.entity.Player;
import io.netty.channel.*;
import org.bukkit.Bukkit;
@@ -13,6 +15,7 @@ import java.util.*;
public class BukkitPacketAnalyzer {
public static final ConcurrentHashMap<UUID, Channel> INJECTED_PLAYERS = new ConcurrentHashMap<>();
private static final ExpireCache<UUID, Object> SENT_PACKET = new ExpireCache<>(2, TimeUnit.SECONDS);
private static final String HANDLER_NAME = "pat-bukkit-handler", PIPELINE_NAME = "packet_handler";
private static final BukkitPacketHandler PACKET_HANDLER = Reflection.getMinor() >= 16 ? new ModernPacketHandler() : new LegacyPacketHandler();
@@ -27,6 +30,14 @@ public class BukkitPacketAnalyzer {
BukkitPacketAnalyzer.INJECTED_PLAYERS.clear();
}
public static void sendPacket(UUID uuid, Object object) {
Channel channel = INJECTED_PLAYERS.get(uuid);
if(channel == null) return;
SENT_PACKET.put(uuid, object);
channel.pipeline().writeAndFlush(object);
}
public static boolean inject(Player player) {
if(Storage.USE_VELOCITY) return true;
@@ -92,7 +103,7 @@ public class BukkitPacketAnalyzer {
String packetName = packetObj.getClass().getSimpleName();
if (packetName.equals("PacketPlayInTabComplete") || packetName.equals("ServerboundCommandSuggestionPacket")) {
if(!PACKET_HANDLER.handleIncomingPacket(player, packetObj)) return;
if (!PACKET_HANDLER.handleIncomingPacket(player, packetObj)) return;
}
}
@@ -107,6 +118,16 @@ public class BukkitPacketAnalyzer {
if (!PermissionUtil.hasBypassPermission(player)) {
String packetName = packetObj.getClass().getSimpleName();
if (packetName.equals("PacketPlayOutTabComplete") || packetName.equals("ClientboundCommandSuggestionsPacket")) {
UUID uuid = player.getUniqueId();
if((packetName.equals("ClientboundCommandSuggestionsPacket") || Reflection.isFoliaServer()) && SENT_PACKET.contains(player.getUniqueId())) {
Object newPacketObj = SENT_PACKET.get(uuid);
SENT_PACKET.remove(uuid);
super.write(channel, newPacketObj, promise);
return;
}
if(!PACKET_HANDLER.handleOutgoingPacket(player, packetObj)) return;
}
}
@@ -1,5 +1,7 @@
package de.rayzs.pat.api.netty.bukkit.handlers;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.event.events.FilteredTabCompletionEvent;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.BukkitLoader;
@@ -8,6 +10,7 @@ import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import de.rayzs.pat.utils.*;
import java.util.*;
import java.util.stream.Collectors;
public class LegacyPacketHandler implements BukkitPacketHandler {
@@ -42,7 +45,7 @@ public class LegacyPacketHandler implements BukkitPacketHandler {
}
cancelsBeforeHand = Storage.Blacklist.isBlocked(player, input, !Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED);
if(!cancelsBeforeHand) cancelsBeforeHand = Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(input);
if(!cancelsBeforeHand) cancelsBeforeHand = Storage.ConfigSections.Settings.CUSTOM_VERSION.isTabCompletable(input) || Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isTabCompletable(input);
} else return true;
for (Field field : Reflection.getFields(packetObj)) {
@@ -69,7 +72,13 @@ public class LegacyPacketHandler implements BukkitPacketHandler {
newResultList.add(s);
}
} else {
if(!cancelsBeforeHand) newResultList.addAll(Arrays.asList(tR));
if(!cancelsBeforeHand) {
FilteredTabCompletionEvent filteredTabCompletionEvent = PATEventHandler.callFilteredTabCompletionEvents(player.getUniqueId(), input, Arrays.asList(tR));
if(!filteredTabCompletionEvent.isCancelled()) {
List<String> suggestions = Arrays.stream(tR).filter(s -> filteredTabCompletionEvent.getCompletion().contains(s)).collect(Collectors.toList());
newResultList.addAll(suggestions);
}
}
}
field.set(packetObj, newResultList.toArray(new String[0]));
@@ -1,13 +1,21 @@
package de.rayzs.pat.api.netty.bukkit.handlers;
import com.mojang.brigadier.suggestion.Suggestions;
import de.rayzs.pat.api.event.events.FilteredTabCompletionEvent;
import de.rayzs.pat.api.event.PATEventHandler;
import com.mojang.brigadier.suggestion.*;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.BukkitLoader;
import de.rayzs.pat.api.netty.bukkit.*;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.utils.scheduler.PATScheduler;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import de.rayzs.pat.utils.*;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.List;
public class ModernPacketHandler implements BukkitPacketHandler {
@@ -21,6 +29,12 @@ public class ModernPacketHandler implements BukkitPacketHandler {
}
String text = (String) stringField.get(packetObj);
if(Storage.ConfigSections.Settings.PATCH_EXPLOITS.isMalicious(text)) {
MessageTranslator.send(Bukkit.getConsoleSender(), Storage.ConfigSections.Settings.PATCH_EXPLOITS.ALERT_MESSAGE.get().replace("%player%", player.getName()));
PATScheduler.createScheduler(() -> player.kickPlayer(ChatColor.translateAlternateColorCodes('&', Storage.ConfigSections.Settings.PATCH_EXPLOITS.KICK_MESSAGE.get())));
return false;
}
BukkitPacketAnalyzer.insertPlayerInput(player, text);
return true;
}
@@ -28,13 +42,15 @@ public class ModernPacketHandler implements BukkitPacketHandler {
@Override
public boolean handleOutgoingPacket(Player player, Object packetObj) throws Exception {
Object suggestionObj;
String input = BukkitPacketAnalyzer.getPlayerInput(player);
String rawInput = BukkitPacketAnalyzer.getPlayerInput(player), input = rawInput;
if(input == null) return false;
boolean cancelsBeforeHand = false;
boolean is121Packet = packetObj.getClass().getSimpleName().equals("ClientboundCommandSuggestionsPacket"),
cancelsBeforeHand = false;
int spaces = 0;
if(input.startsWith("/")) {
if(input.startsWith("/") || is121Packet) {
input = input.replace("/", "");
if(input.contains(" ")) {
String[] split = input.split(" ");
@@ -43,10 +59,63 @@ public class ModernPacketHandler implements BukkitPacketHandler {
}
cancelsBeforeHand = Storage.Blacklist.isBlocked(player, input, !Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED);
if(!cancelsBeforeHand) cancelsBeforeHand = Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(input);
if(!cancelsBeforeHand) cancelsBeforeHand = Storage.ConfigSections.Settings.CUSTOM_VERSION.isTabCompletable(input) || Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isTabCompletable(input);
}
if(packetObj.getClass().getSimpleName().equals("ClientboundCommandSuggestionsPacket")) {
if(is121Packet || Reflection.isFoliaServer() && packetObj.getClass().getSimpleName().equals("PacketPlayOutTabComplete")) {
try {
Field suggestionsField = Reflection.getFieldsByTypeNormal(packetObj.getClass(), "List", Reflection.SearchOption.ENDS).get(0);
List<?> suggestionsTmp = (List<?>) suggestionsField.get(packetObj),
suggestions = new ArrayList<>(suggestionsTmp);
List<Field> intFields = Reflection.getFieldsByTypeNormal(packetObj.getClass(), "int", Reflection.SearchOption.ENDS);
int id = (int) intFields.get(0).get(packetObj),
start = (int) intFields.get(1).get(packetObj),
length = (int) intFields.get(2).get(packetObj);
Class<?> clientboundCommandSuggestionsPacketClass = Class.forName("net.minecraft.network.protocol.game." + (packetObj.getClass().getSimpleName().equals("PacketPlayOutTabComplete") ? "PacketPlayOutTabComplete" : "ClientboundCommandSuggestionsPacket"));
if ((input.isEmpty() || cancelsBeforeHand) && Reflection.isWeird()) return false;
if (spaces >= 1 && cancelsBeforeHand || !BukkitLoader.isLoaded()) {
suggestions.clear();
return true;
}
if (spaces == 0) {
suggestions.removeIf(suggestion -> {
String command = getSuggestionFromEntry(suggestion);
return Storage.Blacklist.isBlocked(player, command);
});
return true;
} else {
List<String> suggestionsAsString = new ArrayList<>();
for (Object suggestion : suggestions)
suggestionsAsString.add(getSuggestionFromEntry(suggestion));
FilteredTabCompletionEvent filteredTabCompletionEvent = PATEventHandler.callFilteredTabCompletionEvents(player.getUniqueId(), rawInput, suggestionsAsString);
if (filteredTabCompletionEvent.isCancelled()) suggestions.clear();
for (int i = 0; i < suggestions.size(); i++) {
Object csO = suggestions.get(i);
String suggestionAsString = getSuggestionFromEntry(csO);
if (!filteredTabCompletionEvent.getCompletion().contains(suggestionAsString))
suggestions.remove(csO);
}
suggestions.removeIf(suggestion -> !filteredTabCompletionEvent.getCompletion().contains(getSuggestionFromEntry(suggestion)));
}
if(!suggestions.isEmpty()) {
Object clientboundCommandSuggestionsPacketObj = clientboundCommandSuggestionsPacketClass
.getConstructor(int.class, int.class, int.class, List.class)
.newInstance(id, start, length, suggestions);
BukkitPacketAnalyzer.sendPacket(player.getUniqueId(), clientboundCommandSuggestionsPacketObj);
}
return false;
} catch (Throwable throwable) { throwable.printStackTrace(); }
return !cancelsBeforeHand;
}
@@ -62,7 +131,7 @@ public class ModernPacketHandler implements BukkitPacketHandler {
Suggestions suggestions = (Suggestions) suggestionObj;
if((input.length() < 1 || cancelsBeforeHand) && Reflection.isWeird()) return false;
if((input.isEmpty() || cancelsBeforeHand) && Reflection.isWeird()) return false;
if(spaces >= 1 && cancelsBeforeHand || !BukkitLoader.isLoaded()) {
suggestions.getList().clear();
return true;
@@ -74,8 +143,31 @@ public class ModernPacketHandler implements BukkitPacketHandler {
return Storage.Blacklist.isBlocked(player, command);
});
return true;
} else {
List<String> suggestionsAsString = new ArrayList<>();
for (Suggestion suggestion : suggestions.getList())
suggestionsAsString.add(suggestion.getText());
FilteredTabCompletionEvent filteredTabCompletionEvent = PATEventHandler.callFilteredTabCompletionEvents(player.getUniqueId(), rawInput, suggestionsAsString);
if(filteredTabCompletionEvent.isCancelled()) suggestions.getList().clear();
suggestions.getList().removeIf(suggestion -> !filteredTabCompletionEvent.getCompletion().contains(suggestion.getText()));
return !suggestions.getList().isEmpty();
}
}
private String getSuggestionFromEntry(Object suggestionObj) {
try {
List<Field> fields = Reflection.getFieldsByTypeNormal(suggestionObj.getClass(), "String", Reflection.SearchOption.ENDS);
if(fields.isEmpty()) return "";
Field field = fields.get(0);
String result = (String) field.get(suggestionObj);
field.setAccessible(false);
return result;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return true;
return "";
}
}
@@ -1,12 +1,17 @@
package de.rayzs.pat.api.netty.proxy;
import com.mojang.brigadier.arguments.StringArgumentType;
import de.rayzs.pat.api.brand.CustomServerBrand;
import de.rayzs.pat.api.communication.client.ClientInfo;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.MessageToMessageDecoder;
import de.rayzs.pat.utils.permission.PermissionUtil;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import de.rayzs.pat.api.communication.Communicator;
import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.PacketWrapper;
import java.nio.ByteBuffer;
import java.util.concurrent.ConcurrentHashMap;
import com.mojang.brigadier.tree.CommandNode;
import net.md_5.bungee.api.plugin.Command;
@@ -159,7 +164,12 @@ public class BungeePacketAnalyzer {
return;
}
if (wrapper.packet instanceof Commands) {
if(wrapper.packet instanceof PluginMessage) {
PluginMessage pluginMessage = (PluginMessage) wrapper.packet;
if(CustomServerBrand.isEnabled() && CustomServerBrand.isBrandTag(pluginMessage.getTag()))
return;
} else if (wrapper.packet instanceof Commands) {
Commands response = (Commands) wrapper.packet;
modifyCommands(player, response, commands);
player.unsafe().sendPacket(response);
@@ -187,7 +197,8 @@ public class BungeePacketAnalyzer {
if(!playerInput.equals("/")) {
cancelsBeforeHand = Storage.Blacklist.isBlocked(player, StringUtils.replaceFirst(playerInput, "/", ""), !Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED, server);
if(!cancelsBeforeHand) cancelsBeforeHand = Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(StringUtils.replaceFirst(playerInput, "/", ""));
if(!cancelsBeforeHand) cancelsBeforeHand = Storage.ConfigSections.Settings.CUSTOM_VERSION.isTabCompletable(StringUtils.replaceFirst(playerInput, "/", "")) || Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isTabCompletable(StringUtils.replaceFirst(playerInput, "/", ""));
}
final String cursor = playerInput;
if(cursor.startsWith("/")) {
@@ -1,15 +1,28 @@
package de.rayzs.pat.api.netty.proxy;
import com.mojang.brigadier.tree.CommandNode;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.proxy.crypto.SignedChatCommand;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.packet.chat.session.UnsignedPlayerCommandPacket;
import de.rayzs.pat.api.brand.CustomServerBrand;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.event.events.FilteredTabCompletionEvent;
import de.rayzs.pat.plugin.listeners.velocity.VelocityBlockCommandListener;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.utils.permission.PermissionUtil;
import com.velocitypowered.proxy.protocol.packet.*;
import java.lang.reflect.Field;
import java.util.concurrent.ConcurrentHashMap;
import com.velocitypowered.api.proxy.Player;
import de.rayzs.pat.plugin.VelocityLoader;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.*;
import io.netty.channel.*;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import java.util.*;
public class VelocityPacketAnalyzer {
@@ -20,7 +33,7 @@ public class VelocityPacketAnalyzer {
private static final HashMap<Player, String> PLAYER_INPUT_CACHE = new HashMap<>();
private static HashMap<String, CommandsCache> COMMANDS_CACHE_MAP = new HashMap<>();
private static Class<?> minecraftConnectionClass, connectedPlayerConnectionClass;
private static Class<?> minecraftConnectionClass, connectedPlayerConnectionClass, signedChatCommandPacketClass;
public static void injectAll() {
VelocityLoader.getServer().getAllPlayers().forEach(VelocityPacketAnalyzer::inject);
@@ -109,11 +122,41 @@ public class VelocityPacketAnalyzer {
MinecraftPacket packet = (MinecraftPacket) msg;
if(packet.getClass().getSimpleName().equals("SignedChatCommand")) {
try {
if(signedChatCommandPacketClass == null)
signedChatCommandPacketClass = Class.forName("com.velocitypowered.proxy.crypto.SignedChatCommand");
Object signedChatCommandPacket = signedChatCommandPacketClass.cast(packet);
Field commandField = signedChatCommandPacket.getClass().getField("command");
String command = (String) commandField.get(signedChatCommandPacket);
if(!VelocityBlockCommandListener.handleCommand(player, command))
return;
} catch (Exception exception) {
exception.printStackTrace();
}
}
if(packet instanceof UnsignedPlayerCommandPacket) {
UnsignedPlayerCommandPacket unsignedPlayerCommandPacket = (UnsignedPlayerCommandPacket) packet;
if(VelocityBlockCommandListener.handleCommand(player, unsignedPlayerCommandPacket.getCommand()))
return;
}
if(packet instanceof TabCompleteRequestPacket) {
TabCompleteRequestPacket request = (TabCompleteRequestPacket) msg;
if(request.getCommand() != null) {
insertPlayerInput(player, request.getCommand());
super.channelRead(ctx, msg);
if(Storage.ConfigSections.Settings.PATCH_EXPLOITS.isMalicious(request.getCommand())) {
MessageTranslator.send(VelocityLoader.getServer().getConsoleCommandSource(), Storage.ConfigSections.Settings.PATCH_EXPLOITS.ALERT_MESSAGE.get().replace("%player%", player.getUsername()));
player.disconnect(LegacyComponentSerializer.legacyAmpersand().deserialize(Storage.ConfigSections.Settings.PATCH_EXPLOITS.KICK_MESSAGE.get()));
} else {
insertPlayerInput(player, request.getCommand());
super.channelRead(ctx, msg);
}
}
} else super.channelRead(ctx, msg);
}
@@ -127,12 +170,20 @@ public class VelocityPacketAnalyzer {
MinecraftPacket packet = (MinecraftPacket) msg;
if(packet instanceof TabCompleteResponsePacket) {
if(packet instanceof PluginMessagePacket) {
PluginMessagePacket pluginMessagePacket = (PluginMessagePacket) packet;
if(CustomServerBrand.isEnabled() && CustomServerBrand.isBrandTag(pluginMessagePacket.getChannel()) && !player.getCurrentServer().isPresent()) {
PacketUtils.BrandManipulate brandManipulatePacket = CustomServerBrand.createBrandPacket(player);
super.write(ctx, new PluginMessagePacket(pluginMessagePacket.getChannel(), brandManipulatePacket.getByteBuf()), promise);
return;
}
} else if(packet instanceof TabCompleteResponsePacket) {
if (!PermissionUtil.hasBypassPermission(player) && player.getCurrentServer().isPresent()) {
TabCompleteResponsePacket response = (TabCompleteResponsePacket) packet;
boolean cancelsBeforeHand = false;
String playerInput = getPlayerInput(player), server = player.getCurrentServer().get().getServerInfo().getName();
String playerInput = getPlayerInput(player), rawPlayerInput = playerInput, server = player.getCurrentServer().get().getServerInfo().getName();
int spaces = 0;
if(playerInput.contains(" ")) {
@@ -143,7 +194,7 @@ public class VelocityPacketAnalyzer {
if(!playerInput.equals("/")) {
cancelsBeforeHand = Storage.Blacklist.isBlocked(player, StringUtils.replaceFirst(playerInput, "/", ""), !Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED, server);
if(!cancelsBeforeHand) cancelsBeforeHand = Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(StringUtils.replaceFirst(playerInput, "/", ""));
if(!cancelsBeforeHand) cancelsBeforeHand = Storage.ConfigSections.Settings.CUSTOM_VERSION.isTabCompletable(StringUtils.replaceFirst(playerInput, "/", "")) || Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isTabCompletable(StringUtils.replaceFirst(playerInput, "/", ""));
}
final String cursor = playerInput;
@@ -163,6 +214,14 @@ public class VelocityPacketAnalyzer {
});
} else {
if (cancelsBeforeHand) return;
List<String> suggestionsAsString = new ArrayList<>();
response.getOffers().forEach(offer -> suggestionsAsString.add(offer.getText()));
FilteredTabCompletionEvent filteredTabCompletionEvent = PATEventHandler.callFilteredTabCompletionEvents(player.getUniqueId(), rawPlayerInput, suggestionsAsString);
if(filteredTabCompletionEvent.isCancelled()) return;
response.getOffers().removeIf(offer -> !filteredTabCompletionEvent.getCompletion().contains(offer.getText()));
if(response.getOffers().isEmpty()) return;
}
}
}
@@ -170,22 +229,33 @@ public class VelocityPacketAnalyzer {
} else if(packet instanceof AvailableCommandsPacket) {
if (!PermissionUtil.hasBypassPermission(player) && player.getCurrentServer().isPresent()) {
AvailableCommandsPacket commands = (AvailableCommandsPacket) packet;
if(commands.getRootNode().getChildren().isEmpty() || !player.getCurrentServer().isPresent()) return;
String serverName = player.getCurrentServer().get().getServer().getServerInfo().getName();
if(!commands.getRootNode().getChildren().isEmpty()) {
String serverName = player.getCurrentServer().get().getServer().getServerInfo().getName();
if(!COMMANDS_CACHE_MAP.containsKey(serverName))
COMMANDS_CACHE_MAP.put(serverName, new CommandsCache().reverse());
CommandsCache commandsCache = COMMANDS_CACHE_MAP.get(serverName);
if (!COMMANDS_CACHE_MAP.containsKey(serverName))
COMMANDS_CACHE_MAP.put(serverName, new CommandsCache().reverse());
CommandsCache commandsCache = COMMANDS_CACHE_MAP.get(serverName);
List<String> commandsAsString = new ArrayList<>();
commands.getRootNode().getChildren().stream().filter(command -> command != null && command.getName() != null).forEach(command -> commandsAsString.add(command.getName()));
commandsCache.handleCommands(commandsAsString, serverName);
List<String> commandsAsString = new ArrayList<>();
commands.getRootNode().getChildren().stream().filter(command -> command != null && command.getName() != null).forEach(command -> commandsAsString.add(command.getName()));
commandsCache.handleCommands(commandsAsString, serverName);
if(PermissionUtil.hasBypassPermission(player)) return;
if (PermissionUtil.hasBypassPermission(player)) return;
final List<String> playerCommands = commandsCache.getPlayerCommands(commandsAsString, player, player.getUniqueId(), serverName);
commands.getRootNode().getChildren().removeIf(command -> command == null || command.getName() == null || playerCommands.contains(command.getName()));
final boolean newer = player.getProtocolVersion().getProtocol() > 340;
final List<String> playerCommands = commandsCache.getPlayerCommands(commandsAsString, player, player.getUniqueId(), serverName);
if(commands.getRootNode().getChildren().size() == 1 && newer
&& commands.getRootNode().getChild("args") != null
&& commands.getRootNode().getChild("args").getChildren().isEmpty()) {
super.write(ctx, msg, promise);
return;
}
commands.getRootNode().getChildren().removeIf(command -> command == null || command.getName() == null || playerCommands.contains(command.getName()));
}
}
}
@@ -1,5 +1,6 @@
package de.rayzs.pat.api.storage;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.storage.placeholders.commands.general.*;
import de.rayzs.pat.api.storage.placeholders.commands.group.*;
import de.rayzs.pat.api.storage.blacklist.BlacklistCreator;
@@ -33,6 +34,8 @@ public class Storage {
loadConfig();
loadToken();
if(loadBlacklist) Blacklist.loadAll();
PATEventHandler.callUpdatePluginEvents();
}
public static void loadToken() {
@@ -91,6 +94,7 @@ public class Storage {
CONFIGURATION = Configurator.get("config"),
STORAGE = Configurator.get("storage"),
PLACEHOLDERS = Configurator.get("placeholders"),
CUSTOM_RESPONSES = Configurator.get("custom-responses"),
TOKEN = Configurator.get("token");
public static void initialize() {}
@@ -105,10 +109,12 @@ public class Storage {
public static BlockNamespaceCommandsSection BLOCK_NAMESPACE_COMMANDS = new BlockNamespaceCommandsSection();
public static HandleThroughProxySection HANDLE_THROUGH_PROXY = new HandleThroughProxySection();
public static PatchExploitSection PATCH_EXPLOITS = new PatchExploitSection();
public static CustomBrandSection CUSTOM_BRAND = new CustomBrandSection();
public static CancelCommandSection CANCEL_COMMAND = new CancelCommandSection();
public static CustomPluginsSection CUSTOM_PLUGIN = new CustomPluginsSection();
public static CustomVersionSection CUSTOM_VERSION = new CustomVersionSection();
public static DisableSyncSection DISABLE_SYNC = new DisableSyncSection();
public static CustomProtocolPingSection CUSTOM_PROTOCOL_PING = new CustomProtocolPingSection();
public static CustomUnknownCommandSection CUSTOM_UNKNOWN_COMMAND = new CustomUnknownCommandSection();
public static TurnBlacklistToWhitelistSection TURN_BLACKLIST_TO_WHITELIST = new TurnBlacklistToWhitelistSection();
@@ -127,6 +133,7 @@ public class Storage {
public static InfoSection INFO = new InfoSection();
public static NoPermissionSection NO_PERMISSION = new NoPermissionSection();
public static NotificationSection NOTIFICATION = new NotificationSection();
public static PermsCheckSection PERMS_CHECK = new PermsCheckSection();
public static PostDebugSection POST_DEBUG = new PostDebugSection();
public static OnlyForProxySection NO_PROXY = new OnlyForProxySection();
public static ReloadSection RELOAD = new ReloadSection();
@@ -184,7 +191,7 @@ public class Storage {
public static class Blacklist {
private static HashMap<String, GeneralBlacklist> SERVER_BLACKLISTS = new HashMap<>();
private static final HashMap<String, GeneralBlacklist> SERVER_BLACKLISTS = new HashMap<>();
private static final GeneralBlacklist BLACKLIST = BlacklistCreator.createGeneralBlacklist();
private static final IgnoredServersStorage IGNORED_SERVERS = new GeneralIgnoredServers();
private static final ExpireCache<String, List<GeneralBlacklist>> CACHED_SERVER_BLACKLIST = new ExpireCache<>(1, TimeUnit.HOURS);
@@ -246,7 +253,9 @@ public class Storage {
public static List<GeneralBlacklist> getBlacklists(String server) {
final String finalServer = server.toLowerCase();
if(CACHED_SERVER_BLACKLIST.contains(finalServer)) return CACHED_SERVER_BLACKLIST.get(finalServer);
if (CACHED_SERVER_BLACKLIST.contains(finalServer))
return CACHED_SERVER_BLACKLIST.get(finalServer);
List<GeneralBlacklist> blacklists = new ArrayList<>();
SERVER_BLACKLISTS.entrySet()
@@ -337,13 +346,22 @@ public class Storage {
}
public static boolean isListed(Object playerObj, String command, boolean intensive, boolean listed, boolean slash, String server) {
return isListed(playerObj, command, intensive, listed, slash, server, false);
}
public static boolean isListed(Object playerObj, String command, boolean intensive, boolean listed, boolean slash, String server, boolean instantReturn) {
if(GroupManager.getGroupsByServer(server).stream().anyMatch(group -> isInListed(command, group.getAllCommands(server), intensive) && group.hasPermission(playerObj)))
return false;
if(!listed) for (GeneralBlacklist blacklist : getBlacklists(server)) {
if(listed) return true;
for (GeneralBlacklist blacklist : getBlacklists(server)) {
listed = blacklist.isListed(command, intensive, true, slash);
if(instantReturn) return listed;
if(listed) break;
}
return listed;
}
@@ -366,19 +384,21 @@ public class Storage {
if(focusOnBlock && blockedGlobal) return true;
for (GeneralBlacklist blacklist : getBlacklists(server)) {
if(!focusOnBlock) {
blockedServer = blacklist.isBlockedIgnorePermission(command, intensive);
if (blockedServer) break;
} else {
if(blacklist.isBlocked(command, intensive)) return true;
}
if(focusOnBlock && blacklist.isBlocked(command, intensive))
return true;
blockedServer = blacklist.isBlockedIgnorePermission(command, intensive);
break;
}
blocked = turn ? blockedGlobal && blockedServer : blockedServer || blockedGlobal;
if(!blocked
// The reason which there's no tab-completion and also why every server-based list needs to exist to avoid this issue.
if (turn && !blocked
&& CACHED_SERVER_BLACKLIST.contains(server)
&& CACHED_SERVER_BLACKLIST.get(server).size() == 0)
if(turn) blocked = true;
&& CACHED_SERVER_BLACKLIST.get(server).isEmpty())
blocked = true;
return blocked;
}
@@ -25,6 +25,7 @@ public class HelpSection extends ConfigStorage {
, "&f info &7to get a few information"
, "&f postdebug &7to post the PAT logs"
, "&f update <player> &7to update player(s) permissions"
, "&f perms <player> &7to check a player's permissions"
, "&f creategroup (group) &7Create a group"
, "&f deletegroup (group) &7Delete a group"
, "&f setpriority (group) (priority) &7to set the priority"
@@ -42,6 +43,7 @@ public class HelpSection extends ConfigStorage {
, "&f info &7to get a few information"
, "&f postdebug &7to post the PAT logs"
, "&f update <player> &7to update player(s) permissions"
, "&f perms <player> &7to check a player's permissions"
, "&f creategroup (group) &7Create a group"
, "&f deletegroup (group) &7Delete a group"
, "&f setpriority (group) (priority) &7to set the priority"
@@ -0,0 +1,21 @@
package de.rayzs.pat.api.storage.config.messages;
import de.rayzs.pat.api.storage.storages.ConfigStorage;
import de.rayzs.pat.utils.configuration.helper.*;
public class PermsCheckSection extends ConfigStorage {
public String MESSAGE, PLAYER_MISSING, PLAYER_NOT_ONLINE;
public PermsCheckSection() {
super("perms-check");
}
@Override
public void load() {
super.load();
MESSAGE = new ConfigSectionHelper<String>(this, "message", "&7All of &e%player%'s &7PAT-related permission: &e%permissions%").getOrSet();
PLAYER_MISSING = new ConfigSectionHelper<String>(this, "player-is-missing", "&cPlease specify the player whose permission you want to check.").getOrSet();
PLAYER_NOT_ONLINE = new ConfigSectionHelper<String>(this, "player-not-online", "&c%player% is not online!").getOrSet();
}
}
@@ -7,7 +7,7 @@ import java.util.Collections;
public class CancelCommandSection extends ConfigStorage {
public boolean ENABLED;
public MultipleMessagesHelper MESSAGE;
public MultipleMessagesHelper BASE_COMMAND_RESPONSE, SUB_COMMAND_RESPONSE;
public CancelCommandSection() {
super("cancel-blocked-commands");
@@ -17,6 +17,7 @@ public class CancelCommandSection extends ConfigStorage {
public void load() {
super.load();
ENABLED = new ConfigSectionHelper<Boolean>(this, "enabled", true).getOrSet();
MESSAGE = new MultipleMessagesHelper(this, "message", Collections.singletonList("&cThe command %command% is blocked!"));
BASE_COMMAND_RESPONSE = new MultipleMessagesHelper(this, "base-command-message", Collections.singletonList("&cThe command %command% is blocked!"));
SUB_COMMAND_RESPONSE = new MultipleMessagesHelper(this, "sub-command-message", Collections.singletonList("&cThis sub-argument is blocked!"));
}
}
@@ -6,7 +6,7 @@ import java.util.*;
public class CustomPluginsSection extends ConfigStorage {
public boolean ENABLED;
public boolean ENABLED, ALWAYS_TAB_COMPLETABLE;
public MultipleMessagesHelper MESSAGE, COMMANDS;
public CustomPluginsSection() {
@@ -17,10 +17,18 @@ public class CustomPluginsSection extends ConfigStorage {
public void load() {
super.load();
ENABLED = new ConfigSectionHelper<Boolean>(this, "enabled", true).getOrSet();
COMMANDS = new MultipleMessagesHelper(this, "commands", Arrays.asList("pl", "plugins", "bukkit:pl", "bukkit:plugins"));
ALWAYS_TAB_COMPLETABLE = new ConfigSectionHelper<Boolean>(this, "always-tab-completable", false).getOrSet();
COMMANDS = new MultipleMessagesHelper(this, "commands", Arrays.asList("pl", "plugins"));
MESSAGE = new MultipleMessagesHelper(this, "message", Collections.singletonList("&fPlugins (0):"));
}
public boolean isTabCompletable(String command) {
if (!isCommand(command))
return false;
return ALWAYS_TAB_COMPLETABLE;
}
public boolean isCommand(String command) {
if(!ENABLED) return false;
@@ -31,7 +39,7 @@ public class CustomPluginsSection extends ConfigStorage {
command = command.split(" ")[0];
}
for (String currentCommand : COMMANDS.getLines()) {
if (currentCommand.equals(command.toLowerCase()))
if (currentCommand.equalsIgnoreCase(command))
return true;
}
return false;
@@ -7,7 +7,7 @@ import java.util.*;
public class CustomVersionSection extends ConfigStorage {
public boolean ENABLED;
public boolean ENABLED, ALWAYS_TAB_COMPLETABLE;
public MultipleMessagesHelper MESSAGE, COMMANDS;
public CustomVersionSection() {
@@ -18,16 +18,24 @@ public class CustomVersionSection extends ConfigStorage {
public void load() {
super.load();
ENABLED = new ConfigSectionHelper<Boolean>(this, "enabled", true).getOrSet();
COMMANDS = new MultipleMessagesHelper(this, "commands", Arrays.asList("icanhasbukkit", "ver", "version", "bukkit:ver", "bukkit:version"));
ALWAYS_TAB_COMPLETABLE = new ConfigSectionHelper<Boolean>(this, "always-tab-completable", false).getOrSet();
COMMANDS = new MultipleMessagesHelper(this, "commands", Arrays.asList("icanhasbukkit", "about", "ver", "version"));
MESSAGE = new MultipleMessagesHelper(this, "message", Collections.singletonList("&fThis server is running CraftBukkit version git-NasaSpigot-294 (MC: X)"));
}
public boolean isTabCompletable(String command) {
if (!isCommand(command))
return false;
return ALWAYS_TAB_COMPLETABLE;
}
public boolean isCommand(String command) {
if(!ENABLED) return false;
command = StringUtils.getFirstArg(command);
for (String currentCommand : COMMANDS.getLines()) {
if (currentCommand.equals(command.toLowerCase()))
if (currentCommand.equalsIgnoreCase(command))
return true;
}
return false;
@@ -0,0 +1,22 @@
package de.rayzs.pat.api.storage.config.settings;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.api.storage.storages.ConfigStorage;
import de.rayzs.pat.utils.configuration.helper.ConfigSectionHelper;
public class DisableSyncSection extends ConfigStorage {
public boolean DISABLED;
public DisableSyncSection() {
super("disable-sync");
}
@Override
public void load() {
super.load();
if(!Reflection.isProxyServer()) return;
DISABLED = new ConfigSectionHelper<Boolean>(this, null, false).getOrSet();
}
}
@@ -0,0 +1,32 @@
package de.rayzs.pat.api.storage.config.settings;
import de.rayzs.pat.api.storage.storages.ConfigStorage;
import de.rayzs.pat.utils.configuration.helper.*;
import de.rayzs.pat.utils.StringUtils;
import java.util.Collections;
public class PatchExploitSection extends ConfigStorage {
public boolean ENABLED;
public ConfigSectionHelper<String> ALERT_MESSAGE, KICK_MESSAGE;
public PatchExploitSection() {
super("patch-exploits");
}
@Override
public void load() {
super.load();
ENABLED = new ConfigSectionHelper<Boolean>(this, "enabled", true).getOrSet();
ALERT_MESSAGE = new ConfigSectionHelper<>(this, "alert-message", "%prefix% &4%player% &ctried to crash/lag the server.");
KICK_MESSAGE = new ConfigSectionHelper(this, "kick-message", "&cFailed to read packet! Please reconnect.");
}
public boolean isMalicious(String text) {
if(!ENABLED) return false;
return text.length() > 256
|| text.contains("nbt")
&& (StringUtils.countMatches('[', text) > 15 || StringUtils.countMatches('{', text) > 25);
}
}
@@ -6,7 +6,7 @@ import java.util.*;
public class UpdateSection extends ConfigStorage {
public boolean ENABLED;
public boolean ENABLED, AUTO_UPDATE_CONFIG;
public int PERIOD;
public MultipleMessagesHelper OUTDATED, UPDATED;
@@ -19,6 +19,7 @@ public class UpdateSection extends ConfigStorage {
super.load();
ENABLED = new ConfigSectionHelper<Boolean>(this, "enabled", true).getOrSet();
PERIOD = new ConfigSectionHelper<Integer>(this, "period", 10000).getOrSet();
AUTO_UPDATE_CONFIG = new ConfigSectionHelper<Boolean>(this, "auto-update-config", true).getOrSet();
UPDATED = new MultipleMessagesHelper(this, "updated", Collections.singletonList("&aYou are using the newest version! ^^"));
OUTDATED = new MultipleMessagesHelper(this, "outdated", Arrays.asList(
"&8[&4ProAntiTab&8] &cThere is a new version available! (%newest_version%)",
@@ -0,0 +1,16 @@
package de.rayzs.pat.api.storage.placeholders.messages;
import de.rayzs.pat.api.storage.storages.PlaceholderStorage;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.StringUtils;
import org.bukkit.entity.Player;
public class BlockedBaseCommandPlaceholder extends PlaceholderStorage {
public BlockedBaseCommandPlaceholder() { super("message_base_blocked"); }
@Override
public String onRequest(Player player, String param) {
return StringUtils.buildStringList(Storage.ConfigSections.Settings.CANCEL_COMMAND.BASE_COMMAND_RESPONSE.getLines());
}
}
@@ -1,16 +1,16 @@
package de.rayzs.pat.api.storage.placeholders.messages;
import de.rayzs.pat.api.storage.storages.PlaceholderStorage;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.api.storage.storages.PlaceholderStorage;
import de.rayzs.pat.utils.StringUtils;
import org.bukkit.entity.Player;
public class BlockedCommandPlaceholder extends PlaceholderStorage {
public class BlockedSubCommandPlaceholder extends PlaceholderStorage {
public BlockedCommandPlaceholder() { super("message_blocked"); }
public BlockedSubCommandPlaceholder() { super("message_sub_blocked"); }
@Override
public String onRequest(Player player, String param) {
return StringUtils.buildStringList(Storage.ConfigSections.Settings.CANCEL_COMMAND.MESSAGE.getLines());
return StringUtils.buildStringList(Storage.ConfigSections.Settings.CANCEL_COMMAND.SUB_COMMAND_RESPONSE.getLines());
}
}
@@ -1,5 +1,6 @@
package de.rayzs.pat.plugin;
import de.rayzs.pat.plugin.modules.subargs.SubArgsModule;
import de.rayzs.pat.utils.configuration.updater.ConfigUpdater;
import de.rayzs.pat.api.netty.bukkit.BukkitPacketAnalyzer;
import de.rayzs.pat.api.communication.BackendUpdater;
@@ -13,11 +14,14 @@ import de.rayzs.pat.plugin.commands.BukkitCommand;
import de.rayzs.pat.api.brand.CustomServerBrand;
import de.rayzs.pat.utils.hooks.PlaceholderHook;
import de.rayzs.pat.plugin.listeners.bukkit.*;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.utils.group.GroupManager;
import de.rayzs.pat.plugin.metrics.bStats;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.response.action.ActionHandler;
import org.bukkit.plugin.java.JavaPlugin;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.scheduler.*;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import de.rayzs.pat.utils.*;
@@ -32,13 +36,14 @@ public class BukkitLoader extends JavaPlugin {
private static java.util.logging.Logger logger;
private static boolean loaded = false, checkUpdate = false, suggestions = false;
private static Map<String, Command> commandsMap = null;
private int updaterTaskId;
private PATSchedulerTask updaterTask;
@Override
public void onLoad() {
Configurator.createResourcedFile(getDataFolder(), "files\\bukkit-config.yml", "config.yml", false);
Configurator.createResourcedFile(getDataFolder(), "files\\bukkit-storage.yml", "storage.yml", false);
Configurator.createResourcedFile(getDataFolder(), "files\\bukkit-placeholders.yml", "placeholders.yml", false);
Configurator.createResourcedFile(getDataFolder(), "files\\bukkit-custom-responses.yml", "custom-responses.yml", false);
}
@Override
@@ -52,6 +57,7 @@ public class BukkitLoader extends JavaPlugin {
ConfigUpdater.initialize();
Storage.CURRENT_VERSION = getDescription().getVersion();
VersionComparer.setCurrentVersion(Storage.CURRENT_VERSION);
Storage.loadAll(true);
@@ -94,9 +100,11 @@ public class BukkitLoader extends JavaPlugin {
ViaVersionAdapter.initialize();
if(Storage.USE_SIMPLECLOUD)
Logger.warning("Detected SimpleCloud and therefore MiniMessages by Kyori are disabled!");
Logger.warning("Detected SimpleCloud. Therefore, MiniMessages are disabled!");
ConfigUpdater.broadcastMissingParts();
ActionHandler.initialize();
SubArgsModule.initialize();
}
@Override
@@ -128,15 +136,36 @@ public class BukkitLoader extends JavaPlugin {
public void startUpdaterTask() {
if (!Storage.ConfigSections.Settings.UPDATE.ENABLED) return;
updaterTaskId = Bukkit.getScheduler().scheduleAsyncRepeatingTask(this, () -> {
updaterTask = PATScheduler.createAsyncScheduler(() -> {
String result = new ConnectionBuilder().setUrl("https://www.rayzs.de/proantitab/api/version.php")
.setProperties("ProAntiTab", "4654").connect().getResponse();
if(result == null) result = "internet";
Storage.NEWER_VERSION = result;
VersionComparer.setNewestVersion(Storage.NEWER_VERSION);
if (!Storage.NEWER_VERSION.equals(Storage.CURRENT_VERSION)) {
Bukkit.getScheduler().cancelTask(updaterTaskId);
if(VersionComparer.isDeveloperVersion()) {
updaterTask.cancelTask();
Logger.info("§8[§fPAT | Bukkit§8] §7Please be aware that you are currently using a §bdeveloper §7version of ProAntiTab. Bugs, errors and a lot of debug messages might be included.");
} else if(!checkUpdate && (VersionComparer.isNewest() || VersionComparer.isUnreleased())) {
updaterTask.cancelTask();
checkUpdate = true;
if(VersionComparer.isUnreleased()) {
Logger.info("§8[§fPAT | Bukkit§8] §7Please be aware that you are currently using an §eunreleased §7version of ProAntiTab.");
return;
}
Storage.ConfigSections.Settings.UPDATE.UPDATED.getLines().forEach(Logger::warning);
} else if(VersionComparer.isOutdated()) {
updaterTask.cancelTask();
Storage.OUTDATED = true;
Storage.ConfigSections.Settings.UPDATE.OUTDATED.getLines().forEach(Logger::warning);
} else if(!Storage.NEWER_VERSION.equals(Storage.CURRENT_VERSION)) {
updaterTask.cancelTask();
switch (result) {
case "internet":
Logger.warning("Failed to build connection to website! (No internet?)");
@@ -147,15 +176,6 @@ public class BukkitLoader extends JavaPlugin {
case "exception":
Logger.warning("Failed to build connection to website! (Outdated java version?)");
break;
default:
Storage.OUTDATED = true;
Storage.ConfigSections.Settings.UPDATE.OUTDATED.getLines().forEach(Logger::warning);
break;
}
} else {
if(!checkUpdate) {
checkUpdate = true;
Storage.ConfigSections.Settings.UPDATE.UPDATED.getLines().forEach(Logger::warning);
}
}
}, 20L, 20L * Storage.ConfigSections.Settings.UPDATE.PERIOD);
@@ -178,7 +198,7 @@ public class BukkitLoader extends JavaPlugin {
Storage.Blacklist.getBlacklist().setList(new ArrayList<>());
else if (!ArrayUtils.compareStringArrays(Storage.Blacklist.getBlacklist().getCommands(), commandsPacket.getCommands())) {
BukkitAntiTabListener.setChangeStatus();
if(Reflection.getMinor() >= 13) BukkitAntiTabListener.setChangeStatus();
Storage.Blacklist.getBlacklist().setList(commandsPacket.getCommands());
}
@@ -195,13 +215,16 @@ public class BukkitLoader extends JavaPlugin {
if(!loaded) loaded = true;
if(Reflection.getMinor() < 16) return;
if(Reflection.getMinor() >= 16) {
if(Storage.USE_VELOCITY)
BukkitAntiTabListener.updateCommands();
if (Storage.USE_VELOCITY)
BukkitAntiTabListener.updateCommands();
Logger.debug("Force server to load all players tab-completion due to received sync!");
BukkitAntiTabListener.handleTabCompletion(Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED ? Storage.Blacklist.getBlacklist().getCommands() : getNotBlockedCommands());
Logger.debug("Force server to load all players tab-completion due to received sync!");
BukkitAntiTabListener.handleTabCompletion(Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED ? Storage.Blacklist.getBlacklist().getCommands() : getNotBlockedCommands());
}
PATEventHandler.callReceiveSyncEvents(packetBundle);
}
public static boolean doesCommandExist(String command, boolean replace) {
@@ -1,19 +1,23 @@
package de.rayzs.pat.plugin;
import de.rayzs.pat.utils.configuration.updater.ConfigUpdater;
import de.rayzs.pat.plugin.modules.subargs.SubArgsModule;
import de.rayzs.pat.api.netty.proxy.BungeePacketAnalyzer;
import de.rayzs.pat.utils.configuration.Configurator;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.utils.adapter.LuckPermsAdapter;
import de.rayzs.pat.api.communication.Communicator;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import de.rayzs.pat.utils.response.action.ActionHandler;
import net.md_5.bungee.api.scheduler.ScheduledTask;
import de.rayzs.pat.plugin.commands.BungeeCommand;
import de.rayzs.pat.api.brand.CustomServerBrand;
import de.rayzs.pat.plugin.listeners.bungee.*;
import de.rayzs.pat.utils.group.GroupManager;
import net.md_5.bungee.api.config.ServerInfo;
import de.rayzs.pat.plugin.metrics.bStats;
import de.rayzs.pat.plugin.logger.Logger;
import net.md_5.bungee.api.connection.*;
import de.rayzs.pat.api.storage.Storage;
import net.md_5.bungee.api.ProxyServer;
import java.util.concurrent.TimeUnit;
@@ -33,6 +37,7 @@ public class BungeeLoader extends Plugin {
Configurator.createResourcedFile(getDataFolder(), "files\\proxy-config.yml", "config.yml", false);
Configurator.createResourcedFile(getDataFolder(), "files\\proxy-storage.yml", "storage.yml", false);
Configurator.createResourcedFile(getDataFolder(), "files\\proxy-placeholders.yml", "placeholders.yml", false);
Configurator.createResourcedFile(getDataFolder(), "files\\proxy-custom-responses.yml", "custom-responses.yml", false);
}
@Override
@@ -45,6 +50,7 @@ public class BungeeLoader extends Plugin {
Storage.USE_SIMPLECLOUD = Reflection.doesClassExist("eu.thesimplecloud.plugin.startup.CloudPlugin");
Storage.CURRENT_VERSION = getDescription().getVersion();
VersionComparer.setCurrentVersion(Storage.CURRENT_VERSION);
Storage.loadAll(true);
@@ -65,7 +71,9 @@ public class BungeeLoader extends Plugin {
manager.registerListener(this, new WaterfallAntiTabListener());
startUpdaterTask();
ProxyServer.getInstance().getScheduler().schedule(this, Communicator::syncData, 5, TimeUnit.SECONDS);
if (!Storage.ConfigSections.Settings.DISABLE_SYNC.DISABLED)
ProxyServer.getInstance().getScheduler().schedule(this, Communicator::syncData, 5, TimeUnit.SECONDS);
Storage.PLUGIN_OBJECT = this;
@@ -82,6 +90,8 @@ public class BungeeLoader extends Plugin {
BungeePacketAnalyzer.injectAll();
ConfigUpdater.broadcastMissingParts();
ActionHandler.initialize();
SubArgsModule.initialize();
}
@Override
@@ -114,26 +124,58 @@ public class BungeeLoader extends Plugin {
String result = new ConnectionBuilder().setUrl("https://www.rayzs.de/proantitab/api/version.php")
.setProperties("ProAntiTab", "4654").connect().getResponse();
Storage.NEWER_VERSION = result;
VersionComparer.setNewestVersion(Storage.NEWER_VERSION);
if (!Storage.NEWER_VERSION.equals(Storage.CURRENT_VERSION)) {
if(VersionComparer.isDeveloperVersion()) {
getProxy().getScheduler().cancel(updaterTask);
if (result.equals("unknown")) {
Logger.warning("Failed reaching web host! (firewall enabled? website down?)");
} else if (result.equals("exception")) {
Logger.warning("Failed creating web instance! (outdated java version?)");
} else {
Storage.OUTDATED = true;
Storage.ConfigSections.Settings.UPDATE.OUTDATED.getLines().forEach(Logger::warning);
Logger.info("§8[§fPAT | Proxy§8] §7Please be aware that you are currently using a §bdeveloper §7version of ProAntiTab. Bugs, errors and a lot of debug messages might be included.");
} else if(!checkUpdate && (VersionComparer.isNewest() || VersionComparer.isUnreleased())) {
getProxy().getScheduler().cancel(updaterTask);
checkUpdate = true;
if(VersionComparer.isUnreleased()) {
Logger.info("§8[§fPAT | Proxy§8] §7Please be aware that you are currently using an §eunreleased §7version of ProAntiTab.");
return;
}
} else {
if(!checkUpdate) {
checkUpdate = true;
Storage.ConfigSections.Settings.UPDATE.UPDATED.getLines().forEach(Logger::warning);
checkUpdate = true;
Storage.ConfigSections.Settings.UPDATE.UPDATED.getLines().forEach(Logger::warning);
} else if(VersionComparer.isOutdated()) {
Storage.OUTDATED = true;
Storage.ConfigSections.Settings.UPDATE.OUTDATED.getLines().forEach(Logger::warning);
} else if(!Storage.NEWER_VERSION.equals(Storage.CURRENT_VERSION)) {
getProxy().getScheduler().cancel(updaterTask);
switch (result) {
case "internet":
Logger.warning("Failed to build connection to website! (No internet?)");
break;
case "unknown":
Logger.warning("Failed to build connection to website! (Firewall enabled or website down?)");
break;
case "exception":
Logger.warning("Failed to build connection to website! (Outdated java version?)");
break;
}
}
}, 20L, Storage.ConfigSections.Settings.UPDATE.PERIOD, TimeUnit.MILLISECONDS);
}
public static String getServerNameByPlayerUUID(UUID uuid) {
ProxiedPlayer proxiedPlayer = ProxyServer.getInstance().getPlayer(uuid);
if(proxiedPlayer == null) return null;
Server server = proxiedPlayer.getServer();
if(server == null) return null;
ServerInfo serverInfo = server.getInfo();
if(serverInfo == null) return null;
return serverInfo.getName();
}
public static Plugin getPlugin() {
return plugin;
}
@@ -2,6 +2,8 @@ package de.rayzs.pat.plugin;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ServerConnection;
import de.rayzs.pat.plugin.modules.subargs.SubArgsModule;
import de.rayzs.pat.utils.configuration.updater.ConfigUpdater;
import de.rayzs.pat.plugin.metrics.impl.VelocityMetrics;
import com.velocitypowered.api.scheduler.ScheduledTask;
@@ -14,22 +16,27 @@ import de.rayzs.pat.utils.adapter.LuckPermsAdapter;
import com.velocitypowered.api.proxy.ProxyServer;
import de.rayzs.pat.api.brand.CustomServerBrand;
import de.rayzs.pat.plugin.listeners.velocity.*;
import de.rayzs.pat.utils.ConnectionBuilder;
import de.rayzs.pat.utils.group.GroupManager;
import de.rayzs.pat.utils.ConnectionBuilder;
import de.rayzs.pat.utils.VersionComparer;
import de.rayzs.pat.plugin.logger.Logger;
import com.velocitypowered.api.plugin.*;
import de.rayzs.pat.api.storage.Storage;
import com.velocitypowered.api.event.*;
import de.rayzs.pat.utils.Reflection;
import java.util.concurrent.TimeUnit;
import com.google.inject.Inject;
import de.rayzs.pat.utils.response.action.ActionHandler;
import java.util.*;
@Plugin(name = "ProAntiTab",
id = "proantitab",
version = "1.8.0",
version = "1.9.2",
authors = "Rayzs_YT",
description = "Hide more then just plugins. Hide almost everything!",
description = "Hide more than just your plugins. Hide almost everything!",
dependencies = {
@Dependency(id = "luckperms", optional = true),
@Dependency(id = "papiproxybridge", optional = true)
@@ -58,12 +65,14 @@ public class VelocityLoader {
Configurator.createResourcedFile("./plugins/ProAntiTab", "files\\proxy-config.yml", "config.yml", false);
Configurator.createResourcedFile("./plugins/ProAntiTab", "files\\proxy-storage.yml", "storage.yml", false);
Configurator.createResourcedFile("./plugins/ProAntiTab", "files\\proxy-placeholders.yml", "placeholders.yml", false);
Configurator.createResourcedFile("./plugins/ProAntiTab", "files\\proxy-custom-responses.yml", "custom-responses.yml", false);
Reflection.initialize(server);
ConfigUpdater.initialize();
Storage.USE_SIMPLECLOUD = Reflection.doesClassExist("eu.thesimplecloud.plugin.startup.CloudPlugin");
Storage.CURRENT_VERSION = pluginContainer.getDescription().getVersion().get();
VersionComparer.setCurrentVersion(Storage.CURRENT_VERSION);
Storage.loadAll(true);
MessageTranslator.initialize();
@@ -80,7 +89,9 @@ public class VelocityLoader {
server.getEventManager().register(this, new VelocityPingListener(server));
startUpdaterTask();
server.getScheduler().buildTask(this, Communicator::syncData).delay(5, TimeUnit.SECONDS).schedule();
if (!Storage.ConfigSections.Settings.DISABLE_SYNC.DISABLED)
server.getScheduler().buildTask(this, Communicator::syncData).delay(5, TimeUnit.SECONDS).schedule();
Storage.PLUGIN_OBJECT = this;
@@ -96,6 +107,8 @@ public class VelocityLoader {
Logger.warning("Detected SimpleCloud and therefore MiniMessages by Kyori are disabled!");
ConfigUpdater.broadcastMissingParts();
ActionHandler.initialize();
SubArgsModule.initialize();
}
public static void delayedPermissionsReload() {
@@ -124,25 +137,59 @@ public class VelocityLoader {
.setProperties("ProAntiTab", "4654").connect().getResponse();
Storage.NEWER_VERSION = result;
if (!Storage.NEWER_VERSION.equals(Storage.CURRENT_VERSION)) {
VersionComparer.setNewestVersion(Storage.NEWER_VERSION);
if (Storage.NEWER_VERSION.equals("unknown")) {
Logger.warning("Failed reaching web host! (firewall enabled? website down?)");
} else if (result.equals("exception")) {
Logger.warning("Failed creating web instance! (outdated java version?)");
} else {
Storage.OUTDATED = true;
MessageTranslator.send(server.getConsoleCommandSource(), Storage.ConfigSections.Settings.UPDATE.OUTDATED.getLines());
if(VersionComparer.isDeveloperVersion()) {
updaterTask.cancel();
MessageTranslator.send(server.getConsoleCommandSource(), "<dark_gray>[</dark_gray><white>PAT | Proxy</white><dark_gray>]</dark_gray> <gray>Please be aware that you are currently using a</gray> <aqua>developer</aqua> <gray>version of ProAntiTab. Bugs, errors and a lot of debug messages might be included.</gray>");
} else if(!checkUpdate && (VersionComparer.isNewest() || VersionComparer.isUnreleased())) {
updaterTask.cancel();
checkUpdate = true;
if(VersionComparer.isUnreleased()) {
MessageTranslator.send(server.getConsoleCommandSource(), "<dark_gray>[</dark_gray><white>PAT | Proxy</white><dark_gray>]</dark_gray> <gray>Please be aware that you are currently using an</gray> <yellow>unreleased</yellow> <gray>version of ProAntiTab.</gray>");
return;
}
} else {
if(!checkUpdate) {
checkUpdate = true;
MessageTranslator.send(server.getConsoleCommandSource(), Storage.ConfigSections.Settings.UPDATE.UPDATED.getLines());
checkUpdate = true;
MessageTranslator.send(server.getConsoleCommandSource(), Storage.ConfigSections.Settings.UPDATE.UPDATED.getLines());
} else if(VersionComparer.isOutdated()) {
Storage.OUTDATED = true;
MessageTranslator.send(server.getConsoleCommandSource(), Storage.ConfigSections.Settings.UPDATE.OUTDATED.getLines());
} else if(!Storage.NEWER_VERSION.equals(Storage.CURRENT_VERSION)) {
updaterTask.cancel();
switch (result) {
case "internet":
Logger.warning("[PAT | Proxy] Failed to build connection to website! (No internet?)");
break;
case "unknown":
Logger.warning("[PAT | Proxy] Failed to build connection to website! (Firewall enabled or website down?)");
break;
case "exception":
Logger.warning("[PAT | Proxy] Failed to build connection to website! (Outdated java version?)");
break;
}
}
}).delay(1, TimeUnit.SECONDS).repeat(Storage.ConfigSections.Settings.UPDATE.PERIOD, TimeUnit.SECONDS).schedule();
}
public static String getServerNameByPlayerUUID(UUID uuid) {
Optional<Player> optPlayer = server.getPlayer(uuid);
if(!optPlayer.isPresent()) return null;
Player player = optPlayer.get();
Optional<ServerConnection> optServer = player.getCurrentServer();
if(!optServer.isPresent()) return null;
ServerConnection server = optServer.get();
if(server.getServerInfo() == null) return null;
return server.getServerInfo().getName();
}
public static ProxyServer getServer() {
return server;
}
@@ -35,7 +35,7 @@ public class BukkitAntiTabListener implements Listener {
return;
}
if(event.getCommands().size() == 0) {
if(event.getCommands().isEmpty()) {
Logger.debug("No available commands to filter! Ignoring rest of the code until at least one command is listed in there.");
return;
}
@@ -55,7 +55,7 @@ public class BukkitAntiTabListener implements Listener {
final List<String> playerCommands = COMMANDS_CACHE.getPlayerCommands(event.getCommands(), player, player.getUniqueId());
event.getCommands().clear();
FilteredSuggestionEvent filteredSuggestionEvent = PATEventHandler.call(uuid, playerCommands);
FilteredSuggestionEvent filteredSuggestionEvent = PATEventHandler.callFilteredSuggestionEvents(player, playerCommands);
if(filteredSuggestionEvent.isCancelled()) return;
event.getCommands().addAll(filteredSuggestionEvent.getSuggestions());
@@ -43,10 +43,10 @@ public class BukkitBlockCommandListener implements Listener {
List<String> notificationMessage = MessageTranslator.replaceMessageList(Storage.ConfigSections.Messages.NOTIFICATION.ALERT, "%player%", player.getName(), "%command%", command, "%world%", worldName);
if(Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isCommand(command) && !PermissionUtil.hasBypassPermission(player, command)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, true);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
if(executeCommandEvent.isCancelled()) return;
event.setCancelled(true);
MessageTranslator.send(player, Storage.ConfigSections.Settings.CUSTOM_PLUGIN.MESSAGE, "%command%", command);
if(Storage.SEND_CONSOLE_NOTIFICATION) Logger.info(notificationMessage);
@@ -59,10 +59,10 @@ public class BukkitBlockCommandListener implements Listener {
}
if(Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(command) && !PermissionUtil.hasBypassPermission(player, command)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, true);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
if(executeCommandEvent.isCancelled()) return;
event.setCancelled(true);
MessageTranslator.send(player, Storage.ConfigSections.Settings.CUSTOM_VERSION.MESSAGE, "%command%", command);
if(Storage.SEND_CONSOLE_NOTIFICATION) Logger.info(notificationMessage);
@@ -75,34 +75,35 @@ public class BukkitBlockCommandListener implements Listener {
}
if(!Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED || Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED || rawCommand.equals("/")) return;
List<String> cancelCommandMessage = MessageTranslator.replaceMessageList(Storage.ConfigSections.Settings.CANCEL_COMMAND.MESSAGE, "%command%", command);
List<String> cancelCommandMessage = MessageTranslator.replaceMessageList(Storage.ConfigSections.Settings.CANCEL_COMMAND.BASE_COMMAND_RESPONSE, "%command%", command);
if(Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED) {
if(Storage.Blacklist.isListed(command, true)) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, false);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
return;
}
if(PermissionUtil.hasBypassPermission(player, command, false)) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, false);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, true);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
if(executeCommandEvent.isCancelled()) return;
event.setCancelled(true);
MessageTranslator.send(player, cancelCommandMessage);
return;
}
if(Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.isCommand(command) && !Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesBypass(player)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, true);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
if(executeCommandEvent.isCancelled()) return;
event.setCancelled(true);
MessageTranslator.send(player, cancelCommandMessage);
if(Storage.SEND_CONSOLE_NOTIFICATION) Logger.info(notificationMessage);
@@ -115,19 +116,21 @@ public class BukkitBlockCommandListener implements Listener {
}
if (!Storage.Blacklist.isListed(command, false)) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, false);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
return;
}
if (PermissionUtil.hasBypassPermission(player, command, false)) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, false);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, true);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
if(executeCommandEvent.isCancelled()) return;
event.setCancelled(true);
MessageTranslator.send(player, cancelCommandMessage);
if(Storage.SEND_CONSOLE_NOTIFICATION) Logger.info(notificationMessage);
@@ -1,5 +1,7 @@
package de.rayzs.pat.plugin.listeners.bukkit;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.event.events.ServerPlayersChangeEvent;
import de.rayzs.pat.api.netty.bukkit.BukkitPacketAnalyzer;
import de.rayzs.pat.api.brand.impl.BukkitServerBrand;
import de.rayzs.pat.api.communication.BackendUpdater;
@@ -18,13 +20,16 @@ public class BukkitPlayerConnectionListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
PATEventHandler.callServerPlayersChangeEvents(player, ServerPlayersChangeEvent.Type.JOINED);
if(Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED)
BackendUpdater.handle();
PermissionUtil.setPlayerPermissions(player.getUniqueId());
CustomServerBrand.preparePlayer(player);
CustomServerBrand.sendBrandToPlayer(player);
if(CustomServerBrand.isEnabled())
CustomServerBrand.sendBrandToPlayer(player);
if(!BukkitPacketAnalyzer.inject(player)) player.kickPlayer("Failed to inject player!");
@@ -40,6 +45,8 @@ public class BukkitPlayerConnectionListener implements Listener {
@EventHandler (priority = EventPriority.LOWEST)
public void onPlayerQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
PATEventHandler.callServerPlayersChangeEvents(player, ServerPlayersChangeEvent.Type.LEFT);
BukkitPacketAnalyzer.uninject(player.getUniqueId());
PermissionUtil.resetPermissions(player.getUniqueId());
if(Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1) return;
@@ -51,5 +58,6 @@ public class BukkitPlayerConnectionListener implements Listener {
Player player = event.getPlayer();
if(Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1) return;
BukkitServerBrand.removeFromModified(player);
CustomServerBrand.sendBrandToPlayer(player);
}
}
@@ -2,6 +2,7 @@ package de.rayzs.pat.plugin.listeners.bukkit;
import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.message.replacer.PlaceholderReplacer;
import org.bukkit.event.*;
import org.bukkit.Bukkit;
@@ -23,6 +24,9 @@ public class PaperServerListPing implements Listener {
if(Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.HIDE_PLAYERS)
event.getPlayerSample().clear();
if(versionName.contains("%"))
PlaceholderReplacer.replace(null, versionName);
event.setVersion(versionName);
}
}
@@ -31,7 +31,7 @@ public class BungeeAntiTabListener implements Listener {
event.getSuggestions().removeIf(command -> Storage.Blacklist.isBlocked(player, command, !Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED, player.getServer().getInfo().getName()));
FilteredSuggestionEvent filteredSuggestionEvent = PATEventHandler.call(player.getUniqueId(), event.getSuggestions());
FilteredSuggestionEvent filteredSuggestionEvent = PATEventHandler.callFilteredSuggestionEvents(player, event.getSuggestions());
if(filteredSuggestionEvent.isCancelled()) event.getSuggestions().clear();
}
}
@@ -40,10 +40,10 @@ public class BungeeBlockCommandListener implements Listener {
List<String> notificationMessage = MessageTranslator.replaceMessageList(Storage.ConfigSections.Messages.NOTIFICATION.ALERT, "%player%", player.getName(), "%command%", command, "%server%", serverName);
if(Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isCommand(command) && !PermissionUtil.hasBypassPermission(player, command)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, true);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
if(executeCommandEvent.isCancelled()) return;
event.setCancelled(true);
MessageTranslator.send(player, Storage.ConfigSections.Settings.CUSTOM_PLUGIN.MESSAGE, "%command%", rawCommand.replaceFirst("/", ""));
if(Storage.SEND_CONSOLE_NOTIFICATION) Logger.info(notificationMessage);
@@ -56,10 +56,10 @@ public class BungeeBlockCommandListener implements Listener {
}
if(Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(command) && !PermissionUtil.hasBypassPermission(player, command)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, true);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
if(executeCommandEvent.isCancelled()) return;
event.setCancelled(true);
MessageTranslator.send(player, Storage.ConfigSections.Settings.CUSTOM_VERSION.MESSAGE, "%command%", rawCommand.replaceFirst("/", ""));
if(Storage.SEND_CONSOLE_NOTIFICATION) Logger.info(notificationMessage);
@@ -73,37 +73,39 @@ public class BungeeBlockCommandListener implements Listener {
if(!Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED) return;
List<String> cancelCommandMessage = MessageTranslator.replaceMessageList(Storage.ConfigSections.Settings.CANCEL_COMMAND.MESSAGE, "%command%", command);
List<String> cancelCommandMessage = MessageTranslator.replaceMessageList(Storage.ConfigSections.Settings.CANCEL_COMMAND.BASE_COMMAND_RESPONSE, "%command%", command);
boolean listed, serverListed, ignored;
if(Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED) {
if(Storage.Blacklist.doesGroupBypass(player, command, true, true, false, serverName)) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, false);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
return;
}
listed = Storage.Blacklist.isListed(command, false, true, false);
serverListed = Storage.Blacklist.isListed(player, command, false, listed, false, serverName);
serverListed = Storage.Blacklist.isListed(player, command, false, listed, false, serverName, true);
ignored = Storage.Blacklist.isOnIgnoredServer(serverName);
if(ignored ? !listed && serverListed : serverListed) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, false);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, true);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
if(executeCommandEvent.isCancelled()) return;
event.setCancelled(true);
MessageTranslator.send(player, cancelCommandMessage);
return;
}
if(Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.isCommand(command) && !Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesBypass(player)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, true);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
if(executeCommandEvent.isCancelled()) return;
event.setCancelled(true);
MessageTranslator.send(player, cancelCommandMessage);
if(Storage.SEND_CONSOLE_NOTIFICATION) Logger.info(notificationMessage);
@@ -116,7 +118,8 @@ public class BungeeBlockCommandListener implements Listener {
}
if(Storage.Blacklist.doesGroupBypass(player, command, true, true, false, serverName)) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, false);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
return;
}
@@ -125,17 +128,15 @@ public class BungeeBlockCommandListener implements Listener {
ignored = Storage.Blacklist.isOnIgnoredServer(serverName);
if(!listed && !serverListed || listed && serverListed && ignored) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, false);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
if(executeCommandEvent.isCancelled()) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, true);
if(executeCommandEvent.isBlocked()) event.setCancelled(true);
if(executeCommandEvent.isCancelled()) return;
event.setCancelled(true);
MessageTranslator.send(player, cancelCommandMessage);
if(Storage.SEND_CONSOLE_NOTIFICATION) Logger.info(notificationMessage);
@@ -1,5 +1,7 @@
package de.rayzs.pat.plugin.listeners.bungee;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.event.events.ServerPlayersChangeEvent;
import de.rayzs.pat.api.netty.proxy.BungeePacketAnalyzer;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.utils.message.MessageTranslator;
@@ -18,6 +20,13 @@ public class BungeePlayerConnectionListener implements Listener {
@EventHandler (priority = EventPriority.LOWEST)
public void onPostLogin(PostLoginEvent event) {
ProxiedPlayer player = event.getPlayer();
PATEventHandler.callServerPlayersChangeEvents(player, ServerPlayersChangeEvent.Type.JOINED);
if(CustomServerBrand.isEnabled())
ProxyServer.getInstance().getScheduler().schedule(BungeeLoader.getPlugin(), () -> {
if (player.isConnected()) CustomServerBrand.sendBrandToPlayer(player);
}, 500, TimeUnit.MILLISECONDS);
PermissionUtil.setPlayerPermissions(player.getUniqueId());
if(Storage.OUTDATED && PermissionUtil.hasPermission(player, "joinupdate")) {
@@ -41,6 +50,8 @@ public class BungeePlayerConnectionListener implements Listener {
@EventHandler (priority = EventPriority.LOWEST)
public void onPlayerDisconnectEvent(PlayerDisconnectEvent event) {
ProxiedPlayer player = event.getPlayer();
PATEventHandler.callServerPlayersChangeEvents(player, ServerPlayersChangeEvent.Type.LEFT);
PermissionUtil.resetPermissions(player.getUniqueId());
BungeePacketAnalyzer.uninject(player);
if(Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1) return;
@@ -39,7 +39,7 @@ public class WaterfallAntiTabListener implements Listener {
List<String> playerCommands = commandsCache.getPlayerCommands(commandsAsString, player, player.getUniqueId(), serverName);
event.getCommands().entrySet().removeIf(command -> playerCommands.contains(command.getKey()));
FilteredSuggestionEvent filteredSuggestionEvent = PATEventHandler.call(player.getUniqueId(), new ArrayList<>(event.getCommands().keySet()));
FilteredSuggestionEvent filteredSuggestionEvent = PATEventHandler.callFilteredSuggestionEvents(player, new ArrayList<>(event.getCommands().keySet()));
if(filteredSuggestionEvent.isCancelled()) event.getCommands().clear();
for (String commandName : filteredSuggestionEvent.getSuggestions()) {
@@ -50,6 +50,6 @@ public class WaterfallAntiTabListener implements Listener {
}
public static void updateCommands() {
COMMANDS_CACHE_MAP.values().forEach(CommandsCache::reset);
new ArrayList<>(COMMANDS_CACHE_MAP.values()).forEach(CommandsCache::reset);
}
}
@@ -2,7 +2,9 @@ package de.rayzs.pat.plugin.listeners.velocity;
import com.velocitypowered.api.event.command.PlayerAvailableCommandsEvent;
import com.velocitypowered.api.event.player.TabCompleteEvent;
import de.rayzs.pat.api.event.events.FilteredSuggestionEvent;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.CommandsCache;
import com.velocitypowered.api.proxy.*;
@@ -24,12 +26,16 @@ public class VelocityAntiTabListener {
if(PermissionUtil.hasBypassPermission(player) || event.getSuggestions().isEmpty() || !player.getCurrentServer().isPresent()) return;
event.getSuggestions().removeIf(command -> Storage.Blacklist.isBlocked(player, command, !Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED, player.getCurrentServer().get().getServerInfo().getName()));
FilteredSuggestionEvent filteredSuggestionEvent = PATEventHandler.callFilteredSuggestionEvents(player, event.getSuggestions());
if(filteredSuggestionEvent.isCancelled()) event.getSuggestions().clear();
}
@Subscribe (order = PostOrder.LAST)
public void onPlayerAvailableCommands(PlayerAvailableCommandsEvent event) {
Player player = event.getPlayer();
if(event.getRootNode().getChildren().isEmpty() || !player.getCurrentServer().isPresent()) return;
String serverName = player.getCurrentServer().get().getServer().getServerInfo().getName();
if(!COMMANDS_CACHE_MAP.containsKey(serverName))
@@ -42,11 +48,19 @@ public class VelocityAntiTabListener {
if(PermissionUtil.hasBypassPermission(player)) return;
final boolean newer = player.getProtocolVersion().getProtocol() > 340;
final List<String> playerCommands = commandsCache.getPlayerCommands(commandsAsString, player, player.getUniqueId(), serverName);
if(event.getRootNode().getChildren().size() == 1 && newer
&& event.getRootNode().getChild("args") != null
&& event.getRootNode().getChild("args").getChildren().isEmpty())
return;
if(event.getRootNode().getChildren().size() == 1 && newer && event.getRootNode().getChild("args") != null) return;
event.getRootNode().getChildren().removeIf(command -> command == null || command.getName() == null || playerCommands.contains(command.getName()));
}
public static void updateCommands() {
COMMANDS_CACHE_MAP.values().forEach(CommandsCache::reset);
new ArrayList<>(COMMANDS_CACHE_MAP.values()).forEach(CommandsCache::reset);
}
}
@@ -3,6 +3,7 @@ package de.rayzs.pat.plugin.listeners.velocity;
import com.velocitypowered.api.event.command.CommandExecuteEvent;
import com.velocitypowered.api.command.CommandSource;
import de.rayzs.pat.api.event.events.ExecuteCommandEvent;
import de.rayzs.pat.plugin.VelocityLoader;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.utils.permission.PermissionUtil;
import com.velocitypowered.api.proxy.ProxyServer;
@@ -41,10 +42,10 @@ public class VelocityBlockCommandListener {
List<String> notificationMessage = MessageTranslator.replaceMessageList(Storage.ConfigSections.Messages.NOTIFICATION.ALERT, "%player%", player.getUsername(), "%command%", command, "%server%", serverName);
if(Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isCommand(command)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, true);
if(executeCommandEvent.isBlocked()) event.setResult(CommandExecuteEvent.CommandResult.denied());
if(executeCommandEvent.isCancelled()) return;
event.setResult(CommandExecuteEvent.CommandResult.denied());
MessageTranslator.send(player, Storage.ConfigSections.Settings.CUSTOM_PLUGIN.MESSAGE, "%command%", command.replaceFirst("/", ""));
if(Storage.SEND_CONSOLE_NOTIFICATION) MessageTranslator.send(server.getConsoleCommandSource(), notificationMessage);
@@ -54,10 +55,10 @@ public class VelocityBlockCommandListener {
}
if(Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(command)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, true);
if(executeCommandEvent.isBlocked()) event.setResult(CommandExecuteEvent.CommandResult.denied());
if(executeCommandEvent.isCancelled()) return;
event.setResult(CommandExecuteEvent.CommandResult.denied());
MessageTranslator.send(player, Storage.ConfigSections.Settings.CUSTOM_VERSION.MESSAGE, "%command%", command.replaceFirst("/", ""));
if(Storage.SEND_CONSOLE_NOTIFICATION) MessageTranslator.send(server.getConsoleCommandSource(), notificationMessage);
@@ -67,13 +68,14 @@ public class VelocityBlockCommandListener {
}
if(!Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED) return;
List<String> cancelCommandMessage = MessageTranslator.replaceMessageList(Storage.ConfigSections.Settings.CANCEL_COMMAND.MESSAGE, "%command%", command.replaceFirst("/", ""));
List<String> cancelCommandMessage = MessageTranslator.replaceMessageList(Storage.ConfigSections.Settings.CANCEL_COMMAND.BASE_COMMAND_RESPONSE, "%command%", command.replaceFirst("/", ""));
boolean listed, serverListed, ignored;
if(Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED) {
if(Storage.Blacklist.doesGroupBypass(player, command, false, true, false, player.getCurrentServer().get().getServerInfo().getName())) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, false);
if(executeCommandEvent.isBlocked()) event.setResult(CommandExecuteEvent.CommandResult.denied());
return;
}
@@ -82,23 +84,24 @@ public class VelocityBlockCommandListener {
ignored = Storage.Blacklist.isOnIgnoredServer(serverName);
if(ignored ? !listed && serverListed : serverListed) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, false);
if(executeCommandEvent.isBlocked()) event.setResult(CommandExecuteEvent.CommandResult.denied());
return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, true);
if(executeCommandEvent.isBlocked()) event.setResult(CommandExecuteEvent.CommandResult.denied());
if(executeCommandEvent.isCancelled()) return;
event.setResult(CommandExecuteEvent.CommandResult.denied());
MessageTranslator.send(player, cancelCommandMessage);
return;
}
if(Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.isCommand(command) && !Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesBypass(player)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, true);
if(executeCommandEvent.isBlocked()) event.setResult(CommandExecuteEvent.CommandResult.denied());
if(executeCommandEvent.isCancelled()) return;
event.setResult(CommandExecuteEvent.CommandResult.denied());
MessageTranslator.send(player, cancelCommandMessage);
if(Storage.SEND_CONSOLE_NOTIFICATION) MessageTranslator.send(server.getConsoleCommandSource(), notificationMessage);
@@ -107,29 +110,150 @@ public class VelocityBlockCommandListener {
return;
}
if(Storage.Blacklist.doesGroupBypass(player, command, true, true, false, player.getCurrentServer().get().getServerInfo().getName())) return;
if(Storage.Blacklist.doesGroupBypass(player, command, true, true, false, player.getCurrentServer().get().getServerInfo().getName())) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, false);
if(executeCommandEvent.isBlocked()) event.setResult(CommandExecuteEvent.CommandResult.denied());
return;
}
listed = Storage.Blacklist.isListed(command, true, true, false);
serverListed = Storage.Blacklist.isListed(player, command, true, listed, false, serverName);
ignored = Storage.Blacklist.isOnIgnoredServer(serverName);
if(!listed && !serverListed || listed && serverListed && ignored) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, false);
if(executeCommandEvent.isBlocked()) event.setResult(CommandExecuteEvent.CommandResult.denied());
return;
}
if(Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.isCommand(command) && Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesBypass(player.getUniqueId())) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, false);
if(executeCommandEvent.isBlocked()) event.setResult(CommandExecuteEvent.CommandResult.denied());
return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, rawCommand, true);
if(executeCommandEvent.isBlocked()) event.setResult(CommandExecuteEvent.CommandResult.denied());
if(executeCommandEvent.isCancelled()) return;
event.setResult(CommandExecuteEvent.CommandResult.denied());
MessageTranslator.send(player, cancelCommandMessage);
if(Storage.SEND_CONSOLE_NOTIFICATION) MessageTranslator.send(server.getConsoleCommandSource(), notificationMessage);
Storage.NOTIFY_PLAYERS.stream().filter(uuid -> server.getPlayer(uuid).isPresent()).forEach(uuid -> MessageTranslator.send(server.getPlayer(uuid).get(), notificationMessage));
}
}
public static boolean handleCommand(Player player, String commandSource) {
String command = commandSource,
serverName = player.getCurrentServer().isPresent() ? player.getCurrentServer().get().getServerInfo().getName() : "unknown";
boolean blocked = false;
command = StringUtils.replaceFirst(command, "/", "");
command = StringUtils.getFirstArg(command);
command = StringUtils.replaceTriggers(command, "", "\\", "<", ">", "&");
if (PermissionUtil.hasBypassPermission(player, command, false)) return false;
List<String> notificationMessage = MessageTranslator.replaceMessageList(Storage.ConfigSections.Messages.NOTIFICATION.ALERT, "%player%", player.getUsername(), "%command%", command, "%server%", serverName);
if (Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isCommand(command)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, commandSource, true);
if (executeCommandEvent.isBlocked()) blocked = true;
if (executeCommandEvent.isCancelled()) return false;
MessageTranslator.send(player, Storage.ConfigSections.Settings.CUSTOM_PLUGIN.MESSAGE, "%command%", command.replaceFirst("/", ""));
if (Storage.SEND_CONSOLE_NOTIFICATION)
MessageTranslator.send(VelocityLoader.getServer().getConsoleCommandSource(), notificationMessage);
Storage.NOTIFY_PLAYERS.stream().filter(uuid -> VelocityLoader.getServer().getPlayer(uuid).isPresent()).forEach(uuid -> MessageTranslator.send(VelocityLoader.getServer().getPlayer(uuid).get(), notificationMessage));
return blocked;
}
if (Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(command)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, commandSource, true);
if (executeCommandEvent.isBlocked()) blocked = true;
if (executeCommandEvent.isCancelled()) return false;
MessageTranslator.send(player, Storage.ConfigSections.Settings.CUSTOM_VERSION.MESSAGE, "%command%", command);
if (Storage.SEND_CONSOLE_NOTIFICATION)
MessageTranslator.send(VelocityLoader.getServer().getConsoleCommandSource(), notificationMessage);
Storage.NOTIFY_PLAYERS.stream().filter(uuid -> VelocityLoader.getServer().getPlayer(uuid).isPresent()).forEach(uuid -> MessageTranslator.send(VelocityLoader.getServer().getPlayer(uuid).get(), notificationMessage));
return blocked;
}
if (!Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED) return false;
List<String> cancelCommandMessage = MessageTranslator.replaceMessageList(Storage.ConfigSections.Settings.CANCEL_COMMAND.BASE_COMMAND_RESPONSE, "%command%", command.replaceFirst("/", ""));
boolean listed, serverListed, ignored;
if (Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED) {
if (Storage.Blacklist.doesGroupBypass(player, command, false, true, false, player.getCurrentServer().get().getServerInfo().getName())) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, commandSource, false);
return executeCommandEvent.isBlocked();
}
listed = Storage.Blacklist.isListed(command, false, true, false);
serverListed = Storage.Blacklist.isListed(player, command, false, listed, false, serverName, true);
ignored = Storage.Blacklist.isOnIgnoredServer(serverName);
if (ignored ? !listed && serverListed : serverListed) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, commandSource, false);
return executeCommandEvent.isBlocked();
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, commandSource, true);
if (executeCommandEvent.isBlocked()) blocked = true;
if (executeCommandEvent.isCancelled()) return true;
MessageTranslator.send(player, cancelCommandMessage);
return blocked;
}
if (Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.isCommand(command) && !Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesBypass(player)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, commandSource, true);
if (executeCommandEvent.isBlocked()) blocked = true;
if (executeCommandEvent.isCancelled()) return false;
MessageTranslator.send(player, cancelCommandMessage);
if (Storage.SEND_CONSOLE_NOTIFICATION)
MessageTranslator.send(VelocityLoader.getServer().getConsoleCommandSource(), notificationMessage);
Storage.NOTIFY_PLAYERS.stream().filter(uuid -> VelocityLoader.getServer().getPlayer(uuid).isPresent()).forEach(uuid -> MessageTranslator.send(VelocityLoader.getServer().getPlayer(uuid).get(), notificationMessage));
return blocked;
}
if (Storage.Blacklist.doesGroupBypass(player, command, true, true, false, player.getCurrentServer().get().getServerInfo().getName())) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, commandSource, false);
return executeCommandEvent.isBlocked();
}
listed = Storage.Blacklist.isListed(command, true, true, false);
serverListed = Storage.Blacklist.isListed(player, command, true, listed, false, serverName);
ignored = Storage.Blacklist.isOnIgnoredServer(serverName);
if (!listed && !serverListed || listed && serverListed && ignored) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, commandSource, false);
return executeCommandEvent.isBlocked();
}
if (Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.isCommand(command) && Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesBypass(player.getUniqueId())) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, commandSource, false);
return executeCommandEvent.isBlocked();
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, commandSource, true);
if (executeCommandEvent.isBlocked()) blocked = true;
if (executeCommandEvent.isCancelled()) return true;
MessageTranslator.send(player, cancelCommandMessage);
if (Storage.SEND_CONSOLE_NOTIFICATION)
MessageTranslator.send(VelocityLoader.getServer().getConsoleCommandSource(), notificationMessage);
Storage.NOTIFY_PLAYERS.stream().filter(uuid -> VelocityLoader.getServer().getPlayer(uuid).isPresent()).forEach(uuid -> MessageTranslator.send(VelocityLoader.getServer().getPlayer(uuid).get(), notificationMessage));
return blocked;
}
}
@@ -1,6 +1,8 @@
package de.rayzs.pat.plugin.listeners.velocity;
import com.velocitypowered.api.event.connection.DisconnectEvent;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.event.events.ServerPlayersChangeEvent;
import de.rayzs.pat.api.netty.proxy.VelocityPacketAnalyzer;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.utils.permission.PermissionUtil;
@@ -25,6 +27,13 @@ public class VelocityConnectionListener {
@Subscribe
public void onServerPreConnect(ServerPreConnectEvent event) {
Player player = event.getPlayer();
PATEventHandler.callServerPlayersChangeEvents(player, ServerPlayersChangeEvent.Type.JOINED);
if(CustomServerBrand.isEnabled())
server.getScheduler().buildTask(loader, () -> {
if (player.isActive()) CustomServerBrand.sendBrandToPlayer(player);
}).delay(500, TimeUnit.MILLISECONDS).schedule();
PermissionUtil.setPlayerPermissions(player.getUniqueId());
if(Storage.OUTDATED && PermissionUtil.hasPermission(player, "joinupdate")) {
@@ -49,8 +58,9 @@ public class VelocityConnectionListener {
@Subscribe
public void onDisconnect(DisconnectEvent event) {
Player player = event.getPlayer();
PATEventHandler.callServerPlayersChangeEvents(player, ServerPlayersChangeEvent.Type.LEFT);
PermissionUtil.resetPermissions(player.getUniqueId());
VelocityPacketAnalyzer.uninject(player);
if(Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1) return;
}
}
@@ -0,0 +1,93 @@
package de.rayzs.pat.plugin.modules.subargs;
import de.rayzs.pat.api.storage.blacklist.impl.GeneralBlacklist;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.plugin.modules.subargs.events.*;
import de.rayzs.pat.utils.response.ResponseHandler;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.subargs.*;
import java.util.stream.Collectors;
import de.rayzs.pat.utils.group.*;
import de.rayzs.pat.plugin.*;
import de.rayzs.pat.utils.*;
import java.util.*;
public class SubArgsModule {
public static List<String> GENERAL_LIST, BLOCKED_MESSAGE, PLAYER_NAMES;
public static HashMap<UUID, Argument> PLAYER_COMMANDS = new HashMap<>();
public static void initialize() {
updateList();
updateMessages();
updatePlayerNames();
PATEventHandler.register(new TabCompletion());
PATEventHandler.register(new ExecuteCommand());
PATEventHandler.register(UpdateList.UPDATE_PLUGIN_EVENT);
PATEventHandler.register(UpdateList.RECEIVE_SYNC_EVENT);
PATEventHandler.register(UpdateList.UPDATE_PLAYER_COMMANDS_EVENT);
PATEventHandler.register(UpdateList.SERVER_PLAYERS_CHANGE_EVENT);
}
public static void updatePlayerNames() {
PLAYER_NAMES = Reflection.isProxyServer()
? Reflection.isVelocityServer()
? VelocityLoader.getPlayerNames()
: BungeeLoader.getPlayerNames()
: BukkitLoader.getPlayerNames();
}
public static List<String> getPlayerNames() {
return PLAYER_NAMES;
}
public static void updateList() {
GENERAL_LIST = Storage.Blacklist.getBlacklist().getCommands().stream().filter(command -> command.contains(" ")).collect(Collectors.toList());
Argument.clearArguments();
GENERAL_LIST.forEach(Argument::buildArguments);
SubArgsModule.PLAYER_COMMANDS = new HashMap<>();
}
public static void updateMessages() {
Storage.Files.CUSTOM_RESPONSES.reload();
ResponseHandler.update();
}
public static List<String> getServerCommands(UUID uuid) {
List<String> commands = new ArrayList<>();
if(!Reflection.isProxyServer()) return commands;
String serverName = Reflection.isVelocityServer() ? VelocityLoader.getServerNameByPlayerUUID(uuid) : BungeeLoader.getServerNameByPlayerUUID(uuid);
if(serverName == null) return commands;
List<GeneralBlacklist> blacklists = Storage.Blacklist.getBlacklists(serverName);
for (GeneralBlacklist blacklist : blacklists)
commands.addAll(blacklist.getCommands());
return commands;
}
public static List<String> getGroupCommands(UUID uuid) {
List<String> commands = new ArrayList<>();
List<Group> groups = new ArrayList<>();
Group currentGroup;
for (String permission : Objects.requireNonNull(PermissionUtil.getPermissions(uuid))) {
if(!permission.startsWith("proantitab.group.")) continue;
currentGroup = GroupManager.getGroupByName(StringUtils.replaceFirst(permission, "proantitab.group.", ""));
if(currentGroup != null && !groups.contains(currentGroup)) groups.add(currentGroup);
}
if(!groups.isEmpty()) {
int highestPriority = groups.stream().mapToInt(Group::getPriority).filter(group -> group <= 9999).min().orElse(9999);
groups.removeIf(group -> group.getPriority() > highestPriority);
for (Group group : groups) commands.addAll(group.getCommands().stream().filter(command -> command.contains(" ")).collect(Collectors.toList()));
}
return commands;
}
}
@@ -0,0 +1,96 @@
package de.rayzs.pat.plugin.modules.subargs.events;
import de.rayzs.pat.api.event.events.ExecuteCommandEvent;
import de.rayzs.pat.plugin.modules.subargs.SubArgsModule;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.utils.response.ResponseHandler;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.subargs.*;
import de.rayzs.pat.utils.*;
public class ExecuteCommand extends ExecuteCommandEvent {
@Override
public void handle(ExecuteCommandEvent event) {
String command = StringUtils.replaceFirst(event.getCommand(), "/", "");
CommandSender sender = new CommandSender(event.getSenderObj());
/* Removed due to the fact that it is not required after all.
if(PermissionUtil.hasBypassPermission(event.getSenderObj(), command.contains(" ") ? command.split(" ")[0] : command))
return;
*/
if(command.contains(" ") && shouldCommandBeBlocked(sender, event, command)) {
event.setBlocked(true);
event.setCancelled(true);
MessageTranslator.send(event.getSenderObj(), ResponseHandler.getResponse(sender.getUniqueId(), event.getCommand()), "%command%", event.getCommand());
return;
}
if(!event.isBlocked()) return;
if(Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isCommand(command) || Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(command))
return;
event.setCancelled(true);
MessageTranslator.send(event.getSenderObj(), ResponseHandler.getResponse(sender.getUniqueId(), event.getCommand(), Storage.ConfigSections.Settings.CANCEL_COMMAND.BASE_COMMAND_RESPONSE.getLines()), "%command%", event.getCommand());
}
private boolean shouldCommandBeBlocked(CommandSender sender, ExecuteCommandEvent event, String command) {
boolean listed = false,
turn = Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED,
blocked = event.isBlocked(),
ignored = false,
useFilter = false,
tooBig = false;
String[] split, originCommandSplit, copiedOriginCommandSplit;
String tmpCommand;
for (String s : SubArgsModule.PLAYER_COMMANDS.getOrDefault(sender.getUniqueId(), Argument.getGeneralArgument()).getInputs()) {
if(s.contains("%hidden_online_players%")) continue;
tmpCommand = command;
if(s.split(" ")[0].equalsIgnoreCase(tmpCommand.split(" ")[0]))
useFilter = true;
originCommandSplit = tmpCommand.split(" ");
split = s.split(" ");
int i;
for(i = 0; i < split.length; i++) {
if(!split[i].equals("%online_players%")) continue;
boolean foundPlayer = false;
for (String playerName : SubArgsModule.getPlayerNames()) {
if(i >= originCommandSplit.length) continue;
if(!playerName.equalsIgnoreCase(originCommandSplit[i])) continue;
foundPlayer = true;
originCommandSplit[i] = "%online_players%";
break;
}
if(!foundPlayer) {
copiedOriginCommandSplit = originCommandSplit.clone();
copiedOriginCommandSplit[copiedOriginCommandSplit.length-1] = null;
String c = String.join(" ", copiedOriginCommandSplit);
if(s.startsWith(c)) return turn;
}
tmpCommand = String.join(" ", originCommandSplit);
}
if (!tmpCommand.toLowerCase().startsWith(StringUtils.replaceFirst(s.toLowerCase(), " _-", "")))
continue;
if (!listed) listed = true;
if (s.endsWith(" _-")) ignored = true;
tooBig = originCommandSplit.length > s.replace(" _-", "").split(" ").length;
}
return !(blocked || !useFilter) && turn != listed || ignored && tooBig;
}
}
@@ -0,0 +1,52 @@
package de.rayzs.pat.plugin.modules.subargs.events;
import de.rayzs.pat.api.event.events.FilteredTabCompletionEvent;
import de.rayzs.pat.plugin.modules.subargs.SubArgsModule;
import de.rayzs.pat.utils.subargs.Argument;
import de.rayzs.pat.api.storage.Storage;
import java.util.stream.Collectors;
import de.rayzs.pat.utils.*;
import java.util.*;
public class TabCompletion extends FilteredTabCompletionEvent {
@Override
public void handle(FilteredTabCompletionEvent event) {
String cursor = StringUtils.replaceFirst(event.getCursor(), "/", "");
if (event.getCompletion().isEmpty()) return;
UUID uuid = event.getSenderObj() instanceof UUID ? (UUID) event.getSenderObj() : new CommandSender(event.getSenderObj()).getUniqueId();
Argument argument = SubArgsModule.PLAYER_COMMANDS.getOrDefault(uuid, Argument.getGeneralArgument());
List<String> possibilities = event.getCompletion(), result = new ArrayList<>(argument.getResult(cursor));
if(Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED) {
possibilities = result;
if(result.contains("%online_players%")) {
possibilities.remove("%online_players%");
possibilities.addAll(SubArgsModule.getPlayerNames());
}
if(result.contains("%hidden_online_players%")) {
possibilities.remove("%hidden_online_players%");
possibilities.addAll(event.getCompletion().stream().filter(completion -> {
if(SubArgsModule.getPlayerNames().contains(completion)) return false;
return result.contains(completion);
}).collect(Collectors.toList()));
if(possibilities.isEmpty()) possibilities.add("///////////");
}
} else {
if(result.contains("%online_players%"))
possibilities.removeIf(possibility -> SubArgsModule.getPlayerNames().contains(possibility));
possibilities.removeAll(result);
}
cursor = StringUtils.getFirstArg(cursor.toLowerCase());
if(possibilities.isEmpty() && !SubArgsModule.GENERAL_LIST.contains(cursor)) return;
event.setCompletion(possibilities);
}
}
@@ -0,0 +1,65 @@
package de.rayzs.pat.plugin.modules.subargs.events;
import de.rayzs.pat.plugin.modules.subargs.SubArgsModule;
import de.rayzs.pat.utils.subargs.Argument;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.CommandSender;
import de.rayzs.pat.api.event.events.*;
import java.util.*;
public class UpdateList {
public static UpdatePluginEvent UPDATE_PLUGIN_EVENT = new UpdatePluginEvent() {
@Override
public void handle(UpdatePluginEvent event) {
SubArgsModule.updateMessages();
SubArgsModule.updateList();
}
};
public static ServerPlayersChangeEvent SERVER_PLAYERS_CHANGE_EVENT = new ServerPlayersChangeEvent() {
@Override
public void handle(ServerPlayersChangeEvent event) {
SubArgsModule.updatePlayerNames();
}
};
public static ReceiveSyncEvent RECEIVE_SYNC_EVENT = new ReceiveSyncEvent() {
@Override
public void handle(ReceiveSyncEvent event) {
SubArgsModule.updateList();
}
};
public static UpdatePlayerCommandsEvent UPDATE_PLAYER_COMMANDS_EVENT = new UpdatePlayerCommandsEvent() {
@Override
public void handle(UpdatePlayerCommandsEvent event) {
final UUID uuid = event.getSenderObj() instanceof UUID ? (UUID) event.getSenderObj() : new CommandSender(event.getSenderObj()).getUniqueId();
final Argument argument = SubArgsModule.PLAYER_COMMANDS.getOrDefault(uuid, new Argument());
argument.clearAllArguments();
if(Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED) {
for (String command : event.getCommands())
argument.buildArgumentStacks(command);
for(String command : Argument.getGeneralArgument().getInputs())
argument.buildArgumentStacks(command);
for (String command : SubArgsModule.getGroupCommands(uuid))
argument.buildArgumentStacks(command);
for (String command : SubArgsModule.getServerCommands(uuid))
argument.buildArgumentStacks(command);
} else {
List<String> groupCommands = SubArgsModule.getGroupCommands(uuid);
for (String command : Argument.getGeneralArgument().getInputs()) {
if(groupCommands.contains(command)) continue;
argument.buildArgumentStacks(command);
}
}
SubArgsModule.PLAYER_COMMANDS.putIfAbsent(uuid, argument);
}
};
}
@@ -202,6 +202,10 @@ public class CommandProcess {
PermissionUtil.reloadPermissions();
sender.sendMessage(Storage.ConfigSections.Messages.UPDATE_PERMISSIONS.UPDATE_ALL);
return;
case "perms":
sender.sendMessage(Storage.ConfigSections.Messages.PERMS_CHECK.PLAYER_MISSING);
return;
}
case 2:
@@ -358,9 +362,11 @@ public class CommandProcess {
if(!PermissionUtil.hasPermissionWithResponse(sender, "perms")) return;
uuid = !Reflection.isProxyServer() ? BukkitLoader.getUUIDByName(sub) : Reflection.isVelocityServer() ? VelocityLoader.getUUIDByName(sub) : BungeeLoader.getUUIDByName(sub);
if(uuid != null) {
sender.sendMessage("§7Permissions from §f" + sub + "§7: §e" + PermissionUtil.getPermissions(uuid));
} else sender.sendMessage("§cThis player isn't online!");
sender.sendMessage((uuid != null
? Storage.ConfigSections.Messages.PERMS_CHECK.MESSAGE.replace("%permissions%", PermissionUtil.getPermissionsAsString(uuid))
: Storage.ConfigSections.Messages.PERMS_CHECK.PLAYER_NOT_ONLINE
).replace("%player%", sub)
);
return;
}
@@ -0,0 +1,19 @@
package de.rayzs.pat.plugin.skript;
import ch.njol.skript.*;
import org.bukkit.plugin.java.JavaPlugin;
import de.rayzs.pat.api.event.events.bukkit.ExecuteCommandEvent;
import de.rayzs.pat.plugin.skript.impl.events.ExecuteCommandSkriptEvent;
public class PATSkriptAddon {
public static SkriptAddon ADDON;
public static void initialize(JavaPlugin javaPlugin) {
ADDON = Skript.getAddon(javaPlugin);
Skript.registerEvent("PAT Command Execution", ExecuteCommandSkriptEvent.class, ExecuteCommandEvent.class, "if [command] is (blocked|cancelled|not blocked|not cancelled)");
}
}
@@ -0,0 +1,44 @@
package de.rayzs.pat.plugin.skript.impl.events;
import ch.njol.skript.doc.*;
import ch.njol.skript.lang.*;
import ch.njol.skript.Skript;
import org.bukkit.event.Event;
import de.rayzs.pat.api.event.events.bukkit.ExecuteCommandEvent;
@Name("PAT Command Execution")
@Description("Fires after a command has been checked by PAT.")
public class ExecuteCommandSkriptEvent extends SkriptEvent {
private boolean triggerOnBlocked;
static {
Skript.registerEvent("PAT Command Execution",
ExecuteCommandSkriptEvent.class, ExecuteCommandEvent.class,
"[if] (blocked|cancelled|not blocked|not cancelled)");
}
@Override
public boolean init(Literal<?>[] literals, int matchedPattern, SkriptParser.ParseResult parseResult) {
// 0 = blocked/cancelled
// 1 = not blocked/cancelled
triggerOnBlocked = matchedPattern == 0;
return true;
}
@Override
public String toString(Event event, boolean debug) {
return "PAT command execution event " + (triggerOnBlocked ? "(if blocked)" : "(if not blocked)");
}
@Override
public boolean check(Event event) {
if (event instanceof ExecuteCommandEvent) {
ExecuteCommandEvent executeCommandEvent = (ExecuteCommandEvent) event;
return executeCommandEvent.isBlocked() == triggerOnBlocked;
}
return false;
}
}
@@ -4,6 +4,14 @@ import java.util.*;
public class ArrayUtils {
public static boolean containsIgnoreCase(List<String> list, String element) {
for (String s : list)
if(s.equalsIgnoreCase(element))
return true;
return false;
}
public static boolean compareStringArrays(List<String> listA, List<String> listB) {
if(listA == null || listB == null) return false;
@@ -1,5 +1,6 @@
package de.rayzs.pat.utils;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.utils.adapter.LuckPermsAdapter;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.api.storage.Storage;
@@ -76,7 +77,9 @@ public class CommandsCache {
if(filteredCommands == null)
return useList ? playerCommands : new LinkedList<>(unfilteredCommands);
if(useList && !Storage.Blacklist.isOnIgnoredServer(serverName)) playerCommands = new LinkedList<>(filteredCommands);
if(useList && !Storage.Blacklist.isOnIgnoredServer(serverName)) {
playerCommands = new LinkedList<>(filteredCommands);
}
boolean permitted, bypassNamespace = true, turn = Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED;
@@ -93,6 +96,16 @@ public class CommandsCache {
if (playerCommands.contains(command)) continue;
if (Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isTabCompletable(command) || Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(command)) {
if (useList)
playerCommands.add(command);
else
playerCommands.remove(command);
continue;
}
permitted = Reflection.isProxyServer() && serverName != null
? !Storage.Blacklist.isBlocked(targetObj, command, !turn, serverName)
: !Storage.Blacklist.isBlocked(targetObj, command, !turn, false, false);
@@ -110,6 +123,7 @@ public class CommandsCache {
else
Logger.debug("Created list of commands for player with uuid " + uuidSubstring + " with a total of " + playerCommands.size() + " commands!");
PATEventHandler.callUpdatePlayerCommandsEvents(targetObj, playerCommands, serverName != null);
return playerCommands;
}
@@ -128,7 +142,10 @@ public class CommandsCache {
}
public void reset() {
if(change) return;
// Removed to reset the change state. Experimental change though
//if(change) return;
// Prob. gonna change it to: if (CONNECTED_TO_BUNGEE && change) return;
updateChangeState();
filteredCommands = null;
}
@@ -8,12 +8,18 @@ public class ConnectionBuilder {
private String url = null, response = null;
private List<String> responseList = new ArrayList<>();
private Object[] parameters = null;
private int timeout = -1;
public ConnectionBuilder setUrl(String url) {
this.url = url;
return this;
}
public ConnectionBuilder setTimeout(int timeout) {
this.timeout = timeout;
return this;
}
public ConnectionBuilder setProperties(Object... parameters) {
this.parameters = parameters;
return this;
@@ -24,6 +30,9 @@ public class ConnectionBuilder {
String rawUrl = url;
URL url = new URL(rawUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
if(timeout != -1) connection.setConnectTimeout(timeout);
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
connection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
if(parameters != null && parameters.length > 0) {
@@ -132,6 +132,10 @@ public class PacketUtils {
return bytes;
}
public String getBrand() {
return brand;
}
public ByteBuf getByteBuf() {
return byteBuf;
}
@@ -2,15 +2,15 @@ package de.rayzs.pat.utils;
import net.md_5.bungee.api.ProxyServer;
import io.netty.channel.Channel;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.lang.reflect.*;
import org.bukkit.Bukkit;
import java.util.*;
public class Reflection {
private static boolean legacy, proxy, velocity, paper, weird;
private static String versionName, rawVersionName, versionPackageName;
private static boolean legacy, proxy, velocity, paper, folia, weird;
private static String versionName, fullVersionName, rawVersionName, versionPackageName;
private static Version version;
private static int major, minor, release;
@@ -25,6 +25,15 @@ public class Reflection {
proxy = false;
} catch (Throwable ignored) { proxy = true; }
if(!proxy) {
try {
Class.forName("com.destroystokyo.paper.proxy.VelocityProxy");
folia = versionName.toLowerCase().contains("folia");
} catch (Throwable throwable) {
folia = false;
}
}
try {
Class.forName("com.destroystokyo.paper.Metrics");
paper = true;
@@ -47,6 +56,8 @@ public class Reflection {
if (proxy) version = Version.UNKNOWN;
}
public static String getVersionPackageName() {return versionPackageName;}
public static int[] getAges() { return new int[]{major, minor, release}; }
public static String getVersionName() { return versionName; }
public static String getRawVersionName() { return rawVersionName; }
@@ -55,6 +66,10 @@ public class Reflection {
public static boolean isLegacy() { return legacy; }
public static boolean isWeird() { return weird; }
public static boolean isFoliaServer() {
return folia;
}
public static boolean isProxyServer() {
return proxy;
}
@@ -203,6 +218,22 @@ public class Reflection {
return result;
}
public static List<Field> getFieldsByTypeNormal(Class<?> clazz, String target, SearchOption type) {
List<Field> result = new ArrayList<>(), fieldLists = getFields(clazz);
for (Field field : fieldLists) {
String typeName = field.getType().getTypeName();
if(type == SearchOption.CONTAINS && typeName.contains(target)
|| type == SearchOption.STARTS && typeName.startsWith(target)
|| type == SearchOption.ENDS && typeName.endsWith(target)
|| type == SearchOption.EQUALS && typeName.equals(target)) {
openAccess(field, true);
result.add(field);
}
}
return result;
}
public static Field getFirstFieldByType(Class<?> clazz, String target, SearchOption type) {
return getFieldsByType(clazz, target, type).get(0);
}
@@ -245,7 +276,8 @@ public class Reflection {
public static Channel getPlayerChannel(Player player) throws Exception {
Object channelObject;
if(paper && Reflection.isWeird()) {
if(folia && minor == 21 && release == 1 || !folia && paper && Reflection.isWeird()) {
Object serverPlayerObj = getMethodsByReturnTypeAndName(player.getClass(), "ServerPlayer", SearchOption.ENDS, "getHandle").get(0).invoke(player),
serverGamePacketListenerImplObj = getFieldByName(serverPlayerObj.getClass(), "connection").get(serverPlayerObj),
connectionObj = getFieldByName(serverGamePacketListenerImplObj.getClass().getSuperclass(), "connection").get(serverGamePacketListenerImplObj);
@@ -310,9 +342,11 @@ public class Reflection {
}
}
private static void loadVersionName(Object serverObject) throws Exception {
versionName = proxy ? ProxyServer.getInstance().getName() : Bukkit.getName();
rawVersionName = (String) serverObject.getClass().getMethod("getBukkitVersion").invoke(serverObject);
fullVersionName = rawVersionName;
rawVersionName = rawVersionName.split("-")[0].replace(".", "_");
versionPackageName = serverObject.getClass().getPackage().getName();
versionPackageName = versionPackageName.substring(versionPackageName.lastIndexOf('.') + 1);
@@ -359,7 +393,8 @@ public class Reflection {
v_1_18_1, v_1_18_2,
v_1_19, v_1_19_1, v_1_19_2, v_1_19_3, v_1_19_4,
v_1_20, v_1_20_1, v_1_20_2, v_1_20_3, v_1_20_4, v_1_20_5, v_1_20_6,
v_1_21, v_1_21_1, v_1_21_2,
v_1_21, v_1_21_1, v_1_21_2, v_1_21_3, v_1_21_4,
v_1_22, v_1_22_1, v_1_22_2
}
public enum SearchOption { CONTAINS, EQUALS, ENDS, STARTS }
@@ -7,7 +7,7 @@ public class StringUtils {
public static String replaceFirst(String input, String trigger, String replacement) {
if (input.contains(trigger)) {
String[] split = input.split(trigger);
String[] split = input.split(trigger.equals("*") ? "\\*" : trigger);
if (split.length >= 1) {
int pointAfter = split[0].length() + trigger.length();
input = split[0] + replacement + input.substring(pointAfter);
@@ -17,6 +17,56 @@ public class StringUtils {
return input;
}
public static String replaceLast(String input, String trigger, String replacement) {
if (input.contains(trigger)) {
String[] split = input.split(trigger.equals("*") ? "\\*" : trigger);
if (split.length >= 1) {
StringBuilder result = new StringBuilder();
String current;
int i;
for(i = 0; i < split.length; i++) {
current = split[i];
result.append(current);
if(i < split.length -1) result.append(" ");
}
input = result.toString();
} else input = input.replace(trigger, replacement);
}
return input;
}
public static int countMatches(Character character, String string) {
int count = 0;
for (char c : string.toCharArray()) {
if(character == c) count++;
}
return count;
}
public static String replaceElementsFromString(String input, List<String> targets, String replacement) {
final String[] args = input.split(" ");
final StringBuilder result = new StringBuilder();
final int max = args.length;
String part;
int i;
for (i = 0; i < max; i++) {
part = args[i];
if(ArrayUtils.containsIgnoreCase(targets, part))
part = replacement;
result.append(part);
if(i < args.length -1) result.append(" ");
}
return result.toString();
}
public static String replaceTriggers(String input, String replacement, String... triggers) {
for (String trigger : triggers) {
if(!input.contains(trigger)) continue;
@@ -0,0 +1,119 @@
package de.rayzs.pat.utils;
import de.rayzs.pat.plugin.logger.Logger;
public class VersionComparer {
private static Version CURRENT_VERSION, NEWEST_VERSION;
public static void setCurrentVersion(String versionName) {
if(CURRENT_VERSION != null && CURRENT_VERSION.getVersionName().equals(versionName)) return;
CURRENT_VERSION = new Version(versionName);
}
public static void setNewestVersion(String versionName) {
if(NEWEST_VERSION != null && NEWEST_VERSION.getVersionName().equals(versionName)) return;
NEWEST_VERSION = new Version(versionName);
}
public static Version getCurrentVersion() {
return CURRENT_VERSION;
}
public static Version getNewestVersion() {
return NEWEST_VERSION;
}
public static boolean isNewest() {
if(CURRENT_VERSION == null || NEWEST_VERSION == null) return true;
return CURRENT_VERSION.isSame(NEWEST_VERSION);
}
public static boolean isUnreleased() {
if(CURRENT_VERSION == null || NEWEST_VERSION == null) return true;
return CURRENT_VERSION.isNewer(NEWEST_VERSION);
}
public static boolean isOutdated() {
if(CURRENT_VERSION == null || NEWEST_VERSION == null) return false;
return CURRENT_VERSION.isOlder(NEWEST_VERSION);
}
public static boolean isDeveloperVersion() {
return CURRENT_VERSION.getState() == State.DEV;
}
public static class Version {
private final String versionName;
private int release = -1, major = -1, patch = -1;
private State state = State.RELEASE;
public Version(String version) {
this.versionName = version;
try {
String[] versionSplit = version.split("\\.");
release = Integer.parseInt(versionSplit[0]);
major = Integer.parseInt(versionSplit[1]);
String patchAsString = versionSplit[2];
patchAsString = patchAsString.contains("-") ? patchAsString.split("-")[0] : patchAsString;
patch = Integer.parseInt(patchAsString);
if(!version.contains("-")) return;
String stateName = version.split("-")[1].toUpperCase();
state = State.valueOf(stateName);
} catch (Throwable throwable) {
Logger.warning("Failed to read version name! [" + version + "]");
throwable.printStackTrace();
}
}
public String getVersionName() {
return versionName;
}
public boolean isSame(Version version) {
return version.getVersionName().equals(versionName);
}
public boolean isNewer(Version comparedVersion) {
return !isSame(comparedVersion) && !isOlder(comparedVersion);
}
public boolean isOlder(Version comparedVersion) {
if(release > comparedVersion.getRelease()) return false;
if(major > comparedVersion.getMajor()) return false;
return patch < comparedVersion.getPatch();
}
public int getRelease() {
return release;
}
public int getMajor() {
return major;
}
public int getPatch() {
return patch;
}
public State getState() {
return state;
}
public boolean isInvalid() {
return release == -1 || major == -1 || patch == -1;
}
}
public enum State {
RELEASE, DEV, ALPHA, BETA
}
}
@@ -58,7 +58,7 @@ public class LuckPermsAdapter {
Map<String, Boolean> permissions = getPermissions(uuid);
if(permissions == null) return false;
return permissions.size() > 0;
return !permissions.isEmpty();
}
public static void setPermissions(UUID uuid) {
@@ -67,9 +67,10 @@ public class LuckPermsAdapter {
permissions.forEach((permission, permitted) -> {
if(permission.startsWith("proantitab.") || permission.equals("*")) PermissionUtil.setPermission(uuid, permission, permitted);
}
);
if(permission.startsWith("proantitab.") || permission.equals("*"))
PermissionUtil.setPermission(uuid, permission, permitted);
});
if(Reflection.isProxyServer()) {
if(Reflection.isVelocityServer()) VelocityAntiTabListener.updateCommands();
@@ -95,11 +96,14 @@ public class LuckPermsAdapter {
if (event.isUser() && event.getTarget() instanceof User) {
User user = (User) event.getTarget();
if (Reflection.isProxyServer()) {
if(Reflection.isVelocityServer())
PermissionUtil.reloadPermissions(user.getUniqueId());
}
else BukkitAntiTabListener.luckpermsNetworkUserSync(user.getUniqueId());
PermissionUtil.reloadPermissions(user.getUniqueId());
} else BukkitAntiTabListener.luckpermsNetworkUserSync(user.getUniqueId());
}
}
}
@@ -3,6 +3,8 @@ package de.rayzs.pat.utils.configuration.updater;
import de.rayzs.pat.utils.configuration.ConfigurationBuilder;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.*;
import de.rayzs.pat.utils.configuration.Configurator;
import java.nio.file.Files;
import java.util.*;
import java.io.*;
@@ -13,7 +15,18 @@ public class ConfigUpdater {
private static boolean LOADED = false;
public static void initialize() {
NEWEST_CONFIG_INPUT = new ConnectionBuilder().setUrl("https://raw.githubusercontent.com/RayzsYT/ProAntiTab/main/src/main/resources/files/"
try {
boolean autoUpdateConfig = (boolean) Configurator.get("config").getOrSet("updater.auto-update-config", true);
if (autoUpdateConfig) {
LOADED = false;
return;
}
} catch (Exception exception) {
Logger.warning("Failed to find section 'updater.auto-config-updater' in config.yml!");
}
NEWEST_CONFIG_INPUT = new ConnectionBuilder().setTimeout(2000).setUrl("https://raw.githubusercontent.com/RayzsYT/ProAntiTab/main/src/main/resources/files/"
+ (Reflection.isProxyServer() ? "proxy" : "bukkit")
+ "-config.yml").connect().getResponseList();
@@ -38,7 +51,7 @@ public class ConfigUpdater {
return;
}
List<String> fileInput = new LinkedList<>(Arrays.asList("# WARNING: This file is auto generated with to solely purpose to be used as comparison!", " ", " "));
List<String> fileInput = new LinkedList<>(Arrays.asList("# WARNING: This file is auto generated and its solely purpose is to be used as comparison!", " ", " "));
fileInput.addAll(NEWEST_CONFIG_INPUT);
try {
@@ -89,6 +89,8 @@ public class MessageTranslator {
}
public static void send(Object target, String text, String... replacements) {
if(text.isEmpty()) return;
text = replaceMessageString(target, text, replacements);
if(text.contains("%no-message%")) return;
@@ -1,6 +1,7 @@
package de.rayzs.pat.utils.permission;
import java.util.*;
import java.util.stream.Collectors;
public class PermissionMap {
@@ -20,7 +21,7 @@ public class PermissionMap {
}
public Set<String> getHashedPermissions() {
return permissionMap.keySet();
return permissionMap.keySet().stream().filter(permissionMap::get).collect(Collectors.toSet());
}
public void clear() {
@@ -25,10 +25,16 @@ public class PermissionUtil {
setPlayerPermissions(uuid);
}
public static String getPermissions(UUID uuid) {
public static String getPermissionsAsString(UUID uuid) {
PermissionMap permissionMap = MAP.get(uuid);
if(permissionMap == null) return "";
return Arrays.toString(permissionMap.getHashedPermissions().toArray());
return Arrays.toString(permissionMap.getHashedPermissions().toArray()).replace("[", "").replace("]", "");
}
public static Set<String> getPermissions(UUID uuid) {
PermissionMap permissionMap = MAP.get(uuid);
if(permissionMap == null) return null;
return permissionMap.getHashedPermissions();
}
public static void setPlayerPermissions(UUID uuid) {
@@ -42,10 +48,12 @@ public class PermissionUtil {
public static void setPermission(UUID uuid, String permission, boolean permitted) {
PermissionMap permissionMap;
if(!MAP.containsKey(uuid)) {
permissionMap = new PermissionMap(uuid);
MAP.put(uuid, permissionMap);
} else permissionMap = MAP.get(uuid);
permissionMap.setState(permission, permitted);
}
@@ -56,7 +64,9 @@ public class PermissionUtil {
if(targetObj instanceof CommandSender) sender = (CommandSender) targetObj;
else sender = new CommandSender(targetObj);
if(sender.isConsole()) return true;
uuid = sender.getUniqueId();
if(!MAP.containsKey(uuid)) {
@@ -0,0 +1,212 @@
package de.rayzs.pat.utils.response;
import de.rayzs.pat.plugin.modules.subargs.SubArgsModule;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.*;
import de.rayzs.pat.utils.*;
import de.rayzs.pat.utils.response.action.ActionHandler;
import java.util.*;
public class ResponseHandler {
private static List<Response> RESPONSES = new ArrayList<>();
public static void update() {
RESPONSES = new ArrayList<>();
Storage.Files.CUSTOM_RESPONSES.getKeys(true).stream().filter(key -> !key.equals("default-message")).forEach(key -> {
if(!key.contains(".")) {
Response response = new Response(key);
RESPONSES.add(response);
}
});
}
public static List<String> getResponse(UUID uuid, String input) {
return getResponse(uuid, input, Storage.ConfigSections.Settings.CANCEL_COMMAND.SUB_COMMAND_RESPONSE.getLines());
}
public static List<String> getResponse(UUID uuid, String input, List<String> defaultMessage) {
final String finalInput = input.startsWith("/") ? StringUtils.replaceFirst(input, "/", "") : input;
final Optional<Response> optionalResponse = RESPONSES.stream().filter(response -> {
for (String trigger : response.triggers)
if(trigger.endsWith("*") ? finalInput.startsWith(StringUtils.replace(trigger, "*", "")) : finalInput.equals(trigger))
return true;
return false;
}).findFirst();
if(uuid != null && optionalResponse.isPresent()) {
optionalResponse.get().executeAction(uuid);
return optionalResponse.get().message;
}
return defaultMessage;
}
private static class Response {
private final List<String> triggers, message, actions;
public Response(final String key) {
this.triggers = (List<String>) Storage.Files.CUSTOM_RESPONSES.get(key + ".triggers");
this.message = (List<String>) Storage.Files.CUSTOM_RESPONSES.getOrSet(key + ".message", SubArgsModule.BLOCKED_MESSAGE);
this.actions = (List<String>) Storage.Files.CUSTOM_RESPONSES.getOrSet(key + ".actions", new ArrayList<>());
}
public void executeAction(UUID uuid) {
String[] split;
for (String action : actions) {
if(!action.contains("::")) {
Logger.warning("! Could not recognise action: " + action);
Logger.warning(" > Syntax does not match at all. Have you used the splitters (::) correctly?");
continue;
}
split = action.split("::");
switch (split[0].toLowerCase()) {
case "effect":
if(Reflection.isProxyServer()) {
Logger.warning("! Could not execute action: " + action);
Logger.warning(" > Effect cannot be added on the proxy side!");
continue;
}
if(split.length != 4) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > Action requires 4 arguments but only has " + split.length);
Logger.warning(" > Here's an example to compare with:");
Logger.warning(" > effect::potionEffect::duration::amplifier");
Logger.warning(" > e.g: effect::BLINDNESS::100::1");
continue;
}
int duration, amplifier;
try {
duration = Integer.parseInt(split[2]);
} catch (Exception exception) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > Duration " + split[2].toUpperCase() + " is not a valid integer! (e.g: 1)");
continue;
}
try {
amplifier = Integer.parseInt(split[3]);
} catch (Exception exception) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > Amplifier " + split[3].toUpperCase() + " is not a valid integer! (e.g: 1)");
continue;
}
ActionHandler.addPotionEffect(action, uuid, split[1].toUpperCase(), duration, amplifier);
continue;
case "title":
if(split.length != 6) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > Action requires 6 arguments but only has " + split.length);
Logger.warning(" > Here's an example to compare with:");
Logger.warning(" > title::title::subtitle::fadeIn::stay::fadeOut");
Logger.warning(" > e.g: title::My title::My subtitle::300::3000::300");
continue;
}
int fadeIn, stay, fadeOut;
try {
fadeIn = Integer.parseInt(split[3]);
} catch (Exception exception) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > Fade-In " + split[3].toUpperCase() + " is not a valid integer! (e.g: 300)");
continue;
}
try {
stay = Integer.parseInt(split[4]);
} catch (Exception exception) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > Stay " + split[4].toUpperCase() + " is not a valid integer! (e.g: 3000)");
continue;
}
try {
fadeOut = Integer.parseInt(split[5]);
} catch (Exception exception) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > Fade-Out " + split[5].toUpperCase() + " is not a valid integer! (e.g: 300)");
continue;
}
ActionHandler.sendTitle(action, uuid, split[1], split[2], fadeIn, stay, fadeOut);
continue;
case "sound":
if(Reflection.isProxyServer()) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > Sounds cannot be played on the proxy side!");
continue;
}
if(split.length != 4) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > Action requires 4 arguments but only has " + split.length);
Logger.warning(" > Here's an example to compare with:");
Logger.warning(" > sound::soundName::volume::pitch");
Logger.warning(" > e.g: sound::ENTITY_ENDER_DRAGON_GROWL::1.0::1.0");
continue;
}
float volume, pitch;
try {
volume = Float.parseFloat(split[2]);
} catch (Exception exception) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > Volume " + split[2].toUpperCase() + " is not a valid float! (e.g: 1.0f)");
continue;
}
try {
pitch = Float.parseFloat(split[3]);
} catch (Exception exception) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > Pitch " + split[3].toUpperCase() + " is not a valid float! (e.g: 1.0f)");
continue;
}
ActionHandler.playSound(action, uuid, split[1].toUpperCase(), volume, pitch);
continue;
case "console":
if(split.length == 1) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > Action requires 1 arguments but only has " + split.length);
Logger.warning(" > Here's an example to compare with:");
Logger.warning(" > console::command");
Logger.warning(" > e.g: console::say Hello world!");
}
ActionHandler.executeConsoleCommand(action, uuid, split[1]);
case "actionbar":
if(split.length == 1) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > Action requires 1 arguments but only has " + split.length);
Logger.warning(" > Here's an example to compare with:");
Logger.warning(" > actionbar::text");
Logger.warning(" > e.g: actionbar::I like COOKIES");
}
ActionHandler.sendActionbar(action, uuid, split[1]);
}
}
}
}
}
@@ -0,0 +1,13 @@
package de.rayzs.pat.utils.response.action;
import java.util.UUID;
public interface Action {
void executeConsoleCommand(String action, UUID uuid, String command);
void sendTitle(String action, UUID uuid, String title, String subTitle, int fadeIn, int stay, int fadeOut);
void addPotionEffect(String action, UUID uuid, String potionEffectTypeName, int duration, int amplifier);
void playSound(String action, UUID uuid, String soundName, float volume, float pitch);
void sendActionbar(String action, UUID uuid, String text);
}
@@ -0,0 +1,31 @@
package de.rayzs.pat.utils.response.action;
import de.rayzs.pat.utils.response.action.impl.*;
import de.rayzs.pat.utils.Reflection;
import java.util.UUID;
public class ActionHandler {
private static final Action ACTION = Reflection.isProxyServer() ? Reflection.isVelocityServer() ? new VelocityAction() : new BungeeAction() : Reflection.getMinor() <= 16 ? new OldBukkitAction() : new ModernBukkitAction();
public static void initialize() {}
public static void executeConsoleCommand(String action, UUID uuid, String command) {
ACTION.executeConsoleCommand(action, uuid, command);
}
public static void sendTitle(String action, UUID uuid, String title, String subTitle, int fadeIn, int stay, int fadeOut) {
ACTION.sendTitle(action, uuid, title, subTitle, fadeIn, stay, fadeOut);
}
public static void addPotionEffect(String action, UUID uuid, String potionEffectType, int duration, int amplifier) {
ACTION.addPotionEffect(action, uuid, potionEffectType, duration, amplifier);
}
public static void playSound(String action, UUID uuid, String soundName, float volume, float pitch) {
ACTION.playSound(action, uuid, soundName, volume, pitch);
}
public static void sendActionbar(String action, UUID uuid, String text) {
ACTION.sendActionbar(action, uuid, text);
}
}
@@ -0,0 +1,54 @@
package de.rayzs.pat.utils.response.action.impl;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.response.action.Action;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.Title;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.UUID;
public class BungeeAction implements Action {
@Override
public void executeConsoleCommand(String action, UUID uuid, String command) {
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid);
if(player != null) command = command.replace("%player%", player.getName());
ProxyServer.getInstance().getPluginManager().dispatchCommand(ProxyServer.getInstance().getConsole(), command);
}
@Override
public void sendTitle(String action, UUID uuid, String title, String subTitle, int fadeIn, int stay, int fadeOut) {
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid);
if(player == null) return;
Title titleObj = ProxyServer.getInstance().createTitle();
titleObj.title(TextComponent.fromLegacyText(StringUtils.replace(title, "&", "§", "%player%", player.getName())));
titleObj.subTitle(TextComponent.fromLegacyText(StringUtils.replace(subTitle, "&", "§", "%player%", player.getName())));
titleObj.fadeIn(fadeIn);
titleObj.stay(stay);
titleObj.fadeOut(fadeOut);
player.sendTitle(titleObj);
}
@Override
public void addPotionEffect(String action, UUID uuid, String potionEffectTypeName, int duration, int amplifier) {
}
@Override
public void playSound(String action, UUID uuid, String soundName, float volume, float pitch) {
}
@Override
public void sendActionbar(String action, UUID uuid, String text) {
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid);
if(player == null) return;
player.sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(StringUtils.replace(text, "%player%", player.getName())));
}
}
@@ -0,0 +1,82 @@
package de.rayzs.pat.utils.response.action.impl;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.message.replacer.PlaceholderReplacer;
import de.rayzs.pat.utils.response.action.Action;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.util.UUID;
public class ModernBukkitAction implements Action {
@Override
public void executeConsoleCommand(String action, UUID uuid, String command) {
Player player = Bukkit.getPlayer(uuid);
if(player != null) command = command.replace("%player%", player.getName());
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
}
@Override
public void sendTitle(String action, UUID uuid, String title, String subTitle, int fadeIn, int stay, int fadeOut) {
Player player = Bukkit.getPlayer(uuid);
if(player == null) return;
title = PlaceholderReplacer.replace(player, StringUtils.replace(title, "&", "§", "%player%", player.getName()));
subTitle = PlaceholderReplacer.replace(player, StringUtils.replace(subTitle, "&", "§", "%player%", player.getName()));
player.sendTitle(title, subTitle, fadeIn, stay, fadeOut);
}
@Override
public void addPotionEffect(String action, UUID uuid, String potionEffectTypeName, int duration, int amplifier) {
Player player = Bukkit.getPlayer(uuid);
if(player == null) return;
PotionEffectType potionEffectType = null;
try {
potionEffectType = PotionEffectType.getByName(potionEffectTypeName);
} catch (Exception ignored) { }
if(potionEffectType == null) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > The effect \"" + potionEffectTypeName + "\" could not be found!");
Logger.warning(" > Here's an example of an existing effect:");
Logger.warning(" > BLINDNESS, REGENERATION");
return;
}
player.addPotionEffect(new PotionEffect(potionEffectType, duration, amplifier));
}
@Override
public void playSound(String action, UUID uuid, String soundName, float volume, float pitch) {
Player player = Bukkit.getPlayer(uuid);
if(player == null) return;
try {
Sound sound = Sound.valueOf(soundName);
player.playSound(player.getLocation(), sound, volume, pitch);
} catch (Exception exception) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > The sound \"" + soundName + "\" could not be found!");
Logger.warning(" > Here's an example of an existing sound effect:");
Logger.warning(" > ENTITY_ENDER_DRAGON_GROWL");
}
}
@Override
public void sendActionbar(String action, UUID uuid, String text) {
Player player = Bukkit.getPlayer(uuid);
if(player == null) return;
text = PlaceholderReplacer.replace(player, StringUtils.replace(text, "&", "§", "%player%", player.getName()));
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(text));
}
}
@@ -0,0 +1,105 @@
package de.rayzs.pat.utils.response.action.impl;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.message.replacer.PlaceholderReplacer;
import de.rayzs.pat.utils.response.action.Action;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Objects;
import java.util.UUID;
public class OldBukkitAction implements Action {
private String versionPackage = null;
@Override
public void executeConsoleCommand(String action, UUID uuid, String command) {
Player player = Bukkit.getPlayer(uuid);
if(player != null) command = command.replace("%player%", player.getName());
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
}
@Override
public void sendTitle(String action, UUID uuid, String title, String subTitle, int fadeIn, int stay, int fadeOut) {
Player player = Bukkit.getPlayer(uuid);
if(player == null) return;
title = PlaceholderReplacer.replace(player, StringUtils.replace(title, "&", "§", "%player%", player.getName()));
subTitle = PlaceholderReplacer.replace(player, StringUtils.replace(subTitle, "&", "§", "%player%", player.getName()));
player.sendTitle(title, subTitle);
}
@Override
public void addPotionEffect(String action, UUID uuid, String potionEffectTypeName, int duration, int amplifier) {
Player player = Bukkit.getPlayer(uuid);
if(player == null) return;
PotionEffectType potionEffectType = null;
try {
potionEffectType = PotionEffectType.getByName(potionEffectTypeName);
} catch (Exception ignored) { }
if(potionEffectType == null) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > The effect \"" + potionEffectTypeName + "\" could not be found!");
Logger.warning(" > Here's an example of an existing effect:");
Logger.warning(" > BLINDNESS, REGENERATION");
return;
}
player.addPotionEffect(new PotionEffect(potionEffectType, duration, amplifier));
}
@Override
public void playSound(String action, UUID uuid, String soundName, float volume, float pitch) {
Player player = Bukkit.getPlayer(uuid);
if(player == null) return;
try {
Sound sound = Sound.valueOf(soundName);
player.playSound(player.getLocation(), sound, volume, pitch);
} catch (Exception exception) {
Logger.warning("! Failed to read action: " + action);
Logger.warning(" > The sound \"" + soundName + "\" could not be found!");
Logger.warning(" > Here's an example of an existing sound effect:");
Logger.warning(" > ENTITY_ENDER_DRAGON_GROWL");
}
}
@Override
public void sendActionbar(String action, UUID uuid, String text) {
Player player = Bukkit.getPlayer(uuid);
if(player == null) return;
text = PlaceholderReplacer.replace(player, StringUtils.replace(text, "&", "§", "%player%", player.getName()));
try {
if(versionPackage == null)
versionPackage = Reflection.getVersionPackageName();
Object entityPlayer = player.getClass().getMethod("getHandle").invoke(player);
Constructor<?> constructor = (Objects.<Class<?>>requireNonNull(Class.forName("net.minecraft.server." + versionPackage + ".PacketPlayOutChat"))).getConstructor(Class.forName("net.minecraft.server." + versionPackage + ".IChatBaseComponent"), byte.class);
Object iChatBaseComponent = (Objects.requireNonNull(Class.forName("net.minecraft.server." + versionPackage + ".IChatBaseComponent"))).getDeclaredClasses()[0].getMethod("a", String.class).invoke(null, "{\"text\":\"" + text + "\"}");
Object actionbarPacket = constructor.newInstance(iChatBaseComponent, (byte) 2);
Object playerConnection = entityPlayer.getClass().getField("playerConnection").get(entityPlayer);
playerConnection.getClass().getMethod("sendPacket", Class.forName("net.minecraft.server." + versionPackage + ".Packet")).invoke(playerConnection, actionbarPacket);
} catch (ClassNotFoundException
| NoSuchMethodException
| IllegalAccessException
| InvocationTargetException
| NoSuchFieldException
| InstantiationException exception) {
Logger.warning("! Failed to run action: " + action);
Logger.warning(" > Actionbars are not supported in this server version!");
}
}
}
@@ -0,0 +1,55 @@
package de.rayzs.pat.utils.response.action.impl;
import de.rayzs.pat.utils.message.MessageTranslator;
import net.kyori.adventure.text.minimessage.MiniMessage;
import de.rayzs.pat.utils.response.action.Action;
import com.velocitypowered.api.proxy.Player;
import de.rayzs.pat.plugin.VelocityLoader;
import net.kyori.adventure.title.Title;
import de.rayzs.pat.utils.StringUtils;
import java.util.*;
import java.time.*;
public class VelocityAction implements Action {
@Override
public void executeConsoleCommand(String action, UUID uuid, String command) {
Optional<Player> optPlayer = VelocityLoader.getServer().getPlayer(uuid);
if (optPlayer.isPresent()) command = command.replace("%player%", optPlayer.get().getUsername());
VelocityLoader.getServer().getCommandManager().executeAsync(VelocityLoader.getServer().getConsoleCommandSource(), command);
}
@Override
public void sendTitle(String action, UUID uuid, String title, String subTitle, int fadeIn, int stay, int fadeOut) {
Optional<Player> optPlayer = VelocityLoader.getServer().getPlayer(uuid);
if(!optPlayer.isPresent()) return;
Player player = optPlayer.get();
Title titleObj = Title.title(
MiniMessage.miniMessage().deserialize(MessageTranslator.replaceMessage(StringUtils.replace(title, "%player%", player.getUsername()))),
MiniMessage.miniMessage().deserialize(MessageTranslator.replaceMessage(StringUtils.replace(subTitle, "%player%", player.getUsername()))),
Title.Times.times(Duration.ofMillis(fadeIn), Duration.ofMillis(stay), Duration.ofMillis(fadeOut))
);
player.showTitle(titleObj);
}
@Override
public void addPotionEffect(String action, UUID uuid, String potionEffectTypeName, int duration, int amplifier) {
}
@Override
public void playSound(String action, UUID uuid, String soundName, float volume, float pitch) {
}
@Override
public void sendActionbar(String action, UUID uuid, String text) {
Optional<Player> optPlayer = VelocityLoader.getServer().getPlayer(uuid);
if(!optPlayer.isPresent()) return;
Player player = optPlayer.get();
player.sendActionBar(MiniMessage.miniMessage().deserialize(MessageTranslator.replaceMessage(StringUtils.replace(text, "%player%", player.getUsername()))));
}
}
@@ -0,0 +1,43 @@
package de.rayzs.pat.utils.scheduler;
import de.rayzs.pat.utils.scheduler.impl.*;
import de.rayzs.pat.utils.Reflection;
public class PATScheduler {
public static PATSchedulerTask createScheduler(Runnable runnable, long time, long period) {
return Reflection.isFoliaServer()
? new FoliaScheduler().getInstance(false, runnable, time, period)
: new BukkitScheduler().getInstance(false, runnable, time, period);
}
public static PATSchedulerTask createScheduler(Runnable runnable, long time) {
return Reflection.isFoliaServer()
? new FoliaScheduler().getInstance(false, runnable, time)
: new BukkitScheduler().getInstance(false, runnable, time);
}
public static PATSchedulerTask createScheduler(Runnable runnable) {
return Reflection.isFoliaServer()
? new FoliaScheduler().getInstance(false, runnable)
: new BukkitScheduler().getInstance(false, runnable);
}
public static PATSchedulerTask createAsyncScheduler(Runnable runnable, long time, long period) {
return Reflection.isFoliaServer()
? new FoliaScheduler().getInstance(true, runnable, time, period)
: new BukkitScheduler().getInstance(true, runnable, time, period);
}
public static PATSchedulerTask createAsyncScheduler(Runnable runnable, long time) {
return Reflection.isFoliaServer()
? new FoliaScheduler().getInstance(true, runnable, time)
: new BukkitScheduler().getInstance(true, runnable, time);
}
public static PATSchedulerTask createAsyncScheduler(Runnable runnable) {
return Reflection.isFoliaServer()
? new FoliaScheduler().getInstance(true, runnable)
: new BukkitScheduler().getInstance(true, runnable);
}
}
@@ -0,0 +1,13 @@
package de.rayzs.pat.utils.scheduler;
public interface PATSchedulerTask {
PATSchedulerTask getInstance(boolean async, Runnable runnable, long time, long period);
PATSchedulerTask getInstance(boolean async, Runnable runnable, long time);
PATSchedulerTask getInstance(boolean async, Runnable runnable);
boolean isActive();
void setTaskId(int taskId);
void cancelTask();
}
@@ -0,0 +1,50 @@
package de.rayzs.pat.utils.scheduler.impl;
import de.rayzs.pat.utils.scheduler.PATSchedulerTask;
import de.rayzs.pat.plugin.BukkitLoader;
import org.bukkit.Bukkit;
public class BukkitScheduler implements PATSchedulerTask {
private int taskId = -1;
@Override
public PATSchedulerTask getInstance(boolean async, Runnable runnable, long time, long period) {
this.taskId = async
? Bukkit.getScheduler().scheduleAsyncRepeatingTask(BukkitLoader.getPlugin(), runnable, time, period)
: Bukkit.getScheduler().scheduleSyncRepeatingTask(BukkitLoader.getPlugin(), runnable, time, period);
return this;
}
@Override
public PATSchedulerTask getInstance(boolean async, Runnable runnable, long time) {
this.taskId = async
? Bukkit.getScheduler().scheduleAsyncDelayedTask(BukkitLoader.getPlugin(), runnable, time)
: Bukkit.getScheduler().scheduleSyncDelayedTask(BukkitLoader.getPlugin(), runnable, time);
return this;
}
@Override
public PATSchedulerTask getInstance(boolean async, Runnable runnable) {
this.taskId = async
? Bukkit.getScheduler().scheduleAsyncDelayedTask(BukkitLoader.getPlugin(), runnable)
: Bukkit.getScheduler().scheduleSyncDelayedTask(BukkitLoader.getPlugin(), runnable);
return this;
}
@Override
public boolean isActive() {
return this.taskId != 1;
}
@Override
public void setTaskId(int taskId) {
this.taskId = taskId;
}
@Override
public void cancelTask() {
Bukkit.getScheduler().cancelTask(taskId);
this.taskId = -1;
}
}
@@ -0,0 +1,48 @@
package de.rayzs.pat.utils.scheduler.impl;
import de.rayzs.pat.utils.scheduler.PATSchedulerTask;
import io.papermc.paper.threadedregions.scheduler.*;
import de.rayzs.pat.plugin.BukkitLoader;
import org.bukkit.Bukkit;
public class FoliaScheduler implements PATSchedulerTask {
private static final GlobalRegionScheduler SCHEDULER = Bukkit.getGlobalRegionScheduler();
private ScheduledTask task;
@Override
public PATSchedulerTask getInstance(boolean async, Runnable runnable, long time, long period) {
this.task = SCHEDULER.runAtFixedRate(BukkitLoader.getPlugin(), __ -> runnable.run(), time, period);
return this;
}
@Override
public PATSchedulerTask getInstance(boolean async, Runnable runnable, long time) {
this.task = SCHEDULER.runDelayed(BukkitLoader.getPlugin(), __ -> runnable.run(), time);
return this;
}
@Override
public PATSchedulerTask getInstance(boolean async, Runnable runnable) {
this.task = SCHEDULER.run(BukkitLoader.getPlugin(), __ -> runnable.run());
return this;
}
@Override
public boolean isActive() {
return !this.task.isCancelled();
}
@Override
public void setTaskId(int taskId) {
if(taskId == -1 || taskId == -5) {
cancelTask();
}
}
@Override
public void cancelTask() {
this.task.cancel();
}
}
@@ -0,0 +1,134 @@
package de.rayzs.pat.utils.subargs;
import de.rayzs.pat.plugin.modules.subargs.SubArgsModule;
import de.rayzs.pat.utils.StringUtils;
import java.util.*;
public class Argument {
private static final Argument GENERAL = new Argument();
private final List<String> INPUTS = new ArrayList<>();
private final HashMap<String, ArgumentStack> ARGUMENT_STACKS = new HashMap<>();
public static Argument getGeneralArgument() {
Argument copiedGeneralArguments = new Argument();
GENERAL.getInputs().forEach(copiedGeneralArguments::buildArgumentStacks);
return copiedGeneralArguments;
}
public static List<String> getOptions(String input) {
return GENERAL.getResult(input);
}
public static void clearArguments() {
GENERAL.clearAllArguments();
}
public static void buildArguments(String input) {
GENERAL.buildArgumentStacks(input);
}
public static List<String> getAllInputs() {
return GENERAL.getInputs();
}
public List<String> getInputs() {
return INPUTS;
}
public List<String> getResult(String input) {
String firstInputArg = input.contains(" ") ? input.split(" ")[0] : input;
for (Map.Entry<String, ArgumentStack> entry : ARGUMENT_STACKS.entrySet()) {
if(!entry.getKey().equals(firstInputArg)) continue;
return ARGUMENT_STACKS.get(entry.getKey()).getResult(input);
}
for (Map.Entry<String, ArgumentStack> entry : ARGUMENT_STACKS.entrySet()) {
if(!entry.getKey().startsWith(firstInputArg)) continue;
return ARGUMENT_STACKS.get(entry.getKey()).getResult(input);
}
return Collections.emptyList();
}
public void clearAllArguments() {
INPUTS.clear();
ARGUMENT_STACKS.clear();
}
public void buildArgumentStacks(String input) {
if(!input.contains(" ")) return;
if(!INPUTS.contains(input))
INPUTS.add(input);
boolean first = true;
ArgumentStack argumentStack = null;
for (String s : input.split(" ")) {
if(!first) {
argumentStack = argumentStack.createAndGetArgumentStack(s);
continue;
}
argumentStack = ARGUMENT_STACKS.get(s);
if (argumentStack == null) {
argumentStack = new ArgumentStack();
ARGUMENT_STACKS.put(s, argumentStack);
}
first = false;
}
}
private static class ArgumentStack {
private final HashMap<String, ArgumentStack> argumentStacks = new HashMap<>();
private final List<String> suggestions = new ArrayList<>();
public List<String> getResult(String input) {
String current;
while(input.contains(" ")) {
current = input.split(" ")[0];
if(suggestions.contains("%online_players%"))
current = StringUtils.replaceElementsFromString(current, SubArgsModule.getPlayerNames(), "%online_players%");
if(suggestions.contains("%hidden_online_players%"))
current = StringUtils.replaceElementsFromString(current, SubArgsModule.getPlayerNames(), "%hidden_online_players%");
input = StringUtils.replaceFirst(input, current, "");
input = input.startsWith(" ") ? StringUtils.replaceFirst(input, " ", "") : input;
for (Map.Entry<String, ArgumentStack> entry : argumentStacks.entrySet()) {
if(!entry.getKey().startsWith(current)) continue;
if(entry.getKey().contains("%online_players%"))
input = StringUtils.replaceElementsFromString(input, SubArgsModule.getPlayerNames(), "%online_players%");
if(entry.getKey().contains("%hidden_online_players%"))
input = StringUtils.replaceElementsFromString(input, SubArgsModule.getPlayerNames(), "%hidden_online_players%");
return entry.getValue().getResult(input);
}
}
return suggestions;
}
public ArgumentStack createAndGetArgumentStack(String origin) {
if(!suggestions.contains(origin))
suggestions.add(origin);
if(!argumentStacks.containsKey(origin)) {
ArgumentStack argumentStack = new ArgumentStack();
argumentStacks.put(origin, argumentStack);
return argumentStack;
}
return argumentStacks.get(origin);
}
}
}
+2 -2
View File
@@ -1,8 +1,8 @@
name: ProAntiTab
description: Hide more then just plugins. Hide almost everything!
description: Hide more than just your plugins. Hide almost everything!
author: Rayzs_YT
version: 1.8.0
version: 1.9.2
main: de.rayzs.pat.plugin.BungeeLoader
softDepends:
+30 -6
View File
@@ -11,6 +11,7 @@
updater:
enabled: true
period: 10000
auto-update-config: true
updated:
- '&8[&2PAT &7| &2Bukkit&8] &aYou are using the newest version! ^^'
outdated:
@@ -83,18 +84,23 @@ custom-unknown-command:
# is being blocked entirely.
cancel-blocked-commands:
enabled: true
message:
base-command-message:
- '%prefix% &cThis command &8(&4%command%&8) &cis blocked!'
sub-command-message:
- '&cCommand &8(&4%command%&8) &cwith the provided sub-argument is not allowed!'
#>> HTP (Overwritten)
# Here you can customize your own fake '/plugins' command.
custom-plugins:
enabled: true
# If this is set to true, the command will always be tab-completable,
# even if the command is supposed to be blocked
always-tab-completable: false
commands:
- pl
- plugins
- bukkit:pl
- bukkit:plugins
message:
- '&fPlugins (0):'
@@ -102,12 +108,16 @@ custom-plugins:
# Here you can customize your own fake '/version' command.
custom-version:
enabled: true
# If this is set to true, the command will always be tab-completable,
# even if the command is supposed to be blocked
always-tab-completable: false
commands:
- icanhasbukkit
- about
- version
- ver
- icanhasbukkit
- bukkit:ver
- bukkit:version
message:
- '&fThis server is running CraftBukkit version git-NasaSpigot-294 (MC: X)'
@@ -118,6 +128,14 @@ custom-version:
block-namespace-commands:
enabled: false
# Patches a small exploit which causes the server to lag.
# Due to the fact that PAT interacts directly with Tab-Completions and their packets,
# it would be a waste not to provide some simple patches like these. ^^
patch-exploits:
enabled: true
alert-message: '%prefix% &4%player% &ctried to crash/lag the server.'
kick-message: '&cFailed to read packet! Please reconnect.'
#>> HTP (Overwritten)
# This feature allows you to customize your server brand you see when you press F3.
# Normally there is something like 'Purpur', or 'Spigot'.
@@ -191,6 +209,11 @@ reload:
loading: '&eReloading all configuration files...'
done: '&aSuccessfully reloaded all configuration files!'
perms-check:
message: "&7All of &e%player%'s &7PAT-related permission: &e%permissions%"
player-is-missing: "&cPlease specify the player whose permission you want to check."
player-not-online: "&c%player% is not online!"
help:
- '&7Available commands are: &f/%label%&7... &8[&fBUKKIT&8]'
- '&7Format: &8<optional> (required)'
@@ -199,6 +222,7 @@ help:
- '&f info &7to get a few information'
- '&f postdebug &7to post the PAT logs'
- '&f update <player> &7to update player(s) permissions'
- "&f perms <player> &7to check a player's permissions"
- '&f add/rem (command) &8<group> &7to manage the list'
- '&f clear &8<group> &7to clear the list'
- '&f creategroup (group) &7to create a group'
@@ -0,0 +1,66 @@
# ____ ___ __ _ ______ __
# / __ \_________ / | ____ / /_(_)_ __/___ _/ /_
# / /_/ / ___/ __ \/ /| | / __ \/ __/ / / / / __ `/ __ \
# / ____/ / / /_/ / ___ |/ / / / /_/ / / / / /_/ / /_/ /
# /_/ /_/ \____/_/ |_/_/ /_/\__/_/ /_/ \__,_/_.___/
# custom-responses.yml
#
# Here you can configure a few of the blocked commands a bit further.
# But what exactly is this here? Every command that would normally respond with the typical "command is blocked" message, can be configured in here!
# And how does it work? It's simple. You just provide the a trigger of the command that would be normally blocked.
# Commands that would normally work won't send the messages you have set here.
# This way PAT can offer you full control over certain commands and their normal responses.
# What are these action section at each block?
# This is an additional feature to make your responses much more alive.
# Example actions that can be used are the following:
# Execute console command:
# Syntax: console::command
# Example: console::say %player% is an evil player
# Send actionbar:
# Syntax: actionbar::text
# Example: actionbar::&cThis is not cool %player%!
# Send title:
# Syntax: title::title::subtitle::5::20::5
# Example: title::&aTest title::&cHello %player%!
# Play sound:
# Syntax: sound::soundName::volume::pitch
# Example: sound::ENTITY_ENDER_DRAGON_GROWL::1.0::1.0
# Give potion effect:
# Syntax: effect::potionEffect::duration::amplifier
# Example: effect::BLINDNESS::45::1
# Here are a few examples:
# Example with kits.
# In here we only trigger the given message, if the player would type "/kit ...".
# If this command would work through sub-arguments, then the player would only able to execute the command with the
# listed sub-arguments assigned to it. Everything else will result with the set message in there.
# --
#example-with-kits:
# triggers:
# - "kit *"
# message:
# - "&cThis kit does not exist!"
# actions:
# - "console::say That's not nice %player%!"
# - "effect::BLINDNESS::45::1"
# - "sound::ENTITY_ENDER_DRAGON_GROWL::1.0::1.0"
# - "title::&cHey!::&cYou can't do that %player%!::5::20::5"
# - "actionbar::&cNop, sorry %player%"
# Here another example with an auctionhouse plugin.
# In here we only trigger the given message, if the player would type "/ah plugin".
# Normally it would print out the "command is blocked" message, because PAT would have blocked it in our case.
# Therefore, we can also assign a custom response message to it.
# ---
#example-with-auctionhouse:
# triggers:
# - "ah plugin"
# message:
# - "&cThis sub-command does not exist. Please type: &e/ah help"
# actions:
# - "console::say That's not nice %player%!"
# - "effect::BLINDNESS::45::1"
# - "sound::ENTITY_ENDER_DRAGON_GROWL::1.0::1.0"
# - "title::&cHey!::&cYou can't do that %player%!::5::20::5"
# - "actionbar::&cNop, sorry %player%"
@@ -18,7 +18,8 @@
# Placeholders of some of the messages in the config.yml:
# %pat_message_unknowncommand% = Get the "unknown command"-message from the config.yml of PAT. [cancel-blocked-command]
# %pat_message_blocked% = Get the "command blocked"-message from the config.yml of PAT. [custom-unknown-command]
# %pat_message_base_blocked% = Get the "command blocked"-message from the config.yml of PAT. [custom-unknown-command]
# %pat_message_sub_blocked% = Get the "sub-command blocked"-message from the config.yml of PAT. [custom-unknown-command]
# Placeholders to list all commands:
# %pat_list_size_commands% = Get the amount of all listed commands.
+37 -6
View File
@@ -11,6 +11,7 @@
updater:
enabled: true
period: 10000
auto-update-config: true
updated:
- '&8[&2PAT &7| &2Proxy&8] &aYou are using the newest version! ^^'
outdated:
@@ -19,6 +20,13 @@ updater:
- '&8[&4PAT &7| &4Proxy&8] &cGet the newest version here:'
- '&8[&4PAT &7| &4Proxy&8] &ehttps://www.rayzs.de/products/proantitab/page'
# If this value is set to 'true', the proxy won't communicate with the backend servers anymore.
# In other words, the backend servers won't receive any updates from the proxy about the storage.yml.
# It's here to prevent any unnecessary communication between the proxy and the backend servers, if PAT is being used on the proxy alone.
# For why this can be the case, read the following: https://github.com/RayzsYT/ProAntiTab/wiki/FAQ#can-i-install-pat-just-on-my-proxy-server
# It is NOT recommended to enable this option, unless you know what you are doing.
disable-sync: false
# This is a very necessary feature if you have way too many commands to block and instead decide
# to whitelist specific commands.
# Enabling this will disable ALL commands except for those that are in the (group-)list.
@@ -66,29 +74,38 @@ custom-unknown-command:
# is being blocked entirely.
cancel-blocked-commands:
enabled: true
message:
base-command-message:
- '%prefix% &cThis command &8(&4%command%&8) &cis blocked!'
sub-command-message:
- '&cCommand &8(&4%command%&8) &cwith the provided sub-argument is not allowed!'
# Here you can customize your own fake '/plugins' command.
custom-plugins:
enabled: true
# If this is set to true, the command will always be tab-completable,
# even if the command is supposed to be blocked
always-tab-completable: false
commands:
- pl
- plugins
- bukkit:pl
- bukkit:plugins
message:
- '&fPlugins (0):'
# Here you can customize your own fake '/version' command.
custom-version:
enabled: true
# If this is set to true, the command will always be tab-completable,
# even if the command is supposed to be blocked
always-tab-completable: false
commands:
- icanhasbukkit
- about
- version
- ver
- icanhasbukkit
- bukkit:ver
- bukkit:version
message:
- '&fThis server is running CraftBukkit version git-NasaSpigot-294 (MC: X)'
@@ -98,6 +115,14 @@ custom-version:
block-namespace-commands:
enabled: false
# Patches a small exploit which causes the server to lag.
# Due to the fact that PAT interacts directly with Tab-Completions and their packets,
# it would be a waste not to provide some simple patches like these. ^^
patch-exploits:
enabled: true
alert-message: '%prefix% &4%player% &ctried to crash/lag the server.'
kick-message: '&cFailed to read packet! Please reconnect.'
# This feature allows you to customize your server brand you see when you press F3.
# Normally there is something like 'Purpur', or 'Spigot'.
# With this feature, you are able to change and even animate it.
@@ -175,6 +200,11 @@ reload:
loading: '&eReloading all configuration files...'
done: '&aSuccessfully reloaded all configuration files!'
perms-check:
message: "&7All of &e%player%'s &7PAT-related permission: &e%permissions%"
player-is-missing: "&cPlease specify the player whose permission you want to check."
player-not-online: "&c%player% is not online!"
help:
- '&7Available commands are: &f/%label%&7... &8[&fPROXY&8]'
- '&7Format: &8<optional> (required)'
@@ -183,6 +213,7 @@ help:
- '&f info &7to get a few information'
- '&f postdebug &7to post the PAT logs'
- '&f update <player> &7to update player(s) permissions'
- "&f perms <player> &7to check a player's permissions"
- '&f add/rem (command) &8<group> &7to manage the list'
- '&f clear &8<group> &7to clear the list'
- '&f creategroup (group) &7to create a group'
@@ -0,0 +1,56 @@
# ____ ___ __ _ ______ __
# / __ \_________ / | ____ / /_(_)_ __/___ _/ /_
# / /_/ / ___/ __ \/ /| | / __ \/ __/ / / / / __ `/ __ \
# / ____/ / / /_/ / ___ |/ / / / /_/ / / / / /_/ / /_/ /
# /_/ /_/ \____/_/ |_/_/ /_/\__/_/ /_/ \__,_/_.___/
# custom-responses.yml
#
# Here you can configure a few of the blocked commands a bit further.
# But what exactly is this here? Every command that would normally respond with the typical "command is blocked" message, can be configured in here!
# And how does it work? It's simple. You just provide the a trigger of the command that would be normally blocked.
# Commands that would normally work won't send the messages you have set here.
# This way PAT can offer you full control over certain commands and their normal responses.
# What are these action section at each block?
# This is an additional feature to make your responses much more alive.
# Example actions that can be used are the following:
# Execute console command:
# Syntax: console::command
# Example: console::send %player% fallback
# Send actionbar:
# Syntax: actionbar::text
# Example: actionbar::&cThis is not cool %player%!
# Send title:
# Syntax: title::title::subtitle::5::20::5
# Example: title::&aTest title::&cHello %player%!
# Here are a few examples:
# Example with kits.
# In here we only trigger the given message, if the player would type "/kit ...".
# If this command would work through sub-arguments, then the player would only able to execute the command with the
# listed sub-arguments assigned to it. Everything else will result with the set message in there.
# --
#example-with-kits:
# triggers:
# - "kit *"
# message:
# - "&cThis kit does not exist!"
# actions:
# - "console::say That's not nice %player%!"
# - "title::Hey!::You can't do that %player%!::30::3000::30"
# - "actionbar::Nop, sorry %player%"
# Here another example with an auctionhouse plugin.
# In here we only trigger the given message, if the player would type "/ah plugin".
# Normally it would print out the "command is blocked" message, because PAT would have blocked it in our case.
# Therefore, we can also assign a custom response message to it.
# ---
#example-with-auctionhouse:
# triggers:
# - "ah plugin"
# message:
# - "&cThis sub-command does not exist. Please type: &e/ah help"
# actions:
# - "console::say That's not nice %player%!"
# - "title::Hey!::You can't do that %player%!::30::3000::30"
# - "actionbar::Nop, sorry %player%"
@@ -17,7 +17,8 @@
# Placeholders of some of the messages in the config.yml:
# %pat_message_unknowncommand% = Get the "unknown command"-message from the config.yml of PAT. [cancel-blocked-command]
# %pat_message_blocked% = Get the "command blocked"-message from the config.yml of PAT. [custom-unknown-command]
# %pat_message_base_blocked% = Get the "command blocked"-message from the config.yml of PAT. [custom-unknown-command]
# %pat_message_sub_blocked% = Get the "sub-command blocked"-message from the config.yml of PAT. [custom-unknown-command]
# Placeholders to list all commands:
# %pat_list_size_commands% = Get the amount of all listed commands.
+3 -2
View File
@@ -1,9 +1,10 @@
name: ProAntiTab
description: Hide more then just plugins. Hide almost everything!
description: Hide more than just your plugins. Hide almost everything!
author: Rayzs_YT
version: 1.8.0
version: 1.9.2
api-version: 1.13
folia-supported: true
main: de.rayzs.pat.plugin.BukkitLoader
softdepend: