Compare commits

...
366 Commits
Author SHA1 Message Date
rayzsyt 4b4ba32191 Update version name 2025-10-12 01:13:08 +02:00
rayzsyt 2ba002d508 Listed GroupManager-Support to debug post to Bukkit servers only 2025-10-12 01:11:20 +02:00
rayzsyt 594f8a25da Listed GroupManager-Support to debug post 2025-10-12 01:10:41 +02:00
rayzsyt 3ad852e1c8 Fix minor misrepresentation 2025-10-12 00:53:06 +02:00
rayzsyt b3a66eebee Update version name 2025-10-12 00:41:51 +02:00
rayzsyt 5baad90145 Added extra variable for %args[...]% 2025-10-12 00:41:23 +02:00
rayzsyt 2ceb0b6219 Improved Responses Argument Replacer 2025-10-12 00:37:34 +02:00
rayzsyt f870625551 Add GroupManager support 2025-10-10 02:57:35 +02:00
rayzsyt 993aa1e439 Update version 2025-10-09 03:31:51 +02:00
rayzsyt 44822601ee Fixed 1.8.8 issues 2025-10-09 03:25:59 +02:00
rayzsyt 19e698cce4 Update SubArgument commands for 1.8.8 2025-10-09 03:25:37 +02:00
rayzsyt f393156471 More generalised with BukkitLoader methods 2025-10-09 03:25:08 +02:00
rayzsyt 08e996d8df Improved 2025-10-09 03:24:48 +02:00
rayzsyt afffeed10f Fix 1.8.8 issues 2025-10-09 03:24:06 +02:00
rayzsyt ac7efd60de Added methods and implement body of getPlayerIds method 2025-10-09 03:23:24 +02:00
rayzsyt f0db105e7f Moved to BukkitLoader 2025-10-09 03:23:00 +02:00
rayzsyt e07a8bdebb Small adjustment 2025-10-08 19:14:17 +02:00
rayzsyt 84cff08785 Update version 2025-10-08 19:05:19 +02:00
rayzsyt 0f8740c54b Reverted some api updates 2025-10-08 19:04:48 +02:00
rayzsyt 35e1c9aca2 Add new config section 2025-10-08 18:36:06 +02:00
rayzsyt 98848cffd1 Small default-settings adjustments 2025-10-08 18:25:17 +02:00
rayzsyt df6b6f447d Add UpdateCommandsPerWorld feature 2025-10-08 18:23:59 +02:00
rayzsyt ae59f6c84b Updated moved class import 2025-10-08 18:20:28 +02:00
rayzsyt 74ee1fa94c Moved class 2025-10-08 18:19:57 +02:00
rayzsyt 9e11143b88 Code cleanup 2025-10-08 18:19:16 +02:00
rayzsyt 9786e3e472 Add 2025-10-08 18:16:36 +02:00
rayzsyt 468c7d9bd7 Rename Listener class 2025-10-08 18:16:30 +02:00
rayzsyt 640d428d70 Update api 2025-10-08 18:16:09 +02:00
rayzsyt 9a8b78ce9c Updated version name 2025-09-30 23:07:35 +02:00
rayzsyt 87e13ea777 New method 2025-09-30 23:06:51 +02:00
rayzsyt 8e70558363 Wrong display of commands 2025-09-30 23:06:43 +02:00
rayzsyt 5764842f52 Reload existing proxy commands after specific iterations 2025-09-27 01:46:01 +02:00
rayzsyt c2634da6af Relocated proxy-commands load into separate function instead 2025-09-20 00:00:07 +02:00
rayzsyt bf04109e91 Added delayed reload of proxy-commands 2025-09-19 23:59:03 +02:00
rayzsyt ebc46247ad Fixed wrong display of missing parts after plugin-reload 2025-09-14 19:35:54 +02:00
rayzsyt bac1361f98 Removed unnecessary part 2025-09-14 19:26:41 +02:00
rayzsyt b26b1eacba Minor change to missing-parts format 2025-09-14 19:21:57 +02:00
rayzsyt 367357821e Minor change 2025-09-14 19:21:29 +02:00
rayzsyt 030154a135 Improved tutorial 2025-09-14 19:05:18 +02:00
rayzsyt b0bb78acdd Add BaseCommandCaseSensitive option 2025-09-14 18:50:58 +02:00
rayzsyt f98aafa8d1 Add BaseCommandCaseSensitive option 2025-09-14 18:50:54 +02:00
rayzsyt 805a041474 Remove lowercasing the commands 2025-09-14 18:50:16 +02:00
rayzsyt 3f5a0ae4a0 Update version name 2025-09-14 18:26:01 +02:00
rayzsyt 27caf727de Added Software-API info 2025-09-14 18:15:07 +02:00
rayzsyt 31a7d9bc9f Shorten Folia-Check 2025-09-14 18:09:02 +02:00
rayzsyt 3eaf2549e8 Integrated toggleInjection method 2025-09-14 18:07:15 +02:00
rayzsyt 6f0d290d0d Add toggleInjection method 2025-09-14 18:07:08 +02:00
rayzsyt a03da1bbd3 Experimental removal for unnecessary copy-operation 2025-09-14 17:42:39 +02:00
rayzsyt 35d6bd9ead Avoided modifying an iterating list 2025-09-14 17:42:23 +02:00
rayzsyt 97e7b712c7 Added try-catch to identify errors more precise 2025-09-14 17:41:48 +02:00
rayzsyt fcdcb8fa1c Small adjustment 2025-09-13 19:10:27 +02:00
rayzsyt 71b64d74e6 Improve check 2025-09-13 19:09:12 +02:00
rayzsyt bd411e3239 Test to avoid ArrayOutOfBounds issue 2025-09-13 18:24:05 +02:00
rayzsyt 91ce9326b2 Test to avoid ArrayOutOfBounds issue 2025-09-13 18:17:20 +02:00
rayzsyt 9711af2ff4 Removed unnecessary backend-only information 2025-09-05 02:44:25 +02:00
rayzsyt dabf1ca089 Add plugins information 2025-09-05 02:44:04 +02:00
rayzsyt f43c4f7680 Changed log priority 2025-08-29 15:22:01 +02:00
rayzsyt 28ecc7c92d Simplified function due to removal of debug logger 2025-08-29 15:21:35 +02:00
rayzsyt b36428b4ab Added info-method & fixed group-commands issue 2025-08-29 15:21:14 +02:00
rayzsyt 21d219ca53 Changed post-debug function 2025-08-29 15:20:47 +02:00
rayzsyt 497ea897d3 Removed debug logger 2025-08-29 15:20:12 +02:00
rayzsyt 35c4908936 Fix Blacklist/Whitelist issue 2025-08-29 15:19:58 +02:00
rayzsyt 091eb9ae8a Remove debug logger 2025-08-29 15:19:39 +02:00
rayzsyt 445a5d37c3 Remove debug logs 2025-08-29 15:19:13 +02:00
rayzsyt e6b8a9383e Update version name 2025-08-29 15:15:32 +02:00
rayzsyt 66b350eb5e Fix minor bug 2025-08-24 15:12:08 +02:00
rayzsyt da84e1164a Fix minor bug 2025-08-24 15:08:45 +02:00
rayzsyt cde86d46c3 Remove unnecessary Message-Formatting 2025-08-24 15:07:55 +02:00
rayzsyt 607ee2a6c8 Additional group-update check 2025-08-23 16:58:40 +02:00
rayzsyt 6219c7ce9a Add getSenderFromUUID method 2025-08-23 16:57:14 +02:00
rayzsyt 098035d280 Fix new groups not getting set 2025-08-23 16:56:56 +02:00
rayzsyt 111b1275c4 Fix logic (I gave every player perms to all groups ;-;) 2025-08-23 16:42:32 +02:00
rayzsyt d6119a41fb Remove unnecessary function calls 2025-08-23 14:34:36 +02:00
rayzsyt 095dfde3bb Change approach of scanning the list 2025-08-23 14:33:25 +02:00
rayzsyt 3bc56bc934 Change version 2025-08-22 18:15:12 +02:00
rayzsyt 14ecc52cda Improve player-groups storaging 2025-08-22 18:09:02 +02:00
rayzsyt 464355c91c Delayed when filteredCommands list is being set to when it's completed 2025-08-22 06:24:37 +02:00
rayzsyt 82e704eaf7 Readded native command handling 2025-08-21 23:33:08 +02:00
rayzsyt 54284a0543 Removed debug logger 2025-08-21 23:32:55 +02:00
rayzsyt 2cf07382df Update version name 2025-08-21 23:32:40 +02:00
rayzsyt 1de01ac745 Fixed Permission-Recognition issue (Without LuckPerms) 2025-08-19 22:45:01 +02:00
rayzsyt 66fce9fb50 Add 2025-08-19 20:49:08 +02:00
rayzsyt 017500fb5a Integrated LimitedList List 2025-08-19 20:49:03 +02:00
rayzsyt ddd8025fe5 Integrated Negation 2025-08-18 18:52:34 +02:00
rayzsyt f27bc065ba Ignore Negation 2025-08-18 18:52:18 +02:00
rayzsyt 9db3819866 Small method replacement 2025-08-18 18:51:55 +02:00
rayzsyt 8a5470dc68 Added Negation Operator (!) 2025-08-18 18:51:41 +02:00
rayzsyt 159f1b5938 Allows uppercase exceptions 2025-08-18 18:49:56 +02:00
rayzsyt 89fc1ef8ee Add (-_) operator 2025-08-17 18:38:12 +02:00
rayzsyt f249f77cfa Updated version 2025-08-17 18:37:59 +02:00
rayzsyt fad7525101 Removed unused import 2025-08-13 20:55:19 +02:00
rayzsyt 8dc3583ec7 Added delayed permission check if there's no LuckPerms installed 2025-08-13 20:54:40 +02:00
rayzsyt 2936faab56 Improved Logic 2025-08-13 20:52:45 +02:00
rayzsyt 637b7a263a Improved Update Command 2025-08-13 20:51:52 +02:00
rayzsyt be26033dfe Updated version name 2025-08-13 20:51:03 +02:00
rayzsyt 4bc7a7f292 Updated version name 2025-08-13 20:50:56 +02:00
rayzsyt 9b6a9061bc Fixed StackOverFlow Exploit 2025-08-13 20:50:46 +02:00
rayzsyt 6358358078 Added m, k and b to number criteria 2025-08-09 01:35:38 +02:00
rayzsyt 4c4224eb09 Update version name 2025-08-09 01:35:16 +02:00
rayzsyt 9100db600e Fixed removal of commands if "spaced" command was included 2025-08-08 17:49:12 +02:00
rayzsyt 263e3e6896 Removed unnecessary boolean 2025-08-08 04:34:42 +02:00
rayzsyt 26f326668f Fixed commands-update issue when reloading 2025-08-08 04:33:17 +02:00
rayzsyt 74e26a05f3 Update version name 2025-08-08 04:32:58 +02:00
rayzsyt 36145b1ee7 Update version name 2025-08-07 18:26:43 +02:00
rayzsyt 5f457c6e4a Fixed wrong display of blocked command in chat 2025-08-07 18:26:00 +02:00
rayzsyt 65dc540577 Improved performance of getAllCommands method 2025-08-07 01:59:32 +02:00
rayzsyt c338e29ec4 Changed method call 2025-08-07 01:59:08 +02:00
rayzsyt c253f6684b Small refactoring 2025-08-07 01:58:56 +02:00
rayzsyt aa740ffabf Fixed potential Folia incompatibility 2025-08-07 01:58:38 +02:00
rayzsyt e9ffe83a93 Integrated new methods from Loader 2025-08-07 01:58:19 +02:00
rayzsyt c83e83bb06 Integrated new method from Loader 2025-08-07 01:58:04 +02:00
rayzsyt b3c2e014c1 Add new methods 2025-08-07 01:57:54 +02:00
rayzsyt 6631da42e1 Fixed BLACKLIST mode issues 2025-08-07 01:57:44 +02:00
rayzsyt ac5233582f Change version name & integrated new default methods 2025-08-07 01:57:18 +02:00
rayzsyt 32a1f4351a Change version name 2025-08-07 01:57:01 +02:00
rayzsyt 2ff88eeb03 Fixed 1.8.8 incompatibility 2025-08-04 21:44:52 +02:00
rayzsyt 62b505450a Update version name 2025-08-04 21:44:11 +02:00
rayzsyt f7fd9dd42a Update version name 2025-08-04 18:31:55 +02:00
rayzsyt acd8e9291a Fix unnecessary offline-player cache spam 2025-08-02 16:20:17 +02:00
rayzsyt 50c80fc708 Change version name 2025-08-02 16:19:47 +02:00
rayzsyt bb02672085 Apply %args[.-.]% for in-game messages as well 2025-07-31 03:17:43 +02:00
rayzsyt f2e7efeaa6 Fix 0 commands 2025-07-31 03:04:39 +02:00
rayzsyt aa0863e726 Fix missing notification on /pl or /ver 2025-07-30 22:16:32 +02:00
rayzsyt 71cec6933f Add setDoesNotify function 2025-07-30 22:16:03 +02:00
rayzsyt c2d407cd62 Improved Update-Notifier 2025-07-30 22:15:54 +02:00
rayzsyt 61adaa19db Improved notification dedicator 2025-07-30 20:53:55 +02:00
rayzsyt 4c1cc0683d Add exceptional version names 2025-07-30 20:53:35 +02:00
rayzsyt ce3b42af38 Improved VersionComparer 2025-07-30 19:46:21 +02:00
rayzsyt 61c204ade0 Improved replaceArgsVariables Function 2025-07-30 17:18:34 +02:00
rayzsyt e13fae6e67 Removed Skript 2025-07-30 05:23:36 +02:00
rayzsyt 31e4c3caa4 Added variable examples for %args[.-.]% 2025-07-30 05:21:52 +02:00
rayzsyt bccb77667d Added variable %args[from-to]% 2025-07-30 05:18:25 +02:00
rayzsyt 4ab0791740 Updated version name 2025-07-30 05:18:04 +02:00
rayzsyt a9afbad0a2 Updated version name 2025-07-28 20:29:33 +02:00
rayzsyt d625212ac1 Code more readable 2025-07-28 20:26:49 +02:00
rayzsyt ee23b2d47e Fixed sub-argument issue with digits 2025-07-28 20:26:09 +02:00
rayzsyt 30714d5b7d Fixed sub-argument issue with digits 2025-07-28 20:26:03 +02:00
rayzsyt 07734f70bb Moved replacePlaceholders method in here 2025-07-28 20:25:39 +02:00
rayzsyt 367d0cec7e Updated version name 2025-07-28 20:25:18 +02:00
rayzsyt ad00b95b88 Removed notification if WHITELIST mode is enabled 2025-07-28 16:14:40 +02:00
rayzsyt 9530b415c7 Improved CommandSender 2025-07-27 17:33:26 +02:00
rayzsyt aff33cf99e Restricted %command% variable to first arg only 2025-07-27 02:49:13 +02:00
rayzsyt 83666bfce3 Fixed issue with per-server group commands 2025-07-27 02:39:05 +02:00
rayzsyt ca5f5670e5 Changed %command% placehoder 2025-07-27 02:38:44 +02:00
rayzsyt ba15d4700e Changed %comand% placehoder 2025-07-27 02:38:37 +02:00
rayzsyt 55bc9bb642 Small refractor 2025-07-27 02:04:33 +02:00
rayzsyt 2728e6c141 Updated version 2025-07-26 04:53:18 +02:00
rayzsyt 2fde07aad2 Fixed Bungeecord commands tab-completions 2025-07-26 04:52:43 +02:00
rayzsyt aa6877e423 Add generalBlacklist return function 2025-07-26 04:52:15 +02:00
rayzsyt 5e88bcd9be Fixed group sub-argument command detection 2025-07-26 04:51:58 +02:00
rayzsyt c117048ecb Reactivated TabCompleteEvent handler 2025-07-26 04:51:34 +02:00
rayzsyt 5ade086d6c Refractor 2025-07-26 04:51:16 +02:00
rayzsyt 78a59912f3 Refractor 2025-07-26 04:50:51 +02:00
rayzsyt 4997017f0f Improve player recognition 2025-07-25 18:26:58 +02:00
rayzsyt 24ba7e179a Improved Proxy command recognition for groups 2025-07-25 03:37:00 +02:00
rayzsyt 2d3d8ba220 Fixed player names 2025-07-24 18:46:38 +02:00
rayzsyt f3ceace3ba Add new example 2025-07-24 17:43:44 +02:00
rayzsyt 6b743772cb Recode 2025-07-24 03:39:13 +02:00
rayzsyt d66c02d0ec Recode 2025-07-24 03:34:55 +02:00
Alihan 09764ab98c Add files via upload 2025-07-23 03:53:52 +02:00
RayzsYT 02f54c986b Updated Netty and MiniMessage library versions 2025-04-19 20:35:02 +02:00
RayzsYT eaad46b391 Fixed exception 2025-04-19 20:34:47 +02:00
RayzsYT 29ee010aad Changed default values 2025-04-19 19:55:13 +02:00
RayzsYT 9210100335 Fixes sub-args accessibility with bypass perms 2025-04-19 19:55:00 +02:00
RayzsYT 621fb6740d Fixed 1.21.1 sub-args issue 2025-04-19 19:54:32 +02:00
RayzsYT d26400f6d6 Small visual changes 2025-04-19 19:54:05 +02:00
RayzsYT 5a4674368a Fixed potential bugs 2025-04-16 15:47:55 +02:00
Alihan Olgun 3b0a0a4db2 Add bypass-permission for 'unknown-command' feature 2025-04-11 10:47:26 +02:00
Alihan 8263df961b Update proxy-storage.yml 2025-04-11 10:43:24 +02:00
Alihan Olgun d8a425665b Implement Disabled-Server option 2025-04-11 10:33:30 +02:00
Alihan Olgun cca0a12dcf Added PlaceholderAPI implementation for custom action commands. 2025-04-11 10:23:00 +02:00
RayzsYT b452d8e031 Fix sub-argument issue with similar command names -- Experimental 2025-04-01 19:02:10 +02:00
RayzsYT 0fb3225f7c Refactor 2025-04-01 19:01:36 +02:00
RayzsYT 0ee6953180 Small import change for some IDEA-related problems 2025-03-30 22:21:03 +02:00
RayzsYT 0602616265 Add Custom-Player-List feature 2025-03-30 22:20:03 +02:00
RayzsYT 89b3a01c71 Removed unused imports 2025-03-29 02:23:06 +01:00
RayzsYT e65fea42f3 Fixed namespace issue with 1.8.8 2025-03-22 15:53:48 +01:00
RayzsYT d5e1ac1968 Removed PlaceholderAPI request if no placeholder exist 2025-03-02 01:15:14 +01:00
RayzsYT 70e2d6805b Small changes 2025-03-02 01:12:39 +01:00
RayzsYT 0370891b68 Add 2025-03-01 23:03:04 +01:00
RayzsYT 22f5737980 Fix 1.8.8 server -> 1.21.4 commands issues 2025-03-01 23:03:00 +01:00
RayzsYT 4c99a226be Changed default storage.yml command list 2025-03-01 21:50:30 +01:00
RayzsYT 80c8dc7e53 Removed wiki from bungee.yml xd 2025-03-01 03:40:36 +01:00
RayzsYT 912732a6c3 Added website to plugin descriptions 2025-03-01 03:10:55 +01:00
RayzsYT 76dd4722cf Changed default placeholder lists 2025-03-01 02:11:37 +01:00
RayzsYT 676b2d1c0a Fixed nested placeholder issues 2025-03-01 01:24:42 +01:00
RayzsYT 133cad70ef Fixed potential exception 2025-03-01 01:13:35 +01:00
RayzsYT 62355aa6db Fixed potential exception 2025-03-01 01:09:22 +01:00
RayzsYT be8b625a90 Added %pat_general_prefix% placeholder 2025-03-01 01:06:19 +01:00
RayzsYT ee4a1da3d5 Added %pat_general_prefix% placeholder 2025-03-01 01:02:44 +01:00
RayzsYT 992a3eda18 Added %pat_general_prefix% placeholder 2025-03-01 00:59:54 +01:00
RayzsYT 37f02b6902 Added extra messages to packet transfer 2025-03-01 00:52:58 +01:00
RayzsYT cbdf43174a Removed debug message 2025-03-01 00:52:45 +01:00
RayzsYT 80becff090 Improved PlaceholderAPI functionality and fixed bugs 2025-03-01 00:37:25 +01:00
RayzsYT ffd52212e1 Fixed issue with Skript alias commands recognition 2025-03-01 00:05:17 +01:00
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
182 changed files with 9757 additions and 3469 deletions

No files matched your search

+29 -7
View File
@@ -6,7 +6,7 @@
<groupId>de.rayzs.pat</groupId>
<artifactId>ProAntiTab</artifactId>
<version>1.8.0</version>
<version>2.0.20</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
@@ -76,6 +76,13 @@
<dependencies>
<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>
@@ -86,7 +93,7 @@
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.0.23.Final</version>
<version>4.2.0.Final</version>
<scope>provided</scope>
</dependency>
@@ -112,6 +119,13 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.ElgarL</groupId>
<artifactId>groupmanager</artifactId>
<version>3.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>brigadier</artifactId>
@@ -213,35 +227,35 @@
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.15.0</version>
<version>4.25.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.17.0</version>
<version>4.25.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.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-bukkit</artifactId>
<version>4.3.2</version>
<version>4.3.4</version>
<scope>compile</scope>
</dependency>
@@ -299,6 +313,14 @@
</artifactSet>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>16</source>
<target>16</target>
</configuration>
</plugin>
</plugins>
</build>
@@ -1,7 +1,9 @@
package de.rayzs.pat.api.brand;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.api.brand.impl.*;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.PacketUtils;
import de.rayzs.pat.utils.Reflection;
public class CustomServerBrand {
@@ -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();
}
@@ -1,12 +1,15 @@
package de.rayzs.pat.api.brand.impl;
import de.rayzs.pat.api.brand.CustomServerBrand;
import de.rayzs.pat.api.netty.bukkit.BukkitPacketAnalyzer;
import de.rayzs.pat.api.brand.ServerBrand;
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;
import org.bukkit.plugin.Plugin;
import de.rayzs.pat.utils.*;
@@ -16,17 +19,19 @@ import java.util.*;
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 boolean INITIALIZED = false;
private static PATSchedulerTask TASK;
private static boolean INITIALIZED = false, NO_PREP_CHANNELS = false;
private static Class<?> brandPayloadClass, clientBoundCustomPacketPayloadPacketClass, customPacketPayloadPacketClass;
@Override
public void initializeTask() {
if(Reflection.isWeird()) {
if (Reflection.isWeird()) {
NO_PREP_CHANNELS = Reflection.getMinor() >= 22 || (Reflection.getMinor() == 21 && Reflection.getRelease() >= 7);
if (brandPayloadClass == null)
brandPayloadClass = Reflection.getClass("net.minecraft.network.protocol.common.custom.BrandPayload");
@@ -38,7 +43,7 @@ public class BukkitServerBrand implements ServerBrand {
}
Bukkit.getOnlinePlayers().forEach(this::preparePlayer);
if(!INITIALIZED)
if (!INITIALIZED)
try {
Method method = Reflection.getMethodsByParameterAndName(SERVER.getMessenger(), "addToOutgoing", Plugin.class, String.class).get(0);
Reflection.invokeMethode(method, SERVER.getMessenger(), BukkitLoader.getPlugin(), CustomServerBrand.CHANNEL_NAME);
@@ -48,22 +53,23 @@ public class BukkitServerBrand implements ServerBrand {
exception.printStackTrace();
}
if(TASK != -1) {
Bukkit.getScheduler().cancelTask(TASK);
TASK = -1;
MODIFIED_BRAND_PLAYERS.clear();
if(TASK != null && TASK.isActive()) {
TASK.cancelTask();
TASK = null;
}
if(!Storage.ConfigSections.Settings.CUSTOM_BRAND.ENABLED) return;
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";
@@ -77,12 +83,16 @@ public class BukkitServerBrand implements ServerBrand {
if(!(playerObj instanceof Player) || !Storage.ConfigSections.Settings.CUSTOM_BRAND.ENABLED) return;
Player player = (Player) playerObj;
if (NO_PREP_CHANNELS) {
return;
}
try {
Field channelsField = Reflection.getFieldByName(player.getClass(), "channels");
Set<String> channels = (Set<String>) channelsField.get(player);
channels.add(CustomServerBrand.CHANNEL_NAME);
Reflection.closeAccess(channelsField);
if(!MODIFIED_BRAND_PLAYERS.contains(player)) MODIFIED_BRAND_PLAYERS.add(player);
} catch (Exception exception) {
exception.printStackTrace();
}
@@ -108,6 +118,7 @@ public class BukkitServerBrand implements ServerBrand {
Object brandPayloadObj = brandPayloadClass.getDeclaredConstructor(String.class).newInstance(MessageTranslator.replaceMessage(player, customBrand)),
customPacketPayloadPacket = clientBoundCustomPacketPayloadPacketClass.getDeclaredConstructor(customPacketPayloadPacketClass).newInstance(brandPayloadObj);
channel.pipeline().writeAndFlush(customPacketPayloadPacket);
} catch (Exception exception) {
@@ -115,12 +126,8 @@ public class BukkitServerBrand implements ServerBrand {
}
}
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);
}
public static void removeFromModified(Player player) {
MODIFIED_BRAND_PLAYERS.remove(player);
@Override
public PacketUtils.BrandManipulate createPacket(Object playerObj) {
return null;
}
}
@@ -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;
}
}
@@ -0,0 +1,47 @@
package de.rayzs.pat.api.command;
import de.rayzs.pat.utils.*;
import de.rayzs.pat.utils.sender.CommandSender;
import java.util.*;
public abstract class ProCommand {
private final String name;
private final List<String> aliases;
protected boolean proxyOnly = false, serverCommand = false;
public ProCommand(String name, String... aliases) {
this.name = name.toLowerCase();
this.aliases = aliases != null && !aliases[0].isBlank() ? Arrays.asList(aliases) : new ArrayList<>();
}
public String getName() {
return name;
}
public boolean isProxyOnly() {
return proxyOnly;
}
public boolean isServerCommand() {
return serverCommand;
}
public List<String> getAliases() {
return aliases;
}
public boolean isCommand(String label) {
String commandName = StringUtils.getFirstArg(label);
if (name.equalsIgnoreCase(commandName))
return true;
return !aliases.isEmpty() && aliases.stream().anyMatch(commandName::equalsIgnoreCase);
}
public abstract boolean execute(CommandSender sender, String[] args);
public abstract List<String> tabComplete(CommandSender sender, String[] args);
}
@@ -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,24 @@ 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();
else stop();
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() {
@@ -1,25 +1,42 @@
package de.rayzs.pat.api.communication;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import de.rayzs.pat.api.communication.client.ClientInfo;
import de.rayzs.pat.api.communication.client.impl.*;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.api.storage.blacklist.impl.*;
import de.rayzs.pat.api.communication.impl.*;
import de.rayzs.pat.plugin.BukkitLoader;
import de.rayzs.pat.api.communication.client.impl.BungeeClientInfo;
import de.rayzs.pat.api.communication.client.impl.VelocityClientInfo;
import de.rayzs.pat.api.communication.impl.BukkitClient;
import de.rayzs.pat.api.communication.impl.BungeeClient;
import de.rayzs.pat.api.communication.impl.VelocityClient;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.storage.Storage;
import java.util.concurrent.TimeUnit;
import de.rayzs.pat.utils.group.*;
import de.rayzs.pat.utils.*;
import java.util.*;
import de.rayzs.pat.api.storage.blacklist.impl.GeneralBlacklist;
import de.rayzs.pat.api.storage.blacklist.impl.GroupBlacklist;
import de.rayzs.pat.plugin.BukkitLoader;
import de.rayzs.pat.utils.CommunicationPackets;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.group.Group;
import de.rayzs.pat.utils.group.GroupManager;
import de.rayzs.pat.utils.group.TinyGroup;
import de.rayzs.pat.utils.permission.PermissionUtil;
public class Communicator {
private static final Client CLIENT = Reflection.isVelocityServer() ? new VelocityClient() : Reflection.isProxyServer() ? new BungeeClient() : new BukkitClient();
private static final Client CLIENT =
Reflection.isVelocityServer() ? new VelocityClient()
: Reflection.isProxyServer() ? new BungeeClient()
: new BukkitClient();
private static final UUID SERVER_ID = UUID.randomUUID();
public static final List<ClientInfo> CLIENTS = new ArrayList<>();
private static final ExpireCache<String, ClientInfo> QUEUE_CLIENTS = new ExpireCache<>(15, TimeUnit.SECONDS);
public static long LAST_DATA_UPDATE = System.currentTimeMillis(), LAST_SENT_REQUEST = 0, LAST_BUKKIT_SYNC = System.currentTimeMillis();
public static int SERVER_DATA_SYNC_COUNT = 0;
public static long LAST_DATA_UPDATE = System.currentTimeMillis(),
LAST_SENT_REQUEST = 0,
LAST_BUKKIT_SYNC = System.currentTimeMillis();
public static void sendPacket(Object packet) {
CLIENT.send(packet);
@@ -30,52 +47,76 @@ public class Communicator {
}
public static void receiveInformation(String serverName, Object packet) {
if(packet instanceof CommunicationPackets.RequestPacket) {
CommunicationPackets.RequestPacket requestPacket = (CommunicationPackets.RequestPacket) packet;
if (!requestPacket.isToken(Storage.TOKEN)) return;
ClientInfo client = getClientByName(serverName);
if (packet instanceof CommunicationPackets.RequestPacket) {
CommunicationPackets.RequestPacket requestPacket = (CommunicationPackets.RequestPacket) packet;
if (!requestPacket.isToken(Storage.TOKEN))
return;
ClientInfo client = getClientByName(serverName);
if (client == null) {
client = Reflection.isVelocityServer() ? new VelocityClientInfo(requestPacket.getServerId(), serverName) : new BungeeClientInfo(requestPacket.getServerId(), serverName);
client = Reflection.isVelocityServer()
? new VelocityClientInfo(requestPacket.getServerId(), serverName)
: new BungeeClientInfo(requestPacket.getServerId(), serverName);
CLIENTS.add(client);
}
if (!client.compareId(requestPacket.getServerId())) client.setId(requestPacket.getServerId());
if (!client.compareId(requestPacket.getServerId()))
client.setId(requestPacket.getServerId());
syncData(client.getId());
return;
}
if(packet instanceof CommunicationPackets.ForcePermissionResetPacket) {
if(Reflection.isProxyServer()) return;
CommunicationPackets.ForcePermissionResetPacket permissionResetPacket = (CommunicationPackets.ForcePermissionResetPacket) packet;
if(!permissionResetPacket.isToken(Storage.TOKEN)) return;
if (packet instanceof CommunicationPackets.ForcePermissionResetPacket) {
if (Reflection.isProxyServer())
return;
CommunicationPackets.ForcePermissionResetPacket permissionResetPacket = (CommunicationPackets.ForcePermissionResetPacket) packet;
if (!permissionResetPacket.isToken(Storage.TOKEN))
return;
if (permissionResetPacket.hasTarget())
PermissionUtil.setPlayerPermissions(permissionResetPacket.getTargetUUID());
else
PermissionUtil.reloadPermissions();
if(permissionResetPacket.hasTarget()) PermissionUtil.setPlayerPermissions(permissionResetPacket.getTargetUUID());
else PermissionUtil.reloadPermissions();
return;
}
if(packet instanceof CommunicationPackets.BackendDataPacket) {
if (packet instanceof CommunicationPackets.BackendDataPacket) {
CommunicationPackets.BackendDataPacket backendDataPacket = (CommunicationPackets.BackendDataPacket) packet;
if (!backendDataPacket.isToken(Storage.TOKEN)) return;
if (!backendDataPacket.isToken(Storage.TOKEN))
return;
Storage.SERVER_NAME = backendDataPacket.getServerName();
return;
}
if(packet instanceof CommunicationPackets.FeedbackPacket) {
if (packet instanceof CommunicationPackets.FeedbackPacket) {
CommunicationPackets.FeedbackPacket feedbackPacket = (CommunicationPackets.FeedbackPacket) packet;
if (!feedbackPacket.isToken(Storage.TOKEN)) return;
if (!feedbackPacket.isToken(Storage.TOKEN))
return;
String serverId = feedbackPacket.getServerId();
ClientInfo client = getClientByName(serverName);
if (client == null) {
client = Reflection.isVelocityServer() ? new VelocityClientInfo(feedbackPacket.getServerId(), serverName) : new BungeeClientInfo(feedbackPacket.getServerId(), serverName);
client = Reflection.isVelocityServer()
? new VelocityClientInfo(feedbackPacket.getServerId(), serverName)
: new BungeeClientInfo(feedbackPacket.getServerId(), serverName);
CLIENTS.add(client);
}
if (!client.compareId(feedbackPacket.getServerId())) client.setId(feedbackPacket.getServerId());
if (client.hasSentFeedback()) return;
if (!client.compareId(feedbackPacket.getServerId()))
client.setId(feedbackPacket.getServerId());
if (client.hasSentFeedback())
return;
client.setFeedback(true);
client.syncTime();
SERVER_DATA_SYNC_COUNT++;
@@ -85,9 +126,10 @@ public class Communicator {
return;
}
if(packet instanceof CommunicationPackets.PacketBundle) {
if (packet instanceof CommunicationPackets.PacketBundle) {
CommunicationPackets.PacketBundle packetBundle = (CommunicationPackets.PacketBundle) packet;
if(!packetBundle.isToken(Storage.TOKEN) || !packetBundle.isId(SERVER_ID.toString())) return;
if (!packetBundle.isToken(Storage.TOKEN) || !packetBundle.isId(SERVER_ID.toString()))
return;
Storage.USE_VELOCITY = packetBundle.isVelocity();
LAST_BUKKIT_SYNC = System.currentTimeMillis();
@@ -100,18 +142,24 @@ 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) {
SERVER_DATA_SYNC_COUNT = 0;
CLIENTS.forEach(currentClient -> syncData(currentClient.getId()));
return;
} else {
clientInfo = getClientById(serverId);
if(clientInfo != null) clientInfo.setFeedback(false);
SERVER_DATA_SYNC_COUNT = SERVER_DATA_SYNC_COUNT -1;
if(SERVER_DATA_SYNC_COUNT <= 0) SERVER_DATA_SYNC_COUNT = 0;
if (clientInfo != null)
clientInfo.setFeedback(false);
SERVER_DATA_SYNC_COUNT = Math.max(0, SERVER_DATA_SYNC_COUNT -1);
}
CommunicationPackets.CommandsPacket commandsPacket = new CommunicationPackets.CommandsPacket();
@@ -120,13 +168,18 @@ public class Communicator {
List<String> commands = new ArrayList<>();
String tempServerName = "";
if(clientInfo != null && clientInfo.getName() != null) {
tempServerName = clientInfo.getName().toLowerCase();
if(!Storage.Blacklist.isOnIgnoredServer(tempServerName))
if (clientInfo != null && clientInfo.getName() != null) {
tempServerName = clientInfo.getName();
if (!Storage.Blacklist.isIgnoredServer(tempServerName))
commands.addAll(Storage.Blacklist.getBlacklist().getCommands());
List<GeneralBlacklist> serverBlacklists = Storage.Blacklist.getBlacklists(clientInfo.getName());
serverBlacklists.stream().filter(serverBlacklist -> serverBlacklist != null && serverBlacklist.getCommands() != null).forEach(serverBlacklist -> commands.addAll(serverBlacklist.getCommands()));
List<GeneralBlacklist> serverBlacklists = Storage.Blacklist.getServerBlacklists(clientInfo.getName());
serverBlacklists.stream().filter(serverBlacklist ->
serverBlacklist != null && serverBlacklist.getCommands() != null
).forEach(serverBlacklist ->
commands.addAll(serverBlacklist.getCommands())
);
}
final String serverName = tempServerName;
@@ -134,7 +187,8 @@ public class Communicator {
TinyGroup tinyGroup;
for (Group group : GroupManager.getGroups()) {
if(groups.stream().anyMatch(cTG -> cTG.getGroupName().equals(group.getGroupName()))) continue;
if (groups.stream().anyMatch(cTG -> cTG.getGroupName().equals(group.getGroupName())))
continue;
tinyGroup = new TinyGroup(group.getGroupName(), group.getPriority(), group.getAllCommands(serverName));
for (GroupBlacklist groupBlacklist : group.getAllServerGroupBlacklist(serverName))
@@ -149,6 +203,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() {
@@ -163,11 +219,6 @@ public class Communicator {
sendPacket(new CommunicationPackets.ForcePermissionResetPacket(Storage.TOKEN));
}
public static void sendFeedback(UUID targetUUID) {
if(Reflection.isProxyServer())
sendPacket(new CommunicationPackets.ForcePermissionResetPacket(Storage.TOKEN, targetUUID));
}
public static void sendFeedback() {
sendPacket(new CommunicationPackets.FeedbackPacket(Storage.TOKEN, SERVER_ID.toString()));
}
@@ -183,18 +234,4 @@ public class Communicator {
public static ClientInfo getClientByName(String name) {
return CLIENTS.isEmpty() ? null : CLIENTS.stream().filter(client -> client != null && client.getName().equalsIgnoreCase(name)).findFirst().orElse(null);
}
public static ClientInfo getQueueClientById(String id) {
return QUEUE_CLIENTS.get(id);
}
public static void resetAllFeedbacks() {
CLIENTS.forEach(client -> client.setFeedback(false));
}
public static List<String> getRegisteredServerNames() {
List<String> result = new ArrayList<>();
CLIENTS.stream().filter(client -> client != null && client.getName() != null).forEach(client -> result.add(client.getName()));
return result;
}
}
@@ -18,6 +18,8 @@ public abstract class ClientInfo {
this.name = name;
}
public abstract void sendBytes(byte[] bytes);
public void setName(String name) {
this.name = name;
}
@@ -26,8 +28,6 @@ public abstract class ClientInfo {
this.id = serverId;
}
public abstract void sendBytes(byte[] bytes);
public String getName() {
return name;
}
@@ -16,37 +16,11 @@ public class BungeeClientInfo extends ClientInfo {
@Override
public void sendBytes(byte[] bytes) {
ProxyServer.getInstance().getServers().entrySet().stream().filter(entry -> entry.getKey().equalsIgnoreCase(getName())).forEach(entry -> entry.getValue().sendData(Client.CHANNEL_NAME, bytes));
}
@Override
public String getId() {
return super.getId();
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getSyncTime() {
return super.getSyncTime();
}
@Override
public void setFeedback(boolean state) {
super.setFeedback(state);
}
@Override
public void setId(String serverId) {
super.setId(serverId);
}
@Override
public void setName(String name) {
super.setName(name);
ProxyServer.getInstance().getServers().entrySet().stream().filter(entry ->
entry.getKey().equalsIgnoreCase(getName())
).forEach(entry ->
entry.getValue().sendData(Client.CHANNEL_NAME, bytes)
);
}
}
@@ -16,36 +16,10 @@ public class VelocityClientInfo extends ClientInfo {
@Override
public void sendBytes(byte[] bytes) {
VelocityLoader.getServer().getAllServers().stream().filter(server -> server.getServerInfo().getName().equalsIgnoreCase(getName())).forEach(server -> server.sendPluginMessage(VelocityClient.getIdentifier(), bytes));
}
@Override
public String getId() {
return super.getId();
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getSyncTime() {
return super.getSyncTime();
}
@Override
public void setFeedback(boolean state) {
super.setFeedback(state);
}
@Override
public void setId(String serverId) {
super.setId(serverId);
}
@Override
public void setName(String name) {
super.setName(name);
VelocityLoader.getServer().getAllServers().stream().filter(server ->
server.getServerInfo().getName().equalsIgnoreCase(getName())
).forEach(server ->
server.sendPluginMessage(VelocityClient.getIdentifier(), bytes)
);
}
}
@@ -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;
@@ -18,18 +19,31 @@ public class BukkitClient implements Client, PluginMessageListener {
@Override
public void send(Object packet) {
try { SERVER.sendPluginMessage(BukkitLoader.getPlugin(), CHANNEL_NAME, CommunicationPackets.convertToBytes(packet));
} catch (Throwable throwable) { throwable.printStackTrace(); }
try {
SERVER.sendPluginMessage(BukkitLoader.getPlugin(), CHANNEL_NAME, CommunicationPackets.convertToBytes(packet));
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
@Override
public void onPluginMessageReceived(String channel, Player player, byte[] bytes) {
if(!channel.equals(CHANNEL_NAME)) return;
if (!channel.equals(CHANNEL_NAME))
return;
try {
Object packetObj = CommunicationPackets.buildFromBytes(bytes);
if(!CommunicationPackets.isPacket(packetObj)) return;
Bukkit.getScheduler().scheduleSyncDelayedTask(BukkitLoader.getPlugin(), () -> Communicator.receiveInformation("proxy", packetObj));
} catch (Throwable throwable) { throwable.printStackTrace(); }
if (!CommunicationPackets.isPacket(packetObj))
return;
PATScheduler.createScheduler(() -> Communicator.receiveInformation("proxy", packetObj));
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
@@ -21,21 +21,37 @@ public class BungeeClient implements Client, Listener {
@Override
public void send(Object packet) {
for(ServerInfo serverInfo : ProxyServer.getInstance().getServers().values()) {
try { serverInfo.sendData(CHANNEL_NAME, CommunicationPackets.convertToBytes(packet));
} catch (Throwable throwable) { throwable.printStackTrace(); }
for (ServerInfo serverInfo : ProxyServer.getInstance().getServers().values()) {
try {
serverInfo.sendData(CHANNEL_NAME, CommunicationPackets.convertToBytes(packet));
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
@EventHandler
public void onQueryReceive(PluginMessageEvent event) {
if (!event.getTag().equalsIgnoreCase(CHANNEL_NAME)) return;
if (!event.getTag().equalsIgnoreCase(CHANNEL_NAME))
return;
try {
Object packetObj = CommunicationPackets.buildFromBytes(event.getData());
if(!CommunicationPackets.isPacket(packetObj)) return;
if (!CommunicationPackets.isPacket(packetObj))
return;
Server server = (Server) event.getSender();
Communicator.receiveInformation(server.getInfo().getName().toLowerCase(), packetObj);
} catch (Throwable throwable) { throwable.printStackTrace(); }
Communicator.receiveInformation(server.getInfo().getName(), packetObj);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
@@ -22,19 +22,30 @@ public class VelocityClient implements Client {
@Override
public void send(Object packet) {
for (RegisteredServer registeredServer : SERVER.getAllServers()) {
try { registeredServer.sendPluginMessage(IDENTIFIER, CommunicationPackets.convertToBytes(packet));
} catch (Throwable throwable) { throwable.printStackTrace(); }
try {
registeredServer.sendPluginMessage(IDENTIFIER, CommunicationPackets.convertToBytes(packet));
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
@Subscribe
public void onQueryReceive(PluginMessageEvent event) {
if (event.getIdentifier() != IDENTIFIER) return;
if (event.getIdentifier() != IDENTIFIER)
return;
Object packetObj = CommunicationPackets.buildFromBytes(event.getData());
if(!CommunicationPackets.isPacket(packetObj)) return;
if (!CommunicationPackets.isPacket(packetObj))
return;
ServerConnection server = (ServerConnection) event.getSource();
Communicator.receiveInformation(server.getServerInfo().getName().toLowerCase(), packetObj);
Communicator.receiveInformation(server.getServerInfo().getName(), packetObj);
}
public static MinecraftChannelIdentifier getIdentifier() {
@@ -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,17 @@
package de.rayzs.pat.api.event;
import de.rayzs.pat.api.event.events.*;
import de.rayzs.pat.utils.CommunicationPackets;
import de.rayzs.pat.utils.Reflection;
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, boolean notify) {
ExecuteCommandEvent event = EmptyEvent.createEmptyExecuteCommandEvent(senderObj, command, blocked, notify);
for (PATEvent patEvent : EVENTS) {
if(patEvent instanceof ExecuteCommandEvent) {
@@ -20,8 +23,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 +36,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 +49,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 +124,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, boolean notify) {
return new ExecuteCommandEvent(senderObj, command, blocked, notify) {
@Override
public void handle(ExecuteCommandEvent event) {
@@ -65,8 +178,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 +187,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,38 +1,42 @@
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> {
private final String command;
private boolean blocked;
private boolean blocked, notify;
public ExecuteCommandEvent() {
super(null);
this.blocked = false;
this.notify = false;
this.command = null;
}
public ExecuteCommandEvent(UUID senderUniqueId, String command, boolean blocked) {
super(senderUniqueId);
public ExecuteCommandEvent(Object senderObj, String command, boolean blocked, boolean notify) {
super(senderObj);
this.blocked = blocked;
this.command = command;
this.notify = notify;
}
public void setDoesNotify(boolean notify) {
this.notify = notify;
}
public String getCommand() {
return command;
}
@Override
public UUID getSenderUniqueId() {
return super.getSenderUniqueId();
}
public boolean isBlocked() {
return blocked;
}
public boolean doesNotify() {
return notify;
}
public void setBlocked(boolean blocked) {
this.blocked = 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;
}
}
@@ -1,10 +1,13 @@
package de.rayzs.pat.api.netty.bukkit;
import de.rayzs.pat.plugin.logger.Logger;
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 +16,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,43 +31,75 @@ 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;
if (Storage.USE_VELOCITY)
return true;
try {
Channel channel = Reflection.getPlayerChannel(player);
if(channel == null) {
System.err.println("Failed to inject " + player.getName() + "! Channel is null.");
if (channel == null) {
return false;
}
if(channel.pipeline().names().contains(BukkitPacketAnalyzer.HANDLER_NAME))
if (channel.pipeline().names().contains(BukkitPacketAnalyzer.HANDLER_NAME))
uninject(channel);
channel.pipeline().addBefore(BukkitPacketAnalyzer.PIPELINE_NAME, BukkitPacketAnalyzer.HANDLER_NAME, new PacketDecoder(player));
BukkitPacketAnalyzer.INJECTED_PLAYERS.put(player.getUniqueId(), channel);
} catch (Throwable throwable) {
throwable.printStackTrace();
} catch (IndexOutOfBoundsException indexOutOfBoundsException) {
Reflection.toggleInjectionMethod();
Logger.info("Injection failed. Switching to secondary injection method.");
boolean success = inject(player);
if (success) {
Logger.info("Secondary injection method was successful.");
} else {
Logger.warning("Secondary injection method failed!");
}
return success;
} catch (Exception exception) {
exception.printStackTrace();
return false;
} return true;
}
return true;
}
public static void uninject(UUID uuid) {
if(Storage.USE_VELOCITY) return;
if (Storage.USE_VELOCITY)
return;
if(BukkitPacketAnalyzer.INJECTED_PLAYERS.containsKey(uuid)) {
if (BukkitPacketAnalyzer.INJECTED_PLAYERS.containsKey(uuid)) {
Channel channel = BukkitPacketAnalyzer.INJECTED_PLAYERS.get(uuid);
uninject(channel);
}
}
public static void uninject(Channel channel) {
if(Storage.USE_VELOCITY) return;
if (Storage.USE_VELOCITY)
return;
if(channel != null) {
if (channel != null) {
channel.eventLoop().submit(() -> {
ChannelPipeline pipeline = channel.pipeline();
if (pipeline.names().contains(BukkitPacketAnalyzer.HANDLER_NAME)) pipeline.remove(BukkitPacketAnalyzer.HANDLER_NAME);
if (pipeline.names().contains(BukkitPacketAnalyzer.HANDLER_NAME))
pipeline.remove(BukkitPacketAnalyzer.HANDLER_NAME);
});
}
}
@@ -88,11 +124,19 @@ public class BukkitPacketAnalyzer {
@Override
public void channelRead(ChannelHandlerContext channel, Object packetObj) {
try {
if (!PermissionUtil.hasBypassPermission(player) && packetObj.getClass() != null) {
if (packetObj.getClass() != null) {
String packetName = packetObj.getClass().getSimpleName();
if (packetName.equals("PacketPlayInTabComplete") || packetName.equals("ServerboundCommandSuggestionPacket")) {
if(!PACKET_HANDLER.handleIncomingPacket(player, packetObj)) return;
if (!packetName.equals("PacketPlayInTabComplete") && !packetName.equals("ServerboundCommandSuggestionPacket")) {
super.channelRead(channel, packetObj);
return;
}
if (!PermissionUtil.hasBypassPermission(player)) {
if (!PACKET_HANDLER.handleIncomingPacket(player, packetObj))
return;
}
}
@@ -103,16 +147,38 @@ public class BukkitPacketAnalyzer {
@Override
public void write(ChannelHandlerContext channel, Object packetObj, ChannelPromise promise) {
try {
if(packetObj.getClass() != null)
if (!PermissionUtil.hasBypassPermission(player)) {
String packetName = packetObj.getClass().getSimpleName();
if (packetName.equals("PacketPlayOutTabComplete") || packetName.equals("ClientboundCommandSuggestionsPacket")) {
if(!PACKET_HANDLER.handleOutgoingPacket(player, packetObj)) return;
}
if(packetObj.getClass() != null) {
String packetName = packetObj.getClass().getSimpleName();
if (!packetName.equals("PacketPlayOutTabComplete") && !packetName.equals("ClientboundCommandSuggestionsPacket")) {
super.write(channel, packetObj, promise);
return;
}
if (!PermissionUtil.hasBypassPermission(player)) {
UUID uuid = player.getUniqueId();
Object sentPacketObj = SENT_PACKET.get(uuid);
if (sentPacketObj != null) {
if (sentPacketObj == packetObj) {
SENT_PACKET.remove(uuid);
super.write(channel, sentPacketObj, promise);
return;
}
}
if (!PACKET_HANDLER.handleOutgoingPacket(player, packetObj))
return;
}
}
super.write(channel, packetObj, promise);
} catch (Throwable exception) { exception.printStackTrace(); }
} catch (Throwable exception) {
exception.printStackTrace();
}
}
}
}
@@ -1,13 +1,20 @@
package de.rayzs.pat.api.netty.bukkit.handlers;
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 org.bukkit.entity.Player;
import java.lang.reflect.Field;
import de.rayzs.pat.utils.*;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import de.rayzs.pat.utils.StringUtils;
import org.bukkit.entity.Player;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.event.events.FilteredTabCompletionEvent;
import de.rayzs.pat.api.netty.bukkit.BukkitPacketAnalyzer;
import de.rayzs.pat.api.netty.bukkit.BukkitPacketHandler;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.Reflection;
public class LegacyPacketHandler implements BukkitPacketHandler {
@@ -26,53 +33,78 @@ public class LegacyPacketHandler implements BukkitPacketHandler {
@Override
public boolean handleOutgoingPacket(Player player, Object packetObj) throws Exception {
String input = BukkitPacketAnalyzer.getPlayerInput(player);
final String rawInput = BukkitPacketAnalyzer.getPlayerInput(player);
if(input == null) return false;
if(rawInput == null)
return false;
boolean cancelsBeforeHand;
int spaces = 0;
String input = rawInput;
boolean cancelsBeforeHand = false;
if(input.startsWith("/")) {
input = input.replace("/", "");
if(input.contains(" ")) {
String[] split = input.split(" ");
spaces = split.length;
if(spaces > 0) input = split[0];
}
if (!input.startsWith("/")) {
return true;
}
cancelsBeforeHand = Storage.Blacklist.isBlocked(player, input, !Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED);
if(!cancelsBeforeHand) cancelsBeforeHand = Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(input);
} else return true;
input = input.substring(1);
final boolean doesBypassNamespace = Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesBypass(player);
final boolean spaces = input.contains(" ");
if (Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.isCommand(input) && !doesBypassNamespace) {
cancelsBeforeHand = true;
}
if (!cancelsBeforeHand && !input.isEmpty()) {
cancelsBeforeHand = !Storage.Blacklist.canPlayerAccessTab(player, StringUtils.getFirstArg(input));
}
if (!cancelsBeforeHand) {
cancelsBeforeHand = Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isTabCompletable(input) || Storage.ConfigSections.Settings.CUSTOM_VERSION.isTabCompletable(input);
}
for (Field field : Reflection.getFields(packetObj)) {
field.setAccessible(true);
Object result = field.get(packetObj);
if (!(result instanceof String[])) continue;
List<String> newResultList = new ArrayList<>();
String[] tR = (String[]) result;
String tempName;
if(spaces == 0) {
for (String s : tR) {
if(!BukkitLoader.isLoaded()) continue;
if(!s.startsWith("/")) {
newResultList.add(s);
continue;
}
tempName = s.replaceFirst("/", "");
if (!Storage.Blacklist.isBlocked(player, tempName, !Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED))
newResultList.add(s);
}
} else {
if(!cancelsBeforeHand) newResultList.addAll(Arrays.asList(tR));
if (!(result instanceof String[])) {
continue;
}
field.set(packetObj, newResultList.toArray(new String[0]));
String[] tR = (String[]) result;
List<String> suggestions = new ArrayList<>(Arrays.asList(tR));
if (spaces) {
if (cancelsBeforeHand) {
suggestions.clear();
field.set(packetObj, suggestions.toArray(new String[0]));
return true;
}
FilteredTabCompletionEvent filteredTabCompletionEvent = PATEventHandler.callFilteredTabCompletionEvents(player.getUniqueId(), rawInput, new ArrayList<>(suggestions));
if (filteredTabCompletionEvent.isCancelled()) {
suggestions.clear();
} else {
suggestions.removeIf(s -> !filteredTabCompletionEvent.getCompletion().contains(s));
}
} else {
suggestions.removeIf(s -> {
String cpy = s;
if (cpy.startsWith("/")) {
cpy = cpy.substring(1);
}
if (Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isTabCompletable(cpy) || Storage.ConfigSections.Settings.CUSTOM_VERSION.isTabCompletable(cpy)) {
return false;
}
return !Storage.Blacklist.canPlayerAccessTab(player, cpy);
});
}
field.set(packetObj, suggestions.toArray(new String[0]));
}
return true;
@@ -1,16 +1,32 @@
package de.rayzs.pat.api.netty.bukkit.handlers;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import com.mojang.brigadier.suggestion.Suggestion;
import com.mojang.brigadier.suggestion.Suggestions;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.event.events.FilteredTabCompletionEvent;
import de.rayzs.pat.api.netty.bukkit.BukkitPacketAnalyzer;
import de.rayzs.pat.api.netty.bukkit.BukkitPacketHandler;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.BukkitLoader;
import de.rayzs.pat.api.netty.bukkit.*;
import org.bukkit.entity.Player;
import de.rayzs.pat.utils.*;
import java.lang.reflect.*;
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.MessageTranslator;
import de.rayzs.pat.utils.scheduler.PATScheduler;
public class ModernPacketHandler implements BukkitPacketHandler {
private static boolean modifiable = true;
@Override
public boolean handleIncomingPacket(Player player, Object packetObj) throws Exception {
Field stringField = Reflection.getFirstFieldByType(packetObj.getClass(), "String", Reflection.SearchOption.ENDS);
@@ -21,6 +37,21 @@ 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(
StringUtils.replace(Storage.ConfigSections.Settings.PATCH_EXPLOITS.KICK_MESSAGE.get(), "&", "§")
)
);
return false;
}
BukkitPacketAnalyzer.insertPlayerInput(player, text);
return true;
}
@@ -28,13 +59,17 @@ public class ModernPacketHandler implements BukkitPacketHandler {
@Override
public boolean handleOutgoingPacket(Player player, Object packetObj) throws Exception {
Object suggestionObj;
String rawInput = BukkitPacketAnalyzer.getPlayerInput(player), input = rawInput;
String input = BukkitPacketAnalyzer.getPlayerInput(player);
if(input == null) return false;
if(input == null)
return false;
boolean is121Packet = packetObj.getClass().getSimpleName().equals("ClientboundCommandSuggestionsPacket"),
cancelsBeforeHand = false;
boolean cancelsBeforeHand = false;
int spaces = 0;
if(input.startsWith("/")) {
if(input.startsWith("/") || is121Packet) {
input = input.replace("/", "");
if(input.contains(" ")) {
String[] split = input.split(" ");
@@ -42,40 +77,191 @@ public class ModernPacketHandler implements BukkitPacketHandler {
if(spaces > 0) input = split[0];
}
cancelsBeforeHand = Storage.Blacklist.isBlocked(player, input, !Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED);
if(!cancelsBeforeHand) cancelsBeforeHand = Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(input);
cancelsBeforeHand = !Storage.Blacklist.canPlayerAccessTab(player, 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.canPlayerAccessTab(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;
}
if (Reflection.getMinor() < 17) {
Field suggestionsField = Reflection.getFieldsByType(packetObj.getClass(), "Suggestions", Reflection.SearchOption.ENDS).get(0);
if (suggestionsField == null) return false;
suggestionObj = suggestionsField.get(packetObj);
} else {
Method suggestionsMethod = Reflection.getMethodsByReturnType(packetObj.getClass(), "Suggestions", Reflection.SearchOption.ENDS).get(0);
if (suggestionsMethod == null) return false;
List<Method> methods = Reflection.getMethodsByReturnType(packetObj.getClass(), "Suggestions", Reflection.SearchOption.ENDS);
if (methods.isEmpty()) return false;
Method suggestionsMethod = methods.get(0);
if (suggestionsMethod == null)
return false;
suggestionObj = suggestionsMethod.invoke(packetObj);
}
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;
}
if(spaces == 0) {
suggestions.getList().removeIf(suggestion -> {
String command = suggestion.getText();
return Storage.Blacklist.isBlocked(player, command);
return !Storage.Blacklist.canPlayerAccessTab(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 (modifiable) {
try {
if (filteredTabCompletionEvent.isCancelled())
suggestions.getList().clear();
else
suggestions.getList().removeIf(suggestion -> !filteredTabCompletionEvent.getCompletion().contains(suggestion.getText()));
return !suggestions.getList().isEmpty();
} catch (UnsupportedOperationException exception) {
modifiable = false;
}
}
return handleUnmodifiableTabCompletion(player, packetObj, suggestions, filteredTabCompletionEvent);
}
}
private boolean handleUnmodifiableTabCompletion(Player player, Object packetObj, Suggestions suggestions, FilteredTabCompletionEvent filteredTabCompletionEvent) {
List<Suggestion> filteredSuggestionsList = new ArrayList<>();
if (!filteredTabCompletionEvent.isCancelled())
for (Suggestion suggestion : suggestions.getList()) {
if (filteredTabCompletionEvent.getCompletion().contains(suggestion.getText())) {
filteredSuggestionsList.add(suggestion);
}
}
Suggestions filteredSuggestions = new Suggestions(suggestions.getRange(), filteredSuggestionsList);
try {
int val = -1;
Method method = Reflection.getMethodByName(packetObj.getClass(), "e");
if (method != null) {
val = (int) method.invoke(packetObj);
}
if (val == -1) {
Logger.warning("Failed to read packet input!");
return false;
}
Object packet = Reflection.getConstructor(packetObj.getClass(), int.class, Suggestions.class)
.newInstance(val, filteredSuggestions);
BukkitPacketAnalyzer.sendPacket(player.getUniqueId(), packet);
} catch (Exception exception) {
exception.printStackTrace();
}
return true;
return false;
}
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 "";
}
}
@@ -1,23 +1,37 @@
package de.rayzs.pat.api.netty.proxy;
import com.mojang.brigadier.arguments.StringArgumentType;
import de.rayzs.pat.api.communication.client.ClientInfo;
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.PacketWrapper;
import java.util.concurrent.ConcurrentHashMap;
import com.mojang.brigadier.tree.CommandNode;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.protocol.packet.*;
import de.rayzs.pat.api.storage.Storage;
import net.md_5.bungee.api.ProxyServer;
import com.mojang.brigadier.builder.*;
import java.lang.reflect.Field;
import de.rayzs.pat.utils.*;
import io.netty.channel.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.tree.CommandNode;
import de.rayzs.pat.api.brand.CustomServerBrand;
import de.rayzs.pat.api.communication.Communicator;
import de.rayzs.pat.api.communication.client.ClientInfo;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.CommandsCache;
import de.rayzs.pat.utils.node.CommandNodeHelper;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.permission.PermissionUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.MessageToMessageDecoder;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.protocol.PacketWrapper;
import net.md_5.bungee.protocol.packet.Commands;
import net.md_5.bungee.protocol.packet.PluginMessage;
import net.md_5.bungee.protocol.packet.TabCompleteResponse;
public class BungeePacketAnalyzer {
@@ -28,10 +42,24 @@ public class BungeePacketAnalyzer {
private static final HashMap<ProxiedPlayer, String> PLAYER_INPUT_CACHE = new HashMap<>();
private static final com.mojang.brigadier.Command DUMMY_COMMAND = (context) -> 0;
private static final List<String> PLUGIN_COMMANDS = new ArrayList<>();
private static Class<?> channelWrapperClass, serverConnectionClass;
private static List<String> PROXY_COMMANDS;
static {
loadProxyCommands();
}
public static void loadProxyCommands() {
PROXY_COMMANDS = ProxyServer.getInstance().getPluginManager().getCommands().stream().map(entry -> {
String key = entry.getKey();
return key.startsWith("/") ? key.substring(1) : key;
}).toList();
}
public static void injectAll() {
ProxyServer.getInstance().getPlayers().forEach(BungeePacketAnalyzer::inject);
}
@@ -64,21 +92,25 @@ public class BungeePacketAnalyzer {
channel = (Channel) Reflection.getFieldsByType(channelWrapperClass, "Channel", Reflection.SearchOption.ENDS).get(0).get(channelWrapperObj);
if(channel == null) {
System.err.println("Failed to inject " + player.getName() + "! Channel is null.");
Logger.warning("Failed to inject " + player.getName() + "! Channel is null.");
return false;
}
channelField.setAccessible(false);
if(channel.pipeline().names().contains(BungeePacketAnalyzer.HANDLER_NAME))
if (channel.pipeline().names().contains(BungeePacketAnalyzer.HANDLER_NAME))
uninject(player);
channel.pipeline().addAfter(BungeePacketAnalyzer.PIPELINE_NAME, BungeePacketAnalyzer.HANDLER_NAME, new PacketDecoder(player));
BungeePacketAnalyzer.INJECTED_PLAYERS.put(player, channel);
} catch (Throwable throwable) {
throwable.printStackTrace();
return false;
} return true;
}
return true;
}
public static void uninject(ProxiedPlayer player) {
@@ -91,7 +123,9 @@ public class BungeePacketAnalyzer {
BungeePacketAnalyzer.INJECTED_PLAYERS.remove(player);
channel.eventLoop().submit(() -> {
ChannelPipeline pipeline = channel.pipeline();
if (pipeline.names().contains(BungeePacketAnalyzer.HANDLER_NAME)) pipeline.remove(BungeePacketAnalyzer.HANDLER_NAME);
if (pipeline.names().contains(BungeePacketAnalyzer.HANDLER_NAME))
pipeline.remove(BungeePacketAnalyzer.HANDLER_NAME);
});
}
}
@@ -103,50 +137,70 @@ public class BungeePacketAnalyzer {
return input;
}
public static void insertPlayerInput(ProxiedPlayer player, String text) {
PLAYER_INPUT_CACHE.put(player, text.toLowerCase());
}
private static void modifyCommands(ProxiedPlayer player, Commands commands) {
ServerInfo serverInfo = player.getServer().getInfo();
String serverName = serverInfo.getName();
private static void modifyCommands(ProxiedPlayer player, Commands commands, List<String> list) {
final String serverName = player.getServer().getInfo().getName();
final boolean turn = Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED;
list.clear();
CommandNodeHelper helper = new CommandNodeHelper<CommandNode>(commands.getRoot());
Map<String, CommandsCache> cache = Storage.getLoader().getCommandsCacheMap();
if (!cache.containsKey(serverName))
cache.put(serverName, new CommandsCache());
CommandsCache commandsCache = cache.get(serverName);
List<String> commandsAsString = new ArrayList<>(PROXY_COMMANDS);
commandsAsString.addAll(helper.getChildrenNames());
commandsCache.handleCommands(commandsAsString, serverName);
List<String> playerCommands = commandsCache.getPlayerCommands(commandsAsString, player, player.getUniqueId(), serverName);
helper.removeIf(str -> !playerCommands.contains(str));
for (Map.Entry<String, Command> command : ProxyServer.getInstance().getPluginManager().getCommands()) {
if (!ProxyServer.getInstance().getDisabledCommands().contains(command.getKey()) && commands.getRoot().getChild(command.getKey()) == null && command.getValue().hasPermission(player)) {
List<String> commandsToCheck =
new ArrayList<>(Arrays.asList(command.getValue().getAliases()));
if(!commandsToCheck.contains(command.getValue().getName()))
commandsToCheck.add(command.getValue().getName());
if(!commandsToCheck.contains(command.getKey()))
commandsToCheck.add(command.getKey());
if (ProxyServer.getInstance().getDisabledCommands().contains(command.getKey()))
continue;
commandsToCheck.removeAll(list);
commandsToCheck.removeIf(commandName -> commandName.startsWith("/"));
if (commands.getRoot().getChild(command.getKey()) != null)
continue;
for (String commandName : commandsToCheck) {
if (!list.contains(commandName)) {
if (!Storage.Blacklist.isBlocked(player, commandName, !turn, serverName)) {
list.add(commandName);
CommandNode dummy = LiteralArgumentBuilder.literal(commandName)
.executes(DUMMY_COMMAND)
.then(RequiredArgumentBuilder.argument("args", StringArgumentType.greedyString())
.suggests(Commands.SuggestionRegistry.ASK_SERVER).executes(DUMMY_COMMAND))
.build();
commands.getRoot().addChild(dummy);
}
}
}
if (!command.getValue().hasPermission(player)) {
continue;
}
String commandName = command.getKey();
commandName = commandName.startsWith("/") ? commandName.substring(1) : commandName;
if (!playerCommands.contains(commandName)) {
continue;
}
CommandNode dummy = createDummyCommandNode(command.getKey());
commands.getRoot().addChild(dummy);
}
// Disabled temporarily
// PROXY_COMMANDS.stream().filter(playerCommands::contains).forEach(helper::add);
// SubArgsModule.handleCommandNode(player.getUniqueId(), helper);
}
private static CommandNode createDummyCommandNode(String command) {
return LiteralArgumentBuilder
.literal(command)
.executes(DUMMY_COMMAND)
.then(RequiredArgumentBuilder
.argument("args", (ArgumentType) StringArgumentType.greedyString())
.suggests(Commands.SuggestionRegistry.ASK_SERVER)
.executes(DUMMY_COMMAND))
.build();
}
private static class PacketDecoder extends MessageToMessageDecoder<PacketWrapper> {
private final ProxiedPlayer player;
private final List<String> commands = new ArrayList<>();
private PacketDecoder(ProxiedPlayer player) {
this.player = player;
@@ -159,9 +213,15 @@ 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);
modifyCommands(player, response);
player.unsafe().sendPacket(response);
return;
@@ -176,35 +236,39 @@ public class BungeePacketAnalyzer {
return;
boolean cancelsBeforeHand = false;
String playerInput = getPlayerInput(player), server = player.getServer().getInfo().getName();
int spaces = 0;
if(playerInput.contains(" ")) {
String[] split = playerInput.split(" ");
spaces = split.length;
if(spaces > 0) playerInput = split[0];
String rawPlayerInput = getPlayerInput(player);
int spaces = rawPlayerInput.contains(" ") ? rawPlayerInput.split(" ").length : 0;
String playerInput = StringUtils.getFirstArg(rawPlayerInput),
server = player.getServer().getInfo().getName();
if (!playerInput.equals("/")) {
cancelsBeforeHand = !Storage.Blacklist.canPlayerAccessTab(player, StringUtils.replaceFirst(playerInput, "/", ""), server);
if (!cancelsBeforeHand)
cancelsBeforeHand = !Storage.ConfigSections.Settings.CUSTOM_VERSION.isTabCompletable(StringUtils.replaceFirst(playerInput, "/", "")) || Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isTabCompletable(StringUtils.replaceFirst(playerInput, "/", ""));
}
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, "/", ""));
}
final String cursor = playerInput;
if(cursor.startsWith("/")) {
if(spaces == 0) {
if (cursor.startsWith("/")) {
if (spaces == 0) {
List<String> suggestions = new ArrayList<>(response.getCommands());
if (Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED) {
setPluginCommands();
Storage.Blacklist.getAllBlacklists(server).forEach(blacklist -> blacklist.getCommands().stream().filter(command -> !suggestions.contains("/" + command)).forEach(command -> {
Storage.Blacklist.getServerBlacklists(server).forEach(blacklist -> blacklist.getCommands().stream().filter(command -> !suggestions.contains("/" + command)).forEach(command -> {
if (BungeePacketAnalyzer.PLUGIN_COMMANDS.contains(command))
suggestions.add("/" + command);
}));
BungeePacketAnalyzer.PLUGIN_COMMANDS.stream().filter(command -> !suggestions.contains(command)).forEach(command -> {
if(command.startsWith("/")) command = StringUtils.replaceFirst(command, "/", "");
if(PermissionUtil.hasBypassPermission(player, command, server)) {
if (command.startsWith("/"))
command = StringUtils.replaceFirst(command, "/", "");
if (Storage.Blacklist.canPlayerAccessTab(player, command, server)) {
suggestions.add("/" + command);
}
});
@@ -213,17 +277,24 @@ public class BungeePacketAnalyzer {
} else {
BungeePacketAnalyzer.PLUGIN_COMMANDS.stream().filter(command -> !suggestions.contains(command)).forEach(suggestions::add);
suggestions.removeIf(command -> {
if(command.startsWith("/")) command = StringUtils.replaceFirst(command, "/", "");
return Storage.Blacklist.isBlocked(player, command, true, server, true);
if (command.startsWith("/"))
command = StringUtils.replaceFirst(command, "/", "");
return !Storage.Blacklist.canPlayerAccessTab(player, command, server);
});
response.getCommands().clear();
suggestions.forEach(command -> response.getCommands().add(command));
}
if (response.getCommands().isEmpty()) return;
if (response.getCommands().isEmpty())
return;
} else {
if(cancelsBeforeHand) return;
if (cancelsBeforeHand)
return;
}
player.unsafe().sendPacket(new TabCompleteResponse(response.getCommands()));
@@ -1,16 +1,39 @@
package de.rayzs.pat.api.netty.proxy;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.permission.PermissionUtil;
import com.velocitypowered.proxy.protocol.packet.*;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.velocitypowered.api.proxy.Player;
import de.rayzs.pat.plugin.VelocityLoader;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket;
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequestPacket;
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket;
import com.velocitypowered.proxy.protocol.packet.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.api.storage.Storage;
import de.rayzs.pat.utils.*;
import io.netty.channel.*;
import java.util.*;
import de.rayzs.pat.plugin.VelocityLoader;
import de.rayzs.pat.plugin.listeners.velocity.VelocityBlockCommandListener;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.CommandsCache;
import de.rayzs.pat.utils.PacketUtils;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.utils.permission.PermissionUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.ChannelPromise;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
public class VelocityPacketAnalyzer {
@@ -18,9 +41,8 @@ public class VelocityPacketAnalyzer {
private static final String PIPELINE_NAME = "pat-velocity-handler", HANDLER_NAME = "handler";
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);
@@ -52,7 +74,7 @@ public class VelocityPacketAnalyzer {
channel = (Channel) Reflection.getMethodsByName(minecraftConnectionClass, "getChannel").get(0).invoke(minecraftConnectionObj);
if(channel == null) {
System.out.println("Failed to inject " + player.getUsername() + "! Channel is null.");
Logger.warning("Failed to inject " + player.getUsername() + "! Channel is null.");
return false;
}
@@ -109,11 +131,42 @@ public class VelocityPacketAnalyzer {
MinecraftPacket packet = (MinecraftPacket) msg;
if(packet instanceof TabCompleteRequestPacket) {
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).getResult().isAllowed())
return;
} catch (Exception exception) {
exception.printStackTrace();
}
}
if (packet instanceof UnsignedPlayerCommandPacket) {
UnsignedPlayerCommandPacket unsignedPlayerCommandPacket = (UnsignedPlayerCommandPacket) packet;
if (!VelocityBlockCommandListener.handleCommand(player, unsignedPlayerCommandPacket.getCommand()).getResult().isAllowed())
return;
}
if (packet instanceof TabCompleteRequestPacket) {
TabCompleteRequestPacket request = (TabCompleteRequestPacket) msg;
if(request.getCommand() != null) {
insertPlayerInput(player, request.getCommand());
super.channelRead(ctx, msg);
if (request.getCommand() != null) {
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 +180,21 @@ 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(" ")) {
@@ -142,50 +204,85 @@ 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, "/", ""));
cancelsBeforeHand = !Storage.Blacklist.canPlayerAccessTab(player, StringUtils.replaceFirst(playerInput, "/", ""), server);
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("/") && spaces < 2 && player.getProtocolVersion().getProtocol() >= 754) {
Logger.debug("Player won't receive TabCompleteResponsePacket because the client protocol id is " + player.getProtocolVersion().getProtocol() + "! This doesn't makes sense, that's why.");
if (!cursor.startsWith("/") && spaces < 2 && player.getProtocolVersion().getProtocol() >= 754) {
return;
}
if(cursor.startsWith("/")) {
if (cursor.startsWith("/")) {
if (spaces == 0) {
response.getOffers().removeIf(offer -> {
String command = offer.getText();
if (command.startsWith("/")) command = StringUtils.replaceFirst(command, "/", "");
return Storage.Blacklist.isBlocked(player, command, !Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED, player.getCurrentServer().get().getServerInfo().getName(), !Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED);
return !Storage.Blacklist.canPlayerAccessTab(player, command, player.getCurrentServer().get().getServerInfo().getName());
});
} 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;
}
}
}
} else if(packet instanceof AvailableCommandsPacket) {
} 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();
Map<String, CommandsCache> cache = Storage.getLoader().getCommandsCacheMap();
if(!COMMANDS_CACHE_MAP.containsKey(serverName))
COMMANDS_CACHE_MAP.put(serverName, new CommandsCache().reverse());
CommandsCache commandsCache = COMMANDS_CACHE_MAP.get(serverName);
if (!cache.containsKey(serverName))
cache.put(serverName, new CommandsCache());
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);
CommandsCache commandsCache = cache.get(serverName);
if(PermissionUtil.hasBypassPermission(player)) return;
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);
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()));
if (PermissionUtil.hasBypassPermission(player)) return;
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 -> {
if (command == null || command.getName() == null)
return true;
if (command.getName().equals("args"))
return false;
return !playerCommands.contains(command.getName());
});
}
}
}
@@ -1,42 +1,143 @@
package de.rayzs.pat.api.storage;
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;
import de.rayzs.pat.api.storage.storages.ConfigStorage;
import de.rayzs.pat.api.storage.placeholders.general.*;
import de.rayzs.pat.api.storage.placeholders.groups.*;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.api.storage.config.messages.*;
import de.rayzs.pat.api.storage.config.settings.*;
import de.rayzs.pat.api.storage.blacklist.impl.*;
import de.rayzs.pat.api.storage.storages.*;
import de.rayzs.pat.utils.configuration.*;
import java.util.concurrent.TimeUnit;
import de.rayzs.pat.utils.group.*;
import org.bukkit.entity.Player;
import de.rayzs.pat.plugin.*;
import de.rayzs.pat.utils.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
import de.rayzs.pat.api.communication.Communicator;
import de.rayzs.pat.api.storage.config.settings.*;
import de.rayzs.pat.plugin.listeners.bukkit.BukkitAntiTabListener;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.plugin.modules.SubArgsModule;
import org.bukkit.entity.Player;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.storage.blacklist.BlacklistCreator;
import de.rayzs.pat.api.storage.blacklist.impl.GeneralBlacklist;
import de.rayzs.pat.api.storage.blacklist.impl.GeneralIgnoredServers;
import de.rayzs.pat.api.storage.config.messages.BlacklistSection;
import de.rayzs.pat.api.storage.config.messages.CommandFailedSection;
import de.rayzs.pat.api.storage.config.messages.GroupSection;
import de.rayzs.pat.api.storage.config.messages.HelpSection;
import de.rayzs.pat.api.storage.config.messages.InfoSection;
import de.rayzs.pat.api.storage.config.messages.NoPermissionSection;
import de.rayzs.pat.api.storage.config.messages.NotificationSection;
import de.rayzs.pat.api.storage.config.messages.OnlyForProxySection;
import de.rayzs.pat.api.storage.config.messages.PermsCheckSection;
import de.rayzs.pat.api.storage.config.messages.PostDebugSection;
import de.rayzs.pat.api.storage.config.messages.PrefixSection;
import de.rayzs.pat.api.storage.config.messages.ReloadSection;
import de.rayzs.pat.api.storage.config.messages.ServerListSection;
import de.rayzs.pat.api.storage.config.messages.StatsSection;
import de.rayzs.pat.api.storage.config.messages.UpdatePermissionsSection;
import de.rayzs.pat.api.storage.placeholders.commands.general.ListCommandsPlaceholder;
import de.rayzs.pat.api.storage.placeholders.commands.general.ListReversedCommandsPlaceholder;
import de.rayzs.pat.api.storage.placeholders.commands.general.ListSizeCommandsPlaceholder;
import de.rayzs.pat.api.storage.placeholders.commands.general.ListSortedCommandsPlaceholder;
import de.rayzs.pat.api.storage.placeholders.commands.group.ListGroupCommandsPlaceholder;
import de.rayzs.pat.api.storage.placeholders.commands.group.ListGroupReversedCommandsPlaceholder;
import de.rayzs.pat.api.storage.placeholders.commands.group.ListGroupSizeCommandsPlaceholder;
import de.rayzs.pat.api.storage.placeholders.commands.group.ListGroupSortedCommandsPlaceholder;
import de.rayzs.pat.api.storage.placeholders.general.GeneralCurrentVersionPlaceholder;
import de.rayzs.pat.api.storage.placeholders.general.GeneralNewestVersionPlaceholder;
import de.rayzs.pat.api.storage.placeholders.general.GeneralPrefixPlaceholder;
import de.rayzs.pat.api.storage.placeholders.general.GeneralUserPlaceholder;
import de.rayzs.pat.api.storage.placeholders.groups.ListGroupsPlaceholder;
import de.rayzs.pat.api.storage.placeholders.groups.ListGroupsReversedPlaceholder;
import de.rayzs.pat.api.storage.placeholders.groups.ListGroupsSortedPlaceholder;
import de.rayzs.pat.api.storage.placeholders.groups.ListSizeGroupsPlaceholder;
import de.rayzs.pat.api.storage.placeholders.messages.BlockedBaseCommandPlaceholder;
import de.rayzs.pat.api.storage.placeholders.messages.BlockedSubCommandPlaceholder;
import de.rayzs.pat.api.storage.placeholders.messages.UnknownCommandPlaceholder;
import de.rayzs.pat.api.storage.storages.ConfigStorage;
import de.rayzs.pat.api.storage.storages.DisabledServersStorage;
import de.rayzs.pat.api.storage.storages.IgnoredServersStorage;
import de.rayzs.pat.api.storage.storages.PlaceholderStorage;
import de.rayzs.pat.plugin.PluginLoader;
import de.rayzs.pat.utils.ExpireCache;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.configuration.ConfigurationBuilder;
import de.rayzs.pat.utils.configuration.Configurator;
import de.rayzs.pat.utils.group.GroupManager;
import de.rayzs.pat.utils.message.replacer.PlaceholderReplacer;
import de.rayzs.pat.utils.permission.PermissionUtil;
public class Storage {
private static PluginLoader LOADER;
public static final List<UUID> NOTIFY_PLAYERS = new ArrayList<>();
public static String TOKEN = "", SERVER_NAME = null, CURRENT_VERSION = "", NEWER_VERSION = "";
public static boolean OUTDATED = false, SEND_CONSOLE_NOTIFICATION = true;
public static Object PLUGIN_OBJECT;
public static boolean USE_LUCKPERMS = false, USE_PLACEHOLDERAPI = false, USE_PAPIPROXYBRIDGE = false, USE_VIAVERSION = false, USE_VELOCITY = false, USE_SIMPLECLOUD;
public static boolean USE_LUCKPERMS = false, USE_GROUPMANAGER = false, USE_PLACEHOLDERAPI = false, USE_PAPIPROXYBRIDGE = false, USE_VIAVERSION = false, USE_VELOCITY = false, USE_SIMPLECLOUD;
public static long LAST_SYNC = System.currentTimeMillis();
public static void initialize(PluginLoader loader, String currentVersion) {
LOADER = loader;
CURRENT_VERSION = currentVersion;
}
public static void loadAll(boolean loadBlacklist) {
loadConfig();
loadToken();
if(loadBlacklist) Blacklist.loadAll();
if (TOKEN != null && !TOKEN.isEmpty()) {
int tokenLength = TOKEN.length(), cutIndex = Math.max(1, tokenLength - 3);
String censoredTokenDisplay = "*".repeat(cutIndex) + TOKEN.substring(cutIndex);
Logger.info("Token found! (" + censoredTokenDisplay + ")");
}
if (loadBlacklist) Blacklist.loadAll();
PATEventHandler.callUpdatePluginEvents();
}
public static void loadToken() {
TOKEN = Reflection.isProxyServer() ? (String) Files.TOKEN.getOrSet("token", UUID.randomUUID().toString()) : ConfigSections.Settings.HANDLE_THROUGH_PROXY.TOKEN;
boolean invalidEnv = false;
if (Reflection.isProxyServer()) {
boolean loadFromEnv = (Boolean) Files.TOKEN.getOrSet("load-from-env.enabled", false);
String envVariable = (String) Files.TOKEN.getOrSet("load-from-env.name", "PAT_TOKEN");
if (loadFromEnv) {
Logger.info("Looking up token from environment variable: " + envVariable);
TOKEN = System.getenv(envVariable);
if (TOKEN != null) {
return;
} else invalidEnv = true;
}
TOKEN = (String) Files.TOKEN.getOrSet("token", UUID.randomUUID().toString());
if (invalidEnv)
Logger.warning("Environment variable not found! Using default Token from the token.yml instead.");
return;
}
if (!ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
return;
}
boolean loadFromEnv = ConfigSections.Settings.HANDLE_THROUGH_PROXY.LOAD_FROM_ENV;
String envVariable = ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENV_NAME;
if (loadFromEnv) {
TOKEN = System.getenv(envVariable);
if (TOKEN != null) {
return;
} else invalidEnv = true;
}
TOKEN = ConfigSections.Settings.HANDLE_THROUGH_PROXY.TOKEN;
if (invalidEnv)
Logger.warning("Environment variable not found! Using default Token from the config.yml instead.");
}
public static void loadConfig() {
@@ -44,34 +145,116 @@ public class Storage {
ConfigSections.Messages.initialize();
ConfigSections.SECTIONS.forEach(ConfigStorage::load);
if(USE_PLACEHOLDERAPI)
if (USE_PLACEHOLDERAPI)
ConfigSections.PLACEHOLDERS.forEach(PlaceholderStorage::load);
}
public static void handleChange() {
handleChange(null);
}
public static void handleChange(String server) {
if (Reflection.isProxyServer()) {
boolean isVelocity = Reflection.isVelocityServer();
if (server != null) {
Storage.Blacklist.clearServerBlacklists(server);
Storage.Blacklist.loadCachedServerBlacklists(server);
List<String> associatedServers = getServers()
.stream()
.filter(s -> !s.equals(server) && isServer(server, s))
.toList();
associatedServers.forEach(s -> {
Storage.Blacklist.clearServerBlacklists(s);
Storage.Blacklist.loadCachedServerBlacklists(s);
});
if (isVelocity) {
associatedServers.forEach(s -> {
List<UUID> playerIds = Storage.getLoader().getPlayerIdsByServer(s);
List<String> commands = new ArrayList<>(SubArgsModule.getServerCommands(s));
playerIds.forEach(playerId -> {
List<String> playerCommands = new ArrayList<>(commands);
playerCommands.addAll(SubArgsModule.getGroupCommands(playerId, s));
PATEventHandler.callUpdatePlayerCommandsEvents(playerId, playerCommands, true);
});
});
}
} else {
Storage.Blacklist.Experimental.forceCacheReset();
if (isVelocity) {
List<UUID> playerIds = Storage.getLoader().getPlayerIds();
playerIds.forEach(playerId -> {
List<String> playerCommands = new ArrayList<>(SubArgsModule.getServerCommands(playerId));
playerCommands.addAll(SubArgsModule.getGroupCommands(playerId));
PATEventHandler.callUpdatePlayerCommandsEvents(playerId, playerCommands, false);
});
}
}
GroupManager.clearServerGroupBlacklists();
Communicator.syncData();
Storage.getLoader().updateCommandCache();
Communicator.sendPermissionReset();
return;
}
PermissionUtil.reloadPermissions();
if (Reflection.getMinor() < 13) {
final List<UUID> playerIds = Storage.getLoader().getPlayerIds();
final List<String> commands = new ArrayList<>(Blacklist.BLACKLIST.getCommands());
playerIds.forEach(playerId -> {
List<String> playerCommands = new ArrayList<>(commands);
playerCommands.addAll(SubArgsModule.getGroupCommands(playerId));
PATEventHandler.callUpdatePlayerCommandsEvents(playerId, playerCommands, true);
});
} else {
BukkitAntiTabListener.handleTabCompletion();
}
}
public static PluginLoader getLoader() {
return LOADER;
}
public static List<String> getServers() {
return getServers(false);
}
public static List<String> getServers(boolean withBlacklist) {
List<String> servers = new ArrayList<>();
if(Reflection.isVelocityServer())
servers.addAll(VelocityLoader.getServerNames());
else if(Reflection.isProxyServer())
servers.addAll(BungeeLoader.getServerNames());
public static List<String> getServers(boolean includingServerSpecifics) {
List<String> servers = LOADER.getServerNames();
if(includingServerSpecifics) {
servers.addAll(Blacklist.getBlacklists().stream().map(Map.Entry::getKey).toList());
}
if(withBlacklist) Blacklist.getBlacklistServers().stream().filter(server -> !servers.contains(server.toLowerCase())).forEach(server -> servers.add(server.toLowerCase()));
return servers;
}
public static boolean isServer(String originServer, Set<String> targetServers) {
List<String> list = new ArrayList<>(targetServers);
return isServer(originServer, list);
}
public static boolean isServer(String targetServers, List<String> servers) {
for (String originServer : servers)
if(isServer(originServer, targetServers))
return true;
return false;
}
@@ -79,10 +262,11 @@ public class Storage {
originServer = originServer.toLowerCase();
targetServer = targetServer.toLowerCase();
if(originServer.endsWith("*")) {
originServer = originServer.replace("*", "");
if (originServer.endsWith("*")) {
originServer = originServer.substring(0, originServer.length() - 2);
return targetServer.startsWith(originServer);
}
return originServer.equalsIgnoreCase(targetServer);
}
@@ -91,6 +275,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() {}
@@ -103,15 +288,20 @@ public class Storage {
public static class Settings {
public static AutoLowercaseCommandsSection AUTO_LOWERCASE_COMMANDS = new AutoLowercaseCommandsSection();
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();
public static BaseCommandCaseSensitiveSection BASE_COMMAND_CASE_SENSITIVE = new BaseCommandCaseSensitiveSection();
public static UpdateCommandsPerWorldSection UPDATE_COMMANDS_PER_WORLD = new UpdateCommandsPerWorldSection();
public static UpdateSection UPDATE = new UpdateSection();
public static void initialize() {}
@@ -127,6 +317,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();
@@ -139,10 +330,15 @@ public class Storage {
public static class Placeholders {
public static GeneralPrefixPlaceholder PREFIX = new GeneralPrefixPlaceholder();
public static GeneralUserPlaceholder USER = new GeneralUserPlaceholder();
public static GeneralCurrentVersionPlaceholder CURRENT_VERSION = new GeneralCurrentVersionPlaceholder();
public static GeneralNewestVersionPlaceholder NEWEST_VERSION = new GeneralNewestVersionPlaceholder();
public static BlockedBaseCommandPlaceholder BLOCKED_BASE_COMMAND = new BlockedBaseCommandPlaceholder();
public static BlockedSubCommandPlaceholder BLOCKED_SUB_COMMAND = new BlockedSubCommandPlaceholder();
public static UnknownCommandPlaceholder UNKNOWN_COMMAND = new UnknownCommandPlaceholder();
public static ListGroupsPlaceholder LIST_GROUP = new ListGroupsPlaceholder();
public static ListGroupsReversedPlaceholder LIST_GROUP_REVERSED = new ListGroupsReversedPlaceholder();
public static ListGroupsSortedPlaceholder LIST_GROUP_SORTED = new ListGroupsSortedPlaceholder();
@@ -163,20 +359,26 @@ public class Storage {
public static String findAndReplace(Player player, String request) {
String result = null, param = "";
if(USE_PLACEHOLDERAPI)
if(USE_PLACEHOLDERAPI) {
for (PlaceholderStorage storage : PLACEHOLDERS) {
if(!storage.getRequest().startsWith(request)) continue;
if (!storage.getRequest().startsWith(request)) continue;
if(storage.getRequest().endsWith("group_") && request.contains("group_"))
if (storage.getRequest().endsWith("group_") && request.contains("group_"))
param = request.split("group_")[1];
result = storage.onRequest(player, param);
if(result == null) continue;
if (result == null) continue;
else result = result.replace("\\n", "\n");
break;
}
// Second time because of nested placeholders
if (result != null && result.contains("%")) {
result = PlaceholderReplacer.replace(player, result);
}
}
return result;
}
}
@@ -184,9 +386,47 @@ public class Storage {
public static class Blacklist {
private static HashMap<String, GeneralBlacklist> SERVER_BLACKLISTS = new HashMap<>();
public static class Experimental {
public static void forceCacheReset() {
for (Object o : CACHED_SERVER_BLACKLIST.getCache().asMap().keySet()) {
String s = (String) o;
clearServerBlacklists(s);
loadCachedServerBlacklists(s);
}
}
}
public enum BlockType {
CHAT("[CMD]"),
TAB("[TAB]"),
NEGATE("!"),
BOTH("");
private final String text;
BlockType(String text) {
this.text = text;
}
@Override
public String toString() {
return this.text;
}
}
private static final BlockType[] BLOCK_TYPES = BlockType.values();
private static final GeneralBlacklist BLACKLIST = BlacklistCreator.createGeneralBlacklist();
private static final IgnoredServersStorage IGNORED_SERVERS = new GeneralIgnoredServers();
private static final DisabledServersStorage DISABLED_SERVERS = new DisabledServersStorage();
// General server-specific list (e.g: server-*)
private static final HashMap<String, GeneralBlacklist> SERVER_BLACKLISTS = new HashMap<>();
// Temporary list for all servers (e.g: server-1)
private static final ExpireCache<String, List<GeneralBlacklist>> CACHED_SERVER_BLACKLIST = new ExpireCache<>(1, TimeUnit.HOURS);
public static void loadAll() {
@@ -194,262 +434,214 @@ public class Storage {
SERVER_BLACKLISTS.clear();
BLACKLIST.load();
if(!Reflection.isProxyServer()) return;
if(!Reflection.isProxyServer())
return;
IGNORED_SERVERS.load();
DISABLED_SERVERS.load();
BLACKLIST.getConfig().getKeys("global.servers", true).forEach(key -> {
GeneralBlacklist blacklist = BlacklistCreator.createGeneralBlacklist(key);
blacklist.load();
SERVER_BLACKLISTS.put(key, blacklist);
});
getServers().forEach(Blacklist::loadCachedServerBlacklists);
}
public static boolean isOnIgnoredServer(String server) {
return IGNORED_SERVERS.isListed(server);
private static void loadCachedServerBlacklists(String server) {
List<GeneralBlacklist> blacklists = SERVER_BLACKLISTS.entrySet().stream()
.filter(entry ->
isServer(entry.getKey(), server)
).map(Map.Entry::getValue).toList();
CACHED_SERVER_BLACKLIST.put(server, blacklists);
}
public static boolean isBlockedGloballyOnServer(boolean blocked, String server, boolean turn) {
if(isOnIgnoredServer(server)) return turn;
else return blocked;
public static GeneralBlacklist getServerBlacklist(String server) {
GeneralBlacklist blacklist = SERVER_BLACKLISTS.get(server);
if(blacklist != null) {
return blacklist;
}
blacklist = BlacklistCreator.createGeneralBlacklist(server);
blacklist.load();
SERVER_BLACKLISTS.put(server, blacklist);
return blacklist;
}
public static List<String> getBlacklistServers() {
return new ArrayList<>(SERVER_BLACKLISTS.keySet());
public static Set<Map.Entry<String, GeneralBlacklist>> getBlacklists() {
return SERVER_BLACKLISTS.entrySet();
}
public static GeneralBlacklist getBlacklist() {
return BLACKLIST;
}
public static GeneralBlacklist getBlacklist(String server) {
GeneralBlacklist blacklist;
public static List<GeneralBlacklist> getServerBlacklists(String server) {
if (!CACHED_SERVER_BLACKLIST.contains(server)) {
loadCachedServerBlacklists(server);
}
if(!SERVER_BLACKLISTS.containsKey(server)) {
blacklist = BlacklistCreator.createGeneralBlacklist(server);
blacklist.load();
SERVER_BLACKLISTS.put(server, blacklist);
} else blacklist = SERVER_BLACKLISTS.get(server);
return SERVER_BLACKLISTS.getOrDefault(server, blacklist);
}
public static List<GeneralBlacklist> getAllBlacklists(String server) {
List<GeneralBlacklist> blacklists = getBlacklists(server);
if (isOnIgnoredServer(server)) return blacklists;
blacklists.add(Storage.Blacklist.getBlacklist());
return blacklists;
return CACHED_SERVER_BLACKLIST.get(server);
}
public static void clearServerBlacklists(String server) {
CACHED_SERVER_BLACKLIST.remove(server.toLowerCase());
CACHED_SERVER_BLACKLIST.remove(server);
}
public static List<GeneralBlacklist> getBlacklists(String server) {
final String finalServer = server.toLowerCase();
if(CACHED_SERVER_BLACKLIST.contains(finalServer)) return CACHED_SERVER_BLACKLIST.get(finalServer);
List<GeneralBlacklist> blacklists = new ArrayList<>();
SERVER_BLACKLISTS.entrySet()
.stream().filter(entry -> entry.getKey().endsWith("*")
? isServer(entry.getKey(), finalServer)
: entry.getKey().equalsIgnoreCase(finalServer))
.forEach(entry -> blacklists.add(entry.getValue()));
return CACHED_SERVER_BLACKLIST.putAndGet(finalServer, blacklists);
public static boolean isDisabledServer(String server) {
return DISABLED_SERVERS.isListed(server);
}
public static boolean isListed(String command, String server) {
boolean turn = ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED,
blocked = isBlockedGloballyOnServer(isBlocked(command, server), server, turn);
public static boolean isIgnoredServer(String server) {
return IGNORED_SERVERS.isListed(server);
}
if(!blocked) for (GeneralBlacklist blacklist : getBlacklists(server)) {
blocked = blacklist.isBlocked(command, server, !turn);
if(blocked) break;
public static boolean canPlayerAccess(Object player, String command, BlockType type) {
return canPlayerAccess(player, command, type, null);
}
public static boolean canPlayerAccessChat(Object player, String command) {
return canPlayerAccess(player, command, BlockType.CHAT, null);
}
public static boolean canPlayerAccessChat(Object player, String command, String server) {
return canPlayerAccess(player, command, BlockType.CHAT, server);
}
public static boolean canPlayerAccessTab(Object player, String command) {
return canPlayerAccess(player, command, BlockType.TAB, null);
}
public static boolean canPlayerAccessTab(Object player, String command, String server) {
return canPlayerAccess(player, command, BlockType.TAB, server);
}
public static boolean canPlayerAccess(Object player, String command, BlockType type, String server) {
boolean blocked = isBlocked(command, type, server);
if (!blocked) {
return true;
}
return blocked;
}
public static boolean isListed(String command, boolean intensive, String server) {
boolean turn = ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED,
blocked = isBlockedGloballyOnServer(isListed(command, intensive), server, turn);
if(!blocked) for (GeneralBlacklist blacklist : getBlacklists(server)) {
blocked = blacklist.isListed(command, intensive);
if(blocked) break;
}
return blocked;
}
public static boolean doesGroupBypass(Object playerObj, String command, boolean intensive, String server) {
int priority = -1;
for (Group group : GroupManager.getGroups()) {
for (GroupBlacklist groupBlacklist : group.getAllServerGroupBlacklist(server)) {
if(priority == -1 || group.getPriority() <= priority)
if(group.hasPermission(playerObj)) {
priority = group.getPriority();
if (groupBlacklist.isListed(command, intensive)) return true;
}
}
if (PermissionUtil.hasBypassPermission(player, command)) {
return true;
}
return false;
return GroupManager.canAccessCommand(player, command, type, server);
}
public static boolean doesGroupBypass(Object playerObj, String command, boolean intensive, boolean convert, boolean slash, String server) {
int priority = -1;
for (Group group : GroupManager.getGroups()) {
for (GroupBlacklist groupBlacklist : group.getAllServerGroupBlacklist(server, true)) {
if(priority == -1 || group.getPriority() <= priority)
if(group.hasPermission(playerObj)) {
priority = group.getPriority();
if (groupBlacklist.isListed(command, intensive, convert, slash)) return true;
}
}
public static boolean isBlockedChat(String command) {
return isBlocked(command, BlockType.CHAT, null);
}
public static boolean isBlockedTab(String command) {
return isBlocked(command, BlockType.TAB, null);
}
public static boolean isBlockedChat(String command, String server) {
return isBlocked(command, BlockType.CHAT, server);
}
public static boolean isBlockedTab(String command, String server) {
return isBlocked(command, BlockType.TAB, server);
}
public static boolean isBlocked(String command, BlockType type) {
return isBlocked(command, type, null);
}
public static boolean isBlocked(String command, BlockType type, String server) {
BlockType negation = BlockType.NEGATE;
String negatedCommand = negation + command;
boolean listed = isListed(command, type, server),
negatedListed = isListed(negatedCommand, type, server),
turn = ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED;
if (!turn && negatedListed) {
listed = !listed;
}
if (turn) {
return !listed;
} else {
return listed;
}
return false;
}
public static boolean isListed(Object playerObj, String command, boolean intensive, String server) {
if(GroupManager.getGroupsByServer(server).stream().anyMatch(group -> isInListed(command, group.getAllCommands(server), intensive) && group.hasPermission(playerObj)))
private static boolean isListed(String unmodifiedCommand, BlockType type, String server) {
if (server != null && isDisabledServer(server))
return false;
boolean listed = isListed(command, intensive);
boolean turn = Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED;
boolean listed = false;
if(!listed) for (GeneralBlacklist blacklist : getBlacklists(server)) {
listed = blacklist.isListed(command, intensive);
if(listed) break;
String command = type.toString() + unmodifiedCommand;
if (server == null || !isIgnoredServer(server)) {
listed = BLACKLIST.isListed(command, !turn);
}
if (server == null) {
if (!listed && type != BlockType.BOTH) {
return isListed(unmodifiedCommand, BlockType.BOTH, null);
}
return listed;
}
List<GeneralBlacklist> blacklists = new ArrayList<>(getServerBlacklists(server));
if (blacklists.isEmpty())
blacklists.add(BLACKLIST);
for (GeneralBlacklist blacklist : blacklists) {
if (listed/* && turn*/) {
break;
}
listed = blacklist.isListed(command, turn);
}
if (!listed && type != BlockType.BOTH) {
return isListed(unmodifiedCommand, BlockType.BOTH, server);
}
return listed;
}
public static boolean isListed(Object playerObj, String command, boolean intensive, boolean listed, String server) {
if(GroupManager.getGroupsByServer(server).stream().anyMatch(group -> isInListed(command, group.getAllCommands(server), intensive) && group.hasPermission(playerObj)))
return false;
public static class BlockTypeFetcher {
if(!listed) for (GeneralBlacklist blacklist : getBlacklists(server)) {
listed = blacklist.isListed(command, intensive);
if(listed) break;
}
return listed;
}
public static BlockType getType(String command) {
for (BlockType blockType : BLOCK_TYPES) {
if (!command.startsWith(blockType.toString()))
continue;
public static boolean isListed(Object playerObj, String command, boolean intensive, boolean listed, boolean slash, String server) {
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)) {
listed = blacklist.isListed(command, intensive, true, slash);
if(listed) break;
}
return listed;
}
public static boolean isBlocked(String command, boolean intensive, String server) {
return isBlocked(command, intensive, server, false);
}
public static boolean isBlocked(Object targetObj, String command, boolean intensive, String server) {
return isBlocked(targetObj, command, intensive, server, false);
}
public static boolean isBlocked(String command, boolean intensive, String server, boolean focusOnBlock) {
server = server.toLowerCase();
boolean turn = ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED,
blocked,
blockedGlobal = isBlockedGloballyOnServer(BLACKLIST.isBlockedIgnorePermission(command, intensive), server, turn),
blockedServer = false;
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;
return blockType;
}
return null;
}
blocked = turn ? blockedGlobal && blockedServer : blockedServer || blockedGlobal;
if(!blocked
&& CACHED_SERVER_BLACKLIST.contains(server)
&& CACHED_SERVER_BLACKLIST.get(server).size() == 0)
if(turn) blocked = true;
public static String modify(String command) {
BlockType type = getType(command);
return modify(command, type);
}
return blocked;
}
public static String modify(String command, BlockType type) {
if (type == null || type == BlockType.BOTH || command.length() <= type.toString().length() || !command.startsWith(type.toString()))
return command;
public static boolean isBlocked(Object targetObj, String command, boolean intensive, String server, boolean focusOnBlock) {
if(server != null) server = server.toLowerCase();
return command.substring(type.toString().length());
}
if(doesGroupBypass(targetObj, command, intensive, server))
return false;
boolean blocked = isBlocked(command, intensive, server, focusOnBlock);
if(blocked)
if(PermissionUtil.hasBypassPermission(targetObj, command))
blocked = false;
return blocked;
}
public static boolean isListed(String command) {
return BLACKLIST.isListed(command);
}
public static boolean isListed(String command, boolean intensive) {
return BLACKLIST.isListed(command, intensive);
}
public static boolean isListed(String command, boolean intensive, boolean convert) {
return BLACKLIST.isListed(command, intensive, convert);
}
public static boolean isListed(String command, boolean intensive, boolean convert, boolean slash) {
return BLACKLIST.isListed(command, intensive, convert, slash);
}
public static boolean isBlocked(Object targetObj, String command) {
return BLACKLIST.isBlocked(targetObj, command);
}
public static boolean isBlocked(Object targetObj, String command, boolean intensive) {
return BLACKLIST.isBlocked(targetObj, command, intensive);
}
public static boolean isBlocked(Object targetObj, String command, boolean intensive, boolean convert, boolean slash) {
return BLACKLIST.isBlocked(targetObj, command, intensive, convert, slash);
}
public static boolean isBlocked(String command, boolean intensive, boolean convert) {
return BLACKLIST.isBlocked(command, intensive, convert);
}
public static boolean isBlocked(String command, boolean intensive, boolean convert, boolean slash) {
return BLACKLIST.isBlocked(command, intensive, convert);
}
public static String convertCommand(String command, boolean intensive, boolean lowercase) {
return BLACKLIST.convertCommand(command, intensive, lowercase);
}
public static String convertCommand(String command, boolean intensive, boolean lowercase, boolean slash) {
return BLACKLIST.convertCommand(command, intensive, lowercase, slash);
}
public static boolean isInListed(String command, List<String> commandList, boolean intensive) {
command = StringUtils.replaceFirst(command, "/", "");
command = convertCommand(command, intensive, false);
for (String commands : commandList)
if(commands.equals(command)) return true;
return false;
}
}
}
}
@@ -10,7 +10,6 @@ public class BlacklistCreator {
}
public static GeneralBlacklist createGeneralBlacklist(String server) {
server = server.toLowerCase();
return new GeneralBlacklist("servers." + server + ".commands");
}
@@ -19,20 +18,18 @@ public class BlacklistCreator {
}
public static GroupBlacklist createGroupBlacklist(String group, String server, boolean ignoreExist) {
server = server.toLowerCase();
if (!exist(group, server) && !ignoreExist)
return null;
return new GroupBlacklist(group, "servers." + server + ".commands");
}
public static boolean exist(String server) {
server = server.toLowerCase();
Object obj = Storage.Blacklist.getBlacklist().getConfig().get("global.servers." + server);
return obj != null;
}
public static boolean exist(String group, String server) {
server = server.toLowerCase();
Object obj = Storage.Blacklist.getBlacklist().getConfig().get("groups." + group + ".servers." + server);
return obj != null;
}
@@ -7,7 +7,7 @@ import de.rayzs.pat.utils.Reflection;
public class BlacklistSection extends ConfigStorage {
public String CLEAR, CLEAR_CONFIRM, CLEAR_SERVER, CLEAR_SERVER_CONFIRM, CLEAR_SERVER_NOT_FOUND;
public String LIST_MESSAGE, LIST_SPLITTER, LIST_COMMAND, LIST_SERVER_MESSAGE, LIST_SERVER_SPLITTER, LIST_SERVER_COMMAND;
public String LIST_MESSAGE, LIST_SPLITTER, LIST_SERVER_MESSAGE, LIST_SERVER_SPLITTER;
public String ADD_SUCCESS, ADD_FAILED;
public String REMOVE_SUCCESS, REMOVE_FAILED;
@@ -26,8 +26,7 @@ public class BlacklistSection extends ConfigStorage {
CLEAR_CONFIRM = new ConfigSectionHelper<String>(this, "clear-confirmation", "&4Warning! &7This command will &cclear the entire list&7! &7Repeat the &esame command &7to confirm this action.").getOrSet();
LIST_MESSAGE = new ConfigSectionHelper<String>(this, "list.message", "&7Listed commands (&f%size%&7)&8: &f%commands%").getOrSet();
LIST_SPLITTER = new ConfigSectionHelper<String>(this, "list.splitter", "&7, ").getOrSet();
LIST_COMMAND = new ConfigSectionHelper<String>(this, "list.command", "&f%command%").getOrSet();
LIST_SPLITTER = new ConfigSectionHelper<String>(this, "list.splitter", "&7, &f").getOrSet();
ADD_SUCCESS = new ConfigSectionHelper<String>(this, "add.success", "&aSuccessfully added %command% into the list!").getOrSet();
ADD_FAILED = new ConfigSectionHelper<String>(this, "add.failed", "&c%command% is already in the list!").getOrSet();
@@ -41,8 +40,7 @@ public class BlacklistSection extends ConfigStorage {
CLEAR_SERVER_NOT_FOUND = new ConfigSectionHelper<String>(this, "clear-server-not-found", "&cThe server %server% does not have any commands!").getOrSet();
LIST_SERVER_MESSAGE = new ConfigSectionHelper<String>(this, "list.message-server", "&7Listed commands of %server% (&f%size%&7)&8: &f%commands%").getOrSet();
LIST_SERVER_SPLITTER = new ConfigSectionHelper<String>(this, "list.splitter-server", "&7, ").getOrSet();
LIST_SERVER_COMMAND = new ConfigSectionHelper<String>(this, "list.command-server", "&f%command%").getOrSet();
LIST_SERVER_SPLITTER = new ConfigSectionHelper<String>(this, "list.splitter-server", "&7, &f").getOrSet();
ADD_SERVER_SUCCESS = new ConfigSectionHelper<String>(this, "add.success-server", "&aSuccessfully added %command% into the list of %server%!").getOrSet();
ADD_SERVER_FAILED = new ConfigSectionHelper<String>(this, "add.failed-server", "&c%command% is already in the list of %server%!").getOrSet();
@@ -10,8 +10,8 @@ public class GroupSection extends ConfigStorage {
public String CLEAR, CLEAR_CONFIRM, CLEAR_SERVER, CLEAR_SERVER_CONFIRM;
public String PRIORITY_SUCCESS, PRIORITY_FAILED;
public String LIST_MESSAGE, LIST_SPLITTER, LIST_COMMAND, LIST_SERVER_MESSAGE, LIST_SERVER_SPLITTER, LIST_SERVER_COMMAND;
public String LIST_GROUP_MESSAGE, LIST_GROUP_SPLITTER, LIST_GROUP_GROUPS, LIST_GROUP_SERVER_MESSAGE, LIST_GROUP_SERVER_SPLITTER, LIST_GROUP_SERVER_GROUPS;
public String LIST_MESSAGE, LIST_SPLITTER, LIST_SERVER_MESSAGE, LIST_SERVER_SPLITTER;
public String LIST_GROUP_MESSAGE, LIST_GROUP_SPLITTER, LIST_GROUP_SERVER_MESSAGE, LIST_GROUP_SERVER_SPLITTER;
public String LIST_PRIORITY_MESSAGE, LIST_PRIORITY_SPLITTER, LIST_PRIORITY_GROUPS;
public String ADD_SUCCESS, ADD_FAILED;
@@ -41,16 +41,14 @@ public class GroupSection extends ConfigStorage {
PRIORITY_FAILED = new ConfigSectionHelper<String>(this, "priority.failed", "&cInvalid priority! Please choose a number which is greater than 0.").getOrSet();
LIST_MESSAGE = new ConfigSectionHelper<String>(this, "list.message", "&7Listed commands of group %group% (&f%size%&7)&8: &f%commands%").getOrSet();
LIST_SPLITTER = new ConfigSectionHelper<String>(this, "list.splitter", "&7, ").getOrSet();
LIST_COMMAND = new ConfigSectionHelper<String>(this, "list.command", "&f").getOrSet();
LIST_SPLITTER = new ConfigSectionHelper<String>(this, "list.splitter", "&7, &f").getOrSet();
LIST_PRIORITY_MESSAGE = new ConfigSectionHelper<String>(this, "list-priorities.message", "&7List of all group priorities (&f%size%&7)&8: &f%groups%").getOrSet();
LIST_PRIORITY_SPLITTER = new ConfigSectionHelper<String>(this, "list-priorities.splitter", "\\n").getOrSet();
LIST_PRIORITY_GROUPS = new ConfigSectionHelper<String>(this, "list-priorities.group", "&8- &e%priority%&8: &f%group%").getOrSet();
LIST_PRIORITY_GROUPS = new ConfigSectionHelper<String>(this, "list-priorities.group", "&8- &e%priority%&8: &e%group%").getOrSet();
LIST_GROUP_MESSAGE = new ConfigSectionHelper<String>(this, "list-groups.message", "&7All groups (&f%size%&7)&8: &f%groups%").getOrSet();
LIST_GROUP_SPLITTER = new ConfigSectionHelper<String>(this, "list-groups.splitter", "&7, ").getOrSet();
LIST_GROUP_GROUPS = new ConfigSectionHelper<String>(this, "list-groups.command", "&f").getOrSet();
LIST_GROUP_SPLITTER = new ConfigSectionHelper<String>(this, "list-groups.splitter", "&7, &f").getOrSet();
ADD_SUCCESS = new ConfigSectionHelper<String>(this, "add.success", "&aSuccessfully added %command% into the list of group %group%!").getOrSet();
ADD_FAILED = new ConfigSectionHelper<String>(this, "add.failed", "&c%command% is already in the list of group %group%!").getOrSet();
@@ -69,12 +67,10 @@ public class GroupSection extends ConfigStorage {
CLEAR_SERVER_CONFIRM = new ConfigSectionHelper<String>(this, "clear-confirmation-server", "&4Warning! &7This command will &cclear the entire list&7 of this group for %server%! &7Repeat the &esame command &7to confirm this action.").getOrSet();
LIST_SERVER_MESSAGE = new ConfigSectionHelper<String>(this, "list.message-server", "&7Listed commands of group %group% from %server% (&f%size%&7)&8: &f%commands%").getOrSet();
LIST_SERVER_SPLITTER = new ConfigSectionHelper<String>(this, "list.splitter-server", "&7, ").getOrSet();
LIST_SERVER_COMMAND = new ConfigSectionHelper<String>(this, "list.command-server", "&f%group%").getOrSet();
LIST_SERVER_SPLITTER = new ConfigSectionHelper<String>(this, "list.splitter-server", "&7, &f").getOrSet();
LIST_GROUP_SERVER_MESSAGE = new ConfigSectionHelper<String>(this, "list-groups.message-server", "&7All groups from %server% (&f%size%&7)&8: &f%groups%").getOrSet();
LIST_GROUP_SERVER_SPLITTER = new ConfigSectionHelper<String>(this, "list-groups.splitter-server", "&7, ").getOrSet();
LIST_GROUP_SERVER_GROUPS = new ConfigSectionHelper<String>(this, "list-groups.command-server", "&f%group%").getOrSet();
LIST_GROUP_SERVER_SPLITTER = new ConfigSectionHelper<String>(this, "list-groups.splitter-server", "&7, &f").getOrSet();
ADD_SERVER_SUCCESS = new ConfigSectionHelper<String>(this, "add.success-server", "&aSuccessfully added %command% into the list of group %group% for %server%!").getOrSet();
ADD_SERVER_FAILED = new ConfigSectionHelper<String>(this, "add.failed-server", "&c%command% is already in the list of group %group% of %server%!").getOrSet();
@@ -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 de.rayzs.pat.utils.Reflection;
public class ServerListSection extends ConfigStorage {
public String SERVER_DOES_NOT_EXIST, GROUP_DOES_NOT_EXIST;
public String LIST_SERVER_MESSAGE, LIST_SERVER_SPLITTER, LIST_SERVER_COMMAND, LIST_GROUP_MESSAGE, LIST_GROUP_SPLITTER, LIST_GROUP_COMMAND;
public String LIST_SERVER_MESSAGE, LIST_SERVER_SPLITTER, LIST_GROUP_MESSAGE, LIST_GROUP_SPLITTER;
public ServerListSection() {
super("server-list");
@@ -22,11 +22,9 @@ public class ServerListSection extends ConfigStorage {
GROUP_DOES_NOT_EXIST = new ConfigSectionHelper<String>(this, "group-does-not-exist", "&cGroup %group% does not exist for %server%!").getOrSet();
LIST_SERVER_MESSAGE = new ConfigSectionHelper<String>(this, "list.server.message", "&7Listed commands of %server% (&f%size%&7)&8: &f%commands%").getOrSet();
LIST_SERVER_SPLITTER = new ConfigSectionHelper<String>(this, "list.server.splitter", "&7, ").getOrSet();
LIST_SERVER_COMMAND = new ConfigSectionHelper<String>(this, "list.server.command", "&f%command%").getOrSet();
LIST_SERVER_SPLITTER = new ConfigSectionHelper<String>(this, "list.server.splitter", "&7, &f").getOrSet();
LIST_GROUP_MESSAGE = new ConfigSectionHelper<String>(this, "list.group.message", "&7Listed commands of %group% from %server% (&f%size%&7)&8: &f%commands%").getOrSet();
LIST_GROUP_SPLITTER = new ConfigSectionHelper<String>(this, "list.group.splitter", "&7, ").getOrSet();
LIST_GROUP_COMMAND = new ConfigSectionHelper<String>(this, "list.group.command", "&f%command%").getOrSet();
LIST_GROUP_SPLITTER = new ConfigSectionHelper<String>(this, "list.group.splitter", "&7, &f").getOrSet();
}
}
@@ -0,0 +1,36 @@
package de.rayzs.pat.api.storage.config.settings;
import de.rayzs.pat.api.storage.storages.ConfigStorage;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.configuration.helper.ConfigSectionHelper;
import de.rayzs.pat.utils.permission.PermissionUtil;
public class AutoLowercaseCommandsSection extends ConfigStorage {
public boolean ENABLED;
public AutoLowercaseCommandsSection() {
super("auto-lowercase-commands");
}
@Override
public void load() {
super.load();
if (Reflection.isProxyServer())
return;
ENABLED = new ConfigSectionHelper<Boolean>(this, "enabled", true).getOrSet();
}
public boolean isCommand(String command) {
if(!ENABLED) return false;
return !StringUtils.isLowercased(command);
}
public boolean doesBypass(Object targetObj) {
return !ENABLED || PermissionUtil.hasPermission(targetObj, "auto-lowercase");
}
}
@@ -0,0 +1,22 @@
package de.rayzs.pat.api.storage.config.settings;
import de.rayzs.pat.api.storage.storages.ConfigStorage;
import de.rayzs.pat.utils.configuration.helper.ConfigSectionHelper;
import de.rayzs.pat.utils.configuration.helper.MultipleMessagesHelper;
import java.util.Collections;
public class BaseCommandCaseSensitiveSection extends ConfigStorage {
public boolean ENABLED;
public BaseCommandCaseSensitiveSection() {
super("base-command-case-sensitive");
}
@Override
public void load() {
super.load();
ENABLED = new ConfigSectionHelper<Boolean>(this, null, true).getOrSet();
}
}
@@ -1,13 +1,11 @@
package de.rayzs.pat.api.storage.config.settings;
import de.rayzs.pat.utils.configuration.helper.ConfigSectionHelper;
import de.rayzs.pat.api.storage.storages.ConfigStorage;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.api.storage.storages.ConfigStorage;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.configuration.helper.ConfigSectionHelper;
import de.rayzs.pat.utils.permission.PermissionUtil;
import java.util.UUID;
public class BlockNamespaceCommandsSection extends ConfigStorage {
public boolean ENABLED;
@@ -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;
@@ -1,13 +1,20 @@
package de.rayzs.pat.api.storage.config.settings;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.configuration.helper.ConfigSectionHelper;
import de.rayzs.pat.api.storage.storages.ConfigStorage;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.configuration.helper.MultipleMessagesHelper;
import java.util.Arrays;
public class CustomProtocolPingSection extends ConfigStorage {
public boolean ENABLED, ALWAYS_SHOW, HIDE_PLAYERS, USE_EXTEND_AS_MAX_COUNT;
public boolean ENABLED, ALWAYS_SHOW, HIDE_PLAYERS, USE_EXTEND_AS_MAX_COUNT, USE_CUSTOM_PLAYERLIST;
public String PROTOCOL;
public MultipleMessagesHelper PLAYERLIST;
public int EXTEND_COUNT;
public CustomProtocolPingSection() {
@@ -17,17 +24,30 @@ public class CustomProtocolPingSection extends ConfigStorage {
@Override
public void load() {
super.load();
if(!Reflection.isProxyServer()) {
if(!Reflection.isPaper() || Reflection.getMinor() < 12)
if (!Reflection.isProxyServer() && (!Reflection.isPaper() || Reflection.getMinor() < 12))
return;
}
ENABLED = new ConfigSectionHelper<Boolean>(this, "enabled", true).getOrSet();
ALWAYS_SHOW = new ConfigSectionHelper<Boolean>(this, "always-show", Reflection.isProxyServer() || Reflection.isPaper()).getOrSet();
USE_EXTEND_AS_MAX_COUNT = new ConfigSectionHelper<Boolean>(this, "use-as-maxplayers", false).getOrSet();
PROTOCOL = new ConfigSectionHelper<String>(this, "protocol", "&f&lProAntiTab &7(&a%online%&7/&c%max%&7)").getOrSet();
EXTEND_COUNT = new ConfigSectionHelper<Integer>(this, "extend-online-count", 1).getOrSet();
if(Reflection.isProxyServer()) return;
HIDE_PLAYERS = new ConfigSectionHelper<Boolean>(this, "hide-players", true).getOrSet();
USE_CUSTOM_PLAYERLIST = new ConfigSectionHelper<Boolean>(this, "custom-playerlist.enabled", false).getOrSet();
PLAYERLIST = new MultipleMessagesHelper(this, "custom-playerlist.list", Arrays.asList(
"&8> &7Online players: &f%online%&7/&c%max%",
"&8> &7Using &fProAntiTab"
));
if (HIDE_PLAYERS && USE_CUSTOM_PLAYERLIST) {
Logger.warning("You can't use both 'hide-players' and 'custom-playerlist' at the same time! (Section: custom-protocol-ping)");
Logger.warning("You gotta choose what feature from those two you want to use.");
Logger.warning("In order to avoid any problems, the 'custom-playerlist' feature has been temporarily disabled.");
}
}
}
@@ -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();
}
}
@@ -7,6 +7,10 @@ import de.rayzs.pat.utils.Reflection;
public class HandleThroughProxySection extends ConfigStorage {
public boolean ENABLED;
public boolean LOAD_FROM_ENV;
public String ENV_NAME;
public String TOKEN;
public HandleThroughProxySection() {
@@ -20,5 +24,8 @@ public class HandleThroughProxySection extends ConfigStorage {
ENABLED = new ConfigSectionHelper<Boolean>(this, "enabled", false).getOrSet();
TOKEN = new ConfigSectionHelper<String>(this, "token", "insert-token-of-proxy-here").getOrSet();
LOAD_FROM_ENV = new ConfigSectionHelper<Boolean>(this, "load-from-env.enabled", false).getOrSet();
ENV_NAME = new ConfigSectionHelper<String>(this, "load-from-env.name", 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);
}
}
@@ -0,0 +1,24 @@
package de.rayzs.pat.api.storage.config.settings;
import de.rayzs.pat.api.storage.storages.ConfigStorage;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.configuration.helper.ConfigSectionHelper;
public class UpdateCommandsPerWorldSection extends ConfigStorage {
public boolean ENABLED;
public UpdateCommandsPerWorldSection() {
super("update-commands-per-world");
}
@Override
public void load() {
super.load();
if (Reflection.isProxyServer())
return;
ENABLED = new ConfigSectionHelper<Boolean>(this, null, false).getOrSet();
}
}
@@ -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%)",
@@ -4,28 +4,23 @@ import de.rayzs.pat.utils.configuration.helper.ConfigSectionHelper;
import de.rayzs.pat.api.storage.storages.PlaceholderStorage;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.group.GroupManager;
import org.bukkit.entity.Player;
public class ListCommandsPlaceholder extends PlaceholderStorage {
public ListCommandsPlaceholder() { super("list_commands"); }
public String COMMAND, SPLITTER;
public String SPLITTER;
@Override
public String onRequest(Player player, String param) {
return StringUtils.buildStringList(
Storage.Blacklist.getBlacklist().getCommands(),
SPLITTER,
COMMAND,
"%command%"
);
return StringUtils.getStringList(Storage.Blacklist.getBlacklist().getCommands(), SPLITTER);
}
@Override
public void load() {
super.load();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7-> ").getOrSet();
COMMAND = new ConfigSectionHelper<String>(this, "command", "&f%command%\\n").getOrSet();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7, &e").getOrSet();
}
}
@@ -10,23 +10,16 @@ public class ListReversedCommandsPlaceholder extends PlaceholderStorage {
public ListReversedCommandsPlaceholder() { super("list_reversed_commands"); }
public String COMMAND, SPLITTER;
public String SPLITTER;
@Override
public String onRequest(Player player, String param) {
return StringUtils.buildSortedStringList(
Storage.Blacklist.getBlacklist().getCommands(),
SPLITTER,
COMMAND,
"%command%",
true
);
return StringUtils.getReversedStringList(Storage.Blacklist.getBlacklist().getCommands(), SPLITTER);
}
@Override
public void load() {
super.load();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7-> ").getOrSet();
COMMAND = new ConfigSectionHelper<String>(this, "command", "&f%command%\\n").getOrSet();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7, &e").getOrSet();
}
}
@@ -10,23 +10,16 @@ public class ListSortedCommandsPlaceholder extends PlaceholderStorage {
public ListSortedCommandsPlaceholder() { super("list_sorted_commands"); }
public String COMMAND, SPLITTER;
public String SPLITTER;
@Override
public String onRequest(Player player, String param) {
return StringUtils.buildSortedStringList(
Storage.Blacklist.getBlacklist().getCommands(),
SPLITTER,
COMMAND,
"%command%",
false
);
return StringUtils.getSortedStringList(Storage.Blacklist.getBlacklist().getCommands(), SPLITTER);
}
@Override
public void load() {
super.load();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7-> ").getOrSet();
COMMAND = new ConfigSectionHelper<String>(this, "command", "&f%command%\\n").getOrSet();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7, &e").getOrSet();
}
}
@@ -10,25 +10,19 @@ public class ListGroupCommandsPlaceholder extends PlaceholderStorage {
public ListGroupCommandsPlaceholder() { super("list_commands_group_"); }
public String COMMAND, SPLITTER;
public String SPLITTER;
@Override
public String onRequest(Player player, String param) {
Group group = GroupManager.getGroupByName(param);
if(group == null) return null;
return StringUtils.buildStringList(
group.getCommands(),
SPLITTER,
COMMAND,
"%command%"
);
return StringUtils.getStringList(group.getCommands(), SPLITTER);
}
@Override
public void load() {
super.load();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7-> ").getOrSet();
COMMAND = new ConfigSectionHelper<String>(this, "command", "&f%command%\\n").getOrSet();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7, &e").getOrSet();
}
}
@@ -10,26 +10,19 @@ public class ListGroupReversedCommandsPlaceholder extends PlaceholderStorage {
public ListGroupReversedCommandsPlaceholder() { super("list_reversed_commands_group_"); }
public String COMMAND, SPLITTER;
public String SPLITTER;
@Override
public String onRequest(Player player, String param) {
Group group = GroupManager.getGroupByName(param);
if(group == null) return null;
return StringUtils.buildSortedStringList(
group.getCommands(),
SPLITTER,
COMMAND,
"%command%",
true
);
return StringUtils.getReversedStringList(group.getCommands(), SPLITTER);
}
@Override
public void load() {
super.load();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7-> ").getOrSet();
COMMAND = new ConfigSectionHelper<String>(this, "command", "&f%command%\\n").getOrSet();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7, &e").getOrSet();
}
}
@@ -10,26 +10,19 @@ public class ListGroupSortedCommandsPlaceholder extends PlaceholderStorage {
public ListGroupSortedCommandsPlaceholder() { super("list_sorted_commands_group_"); }
public String COMMAND, SPLITTER;
public String SPLITTER;
@Override
public String onRequest(Player player, String param) {
Group group = GroupManager.getGroupByName(param);
if(group == null) return null;
return StringUtils.buildSortedStringList(
group.getCommands(),
SPLITTER,
COMMAND,
"%command%",
false
);
return StringUtils.getSortedStringList(group.getCommands(), SPLITTER);
}
@Override
public void load() {
super.load();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7-> ").getOrSet();
COMMAND = new ConfigSectionHelper<String>(this, "command", "&f%command%\\n").getOrSet();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7, &e").getOrSet();
}
}
@@ -0,0 +1,16 @@
package de.rayzs.pat.api.storage.placeholders.general;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.api.storage.storages.PlaceholderStorage;
import org.bukkit.entity.Player;
public class GeneralPrefixPlaceholder extends PlaceholderStorage {
public GeneralPrefixPlaceholder() { super("general_prefix"); }
@Override
public String onRequest(Player player, String param) {
if (Storage.ConfigSections.Messages.PREFIX == null) return null;
return Storage.ConfigSections.Messages.PREFIX.PREFIX;
}
}
@@ -10,25 +10,16 @@ public class ListGroupsPlaceholder extends PlaceholderStorage {
public ListGroupsPlaceholder() { super("list_groups"); }
public String COMMAND, SPLITTER;
public String SPLITTER;
@Override
public String onRequest(Player player, String param) {
Group group = GroupManager.getGroupByName(param);
if(group == null) return null;
return StringUtils.buildStringList(
GroupManager.getGroupNames(),
SPLITTER,
COMMAND,
"%group%"
);
return StringUtils.getStringList(GroupManager.getGroupNames(), SPLITTER);
}
@Override
public void load() {
super.load();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7-> ").getOrSet();
COMMAND = new ConfigSectionHelper<String>(this, "group", "&f%group%\\n").getOrSet();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7, &e").getOrSet();
}
}
@@ -10,26 +10,16 @@ public class ListGroupsReversedPlaceholder extends PlaceholderStorage {
public ListGroupsReversedPlaceholder() { super("list_reversed_groups"); }
public String COMMAND, SPLITTER;
public String SPLITTER;
@Override
public String onRequest(Player player, String param) {
Group group = GroupManager.getGroupByName(param);
if(group == null) return null;
return StringUtils.buildSortedStringList(
GroupManager.getGroupNames(),
SPLITTER,
COMMAND,
"%group%",
true
);
return StringUtils.getReversedStringList(GroupManager.getGroupNames(), SPLITTER);
}
@Override
public void load() {
super.load();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7-> ").getOrSet();
COMMAND = new ConfigSectionHelper<String>(this, "group", "&f%group%\\n").getOrSet();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7, &e").getOrSet();
}
}
@@ -10,26 +10,16 @@ public class ListGroupsSortedPlaceholder extends PlaceholderStorage {
public ListGroupsSortedPlaceholder() { super("list_sorted_groups"); }
public String COMMAND, SPLITTER;
public String SPLITTER;
@Override
public String onRequest(Player player, String param) {
Group group = GroupManager.getGroupByName(param);
if(group == null) return null;
return StringUtils.buildSortedStringList(
GroupManager.getGroupNames(),
SPLITTER,
COMMAND,
"%command%",
false
);
return StringUtils.getSortedStringList(GroupManager.getGroupNames(), SPLITTER);
}
@Override
public void load() {
super.load();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7-> ").getOrSet();
COMMAND = new ConfigSectionHelper<String>(this, "group", "&f%group%\\n").getOrSet();
SPLITTER = new ConfigSectionHelper<String>(this, "splitter", "&7, &e").getOrSet();
}
}
@@ -0,0 +1,17 @@
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) {
if (Storage.ConfigSections.Settings.CANCEL_COMMAND.BASE_COMMAND_RESPONSE == null) return null;
return StringUtils.getStringList(Storage.ConfigSections.Settings.CANCEL_COMMAND.BASE_COMMAND_RESPONSE.getLines(), "\n");
}
}
@@ -1,16 +0,0 @@
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 BlockedCommandPlaceholder extends PlaceholderStorage {
public BlockedCommandPlaceholder() { super("message_blocked"); }
@Override
public String onRequest(Player player, String param) {
return StringUtils.buildStringList(Storage.ConfigSections.Settings.CANCEL_COMMAND.MESSAGE.getLines());
}
}
@@ -0,0 +1,17 @@
package de.rayzs.pat.api.storage.placeholders.messages;
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 BlockedSubCommandPlaceholder extends PlaceholderStorage {
public BlockedSubCommandPlaceholder() { super("message_sub_blocked"); }
@Override
public String onRequest(Player player, String param) {
if (Storage.ConfigSections.Settings.CANCEL_COMMAND.SUB_COMMAND_RESPONSE == null) return null;
return StringUtils.getStringList(Storage.ConfigSections.Settings.CANCEL_COMMAND.SUB_COMMAND_RESPONSE.getLines(), "\n");
}
}
@@ -11,6 +11,7 @@ public class UnknownCommandPlaceholder extends PlaceholderStorage {
@Override
public String onRequest(Player player, String param) {
return StringUtils.buildStringList(Storage.ConfigSections.Settings.CUSTOM_UNKNOWN_COMMAND.MESSAGE.getLines());
if (Storage.ConfigSections.Settings.CUSTOM_UNKNOWN_COMMAND.MESSAGE == null) return null;
return StringUtils.getStringList(Storage.ConfigSections.Settings.CUSTOM_UNKNOWN_COMMAND.MESSAGE.getLines(), "\n");
}
}
@@ -1,8 +1,10 @@
package de.rayzs.pat.api.storage.storages;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.api.storage.*;
import java.io.Serializable;
import java.util.*;
@@ -15,154 +17,57 @@ public class BlacklistStorage extends StorageTemplate implements Serializable {
}
public boolean isListed(String command) {
return isListed(command, false);
return isListed(command, !Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED);
}
public boolean isConverted(String command, boolean intensive) {
return !command.contains(" ") && (intensive && !command.contains(":"));
}
public boolean isListed(String command, boolean ignoreColons) {
final boolean caseSensitive = Storage.ConfigSections.Settings.BASE_COMMAND_CASE_SENSITIVE.ENABLED;
public String convertCommand(String command, boolean intensive, boolean lowerCase) {
return convertCommand(command, intensive, lowerCase, true);
}
public String convertCommand(String command, boolean intensive, boolean lowerCase, boolean slash) {
if(isConverted(command, intensive)) return command;
if(lowerCase) command = command.toLowerCase();
if(slash)
if(command.startsWith("/")) command = command.replaceFirst("/", "");
String[] split;
if(command.contains(" ")) {
split = command.split(" ");
if(split.length > 0) command = split[0];
}
if(intensive && command.contains(":")) {
split = command.split(":");
if(split.length > 0)
command = command.replaceFirst(split[0] + ":", "");
}
return command;
}
public boolean isListed(String command, boolean intensive) {
if(commands == null) {
Logger.warning("&cFailed to check command \"" + command + "\"! PAT couldn't read the commands from the storage.yml at section &4" + getNavigatePath() + "&c! Please ensure that your storage.yml isn't corrupt or contains any spaces or empty commands. If this problem still remains, please join my Discord server to ask for help there. &8(&erayzs.de/discord&8)");
if (commands == null || command.isEmpty()) {
return false;
}
if(!isConverted(command, intensive)) command = convertCommand(command, intensive, true);
if (!isNegated(command) && commands.contains("*")) {
return true;
}
for (String commands : commands) {
if(commands == null) continue;
if (commands.equals(command)) return true;
for (String listedCommand : commands) {
if (listedCommand == null)
continue;
if (ignoreColons) {
command = StringUtils.getFirstArg(command);
if (command.contains(":"))
command = command.substring(command.indexOf(':'));
}
if (caseSensitive) {
if (StringUtils.getFirstArg(listedCommand).equals(StringUtils.getFirstArg(command))) {
return true;
}
} else {
if (StringUtils.getFirstArg(listedCommand).equalsIgnoreCase(StringUtils.getFirstArg(command))) {
return true;
}
}
}
return false;
}
public boolean isListed(String command, boolean intensive, boolean convert, boolean slash) {
if(commands == null) {
Logger.warning("&cFailed to check command \"" + command + "\"! PAT couldn't read the commands from the storage.yml at section &4" + getNavigatePath() + "&c! Please ensure that your storage.yml isn't corrupt or contains any spaces or empty commands. If this problem still remains, please join my Discord server to ask for help there. &8(&erayzs.de/discord&8)");
return false;
}
if(convert)
if(!isConverted(command, intensive)) command = convertCommand(command, intensive, true, slash);
for (String commands : commands) {
if(commands == null) continue;
if (commands.equals(command)) return true;
}
return false;
}
public boolean isListed(String command, boolean intensive, boolean convert) {
if(commands == null) {
Logger.warning("&cFailed to check command \"" + command + "\"! PAT couldn't read the commands from the storage.yml at section &4" + getNavigatePath() + "&c! Please ensure that your storage.yml isn't corrupt or contains any spaces or empty commands. If this problem still remains, please join my Discord server to ask for help there. &8(&erayzs.de/discord&8)");
return false;
}
if(convert)
if(!isConverted(command, intensive)) command = convertCommand(command, intensive, true);
for (String commands : commands) {
if(commands == null) continue;
if (commands.equals(command)) return true;
}
return false;
}
public boolean isBlocked(Object targetObj, String command) {
return isBlocked(targetObj, command, false);
}
public boolean isBlocked(Object targetObj, String command, boolean intensive) {
if(Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED)
return !isListed(command, intensive) && !PermissionUtil.hasBypassPermission(targetObj, command);
else
return isListed(command, intensive) && !PermissionUtil.hasBypassPermission(targetObj, command);
}
public boolean isBlockedIgnorePermission(String command, boolean intensive) {
if(Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED)
return !isListed(command, intensive);
else
return isListed(command, intensive);
}
public boolean isBlocked(Object targetObj, String command, boolean intensive, boolean convert) {
if(Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED)
return !isListed(command, intensive, convert) && !PermissionUtil.hasBypassPermission(targetObj, command);
else
return isListed(command, intensive, convert) && !PermissionUtil.hasBypassPermission(targetObj, command);
}
public boolean isBlocked(Object targetObj, String command, boolean intensive, boolean convert, boolean slash) {
if(Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED)
return !isListed(command, intensive, convert, slash) && !PermissionUtil.hasBypassPermission(targetObj, command);
else
return isListed(command, intensive, convert, slash) && !PermissionUtil.hasBypassPermission(targetObj, command);
}
public boolean isBlocked(String command, boolean intensive) {
if(Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED)
return !isListed(command, intensive);
else
return isListed(command, intensive);
}
public boolean isBlocked(String command, boolean intensive, boolean convert) {
if(Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED)
return !isListed(command, intensive, convert);
else
return isListed(command, intensive, convert);
}
public boolean isBlocked(String command, boolean intensive, boolean convert, boolean slash) {
if(Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED)
return !isListed(command, intensive, convert, slash);
else
return isListed(command, intensive, convert, slash);
}
public void setList(List<String> commands) {
this.commands = commands;
}
public BlacklistStorage add(String command) {
command = command.toLowerCase();
if(!commands.contains(command))
if (!commands.contains(command))
commands.add(command);
return this;
}
public BlacklistStorage remove(String command) {
command = command.toLowerCase();
commands.remove(command);
return this;
}
@@ -186,4 +91,17 @@ public class BlacklistStorage extends StorageTemplate implements Serializable {
getConfig().reload();
commands = (ArrayList<String>) getConfig().getOrSet(getNavigatePath(), commands);
}
private boolean isNegated(String command) {
if (command.isEmpty()) {
return false;
}
boolean negated = command.charAt(0) == '!';
if (!negated && command.length() > 5)
negated = command.charAt(5) == '!';
return negated;
}
}
@@ -0,0 +1,49 @@
package de.rayzs.pat.api.storage.storages;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.api.storage.StorageTemplate;
import de.rayzs.pat.utils.Reflection;
import java.util.ArrayList;
import java.util.List;
public class DisabledServersStorage extends StorageTemplate {
private List<String> servers = new ArrayList<>();
public DisabledServersStorage() {
super(Storage.Files.STORAGE, "disabled-servers");
}
public DisabledServersStorage add(String server) {
server = server.toLowerCase();
if(!servers.contains(server))
servers.add(server);
return this;
}
public DisabledServersStorage remove(String server) {
server = server.toLowerCase();
servers.remove(server);
return this;
}
public boolean isListed(String server) {
if(servers.isEmpty()) return false;
return Storage.isServer(server, servers);
}
public boolean isListEmpty() {
return servers.isEmpty();
}
@Override
public void save() { getConfig().save(); }
@Override
public void load() {
if(!Reflection.isProxyServer()) return;
getConfig().reload();
servers = (ArrayList<String>) getConfig().getOrSet(getNavigatePath(), servers);
}
}
@@ -9,6 +9,7 @@ public abstract class PlaceholderStorage extends StorageTemplate {
public PlaceholderStorage(String request) {
super(Storage.Files.PLACEHOLDERS, request);
this.request = request;
Storage.ConfigSections.PLACEHOLDERS.add(this);
}
@@ -1,23 +1,32 @@
package de.rayzs.pat.plugin;
import de.rayzs.pat.utils.configuration.updater.ConfigUpdater;
import de.rayzs.pat.api.brand.CustomServerBrand;
import de.rayzs.pat.plugin.modules.SubArgsModule;
import de.rayzs.pat.plugin.process.CommandProcess;
import de.rayzs.pat.api.netty.bukkit.BukkitPacketAnalyzer;
import de.rayzs.pat.api.communication.BackendUpdater;
import de.rayzs.pat.utils.adapter.GroupManagerAdapter;
import de.rayzs.pat.utils.configuration.Configurator;
import de.rayzs.pat.utils.configuration.updater.ConfigUpdater;
import de.rayzs.pat.utils.group.TinyGroup;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.utils.adapter.ViaVersionAdapter;
import de.rayzs.pat.api.communication.Communicator;
import de.rayzs.pat.utils.adapter.LuckPermsAdapter;
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.OfflinePlayer;
import org.bukkit.entity.Entity;
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.*;
@@ -25,20 +34,29 @@ import org.bukkit.command.*;
import org.bukkit.plugin.*;
import org.bukkit.Bukkit;
import java.util.*;
import java.util.stream.Collectors;
public class BukkitLoader extends JavaPlugin {
public class BukkitLoader extends JavaPlugin implements PluginLoader {
private static List<String> commands = new ArrayList<>(),
allowedCommands = new ArrayList<>(),
disallowedCommands = new ArrayList<>();
private static Plugin plugin;
private static java.util.logging.Logger logger;
private static boolean loaded = false, checkUpdate = false, suggestions = false;
private static boolean loaded = false, suggestions = false;
private static Map<String, Command> commandsMap = null;
private int updaterTaskId;
private PATSchedulerTask updaterTask;
private final List<String> offlinePlayerNames = new ArrayList<>();
private long lastCommandsLoad = -1;
@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("files\\bukkit-config.yml", "config.yml", false);
Configurator.createResourcedFile("files\\bukkit-storage.yml", "storage.yml", false);
Configurator.createResourcedFile("files\\bukkit-placeholders.yml", "placeholders.yml", false);
Configurator.createResourcedFile("files\\bukkit-custom-responses.yml", "custom-responses.yml", false);
}
@Override
@@ -46,16 +64,22 @@ public class BukkitLoader extends JavaPlugin {
plugin = this;
logger = getLogger();
for (OfflinePlayer offlinePlayerName : Bukkit.getOfflinePlayers()) {
offlinePlayerNames.add(offlinePlayerName.getName());
}
loadCommandMap();
CommandProcess.initialize();
Reflection.initialize(getServer());
ConfigUpdater.initialize();
Storage.CURRENT_VERSION = getDescription().getVersion();
Storage.initialize(this, getDescription().getVersion());
VersionComparer.get().setCurrentVersion(Storage.CURRENT_VERSION);
Storage.loadAll(true);
if(Bukkit.getServer().getPluginManager().getPlugin("PlaceholderAPI") != null)
if (Bukkit.getServer().getPluginManager().getPlugin("PlaceholderAPI") != null)
new PlaceholderHook().register();
MessageTranslator.initialize();
@@ -64,20 +88,21 @@ public class BukkitLoader extends JavaPlugin {
PluginManager manager = getServer().getPluginManager();
if(!Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
if (!Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
loaded = true;
GroupManager.initialize();
BukkitPacketAnalyzer.injectAll();
} else BackendUpdater.handle();
manager.registerEvents(new BukkitPlayerConnectionListener(), this);
manager.registerEvents(new BukkitPlayerListener(), this);
manager.registerEvents(new BukkitBlockCommandListener(), this);
if(Reflection.getMinor() >= 13) {
if (Reflection.getMinor() >= 13) {
suggestions = true;
manager.registerEvents(new BukkitAntiTabListener(), this);
}
if(Reflection.isPaper() && Reflection.getMinor() >= 12)
if (Reflection.isPaper() && Reflection.getMinor() >= 12)
manager.registerEvents(new PaperServerListPing(), this);
registerCommand("proantitab", "pat");
@@ -85,18 +110,29 @@ public class BukkitLoader extends JavaPlugin {
Storage.PLUGIN_OBJECT = this;
if(getServer().getPluginManager().getPlugin("LuckPerms") != null) {
if (getServer().getPluginManager().getPlugin("LuckPerms") != null) {
LuckPermsAdapter.initialize();
Bukkit.getOnlinePlayers().forEach(player -> PermissionUtil.setPlayerPermissions(player.getUniqueId()));
}
if(getServer().getPluginManager().getPlugin("ViaVersion") != null)
final Plugin groupManagerPlugin = getServer().getPluginManager().getPlugin("GroupManager");
if (groupManagerPlugin != null) {
GroupManagerAdapter.initialize(groupManagerPlugin);
Bukkit.getOnlinePlayers().forEach(player -> PermissionUtil.setPlayerPermissions(player.getUniqueId()));
}
if (getServer().getPluginManager().getPlugin("ViaVersion") != null)
ViaVersionAdapter.initialize();
if(Storage.USE_SIMPLECLOUD)
Logger.warning("Detected SimpleCloud and therefore MiniMessages by Kyori are disabled!");
if (Storage.USE_SIMPLECLOUD) {
Logger.warning("Detected SimpleCloud. Therefore, MiniMessages are disabled!");
}
ConfigUpdater.broadcastMissingParts();
ActionHandler.initialize();
SubArgsModule.initialize();
PATScheduler.createScheduler(this::loadAllCommands);
}
@Override
@@ -115,99 +151,221 @@ public class BukkitLoader extends JavaPlugin {
}
}
public static List<String> getPlayerNames() {
List<String> result = new LinkedList<>();
Bukkit.getServer().getOnlinePlayers().forEach(player -> result.add(player.getName()));
return result;
@Override
public void handleReload() {
loadAllCommands();
}
public static UUID getUUIDByName(String playerName) {
Player player = Bukkit.getServer().getPlayer(playerName);
@Override
public boolean doesCommandExist(String command) {
if (commandsMap == null)
return false;
loadAllCommands();
return getAllCommands().contains(command);
}
@Override
public Object getConsoleSender() {
return Bukkit.getConsoleSender();
}
@Override
public Object getPlayerObjByName(String name) {
return Bukkit.getPlayer(name);
}
@Override
public Object getPlayerObjByUUID(UUID uuid) {
return Bukkit.getPlayer(uuid);
}
@Override
public void updateCommandCache() {}
@Override
public HashMap<String, CommandsCache> getCommandsCacheMap() {
return null;
}
@Override
public boolean isPlayerOnline(String playerName) {
return Bukkit.getPlayer(playerName) != null;
}
@Override
public boolean doesPlayerExist(String playerName) {
return isPlayerOnline(playerName) || ArrayUtils.containsIgnoreCase(getPlayerNames(), playerName);
}
@Override
public String getPlayerServerName(UUID uuid) {
return null;
}
@Override
public List<UUID> getPlayerIdsByServer(String server) {
return null;
}
@Override
public List<String> getOnlinePlayerNames(String serverName) {
return getOnlinePlayerNames();
}
@Override
public List<UUID> getPlayerIds() {
return Bukkit.getOnlinePlayers().stream().map(Entity::getUniqueId).collect(Collectors.toList());
}
@Override
public List<String> getOnlinePlayerNames() {
return new ArrayList<>(Bukkit.getServer().getOnlinePlayers().stream().map(Player::getName).toList());
}
@Override
public List<String> getOfflinePlayerNames() {
return offlinePlayerNames;
}
@Override
public List<String> getPlayerNames() {
List<String> playerNames = new ArrayList<>(offlinePlayerNames);
playerNames.addAll(getOnlinePlayerNames());
return playerNames;
}
@Override
public String getNameByUUID(UUID uuid) {
Player player = Bukkit.getPlayer(uuid);
return player != null ? player.getName() : "";
}
@Override
public UUID getUUIDByName(String playerName) {
Player player = Bukkit.getPlayer(playerName);
return player != null ? player.getUniqueId() : null;
}
@Override
public List<String> getServerNames() {
return List.of();
}
public static void delayedPermissionsReload() {
PATScheduler.createScheduler(PermissionUtil::reloadPermissions, 40);
}
public static void userPermissionsReload(UUID uuid) {
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(BukkitLoader.getPlugin(), () -> PermissionUtil.reloadPermissions(uuid));
}
public void startUpdaterTask() {
if (!Storage.ConfigSections.Settings.UPDATE.ENABLED) return;
updaterTaskId = Bukkit.getScheduler().scheduleAsyncRepeatingTask(this, () -> {
String result = new ConnectionBuilder().setUrl("https://www.rayzs.de/proantitab/api/version.php")
.setProperties("ProAntiTab", "4654").connect().getResponse();
if (!Storage.ConfigSections.Settings.UPDATE.ENABLED)
return;
if(result == null) result = "internet";
Storage.NEWER_VERSION = result;
updaterTask = PATScheduler.createAsyncScheduler(() -> {
if (VersionComparer.get().computeComparison())
updaterTask.cancelTask();
if (!Storage.NEWER_VERSION.equals(Storage.CURRENT_VERSION)) {
Bukkit.getScheduler().cancelTask(updaterTaskId);
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;
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);
}
public static void synchronize(CommunicationPackets.PacketBundle packetBundle) {
Storage.LAST_SYNC = System.currentTimeMillis();
Communicator.sendFeedback();
CommunicationPackets.UnknownCommandPacket unknownCommandPacket = packetBundle.getUnknownCommandPacket();
CommunicationPackets.CommandsPacket commandsPacket = packetBundle.getCommandsPacket();
CommunicationPackets.GroupsPacket groupsPacket = packetBundle.getGroupsPacket();
CommunicationPackets.NamespaceCommandsPacket namespaceCommandsPacket = packetBundle.getNamespaceCommandsPacket();
CommunicationPackets.MessagePacket messagePacket = packetBundle.getMessagePacket();
if(!Storage.USE_VELOCITY) {
CommunicationPackets.CommandsPacket commandsPacket = packetBundle.getCommandsPacket();
CommunicationPackets.GroupsPacket groupsPacket = packetBundle.getGroupsPacket();
CommunicationPackets.NamespaceCommandsPacket namespaceCommandsPacket = packetBundle.getNamespaceCommandsPacket();
boolean updatedList = false;
if(Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.ENABLED != namespaceCommandsPacket.isEnabled())
Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.ENABLED = namespaceCommandsPacket.isEnabled();
if (!messagePacket.getBaseBlockedMessage().getLines().isEmpty())
Storage.ConfigSections.Settings.CANCEL_COMMAND.BASE_COMMAND_RESPONSE = messagePacket.getBaseBlockedMessage();
if (commandsPacket.getCommands() == null || commandsPacket.getCommands().isEmpty())
Storage.Blacklist.getBlacklist().setList(new ArrayList<>());
if (!messagePacket.getSubBlockedMessage().getLines().isEmpty())
Storage.ConfigSections.Settings.CANCEL_COMMAND.SUB_COMMAND_RESPONSE = messagePacket.getSubBlockedMessage();
else if (!ArrayUtils.compareStringArrays(Storage.Blacklist.getBlacklist().getCommands(), commandsPacket.getCommands())) {
BukkitAntiTabListener.setChangeStatus();
Storage.Blacklist.getBlacklist().setList(commandsPacket.getCommands());
if (!messagePacket.getPrefix().isEmpty())
Storage.ConfigSections.Messages.PREFIX.PREFIX = messagePacket.getPrefix();
if (Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.ENABLED != namespaceCommandsPacket.isEnabled())
Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.ENABLED = namespaceCommandsPacket.isEnabled();
if (commandsPacket.getCommands() == null || commandsPacket.getCommands().isEmpty())
Storage.Blacklist.getBlacklist().setList(new ArrayList<>());
else if (!ArrayUtils.compareStringArrays(Storage.Blacklist.getBlacklist().getCommands(), commandsPacket.getCommands())) {
updatedList = true;
Storage.Blacklist.getBlacklist().setList(commandsPacket.getCommands());
}
if (Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED != commandsPacket.turnBlacklistToWhitelistEnabled())
Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED = commandsPacket.turnBlacklistToWhitelistEnabled();
Map<String, List<String>> cpyCache = new HashMap<>();
GroupManager.getGroups().forEach(group -> {
cpyCache.put(group.getGroupName(), group.getCommands());
});
GroupManager.clearAllGroups();
for (TinyGroup group : groupsPacket.getGroups()) {
List<String> currentExistingList = cpyCache.get(group.getGroupName());
if (
!updatedList
&& currentExistingList != null
&& !ArrayUtils.compareStringArrays(currentExistingList, group.getCommands())
) {
updatedList = true;
}
if (Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED != commandsPacket.turnBlacklistToWhitelistEnabled())
Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED = commandsPacket.turnBlacklistToWhitelistEnabled();
GroupManager.clearAllGroups();
groupsPacket.getGroups().forEach(group -> GroupManager.setGroup(group.getGroupName(), group.getPriority(), group.getCommands()));
GroupManager.setGroup(group.getGroupName(), group.getPriority(), group.getCommands());
}
Storage.ConfigSections.Settings.CUSTOM_UNKNOWN_COMMAND.MESSAGE = unknownCommandPacket.getMessage();
if(Storage.ConfigSections.Settings.CUSTOM_UNKNOWN_COMMAND.ENABLED != unknownCommandPacket.isEnabled())
if (Storage.ConfigSections.Settings.CUSTOM_UNKNOWN_COMMAND.ENABLED != unknownCommandPacket.isEnabled())
Storage.ConfigSections.Settings.CUSTOM_UNKNOWN_COMMAND.ENABLED = unknownCommandPacket.isEnabled();
if(!loaded) loaded = true;
if (!loaded)
loaded = true;
if(Reflection.getMinor() < 16) return;
if(Storage.USE_VELOCITY)
if (Reflection.getMinor() >= 13 && updatedList) {
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());
PATEventHandler.callReceiveSyncEvents(packetBundle);
}
public static boolean doesCommandExist(String command, boolean replace) {
if(commandsMap == null) return false;
if(replace) command = StringUtils.replaceFirst(command, "/", "");
return getAllCommands().contains(command);
public static List<String> getAllCommands() {
return new ArrayList<>(commands);
}
public static List<String> getAllowedCommands() {
return new ArrayList<>(allowedCommands);
}
public static List<String> getDisallowedCommands() {
return disallowedCommands;
}
@Override
public List<String> getPluginNames() {
List<String> pluginNames = new ArrayList<>();
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
PluginDescriptionFile description = plugin.getDescription();
pluginNames.add(description.getName() + " (" + description.getVersion() + ")");
}
return pluginNames;
}
private void loadCommandMap() {
@@ -218,44 +376,67 @@ public class BukkitLoader extends JavaPlugin {
SimpleCommandMap simpleCommandMap = (SimpleCommandMap) commandMapField.get(Bukkit.getPluginManager());
Field knownCommandsField = SimpleCommandMap.class.getDeclaredField("knownCommands");
knownCommandsField.setAccessible(true);
commandsMap = (Map<String, Command>)knownCommandsField.get(simpleCommandMap);
commandsMap = (Map<String, Command>) knownCommandsField.get(simpleCommandMap);
}
}catch (Throwable ignored) { }
} catch (Throwable ignored) { }
if(commandsMap == null)
if (commandsMap == null) {
Logger.warning("Failed to get server commands!");
}
}
public static List<String> getNotBlockedCommands() {
List<String> commands = new ArrayList<>();
Bukkit.getHelpMap().getHelpTopics().stream()
.filter(topic -> !topic.getName().contains(":") && topic.getName().startsWith("/") && !Storage.Blacklist.getBlacklist().isListed(topic.getName().replaceFirst("/", "")))
.forEach(topic -> commands.add(topic.getName().replaceFirst("/", "")));
return commands;
private void loadAllCommands() {
if (lastCommandsLoad != -1 && System.currentTimeMillis() - lastCommandsLoad < 1000)
return;
List<String> result = new ArrayList<>();
if (commandsMap == null) {
result.addAll(
Bukkit.getHelpMap().getHelpTopics().stream()
.map(topic -> {
String name = topic.getName();
if (name.startsWith("/"))
name = name.substring(1);
return name;
}).toList()
);
return;
}
commandsMap.entrySet().forEach(entry -> {
String key = entry.getKey();
Command command = entry.getValue();
result.add(key);
if (!command.getAliases().isEmpty()) {
result.addAll(command.getAliases());
}
});
boolean turn = Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED;
List<String> allowedCommands = new ArrayList<>(result).stream().filter(command -> {
if (turn) {
return Storage.Blacklist.getBlacklist().isListed(command);
} else {
return !Storage.Blacklist.getBlacklist().isListed(command);
}
}).toList();
lastCommandsLoad = System.currentTimeMillis();
BukkitLoader.commands = result;
BukkitLoader.allowedCommands = allowedCommands;
BukkitLoader.disallowedCommands = commands.stream().filter(command -> !allowedCommands.contains(command)).toList();
}
public static List<String> getAllCommands() {
if(commandsMap == null) return getNotBlockedCommands();
List<String> result = new LinkedList<>();
for (String command : commandsMap.keySet()) if(!result.contains(command)) result.add(command);
if(Reflection.getMinor() == 20 && Reflection.getRelease() >= 5 || Reflection.getMinor() >= 21)
for (String s : commandsMap.keySet())
if (commandsMap.containsKey(s)) {
if(!commandsMap.get(s).getAliases().isEmpty()) {
for (String alias : commandsMap.get(s).getAliases())
if (!result.contains(alias)) result.add(alias);
} else if(Bukkit.getServer().getCommandAliases().get(s) != null)
for (String alias : Bukkit.getServer().getCommandAliases().get(s))
if (!result.contains(alias)) result.add(alias);
}
return result;
}
public static boolean useSuggestions() {
return suggestions;
}
@@ -1,19 +1,24 @@
package de.rayzs.pat.plugin;
import de.rayzs.pat.utils.configuration.updater.ConfigUpdater;
import de.rayzs.pat.api.brand.CustomServerBrand;
import de.rayzs.pat.plugin.process.CommandProcess;
import de.rayzs.pat.plugin.modules.SubArgsModule;
import de.rayzs.pat.api.netty.proxy.BungeePacketAnalyzer;
import de.rayzs.pat.utils.configuration.Configurator;
import de.rayzs.pat.utils.configuration.updater.ConfigUpdater;
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;
@@ -21,18 +26,21 @@ import net.md_5.bungee.api.plugin.*;
import de.rayzs.pat.utils.*;
import java.util.*;
public class BungeeLoader extends Plugin {
public class BungeeLoader extends Plugin implements PluginLoader {
private ScheduledTask updaterTask;
private static Plugin plugin;
private static java.util.logging.Logger logger;
private ScheduledTask updaterTask;
private static boolean checkUpdate = false;
private static final HashMap<String, CommandsCache> commandsCacheMap = new HashMap<>();
@Override
public void onLoad() {
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("files\\proxy-config.yml", "config.yml", false);
Configurator.createResourcedFile("files\\proxy-storage.yml", "storage.yml", false);
Configurator.createResourcedFile("files\\proxy-placeholders.yml", "placeholders.yml", false);
Configurator.createResourcedFile("files\\proxy-custom-responses.yml", "custom-responses.yml", false);
}
@Override
@@ -40,11 +48,14 @@ public class BungeeLoader extends Plugin {
plugin = this;
logger = getLogger();
CommandProcess.initialize();
Reflection.initialize(getProxy());
ConfigUpdater.initialize();
Storage.USE_SIMPLECLOUD = Reflection.doesClassExist("eu.thesimplecloud.plugin.startup.CloudPlugin");
Storage.CURRENT_VERSION = getDescription().getVersion();
Storage.initialize(this, getDescription().getVersion());
VersionComparer.get().setCurrentVersion(Storage.CURRENT_VERSION);
Storage.loadAll(true);
@@ -61,11 +72,13 @@ public class BungeeLoader extends Plugin {
manager.registerListener(this, new BungeeBlockCommandListener());
manager.registerListener(this, new BungeePingListener());
if(Reflection.isPaper())
if (Reflection.isPaper())
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 +95,13 @@ public class BungeeLoader extends Plugin {
BungeePacketAnalyzer.injectAll();
ConfigUpdater.broadcastMissingParts();
ActionHandler.initialize();
SubArgsModule.initialize();
// Reload proxy commands after 1, 5, and 15 seconds.
for (int i : new Integer[] { 1, 5, 15 }) {
ProxyServer.getInstance().getScheduler().schedule(this, BungeePacketAnalyzer::loadProxyCommands, i, TimeUnit.SECONDS);
}
}
@Override
@@ -97,43 +117,165 @@ public class BungeeLoader extends Plugin {
}
}
public static List<String> getPlayerNames() {
List<String> result = new LinkedList<>();
ProxyServer.getInstance().getPlayers().forEach(player -> result.add(player.getName()));
return result;
@Override
public void handleReload() {
BungeePacketAnalyzer.loadProxyCommands();
}
public static UUID getUUIDByName(String playerName) {
ProxiedPlayer proxiedPlayer = ProxyServer.getInstance().getPlayer(playerName);
return proxiedPlayer != null ? proxiedPlayer.getUniqueId() : null;
@Override
public boolean doesCommandExist(String command) {
return false;
}
@Override
public Object getConsoleSender() {
return ProxyServer.getInstance().getConsole();
}
@Override
public Object getPlayerObjByName(String name) {
return plugin.getProxy().getPlayer(name);
}
@Override
public Object getPlayerObjByUUID(UUID uuid) {
return plugin.getProxy().getPlayer(uuid);
}
@Override
public HashMap<String, CommandsCache> getCommandsCacheMap() {
return commandsCacheMap;
}
@Override
public void updateCommandCache() {
new ArrayList<>(commandsCacheMap.values()).forEach(CommandsCache::reset);
}
@Override
public String getPlayerServerName(UUID uuid) {
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid);
if (player == null || player.getServer() == null || player.getServer().getInfo() == null)
return null;
return player.getServer().getInfo().getName();
}
@Override
public List<UUID> getPlayerIds() {
return new ArrayList<>(ProxyServer.getInstance().getPlayers().stream().map(ProxiedPlayer::getUniqueId).toList());
}
@Override
public List<UUID> getPlayerIdsByServer(String server) {
List<UUID> uuids = new ArrayList<>();
getServerNames().stream()
.filter(serverName -> Storage.isServer(server, serverName))
.forEach(serverName -> {
ServerInfo serverInfo = ProxyServer.getInstance().getServerInfo(serverName);
if (serverInfo == null)
return;
uuids.addAll(serverInfo.getPlayers().stream().map(ProxiedPlayer::getUniqueId).toList());
});
return uuids;
}
@Override
public List<String> getOnlinePlayerNames(String serverName) {
return new ArrayList<>(ProxyServer.getInstance().getPlayers().stream()
.filter(player -> {
if (player == null || player.getServer() == null || player.getServer().getInfo() == null)
return false;
return player.getServer().getInfo().getName().equalsIgnoreCase(serverName);
}).map(ProxiedPlayer::getName).toList());
}
@Override
public boolean isPlayerOnline(String playerName) {
return ProxyServer.getInstance().getPlayer(playerName) != null;
}
@Override
public boolean doesPlayerExist(String playerName) {
return isPlayerOnline(playerName);
}
@Override
public List<String> getOnlinePlayerNames() {
return new ArrayList<>(ProxyServer.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).toList());
}
@Override
public List<String> getOfflinePlayerNames() {
return new ArrayList<>(ProxyServer.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).toList());
}
@Override
public List<String> getPlayerNames() {
return new ArrayList<>(ProxyServer.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).toList());
}
@Override
public String getNameByUUID(UUID uuid) {
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid);
return player != null ? player.getName() : "";
}
@Override
public UUID getUUIDByName(String playerName) {
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(playerName);
return player != null ? player.getUniqueId() : null;
}
@Override
public List<String> getServerNames() {
return new ArrayList<>(ProxyServer.getInstance().getServers().keySet().stream().toList());
}
@Override
public List<String> getPluginNames() {
List<String> pluginNames = new ArrayList<>();
for (Plugin plugin : ProxyServer.getInstance().getPluginManager().getPlugins()) {
PluginDescription description = plugin.getDescription();
pluginNames.add(description.getName() + " (" + description.getVersion() + ")");
}
return pluginNames;
}
public void startUpdaterTask() {
if (!Storage.ConfigSections.Settings.UPDATE.ENABLED) return;
updaterTask = getProxy().getScheduler().schedule(this, () -> {
String result = new ConnectionBuilder().setUrl("https://www.rayzs.de/proantitab/api/version.php")
.setProperties("ProAntiTab", "4654").connect().getResponse();
Storage.NEWER_VERSION = result;
if (!Storage.ConfigSections.Settings.UPDATE.ENABLED)
return;
if (!Storage.NEWER_VERSION.equals(Storage.CURRENT_VERSION)) {
updaterTask = getProxy().getScheduler().schedule(this, () -> {
if (VersionComparer.get().computeComparison())
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);
}
} else {
if(!checkUpdate) {
checkUpdate = true;
Storage.ConfigSections.Settings.UPDATE.UPDATED.getLines().forEach(Logger::warning);
}
}
}, 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;
}
@@ -141,12 +283,4 @@ public class BungeeLoader extends Plugin {
public static java.util.logging.Logger getPluginLogger() {
return logger;
}
public static List<String> getServerNames() {
List<String> servers = new LinkedList<>();
for (String serverName : ProxyServer.getInstance().getServers().keySet())
servers.add(serverName.toLowerCase());
return servers;
}
}
@@ -0,0 +1,43 @@
package de.rayzs.pat.plugin;
import de.rayzs.pat.utils.CommandsCache;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
public interface PluginLoader {
void handleReload();
boolean doesCommandExist(String command);
HashMap<String, CommandsCache> getCommandsCacheMap();
void updateCommandCache();
List<String> getServerNames();
Object getConsoleSender();
Object getPlayerObjByName(String name);
Object getPlayerObjByUUID(UUID uuid);
UUID getUUIDByName(String playerName);
String getNameByUUID(UUID uuid);
String getPlayerServerName(UUID uuid);
boolean isPlayerOnline(String playerName);
boolean doesPlayerExist(String playerName);
List<String> getOnlinePlayerNames(String server);
List<UUID> getPlayerIdsByServer(String server);
List<UUID> getPlayerIds();
List<String> getPlayerNames();
List<String> getOnlinePlayerNames();
List<String> getOfflinePlayerNames();
List<String> getPluginNames();
}
@@ -2,51 +2,68 @@ package de.rayzs.pat.plugin;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.proxy.Player;
import de.rayzs.pat.utils.configuration.updater.ConfigUpdater;
import com.velocitypowered.api.proxy.ServerConnection;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import de.rayzs.pat.api.brand.CustomServerBrand;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.plugin.modules.SubArgsModule;
import de.rayzs.pat.plugin.process.CommandProcess;
import de.rayzs.pat.utils.CommandsCache;
import de.rayzs.pat.plugin.metrics.impl.VelocityMetrics;
import com.velocitypowered.api.scheduler.ScheduledTask;
import de.rayzs.pat.utils.configuration.Configurator;
import de.rayzs.pat.utils.configuration.updater.ConfigUpdater;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.plugin.commands.VelocityCommand;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.api.communication.Communicator;
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.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 = "2.0.20",
authors = "Rayzs_YT",
description = "Hide more then just plugins. Hide almost everything!",
description = "Hide more than just your plugins. Hide almost everything!",
url = "https://www.rayzs.de/products/proantitab/page",
dependencies = {
@Dependency(id = "luckperms", optional = true),
@Dependency(id = "papiproxybridge", optional = true)
})
public class VelocityLoader {
public class VelocityLoader implements PluginLoader {
private static VelocityLoader instance;
private static ProxyServer server;
private static org.slf4j.Logger logger;
private final EventManager manager;
private final VelocityMetrics.Factory metricsFactory;
private ScheduledTask updaterTask;
private static boolean checkUpdate = false;
private static final HashMap<String, CommandsCache> commandsCacheMap = new HashMap<>();
@Inject
public VelocityLoader(ProxyServer server, VelocityMetrics.Factory metricsFactory) {
public VelocityLoader(ProxyServer server, org.slf4j.Logger logger, VelocityMetrics.Factory metricsFactory) {
VelocityLoader.instance = this;
VelocityLoader.server = server;
VelocityLoader.logger = logger;
this.manager = server.getEventManager();
this.metricsFactory = metricsFactory;
}
@@ -55,39 +72,43 @@ public class VelocityLoader {
public void onProxyInitialization(ProxyInitializeEvent event) {
PluginContainer pluginContainer = server.getPluginManager().getPlugin("proantitab").get();
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("files\\proxy-config.yml", "config.yml", false);
Configurator.createResourcedFile("files\\proxy-storage.yml", "storage.yml", false);
Configurator.createResourcedFile("files\\proxy-placeholders.yml", "placeholders.yml", false);
Configurator.createResourcedFile("files\\proxy-custom-responses.yml", "custom-responses.yml", false);
CommandProcess.initialize();
Reflection.initialize(server);
ConfigUpdater.initialize();
Storage.USE_SIMPLECLOUD = Reflection.doesClassExist("eu.thesimplecloud.plugin.startup.CloudPlugin");
Storage.CURRENT_VERSION = pluginContainer.getDescription().getVersion().get();
Storage.initialize(this, pluginContainer.getDescription().getVersion().get());
VersionComparer.get().setCurrentVersion(Storage.CURRENT_VERSION);
Storage.loadAll(true);
MessageTranslator.initialize();
CustomServerBrand.initialize();
GroupManager.initialize();
metricsFactory.make(this, 21638);
server.getCommandManager().register("bpat", new VelocityCommand(), "bungeeproantitab");
server.getEventManager().register(this, new VelocityBlockCommandListener(server));
server.getEventManager().register(this, new VelocityBlockCommandListener());
server.getEventManager().register(this, new VelocityAntiTabListener(server));
server.getEventManager().register(this, new VelocityConnectionListener(server, this));
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;
if(server.getPluginManager().getPlugin("luckperms").isPresent())
if (server.getPluginManager().getPlugin("luckperms").isPresent())
LuckPermsAdapter.initialize();
if(server.getPluginManager().getPlugin("papiproxybridge").isPresent()) {
if (server.getPluginManager().getPlugin("papiproxybridge").isPresent()) {
Storage.USE_PAPIPROXYBRIDGE = true;
Logger.info("Successfully hooked into PAPIProxyBridge!");
}
@@ -96,50 +117,185 @@ public class VelocityLoader {
Logger.warning("Detected SimpleCloud and therefore MiniMessages by Kyori are disabled!");
ConfigUpdater.broadcastMissingParts();
ActionHandler.initialize();
SubArgsModule.initialize();
}
public static org.slf4j.Logger getPluginLogger() {
return logger;
}
public static void delayedPermissionsReload() {
server.getScheduler().buildTask(VelocityLoader.instance, () -> {
PermissionUtil.reloadPermissions();
VelocityAntiTabListener.updateCommands();
Storage.getLoader().updateCommandCache();
}).delay(1, TimeUnit.SECONDS).schedule();
}
public static List<String> getPlayerNames() {
List<String> result = new LinkedList<>();
server.getAllPlayers().forEach(player -> result.add(player.getUsername()));
return result;
public static void delayedPlayerReload(UUID uuid) {
server.getScheduler().buildTask(VelocityLoader.instance, () -> {
String serverName = Storage.getLoader().getPlayerServerName(uuid);
List<String> commands = new ArrayList<>(SubArgsModule.getServerCommands(serverName));
commands.addAll(SubArgsModule.getGroupCommands(uuid, serverName));
PATEventHandler.callUpdatePlayerCommandsEvents(uuid, commands, true);
}).delay(1, TimeUnit.SECONDS).schedule();
}
public static UUID getUUIDByName(String playerName) {
if (!server.getPlayer(playerName).isPresent()) return null;
return server.getPlayer(playerName).get().getUniqueId();
@Override
public void handleReload() {}
@Override
public boolean doesCommandExist(String command) {
return false;
}
@Override
public Object getConsoleSender() {
return server.getConsoleCommandSource();
}
@Override
public Object getPlayerObjByName(String name) {
return server.getPlayer(name).orElse(null);
}
@Override
public Object getPlayerObjByUUID(UUID uuid) {
return server.getPlayer(uuid).orElse(null);
}
@Override
public void updateCommandCache() {
new ArrayList<>(commandsCacheMap.values()).forEach(CommandsCache::reset);
}
@Override
public HashMap<String, CommandsCache> getCommandsCacheMap() {
return commandsCacheMap;
}
@Override
public boolean isPlayerOnline(String playerName) {
return server.getPlayer(playerName).isPresent();
}
@Override
public boolean doesPlayerExist(String playerName) {
return isPlayerOnline(playerName);
}
@Override
public List<UUID> getPlayerIdsByServer(String serverName) {
List<UUID> uuids = new ArrayList<>();
getServerNames().stream()
.filter(originServerName -> Storage.isServer(serverName, originServerName))
.forEach(originServerName -> {
Optional<RegisteredServer> optionalRegServerInfo = server.getServer(serverName);
if (optionalRegServerInfo.isEmpty())
return;
RegisteredServer regServerInfo = optionalRegServerInfo.get();
uuids.addAll(regServerInfo.getPlayersConnected().stream().map(Player::getUniqueId).toList());
});
return uuids;
}
@Override
public String getPlayerServerName(UUID uuid) {
Optional<Player> optPlayer = server.getPlayer(uuid);
if (optPlayer.isEmpty())
return null;
Player player = optPlayer.get();
Optional<ServerConnection> optConnection = player.getCurrentServer();
if (optConnection.isEmpty())
return null;
ServerConnection connection = optConnection.get();
return connection.getServer().getServerInfo().getName();
}
@Override
public List<UUID> getPlayerIds() {
return server.getAllPlayers().stream().map(Player::getUniqueId).toList();
}
@Override
public List<String> getOnlinePlayerNames(String serverName) {
return server.getAllPlayers().stream()
.filter(player -> {
Optional<ServerConnection> optConnection = player.getCurrentServer();
if (optConnection.isEmpty())
return false;
ServerConnection connection = optConnection.get();
return connection.getServer().getServerInfo().getName().equalsIgnoreCase(serverName);
}).map(Player::getUsername).toList();
}
@Override
public List<String> getOnlinePlayerNames() {
return server.getAllPlayers().stream().map(Player::getUsername).toList();
}
@Override
public List<String> getOfflinePlayerNames() {
return server.getAllPlayers().stream().map(Player::getUsername).toList();
}
public List<String> getPlayerNames() {
return server.getAllPlayers().stream().map(Player::getUsername).toList();
}
@Override
public String getNameByUUID(UUID uuid) {
Player player = server.getPlayer(uuid).orElse(null);
return player != null ? player.getUsername() : "";
}
@Override
public UUID getUUIDByName(String playerName) {
Player player = server.getPlayer(playerName).orElse(null);
return player != null ? player.getUniqueId() : null;
}
@Override
public List<String> getServerNames() {
return new ArrayList<>(server.getAllServers().stream().map(registeredServer -> registeredServer.getServerInfo().getName()).toList());
}
@Override
public List<String> getPluginNames() {
List<String> pluginNames = new ArrayList<>();
for (PluginContainer plugin : server.getPluginManager().getPlugins()) {
PluginDescription description = plugin.getDescription();
String pluginName = description.getName().orElse("/");
String version = description.getVersion().orElse("/");
pluginNames.add(pluginName + " (" + version + ")");
}
return pluginNames;
}
public void startUpdaterTask() {
if (!Storage.ConfigSections.Settings.UPDATE.ENABLED) return;
updaterTask = server.getScheduler().buildTask(this, () -> {
String result = new ConnectionBuilder().setUrl("https://www.rayzs.de/proantitab/api/version.php")
.setProperties("ProAntiTab", "4654").connect().getResponse();
Storage.NEWER_VERSION = result;
if (!Storage.NEWER_VERSION.equals(Storage.CURRENT_VERSION)) {
if (VersionComparer.get().computeComparison())
updaterTask.cancel();
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());
}
} else {
if(!checkUpdate) {
checkUpdate = true;
MessageTranslator.send(server.getConsoleCommandSource(), Storage.ConfigSections.Settings.UPDATE.UPDATED.getLines());
}
}
}).delay(1, TimeUnit.SECONDS).repeat(Storage.ConfigSections.Settings.UPDATE.PERIOD, TimeUnit.SECONDS).schedule();
}
@@ -150,10 +306,4 @@ public class VelocityLoader {
public static VelocityLoader getInstance() {
return instance;
}
public static List<String> getServerNames() {
List<String> servers = new ArrayList<>();
server.getAllServers().forEach(server -> servers.add(server.getServerInfo().getName().toLowerCase()));
return servers;
}
}
@@ -8,19 +8,20 @@ import java.util.List;
public class BukkitCommand implements CommandExecutor, TabCompleter {
@Override
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) {
public boolean onCommand(CommandSender commandSender, Command command, String label, String[] strings) {
if(commandSender instanceof Player) {
Player player = (Player) commandSender;
CommandProcess.handleCommand(player, strings, s);
CommandProcess.handleCommand(player, strings, label);
return true;
}
CommandProcess.handleCommand(commandSender, strings, s);
CommandProcess.handleCommand(commandSender, strings, label);
return true;
}
@Override
public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String[] strings) {
public List<String> onTabComplete(CommandSender commandSender, Command command, String label, String[] strings) {
return CommandProcess.handleTabComplete(commandSender, strings);
}
}
@@ -4,7 +4,7 @@ import de.rayzs.pat.plugin.process.CommandProcess;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.plugin.*;
public class BungeeCommand extends Command implements TabExecutor {
public class BungeeCommand extends Command implements TabExecutor {
public BungeeCommand(String name) {
super(name);
@@ -5,7 +5,6 @@ import org.bukkit.event.player.PlayerCommandSendEvent;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.utils.adapter.ViaVersionAdapter;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.BukkitLoader;
import org.bukkit.entity.Player;
@@ -24,71 +23,38 @@ public class BukkitAntiTabListener implements Listener {
UUID uuid = player.getUniqueId();
String uuidSubstring = uuid.toString().substring(uuid.toString().length() - 5);
if(Storage.USE_VELOCITY || player.isOp()) {
Logger.debug("Doesn't even tried to create the commands list for player with uuid " + uuidSubstring + ". (Veloctiy? " + Storage.USE_VELOCITY + ". OP? " + player.isOp() + ")");
if (Storage.USE_VELOCITY || player.isOp()) {
return;
}
if(!BukkitLoader.isLoaded()) {
if (!BukkitLoader.isLoaded()) {
event.getCommands().clear();
Logger.debug("Doesn't even tried to create the commands list for player with uuid " + uuidSubstring + ". (not loaded)");
return;
}
if(event.getCommands().size() == 0) {
Logger.debug("No available commands to filter! Ignoring rest of the code until at least one command is listed in there.");
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED)
return;
if (event.getCommands().isEmpty()) {
return;
}
List<String> allCommands = getCommands();
COMMANDS_CACHE.handleCommands(allCommands);
if (PermissionUtil.hasBypassPermission(player)) {
Logger.debug("Player with uuid " + uuidSubstring + " skipped the commands-list creation due to its permissions.");
return;
}
if(Storage.USE_VIAVERSION)
if(Reflection.getMinor() >= 16 && ViaVersionAdapter.getPlayerProtocol(uuid) < 754)
event.getCommands().clear();
final List<String> playerCommands = COMMANDS_CACHE.getPlayerCommands(new ArrayList<>(event.getCommands()), player, player.getUniqueId());
FilteredSuggestionEvent filteredSuggestionEvent = PATEventHandler.callFilteredSuggestionEvents(player, playerCommands);
final List<String> playerCommands = COMMANDS_CACHE.getPlayerCommands(event.getCommands(), player, player.getUniqueId());
event.getCommands().clear();
FilteredSuggestionEvent filteredSuggestionEvent = PATEventHandler.call(uuid, playerCommands);
if(filteredSuggestionEvent.isCancelled()) return;
if (filteredSuggestionEvent.isCancelled())
return;
event.getCommands().addAll(filteredSuggestionEvent.getSuggestions());
Logger.debug("Player with uuid " + uuidSubstring + " has a total of " + playerCommands.size() + " commands.");
}
public static void updateCommands(Player player) {
if(notUpdatablePlayer(player.getUniqueId())) return;
if(Reflection.getMinor() >= 16) player.updateCommands();
}
public static void updateCommands() {
if(Reflection.getMinor() >= 16) Bukkit.getOnlinePlayers().forEach(BukkitAntiTabListener::updateCommands);
}
public static void setChangeStatus() {
COMMANDS_CACHE.updateChangeState();
}
public static void handleTabCompletion(List<String> commands) {
if(Storage.USE_VELOCITY) return;
COMMANDS_CACHE.reset();
Bukkit.getOnlinePlayers().forEach(player -> handleTabCompletion(player, commands));
}
public static void handleTabCompletion() {
COMMANDS_CACHE.reset();
Bukkit.getOnlinePlayers().forEach(BukkitAntiTabListener::handleTabCompletion);
}
public static void handleTabCompletion(Player player) {
handleTabCompletion(player, getCommands());
}
public static List<String> getCommands() {
@@ -96,33 +62,45 @@ public class BukkitAntiTabListener implements Listener {
? Storage.Blacklist.getBlacklist().getCommands() : BukkitLoader.getAllCommands();
}
public static void handleTabCompletion(UUID uuid) {
if(notUpdatablePlayer(uuid)) return;
private static boolean notUpdatablePlayer(UUID uuid) {
return Storage.USE_VIAVERSION && Reflection.getMinor() >= 16 && ViaVersionAdapter.getPlayerProtocol(uuid) < 754;
}
// --------------- LUCKPERMS SECTIONS --------------- //
public static void updateCommands() {
Bukkit.getOnlinePlayers().forEach(BukkitAntiTabListener::updateCommands);
}
public static void updateCommands(Player player) {
if (Reflection.getMinor() >= 13 && !notUpdatablePlayer(player.getUniqueId()))
player.updateCommands();
}
// --------------- UPDATE SECTIONS --------------- //
public static void handleTabCompletion() {
COMMANDS_CACHE.reset();
Bukkit.getOnlinePlayers().forEach(BukkitAntiTabListener::handleTabCompletion);
}
public static void handleTabCompletion(UUID uuid) {
Player player = Bukkit.getPlayer(uuid);
if(player == null) return;
if (player == null)
return;
handleTabCompletion(player);
}
public static void handleTabCompletion(UUID uuid, List<String> commands) {
if(notUpdatablePlayer(uuid)) return;
Player player = Bukkit.getPlayer(uuid);
if(player == null) return;
handleTabCompletion(player, commands);
}
public static void luckpermsNetworkSync() {
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(BukkitLoader.getPlugin(), PermissionUtil::reloadPermissions, 40);
}
public static void luckpermsNetworkUserSync(UUID uuid) {
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(BukkitLoader.getPlugin(), () -> PermissionUtil.reloadPermissions(uuid));
public static void handleTabCompletion(Player player) {
handleTabCompletion(player, getCommands());
}
public static void handleTabCompletion(Player player, List<String> commands) {
if(Storage.USE_VELOCITY) return;
if(notUpdatablePlayer(player.getUniqueId())) return;
if (notUpdatablePlayer(player.getUniqueId()))
return;
List<String> dummy = new ArrayList<>(commands);
PlayerCommandSendEvent event = new PlayerCommandSendEvent(player, dummy);
@@ -130,11 +108,4 @@ public class BukkitAntiTabListener implements Listener {
updateCommands(player);
}
private static boolean notUpdatablePlayer(UUID uuid) {
if(Storage.USE_VIAVERSION)
return Reflection.getMinor() >= 16 && ViaVersionAdapter.getPlayerProtocol(uuid) < 754;
return false;
}
}
@@ -1,18 +1,22 @@
package de.rayzs.pat.plugin.listeners.bukkit;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.event.events.ExecuteCommandEvent;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.BukkitLoader;
import de.rayzs.pat.utils.StringUtils;
import org.bukkit.entity.Player;
import de.rayzs.pat.api.event.*;
import org.bukkit.event.*;
import java.util.List;
import org.bukkit.*;
public class BukkitBlockCommandListener implements Listener {
@@ -20,11 +24,20 @@ public class BukkitBlockCommandListener implements Listener {
public void onUnknownCommandRecognition(PlayerCommandPreprocessEvent event) {
Player player = event.getPlayer();
World world = player.getWorld();
String rawCommand = StringUtils.getFirstArg(event.getMessage()), command = StringUtils.replaceFirst(rawCommand, "/", "");
if(!Storage.ConfigSections.Settings.CUSTOM_UNKNOWN_COMMAND.ENABLED || event.isCancelled()) return;
if(BukkitLoader.doesCommandExist(command, false)) return;
if(Bukkit.getHelpMap().getHelpTopic(rawCommand) != null) return;
String rawCommand = StringUtils.getFirstArg(event.getMessage()),
command = rawCommand.substring(1);
if (!Storage.ConfigSections.Settings.CUSTOM_UNKNOWN_COMMAND.ENABLED || event.isCancelled()) return;
if (PermissionUtil.hasBypassPermission(player))
return;
if (Storage.getLoader().doesCommandExist(command))
return;
if (Bukkit.getHelpMap().getHelpTopic(rawCommand) != null)
return;
event.setCancelled(true);
MessageTranslator.send(player, Storage.ConfigSections.Settings.CUSTOM_UNKNOWN_COMMAND.MESSAGE, "%command%", command, "%world%", world.getName());
@@ -33,107 +46,81 @@ public class BukkitBlockCommandListener implements Listener {
@EventHandler (priority = EventPriority.LOWEST)
public void onPlayerCommandProcess(PlayerCommandPreprocessEvent event) {
Player player = event.getPlayer();
final String commandFirstArg = StringUtils.getFirstArg(event.getMessage());
if (Storage.ConfigSections.Settings.AUTO_LOWERCASE_COMMANDS.isCommand(commandFirstArg)) {
String command = event.getMessage();
if (command.contains(" ")) {
String[] args = command.split(" ");
args[0] = args[0].toLowerCase();
command = String.join(" ", args);
} else command = command.toLowerCase();
if (!commandFirstArg.equals(command)) {
player.chat(command);
event.setCancelled(true);
return;
}
}
World world = player.getWorld();
String rawCommand = event.getMessage(), command = rawCommand, worldName = world.getName();
String command = event.getMessage(),
worldName = world.getName();
command = StringUtils.replaceFirst(command, "/", "");
boolean bypassPermission = PermissionUtil.hasBypassPermission(player, command);
command = command.substring(1);
command = StringUtils.getFirstArg(command);
command = StringUtils.replaceTriggers(command, "", "\\", "<", ">", "&");
List<String> notificationMessage = MessageTranslator.replaceMessageList(Storage.ConfigSections.Messages.NOTIFICATION.ALERT, "%player%", player.getName(), "%command%", command, "%world%", worldName);
final String displayName = StringUtils.replaceTriggers(command, "", "\\", "<", ">", "&");
//command = command.toLowerCase();
if(Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isCommand(command) && !PermissionUtil.hasBypassPermission(player, command)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, 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);
Storage.NOTIFY_PLAYERS.stream().filter(uuid -> Bukkit.getServer().getPlayer(uuid) != null).forEach(uuid -> {
Player target = Bukkit.getServer().getPlayer(uuid);
MessageTranslator.send(target, notificationMessage);
});
List<String> notificationMessage = MessageTranslator.replaceMessageList(
Storage.ConfigSections.Messages.NOTIFICATION.ALERT,
"%player%", player.getName(),
"%command%", displayName,
"%world%", worldName);
if (bypassPermission)
return;
}
if(Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(command) && !PermissionUtil.hasBypassPermission(player, command)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, 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);
Storage.NOTIFY_PLAYERS.stream().filter(uuid -> Bukkit.getServer().getPlayer(uuid) != null).forEach(uuid -> {
Player target = Bukkit.getServer().getPlayer(uuid);
MessageTranslator.send(target, notificationMessage);
});
if (!Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED)
return;
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED)
return;
}
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);
if (!Storage.Blacklist.canPlayerAccessChat(player, command)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(
player,
event.getMessage(),
true,
!Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED
);
if(Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED) {
if (executeCommandEvent.isBlocked()) {
event.setCancelled(true);
if (!executeCommandEvent.doesNotify())
return;
if (Storage.SEND_CONSOLE_NOTIFICATION)
Logger.info(notificationMessage);
Storage.NOTIFY_PLAYERS.stream().filter(uuid -> Bukkit.getServer().getPlayer(uuid) != null).forEach(uuid -> {
Player target = Bukkit.getServer().getPlayer(uuid);
MessageTranslator.send(target, notificationMessage);
});
if(Storage.Blacklist.isListed(command, true)) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
return;
}
if(PermissionUtil.hasBypassPermission(player, command, false)) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
if (executeCommandEvent.isCancelled())
return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
if(executeCommandEvent.isCancelled()) return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, event.getMessage(), false, false);
if (executeCommandEvent.isBlocked())
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);
if(executeCommandEvent.isCancelled()) return;
event.setCancelled(true);
MessageTranslator.send(player, cancelCommandMessage);
if(Storage.SEND_CONSOLE_NOTIFICATION) Logger.info(notificationMessage);
Storage.NOTIFY_PLAYERS.stream().filter(uuid -> Bukkit.getServer().getPlayer(uuid) != null).forEach(uuid -> {
Player target = Bukkit.getServer().getPlayer(uuid);
MessageTranslator.send(target, notificationMessage);
});
return;
}
if (!Storage.Blacklist.isListed(command, false)) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
return;
}
if (PermissionUtil.hasBypassPermission(player, command, false)) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
if(executeCommandEvent.isCancelled()) return;
event.setCancelled(true);
MessageTranslator.send(player, cancelCommandMessage);
if(Storage.SEND_CONSOLE_NOTIFICATION) Logger.info(notificationMessage);
Storage.NOTIFY_PLAYERS.stream().filter(uuid -> Bukkit.getServer().getPlayer(uuid) != null).forEach(uuid -> {
Player target = Bukkit.getServer().getPlayer(uuid);
MessageTranslator.send(target, notificationMessage);
});
}
}
@@ -1,55 +0,0 @@
package de.rayzs.pat.plugin.listeners.bukkit;
import de.rayzs.pat.api.netty.bukkit.BukkitPacketAnalyzer;
import de.rayzs.pat.api.brand.impl.BukkitServerBrand;
import de.rayzs.pat.api.communication.BackendUpdater;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.api.brand.CustomServerBrand;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.BukkitLoader;
import org.bukkit.event.player.*;
import org.bukkit.entity.Player;
import org.bukkit.event.*;
import org.bukkit.Bukkit;
public class BukkitPlayerConnectionListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
if(Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED)
BackendUpdater.handle();
PermissionUtil.setPlayerPermissions(player.getUniqueId());
CustomServerBrand.preparePlayer(player);
CustomServerBrand.sendBrandToPlayer(player);
if(!BukkitPacketAnalyzer.inject(player)) player.kickPlayer("Failed to inject player!");
if(Storage.OUTDATED && PermissionUtil.hasPermission(player, "joinupdate")) {
Bukkit.getScheduler().runTaskLater(BukkitLoader.getPlugin(), () -> {
if(player.isOnline()) {
MessageTranslator.send(player, Storage.ConfigSections.Settings.UPDATE.OUTDATED.getLines());
}
}, 20);
}
}
@EventHandler (priority = EventPriority.LOWEST)
public void onPlayerQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
BukkitPacketAnalyzer.uninject(player.getUniqueId());
PermissionUtil.resetPermissions(player.getUniqueId());
if(Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1) return;
BukkitServerBrand.removeFromModified(player);
}
@EventHandler (priority = EventPriority.LOWEST)
public void onPlayerChangedWorld(PlayerChangedWorldEvent event) {
Player player = event.getPlayer();
if(Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1) return;
BukkitServerBrand.removeFromModified(player);
}
}
@@ -0,0 +1,113 @@
package de.rayzs.pat.plugin.listeners.bukkit;
import de.rayzs.pat.api.brand.CustomServerBrand;
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.communication.BackendUpdater;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.plugin.modules.SubArgsModule;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.scheduler.PATScheduler;
import de.rayzs.pat.utils.sender.CommandSender;
import de.rayzs.pat.utils.sender.CommandSenderHandler;
import org.bukkit.event.player.*;
import org.bukkit.entity.Player;
import org.bukkit.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class BukkitPlayerListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
final Player player = event.getPlayer();
final UUID uuid = player.getUniqueId();
PATEventHandler.callServerPlayersChangeEvents(player, ServerPlayersChangeEvent.Type.JOINED);
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
BackendUpdater.handle();
}
PermissionUtil.setPlayerPermissions(player.getUniqueId());
CustomServerBrand.preparePlayer(player);
if (CustomServerBrand.isEnabled()) {
CustomServerBrand.sendBrandToPlayer(player);
}
if (!Storage.USE_LUCKPERMS && !Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
PATScheduler.createScheduler(() -> {
CommandSender sender = CommandSenderHandler.from(player);
assert sender != null;
PermissionUtil.reloadPermissions(sender);
if (Reflection.getMinor() >= 13) {
BukkitAntiTabListener.handleTabCompletion(player.getUniqueId());
}
}, 20);
}
if (!BukkitPacketAnalyzer.inject(player)) {
PATScheduler.createScheduler(() -> {
if (player.isOnline()) {
if (!BukkitPacketAnalyzer.inject(player)) {
Logger.warning("Failed to inject into player! (" + player.getName() + ")" );
player.kickPlayer("Failed to inject player!");
}
}
}, 10);
}
if (Reflection.getMinor() < 13) {
List<String> playerCommands = new ArrayList<>(SubArgsModule.getServerCommands(uuid));
playerCommands.addAll(SubArgsModule.getGroupCommands(uuid));
PATEventHandler.callUpdatePlayerCommandsEvents(uuid, playerCommands, false);
}
if (Storage.OUTDATED && PermissionUtil.hasPermission(player, "joinupdate")) {
PATScheduler.createScheduler(() -> {
if (player.isOnline()) {
MessageTranslator.send(player, Storage.ConfigSections.Settings.UPDATE.OUTDATED.getLines());
}
}, 20);
}
}
@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());
}
@EventHandler (priority = EventPriority.LOWEST)
public void onPlayerChangedWorld(PlayerChangedWorldEvent event) {
Player player = event.getPlayer();
if (Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY == -1) {
CustomServerBrand.sendBrandToPlayer(player);
}
if (Storage.ConfigSections.Settings.UPDATE_COMMANDS_PER_WORLD.ENABLED) {
CommandSender sender = CommandSenderHandler.from(player);
assert sender != null;
PermissionUtil.reloadPermissions(sender);
if (Reflection.getMinor() >= 13) {
BukkitAntiTabListener.handleTabCompletion(player);
}
}
}
}
@@ -1,12 +1,29 @@
package de.rayzs.pat.plugin.listeners.bukkit;
import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
import com.destroystokyo.paper.profile.PlayerProfile;
import com.destroystokyo.paper.profile.ProfileProperty;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.ExpireCache;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.message.replacer.PlaceholderReplacer;
import org.bukkit.event.*;
import org.bukkit.Bukkit;
import org.bukkit.profile.PlayerTextures;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.plaf.BorderUIResource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class PaperServerListPing implements Listener {
private static final ExpireCache<Integer, List<ProtocolHoverLine>> CACHED_PROTOCOL_NAMES = new ExpireCache<>(1, TimeUnit.SECONDS);
private static final UUID RANDOM_UUID = UUID.randomUUID();
private static final int CACHE_KEY = 0;
@EventHandler (priority = EventPriority.LOWEST)
public void onPaperServerListPing(PaperServerListPingEvent event) {
if(!Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.ENABLED) return;
@@ -16,13 +33,194 @@ public class PaperServerListPing implements Listener {
onlineExtend = online + Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.EXTEND_COUNT,
max = Bukkit.getMaxPlayers();
if(Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.USE_EXTEND_AS_MAX_COUNT)
if (Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.USE_EXTEND_AS_MAX_COUNT)
event.setMaxPlayers(onlineExtend);
String versionName = Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.PROTOCOL.replace("%online_extended%", String.valueOf(onlineExtend)).replace("%online%", String.valueOf(online)).replace("%max%", String.valueOf(max));
if(Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.HIDE_PLAYERS)
if (Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.HIDE_PLAYERS) {
event.getPlayerSample().clear();
event.setHidePlayers(true);
}
else if (Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.USE_CUSTOM_PLAYERLIST) {
List<ProtocolHoverLine> cachedPlayerNames = CACHED_PROTOCOL_NAMES.get(CACHE_KEY);
event.getPlayerSample().clear();
event.setVersion(versionName);
if (cachedPlayerNames != null) {
event.getPlayerSample().addAll(cachedPlayerNames);
} else {
Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.PLAYERLIST.getLines().forEach(line -> {
if (line.contains("%players%")) {
List<String> playerNames = Storage.getLoader().getOnlinePlayerNames();
playerNames = playerNames.size() > 30
? playerNames.subList(0, 30)
: playerNames;
for (String currentPlayerName : playerNames) {
String playerName = StringUtils.replace(line,
"%players%", currentPlayerName, "&", "§"
);
event.getPlayerSample().add(new ProtocolHoverLine(playerName, RANDOM_UUID));
}
} else {
String playerName = replaceString(line, online, onlineExtend, max);
if (playerName.contains("\n")) {
String[] nameSplit = playerName.split("\n");
nameSplit = nameSplit.length > 30
? Arrays.copyOfRange(nameSplit, 0, 30)
: nameSplit;
for (String name : nameSplit) {
event.getPlayerSample().add(new ProtocolHoverLine(name, RANDOM_UUID));
}
} else {
event.getPlayerSample().add(new ProtocolHoverLine(playerName, RANDOM_UUID));
}
}
});
}
}
event.setVersion(replaceString(versionName, online, onlineExtend, max));
}
private String replaceString(String string, int online, int onlineExtend, int max) {
String replaced = string
.replace("&", "§")
.replace("%online_extended%", String.valueOf(onlineExtend))
.replace("%online%", String.valueOf(online))
.replace("%max%", String.valueOf(max));
return replaced.contains("%") ? PlaceholderReplacer.replace(null, replaced) : replaced;
}
private static class ProtocolHoverLine implements PlayerProfile {
private String name, id;
public ProtocolHoverLine(String name, UUID id) {
this.name = name;
this.id = id.toString();
}
@Override
public @Nullable UUID getUniqueId() {
return UUID.fromString(id);
}
@Override
public @Nullable String getName() {
return name;
}
@Override
public @NotNull String setName(@Nullable String s) {
return "";
}
@Override
public @Nullable UUID getId() {
return getUniqueId();
}
@Override
public @Nullable UUID setId(@Nullable UUID uuid) {
return null;
}
@Override
public @NotNull PlayerTextures getTextures() {
return null;
}
@Override
public void setTextures(@Nullable PlayerTextures playerTextures) {
}
@Override
public Set<ProfileProperty> getProperties() {
return null;
}
@Override
public boolean hasProperty(@Nullable String s) {
return false;
}
@Override
public void setProperty(@NotNull ProfileProperty profileProperty) {
}
@Override
public void setProperties(@NotNull Collection<ProfileProperty> collection) {
}
@Override
public boolean removeProperty(@Nullable String s) {
return false;
}
@Override
public void clearProperties() {
}
@Override
public boolean isComplete() {
return false;
}
@Override
public boolean completeFromCache() {
return false;
}
@Override
public boolean completeFromCache(boolean b) {
return false;
}
@Override
public boolean completeFromCache(boolean b, boolean b1) {
return false;
}
@Override
public boolean complete(boolean b) {
return false;
}
@Override
public boolean complete(boolean b, boolean b1) {
return false;
}
@Override
public @NotNull CompletableFuture<PlayerProfile> update() {
return null;
}
@Override
public org.bukkit.profile.@NotNull PlayerProfile clone() {
return null;
}
@Override
public Map<String, Object> serialize() {
return null;
}
}
}
@@ -1,14 +1,16 @@
package de.rayzs.pat.plugin.listeners.bungee;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.event.events.FilteredSuggestionEvent;
import de.rayzs.pat.api.event.events.FilteredTabCompletionEvent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import de.rayzs.pat.utils.permission.PermissionUtil;
import net.md_5.bungee.api.plugin.Listener;
import de.rayzs.pat.api.storage.Storage;
import net.md_5.bungee.api.event.*;
import net.md_5.bungee.event.*;
import de.rayzs.pat.utils.permission.PermissionUtil;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.TabCompleteEvent;
import net.md_5.bungee.api.event.TabCompleteResponseEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.event.EventHandler;
import java.util.List;
public class BungeeAntiTabListener implements Listener {
@@ -17,21 +19,49 @@ public class BungeeAntiTabListener implements Listener {
if(!(event.getSender() instanceof ProxiedPlayer)) return;
ProxiedPlayer player = (ProxiedPlayer) event.getSender();
if(PermissionUtil.hasBypassPermission(player)) return;
if(Storage.Blacklist.isBlocked(player, event.getCursor(), !Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED, player.getServer().getInfo().getName()))
event.getSuggestions().clear();
ServerInfo serverInfo = player.getServer().getInfo();
String serverName = serverInfo.getName();
String cursor = event.getCursor().substring(1);
if (event.getSuggestions().isEmpty())
return;
if (Storage.Blacklist.isDisabledServer(serverName))
return;
if (PermissionUtil.hasBypassPermission(player))
return;
FilteredTabCompletionEvent filteredTabCompletionEvent = PATEventHandler.callFilteredTabCompletionEvents(player, cursor, event.getSuggestions());
List<String> suggestions = filteredTabCompletionEvent.getCompletion();
event.getSuggestions().removeIf(suggestion -> !suggestions.contains(suggestion));
}
@EventHandler
public void onTabComplete(TabCompleteResponseEvent event) {
if(!(event.getSender() instanceof ProxiedPlayer)) return;
// Ignoring this at first, due to transfer to the packet-based solution only. Hehe
/*
if (!(event.getSender() instanceof ProxiedPlayer))
return;
ProxiedPlayer player = (ProxiedPlayer) event.getSender();
if(PermissionUtil.hasBypassPermission(player)) return;
event.getSuggestions().removeIf(command -> Storage.Blacklist.isBlocked(player, command, !Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED, player.getServer().getInfo().getName()));
ServerInfo serverInfo = player.getServer().getInfo();
String serverName = serverInfo.getName();
FilteredSuggestionEvent filteredSuggestionEvent = PATEventHandler.call(player.getUniqueId(), event.getSuggestions());
if(filteredSuggestionEvent.isCancelled()) event.getSuggestions().clear();
if (Storage.Blacklist.isDisabledServer(serverName))
return;
if(PermissionUtil.hasBypassPermission(player))
return;
event.getSuggestions().removeIf(command -> !Storage.Blacklist.canPlayerAccessTab(player, command, serverName));
FilteredSuggestionEvent filteredSuggestionEvent = PATEventHandler.callFilteredSuggestionEvents(player, event.getSuggestions());
if (filteredSuggestionEvent.isCancelled()) event.getSuggestions().clear();
*/
}
}
@@ -3,145 +3,85 @@ package de.rayzs.pat.plugin.listeners.bungee;
import de.rayzs.pat.api.event.events.ExecuteCommandEvent;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.utils.message.MessageTranslator;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.event.ChatEvent;
import net.md_5.bungee.api.plugin.Listener;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.api.storage.Storage;
import net.md_5.bungee.api.connection.*;
import net.md_5.bungee.api.ProxyServer;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.api.event.*;
import net.md_5.bungee.event.*;
import java.util.List;
public class BungeeBlockCommandListener implements Listener {
@EventHandler (priority = EventPriority.HIGHEST)
public void onChat(ChatEvent event) {
if(event.isCancelled()) return;
if (event.isCancelled()) return;
Connection connection = event.getSender();
if(!(connection instanceof ProxiedPlayer) || !event.getMessage().startsWith("/")) return;
if (! (connection instanceof ProxiedPlayer) || !event.getMessage().startsWith("/"))
return;
ProxiedPlayer player = (ProxiedPlayer) connection;
String serverName = player.getServer().getInfo().getName();
String command = event.getMessage();
String rawCommand = event.getMessage(), command = rawCommand.toLowerCase();
boolean bypassPermission = PermissionUtil.hasBypassPermission(player, command);
command = StringUtils.replaceFirst(command, "/", "");
if (bypassPermission)
return;
command = command.startsWith("/") ? command.substring(1) : command;
command = StringUtils.getFirstArg(command);
command = StringUtils.replaceTriggers(command, "", "\\", "<", ">", "&");
if(PermissionUtil.hasBypassPermission(player, command, false)) return;
final String displayCommand = StringUtils.replaceTriggers(command, "", "\\", "<", ">", "&");
if(rawCommand.equals("/")) return;
ServerInfo serverInfo = player.getServer().getInfo();
String serverName = serverInfo != null ? serverInfo.getName() : "unknown";
List<String> notificationMessage = MessageTranslator.replaceMessageList(Storage.ConfigSections.Messages.NOTIFICATION.ALERT, "%player%", player.getName(), "%command%", command, "%server%", serverName);
//command = command.toLowerCase();
if(Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isCommand(command) && !PermissionUtil.hasBypassPermission(player, command)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, 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);
Storage.NOTIFY_PLAYERS.forEach(uuid -> {
ProxiedPlayer proxiedPlayer = ProxyServer.getInstance().getPlayer(uuid);
if(proxiedPlayer != null) MessageTranslator.send(proxiedPlayer, notificationMessage);
});
List<String> notificationMessage = MessageTranslator.replaceMessageList(
Storage.ConfigSections.Messages.NOTIFICATION.ALERT,
"%player%", player.getName(),
"%command%", displayCommand,
"%server%", serverName);
if (!Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED)
return;
}
if(Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(command) && !PermissionUtil.hasBypassPermission(player, command)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
if(executeCommandEvent.isCancelled()) return;
if (!Storage.Blacklist.canPlayerAccessChat(player, command, serverName)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(
player,
event.getMessage(),
true,
!Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED
);
event.setCancelled(true);
MessageTranslator.send(player, Storage.ConfigSections.Settings.CUSTOM_VERSION.MESSAGE, "%command%", rawCommand.replaceFirst("/", ""));
if (executeCommandEvent.isBlocked()) {
event.setCancelled(true);
if(Storage.SEND_CONSOLE_NOTIFICATION) Logger.info(notificationMessage);
Storage.NOTIFY_PLAYERS.forEach(uuid -> {
ProxiedPlayer proxiedPlayer = ProxyServer.getInstance().getPlayer(uuid);
if(proxiedPlayer != null) MessageTranslator.send(proxiedPlayer, notificationMessage);
});
if (!executeCommandEvent.doesNotify())
return;
return;
}
if (Storage.SEND_CONSOLE_NOTIFICATION)
Logger.info(notificationMessage);
if(!Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED) return;
Storage.NOTIFY_PLAYERS.forEach(uuid -> {
Object p = Storage.getLoader().getPlayerObjByUUID(uuid);
List<String> cancelCommandMessage = MessageTranslator.replaceMessageList(Storage.ConfigSections.Settings.CANCEL_COMMAND.MESSAGE, "%command%", command);
if (p != null) {
MessageTranslator.send(p, notificationMessage);
}
});
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);
return;
}
listed = Storage.Blacklist.isListed(command, false, true, false);
serverListed = Storage.Blacklist.isListed(player, command, false, listed, false, serverName);
ignored = Storage.Blacklist.isOnIgnoredServer(serverName);
if(ignored ? !listed && serverListed : serverListed) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
if (executeCommandEvent.isCancelled())
return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
if(executeCommandEvent.isCancelled()) return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, event.getMessage(), false, false);
if (executeCommandEvent.isBlocked())
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);
if(executeCommandEvent.isCancelled()) return;
event.setCancelled(true);
MessageTranslator.send(player, cancelCommandMessage);
if(Storage.SEND_CONSOLE_NOTIFICATION) Logger.info(notificationMessage);
Storage.NOTIFY_PLAYERS.forEach(uuid -> {
ProxiedPlayer proxiedPlayer = ProxyServer.getInstance().getPlayer(uuid);
if(proxiedPlayer != null) MessageTranslator.send(proxiedPlayer, notificationMessage);
});
return;
}
if(Storage.Blacklist.doesGroupBypass(player, command, true, true, false, serverName)) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
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);
return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
if(executeCommandEvent.isCancelled()) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
return;
}
event.setCancelled(true);
MessageTranslator.send(player, cancelCommandMessage);
if(Storage.SEND_CONSOLE_NOTIFICATION) Logger.info(notificationMessage);
Storage.NOTIFY_PLAYERS.forEach(uuid -> {
ProxiedPlayer proxiedPlayer = ProxyServer.getInstance().getPlayer(uuid);
if(proxiedPlayer != null) MessageTranslator.send(proxiedPlayer, notificationMessage);
});
}
}
@@ -4,10 +4,12 @@ import de.rayzs.pat.plugin.logger.Logger;
import net.md_5.bungee.api.event.ProxyPingEvent;
import net.md_5.bungee.api.plugin.Listener;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.BungeeLoader;
import de.rayzs.pat.plugin.*;
import net.md_5.bungee.event.*;
import net.md_5.bungee.api.*;
import java.util.List;
public class BungeePingListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST)
@@ -22,16 +24,41 @@ public class BungeePingListener implements Listener {
try {
max = proxyServer.getConfigurationAdapter().getListeners().iterator().next().getMaxPlayers();
} catch (Throwable throwable) {
Logger.debug("Failed to read max-players count for %max% placeholder! Using -1 as default value instead.");
Logger.warning("Failed to read max-players count for %max% placeholder! Using -1 as default value instead.");
}
ServerPing serverPing = event.getResponse();
ServerPing.Protocol newProtocol = new ServerPing.Protocol(Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.PROTOCOL.replace("%online_extended%", String.valueOf(onlineExtend)).replace("%online%", String.valueOf(online)).replace("%max%", String.valueOf(max)), !Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.ALWAYS_SHOW ? serverPing.getVersion().getProtocol() : 0);
int protocol = Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.ALWAYS_SHOW ? -1 : serverPing.getVersion().getProtocol();
String version = replaceString(Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.PROTOCOL, online, onlineExtend, max);
ServerPing.Protocol newProtocol = new ServerPing.Protocol(version, protocol);
serverPing.setVersion(newProtocol);
if(Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.USE_EXTEND_AS_MAX_COUNT)
if (Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.USE_EXTEND_AS_MAX_COUNT)
serverPing.getPlayers().setMax(onlineExtend);
if (Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.HIDE_PLAYERS)
serverPing.getPlayers().setSample(new ServerPing.PlayerInfo[0]);
else if (Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.USE_CUSTOM_PLAYERLIST) {
List<String> lines = Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.PLAYERLIST.getLines();
ServerPing.PlayerInfo[] playerInfos = new ServerPing.PlayerInfo[lines.size()];
for (int i = 0; i < lines.size(); i++) {
playerInfos[i] = new ServerPing.PlayerInfo(replaceString(lines.get(i), online, onlineExtend, max), "");
}
serverPing.getPlayers().setSample(playerInfos);
}
event.setResponse(serverPing);
}
private String replaceString(String string, int online, int onlineExtend, int max) {
return string
.replace("&", "§")
.replace("%online_extended%", String.valueOf(onlineExtend))
.replace("%online%", String.valueOf(online))
.replace("%max%", String.valueOf(max));
}
}
@@ -1,10 +1,12 @@
package de.rayzs.pat.plugin.listeners.bungee;
import de.rayzs.pat.api.brand.CustomServerBrand;
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;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import de.rayzs.pat.api.brand.CustomServerBrand;
import net.md_5.bungee.api.plugin.Listener;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.BungeeLoader;
@@ -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")) {
@@ -34,16 +43,24 @@ public class BungeePlayerConnectionListener implements Listener {
ProxiedPlayer player = event.getPlayer();
BungeePacketAnalyzer.inject(player);
if(Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1) return;
if (Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1)
return;
CustomServerBrand.sendBrandToPlayer(player);
}
@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;
if (Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1)
return;
CustomServerBrand.sendBrandToPlayer(player);
}
}
@@ -1,33 +1,43 @@
package de.rayzs.pat.plugin.listeners.bungee;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.event.events.FilteredSuggestionEvent;
import io.github.waterfallmc.waterfall.event.ProxyDefineCommandsEvent;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.CommandsCache;
import de.rayzs.pat.utils.permission.PermissionUtil;
import io.github.waterfallmc.waterfall.event.ProxyDefineCommandsEvent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.api.plugin.Listener;
import de.rayzs.pat.utils.CommandsCache;
import net.md_5.bungee.event.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import net.md_5.bungee.event.EventHandler;
import net.md_5.bungee.event.EventPriority;
public class WaterfallAntiTabListener implements Listener {
private static final HashMap<String, CommandsCache> COMMANDS_CACHE_MAP = new HashMap<>();
@EventHandler(priority = EventPriority.LOWEST)
public void onProxyDefineCommands(ProxyDefineCommandsEvent event) {
System.out.println("CALL");
if(!(event.getReceiver() instanceof ProxiedPlayer) || event.getCommands().isEmpty()) return;
ProxiedPlayer player = (ProxiedPlayer) event.getReceiver();
String serverName = player.getServer().getInfo().getName();
if(!COMMANDS_CACHE_MAP.containsKey(serverName))
COMMANDS_CACHE_MAP.put(serverName, new CommandsCache().reverse());
if (Storage.Blacklist.isDisabledServer(serverName))
return;
CommandsCache commandsCache = COMMANDS_CACHE_MAP.get(serverName);
Map<String, CommandsCache> cache = Storage.getLoader().getCommandsCacheMap();
if(!cache.containsKey(serverName))
cache.put(serverName, new CommandsCache());
CommandsCache commandsCache = cache.get(serverName);
List<String> commandsAsString = new ArrayList<>();
HashMap<String, Command> commandsMap = new HashMap<>(event.getCommands());
@@ -39,17 +49,14 @@ 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()) {
if(!event.getCommands().containsKey(commandName)) event.getCommands().put(commandName, commandsMap.get(commandName));
if (!event.getCommands().containsKey(commandName))
event.getCommands().put(commandName, commandsMap.get(commandName));
}
commandsMap = null;
}
public static void updateCommands() {
COMMANDS_CACHE_MAP.values().forEach(CommandsCache::reset);
}
}
@@ -1,18 +1,26 @@
package de.rayzs.pat.plugin.listeners.velocity;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.velocitypowered.api.event.PostOrder;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.command.PlayerAvailableCommandsEvent;
import com.velocitypowered.api.event.player.TabCompleteEvent;
import de.rayzs.pat.utils.permission.PermissionUtil;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyServer;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.event.events.FilteredSuggestionEvent;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.CommandsCache;
import com.velocitypowered.api.proxy.*;
import com.velocitypowered.api.event.*;
import java.util.*;
import de.rayzs.pat.utils.permission.PermissionUtil;
public class VelocityAntiTabListener {
private static ProxyServer server;
private static final HashMap<String, CommandsCache> COMMANDS_CACHE_MAP = new HashMap<>();
public VelocityAntiTabListener(ProxyServer server) {
VelocityAntiTabListener.server = server;
@@ -21,32 +29,70 @@ public class VelocityAntiTabListener {
@Subscribe (order = PostOrder.LAST)
public void onTabComplete(TabCompleteEvent event) {
Player player = event.getPlayer();
if(PermissionUtil.hasBypassPermission(player) || event.getSuggestions().isEmpty() || !player.getCurrentServer().isPresent()) return;
String serverName = player.getCurrentServer().isPresent() ? player.getCurrentServer().get().getServerInfo().getName() : "unknown";
event.getSuggestions().removeIf(command -> Storage.Blacklist.isBlocked(player, command, !Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED, player.getCurrentServer().get().getServerInfo().getName()));
if (Storage.Blacklist.isDisabledServer(serverName))
return;
if (PermissionUtil.hasBypassPermission(player) || event.getSuggestions().isEmpty() || !player.getCurrentServer().isPresent()) return;
event.getSuggestions().removeIf(command -> !Storage.Blacklist.canPlayerAccessTab(player, command, serverName));
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();
try {
Player player = event.getPlayer();
if(!COMMANDS_CACHE_MAP.containsKey(serverName))
COMMANDS_CACHE_MAP.put(serverName, new CommandsCache().reverse());
CommandsCache commandsCache = COMMANDS_CACHE_MAP.get(serverName);
if (event.getRootNode().getChildren().isEmpty() || !player.getCurrentServer().isPresent()) {
return;
}
List<String> commandsAsString = new ArrayList<>();
event.getRootNode().getChildren().stream().filter(command -> command != null && command.getName() != null).forEach(command -> commandsAsString.add(command.getName()));
commandsCache.handleCommands(commandsAsString, serverName);
String serverName = player.getCurrentServer().get().getServer().getServerInfo().getName();
if(PermissionUtil.hasBypassPermission(player)) return;
Map<String, CommandsCache> cache = Storage.getLoader().getCommandsCacheMap();
final List<String> playerCommands = commandsCache.getPlayerCommands(commandsAsString, player, player.getUniqueId(), serverName);
event.getRootNode().getChildren().removeIf(command -> command == null || command.getName() == null || playerCommands.contains(command.getName()));
}
if (!cache.containsKey(serverName)) {
cache.put(serverName, new CommandsCache());
}
public static void updateCommands() {
COMMANDS_CACHE_MAP.values().forEach(CommandsCache::reset);
CommandsCache commandsCache = cache.get(serverName);
List<String> commandsAsString = new ArrayList<>();
event.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;
}
final boolean newer = player.getProtocolVersion().getProtocol() > 340, argsChildrenExist = event.getRootNode().getChild("args") != null;
final List<String> playerCommands = commandsCache.getPlayerCommands(commandsAsString, player, player.getUniqueId(), serverName);
if (event.getRootNode().getChildren().size() == 1
&& newer && argsChildrenExist
&& event.getRootNode().getChild("args").getChildren().isEmpty()) {
return;
}
if (event.getRootNode().getChildren().size() == 1 && newer && argsChildrenExist) {
return;
}
event.getRootNode().getChildren().removeIf(command -> {
if (command == null || command.getName() == null)
return true;
if (command.getName().equals("args"))
return false;
return !playerCommands.contains(command.getName());
});
} catch (Exception exception) {
System.out.println("An error occurred while processing commands in PAT: " + exception.getMessage());
exception.printStackTrace();
}
}
}
@@ -1,135 +1,97 @@
package de.rayzs.pat.plugin.listeners.velocity;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.command.CommandExecuteEvent;
import com.velocitypowered.api.command.CommandSource;
import de.rayzs.pat.api.event.events.ExecuteCommandEvent;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.utils.permission.PermissionUtil;
import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.Player;
import de.rayzs.pat.api.storage.Storage;
import com.velocitypowered.api.event.*;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.api.event.*;
import java.util.List;
public class VelocityBlockCommandListener {
private final ProxyServer server;
public VelocityBlockCommandListener(ProxyServer server) {
this.server = server;
@Subscribe
public void onCommandExecute(CommandExecuteEvent event) {
handleCommand(event);
}
@Subscribe (order = PostOrder.EARLY)
public void onCommandExecute(CommandExecuteEvent event) {
if(!event.getResult().isAllowed()) return;
CommandSource commandSource = event.getCommandSource();
public static CommandExecuteEvent handleCommand(Player player, String command) {
return handleCommand(new CommandExecuteEvent(player, command));
}
if(!(commandSource instanceof Player)) return;
public static CommandExecuteEvent handleCommand(CommandExecuteEvent event) {
if(!event.getResult().isAllowed())
return event;
CommandSource commandSource = event.getCommandSource();
Object consoleSender = Storage.getLoader().getConsoleSender();
if(! (commandSource instanceof Player))
return event;
Player player = (Player) commandSource;
String rawCommand = event.getCommand(), command = rawCommand,
serverName = player.getCurrentServer().isPresent() ? player.getCurrentServer().get().getServerInfo().getName() : "unknown";
String command = StringUtils.getFirstArg(event.getCommand());
command = StringUtils.replaceFirst(command, "/", "");
command = StringUtils.getFirstArg(command);
command = StringUtils.replaceTriggers(command, "", "\\", "<", ">", "&");
String serverName = player.getCurrentServer().isPresent()
? player.getCurrentServer().get().getServerInfo().getName()
: "unknown";
if(PermissionUtil.hasBypassPermission(player, command, false)) return;
boolean bypassPermission = PermissionUtil.hasBypassPermission(player, command);
List<String> notificationMessage = MessageTranslator.replaceMessageList(Storage.ConfigSections.Messages.NOTIFICATION.ALERT, "%player%", player.getUsername(), "%command%", command, "%server%", serverName);
if (bypassPermission)
return event;
if(Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isCommand(command)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
if(executeCommandEvent.isCancelled()) return;
final String displayCommand = StringUtils.replaceTriggers(command, "", "\\", "<", ">", "&");
event.setResult(CommandExecuteEvent.CommandResult.denied());
MessageTranslator.send(player, Storage.ConfigSections.Settings.CUSTOM_PLUGIN.MESSAGE, "%command%", command.replaceFirst("/", ""));
//command = command.toLowerCase();
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));
return;
}
List<String> notificationMessage = MessageTranslator.replaceMessageList(
Storage.ConfigSections.Messages.NOTIFICATION.ALERT,
"%player%", player.getUsername(),
"%command%", displayCommand,
"%server%", serverName
);
if(Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(command)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
if(executeCommandEvent.isCancelled()) return;
if (!Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED)
return event;
event.setResult(CommandExecuteEvent.CommandResult.denied());
MessageTranslator.send(player, Storage.ConfigSections.Settings.CUSTOM_VERSION.MESSAGE, "%command%", command.replaceFirst("/", ""));
if (!Storage.Blacklist.canPlayerAccessChat(player, command, serverName)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(
player,
event.getCommand(),
true,
!Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED);
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));
if (executeCommandEvent.isBlocked()) {
event.setResult(CommandExecuteEvent.CommandResult.denied());
return;
}
if (!executeCommandEvent.doesNotify())
return event;
if(!Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED) return;
List<String> cancelCommandMessage = MessageTranslator.replaceMessageList(Storage.ConfigSections.Settings.CANCEL_COMMAND.MESSAGE, "%command%", command.replaceFirst("/", ""));
if (Storage.SEND_CONSOLE_NOTIFICATION)
MessageTranslator.send(consoleSender, notificationMessage);
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);
return;
Storage.NOTIFY_PLAYERS.stream().forEach(uuid -> {
Object p = Storage.getLoader().getPlayerObjByUUID(uuid);
if (p != null) {
MessageTranslator.send(p, notificationMessage);
}
});
}
listed = Storage.Blacklist.isListed(command, false, true, false);
serverListed = Storage.Blacklist.isListed(player, command, false, listed, false, serverName);
ignored = Storage.Blacklist.isOnIgnoredServer(serverName);
if(ignored ? !listed && serverListed : serverListed) {
PATEventHandler.call(player.getUniqueId(), rawCommand, false);
return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
if(executeCommandEvent.isCancelled()) return;
if (executeCommandEvent.isCancelled())
return event;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, event.getCommand(), false, false);
if (executeCommandEvent.isBlocked())
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);
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));
return;
}
if(Storage.Blacklist.doesGroupBypass(player, command, true, true, false, player.getCurrentServer().get().getServerInfo().getName())) 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);
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);
return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.call(player.getUniqueId(), rawCommand, true);
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));
return event;
}
}
}
@@ -1,10 +1,12 @@
package de.rayzs.pat.plugin.listeners.velocity;
import com.velocitypowered.api.event.connection.DisconnectEvent;
import de.rayzs.pat.api.brand.CustomServerBrand;
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;
import de.rayzs.pat.api.brand.CustomServerBrand;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.player.*;
import de.rayzs.pat.plugin.VelocityLoader;
@@ -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;
}
}
@@ -5,10 +5,12 @@ import com.velocitypowered.api.proxy.server.ServerPing;
import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.event.Subscribe;
import de.rayzs.pat.api.storage.Storage;
import java.util.UUID;
public class VelocityPingListener {
private static ProxyServer server;
private static final UUID RANDOM_UUID = UUID.randomUUID();
public VelocityPingListener(ProxyServer server) {
VelocityPingListener.server = server;
@@ -16,15 +18,42 @@ public class VelocityPingListener {
@Subscribe
public void onProxyPing(ProxyPingEvent event) {
if(!Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.ENABLED) return;
if (!Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.ENABLED) return;
ServerPing oldPing = event.getPing();
ServerPing.Builder builder = oldPing.asBuilder();
int online = server.getPlayerCount(),
onlineExtend = online + Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.EXTEND_COUNT,
max = server.getConfiguration().getShowMaxPlayers();
ServerPing oldServerPing = event.getPing(), newServerPing;
ServerPing.Version newVersion = new ServerPing.Version(!Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.ALWAYS_SHOW ? oldServerPing.getVersion().getProtocol() : -1, Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.PROTOCOL.replace("%online_extended%", String.valueOf(onlineExtend)).replace("%online%", String.valueOf(online)).replace("%max%", String.valueOf(max)));
newServerPing = oldServerPing.asBuilder().version(newVersion).build();
max = server.getConfiguration().getShowMaxPlayers(),
protocol = Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.ALWAYS_SHOW ? -1 : oldPing.getVersion().getProtocol(),
extend = online + Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.EXTEND_COUNT;
event.setPing(newServerPing);
builder.version(new ServerPing.Version(protocol,
replaceString(Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.PROTOCOL, online, extend, max))
);
if (Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.USE_EXTEND_AS_MAX_COUNT)
builder.maximumPlayers(extend);
if (Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.HIDE_PLAYERS)
builder.clearSamplePlayers();
else if (Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.USE_CUSTOM_PLAYERLIST) {
builder.clearSamplePlayers();
Storage.ConfigSections.Settings.CUSTOM_PROTOCOL_PING.PLAYERLIST.getLines().forEach(line ->
builder.samplePlayers(new ServerPing.SamplePlayer(replaceString(line, online, extend, max), RANDOM_UUID))
);
}
event.setPing(builder.build());
}
private String replaceString(String string, int online, int onlineExtend, int max) {
return string
.replace("&", "§")
.replace("%online_extended%", String.valueOf(onlineExtend))
.replace("%online%", String.valueOf(online))
.replace("%max%", String.valueOf(max));
}
}
@@ -1,74 +1,60 @@
package de.rayzs.pat.plugin.logger;
import de.rayzs.pat.utils.message.MessageTranslator;
import java.nio.charset.StandardCharsets;
import de.rayzs.pat.api.communication.Communicator;
import de.rayzs.pat.api.communication.client.ClientInfo;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.api.storage.blacklist.impl.GeneralBlacklist;
import de.rayzs.pat.plugin.logger.impl.*;
import java.nio.charset.StandardCharsets;
import javax.net.ssl.HttpsURLConnection;
import net.md_5.bungee.api.ProxyServer;
import de.rayzs.pat.utils.Reflection;
import java.text.SimpleDateFormat;
import java.util.logging.Level;
import de.rayzs.pat.plugin.*;
import org.bukkit.Bukkit;
import de.rayzs.pat.utils.*;
import de.rayzs.pat.utils.group.Group;
import de.rayzs.pat.utils.group.GroupManager;
import java.net.URL;
import java.util.*;
import java.io.*;
public class Logger {
private static final ArrayList<String> LOGS = new ArrayList<>();
private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss:SS");
private static final String LOG_HEADER;
private final static java.util.logging.Logger LOGGER =
Reflection.isVelocityServer() ? null
: Reflection.isProxyServer()
? BungeeLoader.getPluginLogger()
: BukkitLoader.getPluginLogger();
static {
final String software = Reflection.isProxyServer()
? Reflection.isVelocityServer() ? "Velocity" : "Bungeecord"
: (Reflection.isPaper() ? "Paper" : Reflection.isFoliaServer() ? "Folia" : "Spigot/Bukkit");
public static void info(List<String> texts) { texts.forEach(text -> send(Priority.INFO, text)); }
public static void warning(List<String> texts) { texts.forEach(text -> send(Priority.WARNING, text)); }
public static void info(String text) { send(Priority.INFO, text); }
public static void warning(String text) { send(Priority.WARNING, text); }
public static void debug(String text) { send(Priority.DEBUG, text); }
final String version = Reflection.isProxyServer() ? "" : " " + Reflection.getRawVersionName().replace("_", ".");
protected static void send(Priority priority, String text) {
text = MessageTranslator.replaceMessage(text);
LOG_HEADER = "> ProAntiTab v" + Storage.CURRENT_VERSION + " [" + software + version + "]";
}
String time = TIME_FORMAT.format(new Date(System.currentTimeMillis()));
if(time.length() != 12) time = time.substring(0, 9) + 0 + time.split(":")[3];
LOGS.add("[" + priority.name() + " |" + time + "] " + MessageTranslator.colorless(text));
private final static LoggerTemplate LOGGER =
Reflection.isVelocityServer() ? new VelocityLogger()
: Reflection.isProxyServer() ? new BungeeLogger()
: new BukkitLogger();
if(priority == Priority.DEBUG) return;
if(LOGGER == null) {
System.out.println(text);
return;
}
public static void info(List<String> messages) {
LOGGER.info(messages);
}
boolean hasColors = text.contains("§");
if(hasColors) {
if (Reflection.isProxyServer()) MessageTranslator.send(ProxyServer.getInstance().getConsole(), text);
else MessageTranslator.send(Bukkit.getServer().getConsoleSender(), text);
return;
}
public static void warning(List<String> messages) {
LOGGER.warn(messages);
}
Level level = Level.parse(priority.name());
LOGGER.log(level, text);
public static void info(String message) {
LOGGER.info(message);
}
public static void warning(String message) {
LOGGER.warn(message);
}
public static String post() throws IOException {
ArrayList<String> clonedLogs = (ArrayList<String>) LOGS.clone();
int startIndex = clonedLogs.size() > 980 ? clonedLogs.size() - 980 : 0;
StringBuilder textBuilder = new StringBuilder("[ProAntiTab " + Storage.CURRENT_VERSION + " | " + (Reflection.isProxyServer() ? Reflection.isVelocityServer() ? "Velocity" : "Proxy" : Reflection.isPaper() ? "Paper" : "Bukkit") + "]" + (Reflection.getRawVersionName() != null ? " Server version: " + Reflection.getVersionName() + " " + Reflection.getRawVersionName().replace("_", ".") : "") + "\n" + (startIndex != 0 ? "... another part is split!\n\n" : ""));
for(int i = startIndex; i < clonedLogs.size(); i++) {
if (clonedLogs.get(i) == null) continue;
String line = clonedLogs.get(i);
textBuilder.append("\n");
textBuilder.append(line);
}
byte[] textInBytes = textBuilder.toString().getBytes(StandardCharsets.UTF_8);
byte[] textInBytes = (LOG_HEADER + "\n\n" + createInfo()).getBytes(StandardCharsets.UTF_8);
int postDataLength = textInBytes.length;
URL url = new URL("https://haste.rayzs.de/documents");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
@@ -92,5 +78,99 @@ public class Logger {
return "https://haste.rayzs.de/" + response + ".txt";
}
protected enum Priority { INFO, WARNING, DEBUG }
}
private static String createInfo() {
StringBuilder builder = new StringBuilder();
builder.append("Updated: ")
.append(!Storage.OUTDATED)
.append("\n\n");
builder.append("Mode: ")
.append(Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED ? "WHITELIST" : "BLACKLIST")
.append("\n");
builder.append("Detected Software-API: ")
.append(Reflection.isProxyServer()
? Reflection.isPaper() ? "Waterfall" :
Reflection.isVelocityServer() ? "Velocity" : "Bungeecord"
: Reflection.isFoliaServer() ? "Folia"
: Reflection.isPaper() ? "Paper" : "Spigot")
.append("\n");
builder.append("Installed plugins: \n ")
.append(String.join("\n ", Storage.getLoader().getPluginNames()))
.append("\n\n");
builder.append("Detected supported plugins:")
.append("\n");
builder.append(" LuckPerms: ")
.append(Storage.USE_LUCKPERMS)
.append("\n");
if (!Reflection.isProxyServer()) {
builder.append(" GroupManager: ")
.append(Storage.USE_GROUPMANAGER)
.append("\n");
}
builder.append(" PlaceholderAPI: ")
.append(Storage.USE_PLACEHOLDERAPI)
.append("\n");
builder.append(" ViaVersion: ")
.append(Storage.USE_VIAVERSION)
.append("\n\n");
if (!Reflection.isProxyServer()) {
builder.append("server-name: ")
.append(Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED ? Storage.SERVER_NAME : "Not connected to a proxy using PAT")
.append("\n");
builder.append("last-received-sync: ")
.append(Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED ? Storage.LAST_SYNC : "Deactivated")
.append("\n");
}
builder.append("\ncommands: ")
.append(String.join(", ", Storage.Blacklist.getBlacklist().getCommands()))
.append("\n\n");
if (Reflection.isProxyServer()) {
builder.append("\nservers: ")
.append(String.join(", ", Storage.getServers()))
.append("\n");
builder.append("last-sent-sync: ")
.append(Storage.ConfigSections.Settings.DISABLE_SYNC.DISABLED ? "Deactivated" : (System.currentTimeMillis() - Storage.LAST_SYNC))
.append("\n\n");
for (ClientInfo client : Communicator.CLIENTS) {
builder.append("synced-server: ")
.append(client.getName() + " (" + client.getSyncTime() + ")")
.append(", ");
}
builder.append("\n\n");
}
if (Reflection.isProxyServer()) {
builder.append("server-commands:").append("\n");
for (Map.Entry<String, GeneralBlacklist> blacklist : Storage.Blacklist.getBlacklists()) {
builder.append(" ")
.append(blacklist.getKey()).append(": ")
.append(String.join(", ", blacklist.getValue().getCommands()))
.append("\n");
}
}
builder.append("\ngroups:");
for (Group group : GroupManager.getGroups()) {
builder.append("\n")
.append(group.getGroupInfo());
}
return builder.toString();
}
}
@@ -0,0 +1,3 @@
package de.rayzs.pat.plugin.logger;
public enum LoggerPriority { INFO, WARNING }
@@ -0,0 +1,16 @@
package de.rayzs.pat.plugin.logger;
import java.util.List;
public interface LoggerTemplate {
void info(List<String> messages);
void warn(List<String> messages);
void send(LoggerPriority priority, List<String> messages);
void info(String message);
void warn(String message);
void send(LoggerPriority priority, String message);
}
@@ -0,0 +1,52 @@
package de.rayzs.pat.plugin.logger.impl;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.plugin.BukkitLoader;
import de.rayzs.pat.plugin.logger.*;
import org.bukkit.Bukkit;
import java.util.*;
public class BukkitLogger implements LoggerTemplate {
private final java.util.logging.Logger logger = BukkitLoader.getPluginLogger();
@Override
public void info(List<String> messages) {
messages.forEach(this::info);
}
@Override
public void warn(List<String> messages) {
messages.forEach(this::warn);
}
@Override
public void send(LoggerPriority priority, List<String> messages) {
messages.forEach(message -> send(priority, message));
}
@Override
public void info(String message) {
send(LoggerPriority.INFO, message);
}
@Override
public void warn(String message) {
send(LoggerPriority.WARNING, message);
}
@Override
public void send(LoggerPriority priority, String message) {
message = MessageTranslator.replaceMessage(message);
if (message.contains("§")) {
MessageTranslator.send(Bukkit.getServer().getConsoleSender(), message);
return;
}
switch (priority) {
case INFO -> logger.info(message);
case WARNING -> logger.warning(message);
}
}
}
@@ -0,0 +1,52 @@
package de.rayzs.pat.plugin.logger.impl;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.plugin.BungeeLoader;
import net.md_5.bungee.api.ProxyServer;
import de.rayzs.pat.plugin.logger.*;
import java.util.*;
public class BungeeLogger implements LoggerTemplate {
private final java.util.logging.Logger logger = BungeeLoader.getPluginLogger();
@Override
public void info(List<String> messages) {
messages.forEach(this::info);
}
@Override
public void warn(List<String> messages) {
messages.forEach(this::warn);
}
@Override
public void send(LoggerPriority priority, List<String> messages) {
messages.forEach(message -> send(priority, message));
}
@Override
public void info(String message) {
send(LoggerPriority.INFO, message);
}
@Override
public void warn(String message) {
send(LoggerPriority.WARNING, message);
}
@Override
public void send(LoggerPriority priority, String message) {
message = MessageTranslator.replaceMessage(message);
if (message.contains("§")) {
MessageTranslator.send(ProxyServer.getInstance().getConsole(), message);
return;
}
switch (priority) {
case INFO -> logger.info(message);
case WARNING -> logger.warning(message);
}
}
}
@@ -0,0 +1,52 @@
package de.rayzs.pat.plugin.logger.impl;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.plugin.VelocityLoader;
import de.rayzs.pat.plugin.logger.*;
import org.slf4j.Logger;
import java.util.*;
public class VelocityLogger implements LoggerTemplate {
private final Logger logger = VelocityLoader.getPluginLogger();
@Override
public void info(List<String> messages) {
messages.forEach(this::info);
}
@Override
public void warn(List<String> messages) {
messages.forEach(this::warn);
}
@Override
public void send(LoggerPriority priority, List<String> messages) {
messages.forEach(message -> send(priority, message));
}
@Override
public void info(String message) {
send(LoggerPriority.INFO, message);
}
@Override
public void warn(String message) {
send(LoggerPriority.WARNING, message);
}
@Override
public void send(LoggerPriority priority, String message) {
message = MessageTranslator.replaceMessage(message);
if (message.contains("§")) {
MessageTranslator.send(VelocityLoader.getServer().getConsoleCommandSource(), message);
return;
}
switch (priority) {
case INFO -> logger.info(message);
case WARNING -> logger.warn(message);
}
}
}
@@ -1,5 +1,6 @@
package de.rayzs.pat.plugin.metrics.impl;
import de.rayzs.pat.utils.scheduler.PATScheduler;
import org.bukkit.configuration.file.YamlConfiguration;
import java.nio.charset.StandardCharsets;
import javax.net.ssl.HttpsURLConnection;
@@ -171,7 +172,7 @@ public class BukkitMetrics {
}
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
Bukkit.getScheduler().runTask(plugin, this::submitData);
PATScheduler.createScheduler(this::submitData);
};
// Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution of requests on the
@@ -0,0 +1,159 @@
package de.rayzs.pat.plugin.modules;
import de.rayzs.pat.api.storage.blacklist.impl.GeneralBlacklist;
import de.rayzs.pat.plugin.modules.events.ExecuteCommand;
import de.rayzs.pat.plugin.modules.events.TabCompletion;
import de.rayzs.pat.plugin.modules.events.UpdateList;
import de.rayzs.pat.utils.node.CommandNodeHelper;
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.utils.*;
import java.util.*;
public class SubArgsModule {
public static List<String> GENERAL_LIST, BLOCKED_MESSAGE, PLAYER_NAMES, ONLINE_PLAYERS;
public static HashMap<UUID, Arguments> 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 = Storage.getLoader().getPlayerNames();
ONLINE_PLAYERS = Storage.getLoader().getOnlinePlayerNames();
}
public static List<String> getPlayerNames() {
return PLAYER_NAMES;
}
public static List<String> getOnlinePlayerNames() {
return ONLINE_PLAYERS;
}
public static void updateList() {
GENERAL_LIST = Storage.Blacklist.getBlacklist().getCommands().stream().filter(command -> command.contains(" ")).collect(Collectors.toList());
Arguments.ARGUMENTS.clearArguments();
GENERAL_LIST.forEach(command -> Arguments.ARGUMENTS.buildArgumentStacks(command));
SubArgsModule.PLAYER_COMMANDS = new HashMap<>();
}
public static void updateMessages() {
Storage.Files.CUSTOM_RESPONSES.reload();
ResponseHandler.update();
}
public static void handleCommandNode(UUID uuid, CommandNodeHelper helper) {
if (!Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED)
return;
Arguments arguments = PLAYER_COMMANDS.get(uuid);
if (arguments == null) {
return;
}
ArgumentSource source = arguments.TAB_ARGUMENTS;
if (source == null) return;
List<String> inputs = source.getAllInputs().stream().filter(str -> !str.contains("%")).toList();
List<String> allEntries = inputs.stream().map(StringUtils::getFirstArg).toList();
helper.removeIf(allEntries::contains);
inputs.forEach(helper::add);
}
public static List<String> getServerCommands(UUID uuid) {
return getServerCommands(Storage.getLoader().getPlayerServerName(uuid));
}
public static List<String> getServerCommands(String serverName) {
List<String> commands = new ArrayList<>(Storage.Blacklist.getBlacklist().getCommands());
if (!Reflection.isProxyServer())
return commands;
if (serverName == null)
return commands;
List<GeneralBlacklist> blacklists = Storage.Blacklist.getServerBlacklists(serverName);
for (GeneralBlacklist blacklist : blacklists)
commands.addAll(blacklist.getCommands());
return commands;
}
public static List<String> getGroupCommands(UUID uuid) {
return getGroupCommands(uuid, null);
}
public static List<String> getGroupCommands(UUID uuid, String serverName) {
List<String> commands = new ArrayList<>();
List<Group> groups = GroupManager.getPlayerGroups(uuid);
if (serverName == null) {
groups.forEach(group -> commands.addAll(group.getCommands()));
return commands;
}
groups.forEach(group -> {
commands.addAll(group.getCommands());
List<String> associatedServerNames = group.getBlacklistServerNames(serverName);
associatedServerNames.forEach(s -> {
commands.addAll(group.getCommands(s));
});
});
return commands;
}
public static String replacePlaceholders(String input) {
String[] split = input.split(" ");
for (int i = 0; i < split.length; i++) {
String s = split[i];
boolean number = NumberUtils.isDigit(split[i]),
online = Storage.getLoader().isPlayerOnline(s),
general = Storage.getLoader().doesPlayerExist(s);
if (number) {
split[i] = "%numbers%";
continue;
}
if (online && general) {
split[i] = "%both_players%";
continue;
}
if (online) {
split[i] = "%online_players%";
continue;
}
if (general)
split[i] = "%players%";
}
return String.join(" ", split);
}
}
@@ -0,0 +1,185 @@
package de.rayzs.pat.plugin.modules.events;
import de.rayzs.pat.api.event.events.ExecuteCommandEvent;
import de.rayzs.pat.plugin.modules.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.sender.CommandSender;
import de.rayzs.pat.utils.sender.CommandSenderHandler;
import de.rayzs.pat.utils.subargs.*;
import de.rayzs.pat.utils.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class ExecuteCommand extends ExecuteCommandEvent {
@Override
public void handle(ExecuteCommandEvent event) {
String command = event.getCommand();
command = command.startsWith("/")
? command.substring(1)
: command;
final String displayCommand = StringUtils.replaceTriggers(
command, "",
"\\", "<", ">", "&"
);
CommandSender sender = CommandSenderHandler.from(event.getSenderObj());
if (sender == null)
return;
UUID uuid = sender.getUniqueId();
if (Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isCommand(command)) {
MessageTranslator.send(
event.getSenderObj(),
Storage.ConfigSections.Settings.CUSTOM_PLUGIN.MESSAGE,
"%command%", StringUtils.getFirstArg(displayCommand)
);
event.setBlocked(true);
event.setCancelled(true);
event.setDoesNotify(true);
return;
}
if (Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(command)) {
MessageTranslator.send(
event.getSenderObj(),
Storage.ConfigSections.Settings.CUSTOM_VERSION.MESSAGE,
"%command%", StringUtils.getFirstArg(displayCommand)
);
event.setBlocked(true);
event.setCancelled(true);
event.setDoesNotify(true);
return;
}
if (isBlocked(sender, command)) {
event.setBlocked(true);
event.setCancelled(true);
MessageTranslator.send(event.getSenderObj(),
ResponseHandler.getResponse(uuid, event.getCommand()),
"%command%", displayCommand);
return;
}
if (!event.isBlocked())
return;
event.setCancelled(true);
MessageTranslator.send(
event.getSenderObj(),
ResponseHandler.getResponse(uuid, event.getCommand(), Storage.ConfigSections.Settings.CANCEL_COMMAND.BASE_COMMAND_RESPONSE.getLines()),
"%command%", StringUtils.getFirstArg(displayCommand)
);
}
private boolean isBlocked(CommandSender sender, String command) {
final Arguments arguments = SubArgsModule.PLAYER_COMMANDS.getOrDefault(sender.getUniqueId(), Arguments.ARGUMENTS);
final List<String> commands = new ArrayList<>(arguments.CHAT_ARGUMENTS.getGeneralArgument().getInputs());
final String firstArgument = StringUtils.getFirstArg(command);
final String blockBaseCommandStr = firstArgument + " -_";
final boolean blockBaseCommand = commands.contains(blockBaseCommandStr);
if (!command.contains(" ")) {
return blockBaseCommand;
}
if (blockBaseCommand) {
commands.remove(blockBaseCommandStr);
}
boolean inCommands = commands.stream().anyMatch(c -> StringUtils.getFirstArg(c).equalsIgnoreCase(firstArgument));
boolean negationInCommands = commands.stream().anyMatch(c -> StringUtils.getFirstArg(c).equalsIgnoreCase("!" + firstArgument));
if (!inCommands && !negationInCommands) {
return false;
}
boolean turn = Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED;
boolean listed = isListed(command, commands);
boolean negated = isListed("!" + command, commands);
if (!listed && !inCommands) {
listed = turn;
}
if (negated) {
listed = !turn;
}
return turn != listed;
}
private boolean isListed(String command, List<String> commands) {
boolean listed = false;
final String unmodifiable = command;
final String firstArgUnmodifiable = StringUtils.getFirstArg(unmodifiable);
commands = commands.stream().map(c -> {
if (c.contains("%hidden")) {
return c.replace("%hidden_", "%");
}
return c;
}).toList();
List<String> placeholderCommands = commands.stream().filter(s ->
StringUtils.getFirstArg(s).equalsIgnoreCase(firstArgUnmodifiable) && s.contains("%")
).toList();
if (!placeholderCommands.isEmpty()) {
command = SubArgsModule.replacePlaceholders(command);
}
String cpyCommand;
for (String c : commands) {
cpyCommand = command;
if (listed)
break;
if (cpyCommand.contains("%both_players%")) {
if (c.contains("%online_players%"))
cpyCommand = StringUtils.replace(command, "%both_players%", "%online_players%");
if (c.contains("%players%"))
cpyCommand = StringUtils.replace(command, "%both_players%", "%players%");
}
boolean ends = c.endsWith("_-");
if (ends) {
c = StringUtils.replace(c, "_-", "");
if (c.endsWith(" "))
c = StringUtils.replaceLast(c, " ", "");
}
listed = c.equalsIgnoreCase(cpyCommand) || cpyCommand.startsWith(c + " ");
if (listed && ends && cpyCommand.length() > c.length()) {
listed = false;
break;
}
}
return listed;
}
}
@@ -0,0 +1,134 @@
package de.rayzs.pat.plugin.modules.events;
import de.rayzs.pat.api.event.events.FilteredTabCompletionEvent;
import de.rayzs.pat.plugin.modules.SubArgsModule;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.*;
import de.rayzs.pat.utils.sender.CommandSenderHandler;
import de.rayzs.pat.utils.subargs.Arguments;
import java.util.*;
public class TabCompletion extends FilteredTabCompletionEvent {
@Override
public void handle(FilteredTabCompletionEvent event) {
final String cursor = event.getCursor().substring(1);
if (event.getCompletion().isEmpty()) return;
final boolean turn = Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED;
final UUID uuid = event.getSenderObj() instanceof UUID
? (UUID) event.getSenderObj()
: CommandSenderHandler.from(event.getSenderObj()).getUniqueId();
final Arguments arguments = SubArgsModule.PLAYER_COMMANDS.getOrDefault(uuid, Arguments.ARGUMENTS);
List<String> possibilities = event.getCompletion(), result = new ArrayList<>(arguments.getResultTab(cursor));
final List<String> negated = new ArrayList<>(arguments.getResultTab("!" + cursor));
final List<String> negatedInputs = new ArrayList<>(arguments.TAB_ARGUMENTS.INPUTS).stream().filter(s -> {
if (s.isEmpty())
return false;
boolean n = s.charAt(0) == '!';
if (!n && s.length() > 5)
n = s.charAt(5) == '!';
return n;
}).map(s -> s.substring(1 + (s.charAt(0) == '[' ? 5 : 0))).toList();
if (negatedInputs.stream().anyMatch(cursor::startsWith)) {
if (turn) {
event.setCompletion(new ArrayList<>());
}
return;
}
result.removeIf(s -> s.contains("-_"));
if (turn) {
possibilities = result;
if (possibilities.isEmpty() && !negated.isEmpty()) {
possibilities = event.getCompletion();
possibilities.removeAll(negated);
}
if (result.contains("%numbers%")) {
possibilities.remove("%numbers%");
possibilities.addAll(event.getCompletion().stream().filter(NumberUtils::isDigit).toList());
if (possibilities.isEmpty())
possibilities.add("///////////");
}
if (result.contains("%players%")) {
possibilities.remove("%players%");
possibilities.addAll(SubArgsModule.getPlayerNames());
}
if (result.contains("%online_players%")) {
possibilities.remove("%online_players%");
possibilities.addAll(SubArgsModule.getOnlinePlayerNames());
}
if (result.contains("%hidden_players%")) {
possibilities.remove("%hidden_players%");
possibilities.addAll(event.getCompletion().stream().filter(completion -> {
if (SubArgsModule.getPlayerNames().contains(completion))
return false;
return result.contains(completion);
}).toList());
if (possibilities.isEmpty())
possibilities.add("///////////");
}
if (result.contains("%hidden_online_players%")) {
possibilities.remove("%hidden_online_players%");
possibilities.addAll(event.getCompletion().stream().filter(completion -> {
if (SubArgsModule.getOnlinePlayerNames().contains(completion))
return false;
return result.contains(completion);
}).toList());
if (possibilities.isEmpty())
possibilities.add("///////////");
}
} else {
if (result.contains("%numbers%"))
possibilities.removeIf(NumberUtils::isDigit);
if (result.contains("%players%"))
possibilities.removeIf(possibility -> SubArgsModule.getPlayerNames().contains(possibility));
if (result.contains("%online_players%"))
possibilities.removeIf(possibility -> SubArgsModule.getOnlinePlayerNames().contains(possibility));
possibilities.removeIf(s -> {
if (negated.contains(s)) {
return false;
}
return result.contains(s);
});
}
String firstCursorArg = StringUtils.getFirstArg(cursor.toLowerCase());
if (possibilities.isEmpty() && !SubArgsModule.GENERAL_LIST.contains(firstCursorArg)) {
return;
}
event.setCompletion(possibilities);
}
}
@@ -0,0 +1,97 @@
package de.rayzs.pat.plugin.modules.events;
import de.rayzs.pat.plugin.modules.SubArgsModule;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.sender.CommandSenderHandler;
import de.rayzs.pat.api.event.events.*;
import de.rayzs.pat.utils.subargs.Arguments;
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()
: CommandSenderHandler.from(event.getSenderObj()).getUniqueId();
final Arguments argument = SubArgsModule.PLAYER_COMMANDS.getOrDefault(uuid, new Arguments());
final String serverName = Storage.getLoader().getPlayerServerName(uuid);
argument.clearArguments();
if (Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED) {
for (String command : event.getCommands())
argument.buildArgumentStacks(command);
final List<String> chatInputs = new ArrayList<>(argument.CHAT_ARGUMENTS.getGeneralArgument().getInputs());
final List<String> tabInput = new ArrayList<>(argument.TAB_ARGUMENTS.getGeneralArgument().getInputs());
for (String command : chatInputs) {
Storage.Blacklist.BlockType type = Storage.Blacklist.BlockTypeFetcher.getType(command);
if (type != Storage.Blacklist.BlockType.NEGATE)
command = Storage.Blacklist.BlockTypeFetcher.modify(command, type);
argument.CHAT_ARGUMENTS.buildArguments(Storage.Blacklist.BlockTypeFetcher.modify(command));
}
for (String command : tabInput) {
Storage.Blacklist.BlockType type = Storage.Blacklist.BlockTypeFetcher.getType(command);
if (type != Storage.Blacklist.BlockType.NEGATE)
command = Storage.Blacklist.BlockTypeFetcher.modify(command, type);
argument.TAB_ARGUMENTS.buildArguments(command);
}
for (String command : SubArgsModule.getGroupCommands(uuid, serverName))
argument.buildArgumentStacks(command);
for (String command : SubArgsModule.getServerCommands(uuid))
argument.buildArgumentStacks(command);
} else {
List<String> groupCommands = SubArgsModule.getGroupCommands(uuid, serverName);
for (String command : argument.CHAT_ARGUMENTS.getGeneralArgument().getInputs()) {
if (groupCommands.contains(command)) continue;
argument.CHAT_ARGUMENTS.buildArguments(Storage.Blacklist.BlockTypeFetcher.modify(command));
}
for (String command : argument.TAB_ARGUMENTS.getGeneralArgument().getInputs()) {
if (groupCommands.contains(command)) continue;
argument.TAB_ARGUMENTS.buildArguments(Storage.Blacklist.BlockTypeFetcher.modify(command));
}
}
SubArgsModule.PLAYER_COMMANDS.putIfAbsent(uuid, argument);
}
};
}
Loaded 100 of 182 files, more files were not shown because too many files have changed in this diff. Show more