Compare commits

...
281 Commits
Author SHA1 Message Date
rayzsyt 0fc23712e4 Fixed exception 2025-12-10 23:18:18 +01:00
rayzsyt 6b9c717ec4 Fixed missing server-name 2025-12-10 09:08:41 +01:00
rayzsyt 0c3e82c01e Fixed TOKEN not automatically updating after PAT reload 2025-12-09 23:59:35 +01:00
rayzsyt 8e6e544b60 Deactivated netty injection if Handle-Through-Proxy is enabled 2025-12-09 23:28:48 +01:00
rayzsyt a4196fc118 Added removal from hiddenCommands 2025-12-09 23:21:30 +01:00
rayzsyt d5a9b99a7a Deactivated backend-side sub-argument handling entirely 2025-12-09 22:50:57 +01:00
rayzsyt 6d850f9f07 Added missing server name 2025-12-09 22:35:34 +01:00
rayzsyt c4987b7c5e Fix error while modifying serv commands 2025-12-09 21:32:21 +01:00
rayzsyt 3880738ed9 Modified behavior in regard to block-namespaced-commands in regard to the new option (executions only) 2025-12-09 21:18:08 +01:00
rayzsyt 68c00b843b Add command to hiddenCommands as well 2025-12-09 21:12:29 +01:00
rayzsyt dc352275b6 Add new option 2025-12-09 21:01:38 +01:00
rayzsyt b3362987e5 Reload file on clearance 2025-12-09 21:01:26 +01:00
rayzsyt fb3ec45059 Removed one line 2025-12-09 18:08:27 +01:00
rayzsyt 5100b4a852 Update all commands on first schedule tick (after all plugin loads) 2025-12-09 12:33:46 +01:00
rayzsyt e9ec801dc5 Update if plugin=X or ! command has been added 2025-12-09 12:33:27 +01:00
rayzsyt 70c31b8597 Added plugin=X feature 2025-12-09 12:33:08 +01:00
rayzsyt a078de1fc3 Lowercase by default 2025-12-09 11:19:04 +01:00
rayzsyt a1d759451c Created plugin=X to add all plugin commands 2025-12-09 11:07:26 +01:00
rayzsyt 8a9373963c Ignore packet-handling if Velocity is being used 2025-12-09 11:07:09 +01:00
rayzsyt d964d5b859 Shorten to use new getPluginCommands(String, boolean) method 2025-12-09 11:06:40 +01:00
rayzsyt b468865041 Created getPluginCommands(String, boolean) method 2025-12-09 11:06:22 +01:00
rayzsyt d6fec721ad Deactivated netty tab-completion process for 1.8.8 player 2025-12-08 19:01:40 +01:00
rayzsyt 9256398fa2 Fixed wrong 1.8.8 tab-completion filtering 2025-12-08 19:00:53 +01:00
rayzsyt 4fed08a8f9 Remove changes.txt from final built 2025-12-07 16:58:08 +01:00
rayzsyt b650156e57 Update version name 2025-12-07 16:52:34 +01:00
rayzsyt 4737d15be5 Added option to negate commands via PAT groups 2025-12-07 16:05:22 +01:00
rayzsyt aca6dd7e1d Added experimental code 2025-12-07 01:18:48 +01:00
rayzsyt 5aa0d000dd Better understanding 2025-12-07 01:18:40 +01:00
rayzsyt e2b238fb81 Improved readability 2025-12-06 05:05:59 +01:00
rayzsyt ebdb3edbc1 Fixed wrong display of last-sync time 2025-12-05 21:19:26 +01:00
rayzsyt b9f4e46d65 Attempt to make negatable commands more effective 2025-12-04 16:56:06 +01:00
rayzsyt 287ebd4e9c Ignore if Handle-Through-Proxy is enabled 2025-12-04 16:54:48 +01:00
rayzsyt befdc3de6a Fixed missing tab-completion for Bungeecord commands 2025-12-04 13:55:27 +01:00
rayzsyt 55d00876a7 Recode planned 2025-11-30 14:11:45 +01:00
rayzsyt be0ee15448 Removed unmodifiable, since it's modified later on 2025-11-30 14:11:27 +01:00
rayzsyt 7f91b85d6e Fixed wrong tab-completion of available commands 2025-11-23 22:36:29 +01:00
rayzsyt 80beacaef9 Improved 2025-11-23 05:04:18 +01:00
rayzsyt 9f0521f9de Shorten 2025-11-23 04:53:10 +01:00
rayzsyt 3e1fffcfbb Added reload function 2025-11-23 04:44:29 +01:00
rayzsyt c0e77efad6 Set ignoreColons to false by default 2025-11-23 04:44:08 +01:00
rayzsyt 490f6f420b Set default ignoreColons value to false 2025-11-23 04:43:24 +01:00
rayzsyt 228185291d Added new converters 2025-11-23 04:42:59 +01:00
rayzsyt ab17861e7c Shorten 2025-11-23 04:42:38 +01:00
rayzsyt 567ca5192c Implemented Code 2025-11-23 04:42:25 +01:00
rayzsyt 442a0797a2 Added 2025-11-23 04:42:05 +01:00
rayzsyt c1be977abd Improved 2025-11-23 04:42:00 +01:00
rayzsyt a6f670dcfb Fixed wrong default value 2025-11-20 01:27:48 +01:00
rayzsyt 1d3e72aae2 Fixed error 2025-11-19 21:19:18 +01:00
rayzsyt 513fce2059 Prevent permissions reload if uuid is null 2025-11-19 21:16:22 +01:00
rayzsyt 6247aee871 Added secondary injection attempt. 2025-11-19 21:14:37 +01:00
rayzsyt fc0e230ca5 Stop attempt of working with invalid uuids 2025-11-19 21:14:23 +01:00
rayzsyt d2972f602f More refined information to work with 2025-11-19 21:13:57 +01:00
rayzsyt 0f3b858a75 Fixed missing "usage" message 2025-11-19 17:15:02 +01:00
rayzsyt 70b449e83d Changed message 2025-11-19 17:14:37 +01:00
rayzsyt 2a58b6644e Changed warning message 2025-11-19 16:57:26 +01:00
rayzsyt 96f4386f7a Shorten and improve logic 2025-11-19 16:57:14 +01:00
rayzsyt 3e9de4e859 Added messages 2025-11-19 16:56:57 +01:00
rayzsyt dad2db500c Fixed wrong display of group commands 2025-11-19 16:03:58 +01:00
rayzsyt 9bd33477b1 Apply parameter 2025-11-19 15:23:43 +01:00
rayzsyt 01c680b69a Added format parameter 2025-11-19 15:23:33 +01:00
rayzsyt d20c3c2820 Add 2025-11-19 14:58:51 +01:00
rayzsyt dcb73b1672 Implement more save way to iterate through list 2025-11-19 14:58:43 +01:00
rayzsyt 389f006d02 Added Convert and Extract Command 2025-11-19 14:58:19 +01:00
rayzsyt 0266a6c5f9 Initialized StorageConverter 2025-11-19 14:58:02 +01:00
rayzsyt 9b53123e92 Update version 2025-11-19 14:56:54 +01:00
rayzsyt 9e21110011 Updated version name 2025-11-09 01:58:43 +01:00
rayzsyt 5377c67614 Minor refactoring 2025-11-09 01:26:58 +01:00
rayzsyt 32f8c61d43 Added missing "disabled server" check 2025-11-09 01:26:51 +01:00
rayzsyt 2a16db32ba Added missing "disabled server" check 2025-11-09 01:23:59 +01:00
rayzsyt 735c3764db Edit 2025-11-02 01:55:04 +01:00
rayzsyt c160feb422 Readded notification for custom-plugins & custom-version feature 2025-11-02 01:24:33 +01:00
rayzsyt 21ed81d9ce Removed custom-plugin and custom-version check from there 2025-11-02 01:21:15 +01:00
rayzsyt 6c25c8570d Readded command blocking if command is part of custom-plugins or custom-versions feature 2025-11-02 01:20:23 +01:00
rayzsyt 560c9c3c8b Removed UpdateGroupsPerServer feature for now 2025-10-30 23:53:16 +01:00
rayzsyt 095f4d6179 Fixed issue 2025-10-30 22:16:24 +01:00
rayzsyt 4d389a3e3b Fixed wrong tab-completion filtering 2025-10-28 22:25:26 +01:00
rayzsyt 7f6a5aeba4 Minor logic change 2025-10-22 07:54:18 +02:00
rayzsyt 3006ffac30 Minor rename implementation 2025-10-18 10:07:38 +02:00
rayzsyt d0a256a281 Minor description adjustments 2025-10-18 10:07:18 +02:00
rayzsyt fceab89bc7 Added UpdateGroupPerServer 2025-10-18 10:07:08 +02:00
rayzsyt 6c11525879 Add 2025-10-18 03:47:31 +02:00
rayzsyt 3decc0453b Renamed 2025-10-18 03:47:00 +02:00
rayzsyt b4f9aec084 Mini refactor 2025-10-18 03:41:18 +02:00
rayzsyt 4cd1901e48 Mini refactor 2025-10-18 03:39:38 +02:00
rayzsyt 2aca1d42b0 Fixed missing permissions update after (de)op 2025-10-18 02:46:44 +02:00
rayzsyt 23050b6788 Improved performance by *literally* using a list I already had ;-; 2025-10-18 01:49:02 +02:00
rayzsyt 07bd37bc51 Changed UUID to senderObj 2025-10-17 21:59:44 +02:00
rayzsyt de2ffe910f Update player groups 2025-10-16 02:10:23 +02:00
rayzsyt e3f33e0df4 Wrong display of count 2025-10-16 02:04:41 +02:00
rayzsyt d919bee580 Shorten 2025-10-16 01:40:59 +02:00
rayzsyt ab10f02e3e Replaced with Logger 2025-10-16 01:08:59 +02:00
rayzsyt 647a4ed2b4 Removed debug messages 2025-10-16 01:07:41 +02:00
rayzsyt 5b11e09ece Made task sync 2025-10-16 01:07:16 +02:00
rayzsyt 5c006b3ba7 Implemented method 2025-10-16 01:06:55 +02:00
rayzsyt ba970a2ae4 Moved body to Storage.quickSubArgumentUpdate 2025-10-16 01:06:41 +02:00
rayzsyt 2a51caba40 Improved logic 2025-10-16 01:05:53 +02:00
rayzsyt 5b9035b766 Moved bypass permission check 2025-10-15 23:39:34 +02:00
rayzsyt 41365e07f6 Minor logic adjustments and removal of message 2025-10-15 23:38:51 +02:00
rayzsyt 9fbaf9c628 Minor method adjustment 2025-10-15 23:38:26 +02:00
rayzsyt 730fe64eeb Minor refactor changes 2025-10-15 23:38:05 +02:00
rayzsyt 266fc497d8 Skip if bypass permission exists 2025-10-15 23:37:18 +02:00
rayzsyt 871443b643 Adjustment for non-LuckPerms servers 2025-10-15 23:37:00 +02:00
rayzsyt 4094ee0211 Add broadcastPermissionsPluginNotice method 2025-10-15 23:36:31 +02:00
rayzsyt 0bcd099dcd Improved for non-LuckPerms servers 2025-10-15 23:36:00 +02:00
rayzsyt 04b603569d Improved auto update process 2025-10-15 23:35:40 +02:00
rayzsyt 5a4951aec2 Improved and shorten code 2025-10-15 23:34:59 +02:00
rayzsyt a16aa53561 Minor refactor changes 2025-10-15 23:34:08 +02:00
rayzsyt a4bbcd5f99 Remove unnecessary tab-completion 2025-10-15 23:33:34 +02:00
rayzsyt 75263af008 Implement new packet UpdateCommandsPacket 2025-10-15 23:32:59 +02:00
rayzsyt 6c74c6f1d1 Add new packet 2025-10-15 23:32:47 +02:00
rayzsyt 1ba064db1b Implement updateSenderObject method 2025-10-15 23:32:37 +02:00
rayzsyt e10c55a35b Skip filtering if bypass permission exists 2025-10-15 23:32:26 +02:00
rayzsyt 29a234d94d Implement updateSenderObject method 2025-10-15 23:31:40 +02:00
rayzsyt ccf97cca20 Implement updateSenderObject method 2025-10-15 23:31:33 +02:00
rayzsyt 4ee5908c96 Improve PermissionCheck for non-LuckPerms users 2025-10-15 23:31:20 +02:00
rayzsyt 53128a49bb Added check for bypass permission 2025-10-15 23:30:50 +02:00
rayzsyt 6092960af5 Minor refactor changes 2025-10-15 23:30:22 +02:00
rayzsyt c9e4c9f077 Implement updateSenderObject method 2025-10-15 23:30:00 +02:00
rayzsyt d00a44de53 Improve PermissionCheck for non-LuckPerms users 2025-10-15 23:29:30 +02:00
rayzsyt adfff4c520 Minor refactor changes 2025-10-15 23:29:01 +02:00
rayzsyt fb0dac4e3b Minor refactor changes 2025-10-15 23:28:52 +02:00
rayzsyt 71a43bd431 Updated version name 2025-10-15 23:28:29 +02:00
rayzsyt 339f0490cf Added broadcastPermissionsPluginNotice call and handleUpdateCommandsPacket method 2025-10-15 23:28:15 +02:00
rayzsyt 3e9e71812a Added broadcastPermissionsPluginNotice call 2025-10-15 23:27:44 +02:00
rayzsyt fd0e7c6f7f New 2025-10-15 23:27:15 +02:00
rayzsyt 07a61712ea Added new method 2025-10-15 23:25:49 +02:00
rayzsyt 33080da0b1 Added better PermissionSystem detection 2025-10-15 14:53:41 +02:00
rayzsyt 02f48525e2 Removed display of sub-arguments if using Handle-Through-Proxy 2025-10-12 16:42:35 +02:00
rayzsyt c2aacd1b0c Small improvement 2025-10-12 16:42:14 +02:00
rayzsyt b524ff0701 Moved Methods 2025-10-12 16:09:23 +02:00
rayzsyt b5bffb6731 Update version name 2025-10-12 14:43:00 +02:00
rayzsyt cf84c608a6 Reload Allowed/Disallowed-Commands after change 2025-10-12 14:41:22 +02:00
rayzsyt e61ea7c8b3 Improved 2025-10-12 14:41:00 +02:00
rayzsyt a63df948d7 Removed unused libraries 2025-10-12 14:26:55 +02:00
rayzsyt 509bad85c2 Auto-Command-Sync for Bungeecord 2025-10-12 14:26:46 +02:00
rayzsyt ef48117ab4 Added Bungeecord-intern SubArgument Filter 2025-10-12 14:06:18 +02:00
rayzsyt 08724d4fa8 Small adjustments 2025-10-12 14:04:53 +02:00
rayzsyt 59e5c15c0f Fix minor issue 2025-10-12 03:01:43 +02:00
rayzsyt e96572b62b Fix minor issue 2025-10-12 02:31:23 +02:00
rayzsyt 441eb3f439 Accidental wrong method 2025-10-12 02:07:56 +02:00
rayzsyt 479beb17de Fix minor issues 2025-10-12 02:02:36 +02:00
rayzsyt 92939ba2fd Fix minor issues 2025-10-12 02:02:32 +02:00
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
116 changed files with 3845 additions and 1339 deletions

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2024 Alihan
Copyright (c) 2025 Alihan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+20 -18
View File
@@ -6,7 +6,7 @@
<groupId>de.rayzs.pat</groupId>
<artifactId>ProAntiTab</artifactId>
<version>2.0.2</version>
<version>2.2.0</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
@@ -72,25 +72,10 @@
<url>https://repo.william278.net/papiproxybridge</url>
</repository>
<repository>
<id>skript-releases</id>
<name>Skript Repository</name>
<url>https://repo.skriptlang.org/releases</url>
</repository>
</repositories>
<dependencies>
<!--
<dependency>
<groupId>org.skriptlang</groupId>
<artifactId>Skript</artifactId>
<version>2.10.1</version>
<scope>provided</scope>
</dependency>
!-->
<dependency>
<groupId>dev.folia</groupId>
<artifactId>folia-api</artifactId>
@@ -134,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>
@@ -235,14 +227,14 @@
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.20.0</version>
<version>4.25.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.20.0</version>
<version>4.25.0</version>
<scope>compile</scope>
</dependency>
@@ -299,6 +291,16 @@
<build>
<finalName>IgnoreThisJar</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>*.txt</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -71,6 +71,14 @@ public class Communicator {
return;
}
if (packet instanceof CommunicationPackets.UpdateCommandsPacket) {
if (Reflection.isProxyServer())
return;
CommunicationPackets.UpdateCommandsPacket updateCommandsPacket = (CommunicationPackets.UpdateCommandsPacket) packet;
BukkitLoader.handleUpdateCommandsPacket(updateCommandsPacket);
}
if (packet instanceof CommunicationPackets.ForcePermissionResetPacket) {
if (Reflection.isProxyServer())
return;
@@ -219,6 +227,14 @@ public class Communicator {
sendPacket(new CommunicationPackets.ForcePermissionResetPacket(Storage.TOKEN));
}
public static void sendUpdateCommand() {
sendPacket(new CommunicationPackets.UpdateCommandsPacket(Storage.TOKEN));
}
public static void sendUpdateCommand(UUID targetUUID) {
sendPacket(new CommunicationPackets.UpdateCommandsPacket(Storage.TOKEN, targetUUID));
}
public static void sendFeedback() {
sendPacket(new CommunicationPackets.FeedbackPacket(Storage.TOKEN, SERVER_ID.toString()));
}
@@ -10,8 +10,8 @@ public class PATEventHandler {
private static List<PATEvent> EVENTS = new ArrayList<>();
public static ExecuteCommandEvent callExecuteCommandEvents(Object senderObj, String command, boolean blocked) {
ExecuteCommandEvent event = EmptyEvent.createEmptyExecuteCommandEvent(senderObj, 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) {
@@ -169,8 +169,8 @@ public class PATEventHandler {
};
}
public static ExecuteCommandEvent createEmptyExecuteCommandEvent(Object senderObj, String command, boolean blocked) {
return new ExecuteCommandEvent(senderObj, command, blocked) {
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) {
@@ -5,18 +5,24 @@ import de.rayzs.pat.api.event.PATEvent;
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(Object senderObj, String command, boolean blocked) {
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() {
@@ -27,6 +33,10 @@ public abstract class ExecuteCommandEvent extends PATEvent<ExecuteCommandEvent>
return blocked;
}
public boolean doesNotify() {
return notify;
}
public void setBlocked(boolean blocked) {
this.blocked = blocked;
}
@@ -42,13 +42,13 @@ public class BukkitPacketAnalyzer {
}
public static boolean inject(Player player) {
if (Storage.USE_VELOCITY)
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED)
return true;
try {
Channel channel = Reflection.getPlayerChannel(player);
if (channel == null) {
Logger.warning("Failed to inject " + player.getName() + "! Channel is null.");
return false;
}
@@ -57,8 +57,22 @@ public class BukkitPacketAnalyzer {
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;
}
@@ -67,7 +81,7 @@ public class BukkitPacketAnalyzer {
}
public static void uninject(UUID uuid) {
if (Storage.USE_VELOCITY)
if (Storage.SEND_CONSOLE_NOTIFICATION)
return;
if (BukkitPacketAnalyzer.INJECTED_PLAYERS.containsKey(uuid)) {
@@ -77,7 +91,7 @@ public class BukkitPacketAnalyzer {
}
public static void uninject(Channel channel) {
if (Storage.USE_VELOCITY)
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED)
return;
if (channel != null) {
@@ -110,22 +124,25 @@ public class BukkitPacketAnalyzer {
@Override
public void channelRead(ChannelHandlerContext channel, Object packetObj) {
try {
if (packetObj.getClass() != null) {
String packetName = packetObj.getClass().getSimpleName();
if (!packetName.equals("PacketPlayInTabComplete") && !packetName.equals("ServerboundCommandSuggestionPacket")) {
super.channelRead(channel, packetObj);
return;
}
if (!PermissionUtil.hasBypassPermission(player)) {
if (!PACKET_HANDLER.handleIncomingPacket(player, packetObj))
return;
}
if (packetObj.getClass() == null || Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
super.channelRead(channel, packetObj);
return;
}
String packetName = packetObj.getClass().getSimpleName();
if (!packetName.equals("PacketPlayInTabComplete") && !packetName.equals("ServerboundCommandSuggestionPacket")) {
super.channelRead(channel, packetObj);
return;
}
if (!PermissionUtil.hasBypassPermission(player)) {
if (!PACKET_HANDLER.handleIncomingPacket(player, packetObj))
return;
}
super.channelRead(channel, packetObj);
} catch (Throwable exception) { exception.printStackTrace(); }
}
@@ -134,30 +151,33 @@ public class BukkitPacketAnalyzer {
public void write(ChannelHandlerContext channel, Object packetObj, ChannelPromise promise) {
try {
if(packetObj.getClass() != null) {
String packetName = packetObj.getClass().getSimpleName();
if(packetObj.getClass() == null || Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
super.write(channel, packetObj, promise);
return;
}
if (!packetName.equals("PacketPlayOutTabComplete") && !packetName.equals("ClientboundCommandSuggestionsPacket")) {
super.write(channel, packetObj, promise);
return;
}
String packetName = packetObj.getClass().getSimpleName();
if (!PermissionUtil.hasBypassPermission(player)) {
if (!packetName.equals("PacketPlayOutTabComplete") && !packetName.equals("ClientboundCommandSuggestionsPacket")) {
super.write(channel, packetObj, promise);
return;
}
UUID uuid = player.getUniqueId();
Object sentPacketObj = SENT_PACKET.get(uuid);
if (!PermissionUtil.hasBypassPermission(player)) {
if (sentPacketObj != null) {
if (sentPacketObj == packetObj) {
SENT_PACKET.remove(uuid);
super.write(channel, sentPacketObj, promise);
return;
}
}
UUID uuid = player.getUniqueId();
Object sentPacketObj = SENT_PACKET.get(uuid);
if (!PACKET_HANDLER.handleOutgoingPacket(player, packetObj))
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);
@@ -4,8 +4,8 @@ import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import de.rayzs.pat.utils.StringUtils;
import org.bukkit.entity.Player;
import de.rayzs.pat.api.event.PATEventHandler;
@@ -13,7 +13,6 @@ 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.plugin.logger.Logger;
import de.rayzs.pat.utils.Reflection;
@@ -34,75 +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)
if(rawInput == null)
return false;
boolean cancelsBeforeHand;
int spaces = 0;
String input = rawInput;
boolean cancelsBeforeHand = false;
if (input.startsWith("/")) {
input = input.replace("/", "");
if (!input.startsWith("/")) {
return true;
}
if (input.contains(" ")) {
String[] split = input.split(" ");
spaces = split.length;
if (spaces > 0)
input = split[0];
}
input = input.substring(1);
cancelsBeforeHand = Storage.Blacklist.canPlayerAccessTab(player, input);
if (!cancelsBeforeHand)
cancelsBeforeHand = Storage.ConfigSections.Settings.CUSTOM_VERSION.isTabCompletable(input) || Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isTabCompletable(input);
} else return true;
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.isCommand(input) || Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(input);
}
for (Field field : Reflection.getFields(packetObj)) {
field.setAccessible(true);
Object result = field.get(packetObj);
if (!(result instanceof String[]))
if (!(result instanceof String[])) {
continue;
List<String> newResultList = new ArrayList<>();
String[] tR = (String[]) result;
String tempName;
boolean doesBypassNamespace = Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesBypass(player);
if (spaces == 0) {
for (String s : tR) {
if (!BukkitLoader.isLoaded())
continue;
if (!s.startsWith("/")) {
newResultList.add(s);
continue;
}
tempName = s.replaceFirst("/", "");
if (!doesBypassNamespace && Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.isCommand(tempName))
continue;
if (!Storage.Blacklist.canPlayerAccessTab(player, tempName))
newResultList.add(s);
}
} else {
if (!cancelsBeforeHand) {
FilteredTabCompletionEvent filteredTabCompletionEvent = PATEventHandler.callFilteredTabCompletionEvents(player.getUniqueId(), input, Arrays.asList(tR));
if (!filteredTabCompletionEvent.isCancelled()) {
List<String> suggestions = Arrays.stream(tR).filter(s -> filteredTabCompletionEvent.getCompletion().contains(s)).collect(Collectors.toList());
newResultList.addAll(suggestions);
}
}
}
field.set(packetObj, newResultList.toArray(new String[0]));
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;
@@ -3,6 +3,7 @@ package de.rayzs.pat.api.netty.proxy;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
@@ -10,12 +11,15 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.RootCommandNode;
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.plugin.modules.SubArgsModule;
import de.rayzs.pat.utils.CommandsCache;
import de.rayzs.pat.utils.ExpireCache;
import de.rayzs.pat.utils.node.CommandNodeHelper;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.StringUtils;
@@ -31,6 +35,7 @@ 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.TabCompleteRequest;
import net.md_5.bungee.protocol.packet.TabCompleteResponse;
public class BungeePacketAnalyzer {
@@ -39,17 +44,20 @@ public class BungeePacketAnalyzer {
private static final String HANDLER_NAME = "pat-bungee-handler", PIPELINE_NAME = "packet-decoder";
private static final HashMap<ProxiedPlayer, Boolean> PLAYER_MODIFIED = new HashMap<>();
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 ExpireCache<UUID, String> PLAYER_INPUT_CACHE = new ExpireCache<>(5, TimeUnit.SECONDS);
private static final List<String> PLUGIN_COMMANDS = new ArrayList<>();
private static Class<?> channelWrapperClass, serverConnectionClass;
private static final List<String> PROXY_COMMANDS;
private static List<String> PROXY_COMMANDS;
static {
CommandNodeHelper.setDefaultSuggestionProvider(Commands.SuggestionRegistry.ASK_SERVER);
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;
@@ -110,7 +118,7 @@ public class BungeePacketAnalyzer {
}
public static void uninject(ProxiedPlayer player) {
BungeePacketAnalyzer.PLAYER_INPUT_CACHE.remove(player);
BungeePacketAnalyzer.PLAYER_INPUT_CACHE.remove(player.getUniqueId());
BungeePacketAnalyzer.PLAYER_MODIFIED.remove(player);
if(BungeePacketAnalyzer.INJECTED_PLAYERS.containsKey(player)) {
@@ -127,9 +135,13 @@ public class BungeePacketAnalyzer {
}
}
public static void setPlayerInput(ProxiedPlayer player, String input) {
PLAYER_INPUT_CACHE.putIgnoreIfContains(player.getUniqueId(), input);
}
public static String getPlayerInput(ProxiedPlayer player) {
String input = PLAYER_INPUT_CACHE.get(player);
PLAYER_INPUT_CACHE.remove(player);
String input = PLAYER_INPUT_CACHE.get(player.getUniqueId());
PLAYER_INPUT_CACHE.remove(player.getUniqueId());
return input;
}
@@ -137,23 +149,38 @@ public class BungeePacketAnalyzer {
ServerInfo serverInfo = player.getServer().getInfo();
String serverName = serverInfo.getName();
final boolean ignore = PermissionUtil.hasBypassPermission(player) || Storage.Blacklist.isDisabledServer(serverName);
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<String>(PROXY_COMMANDS);
List<String> commandsAsString = new ArrayList<>(PROXY_COMMANDS);
commandsAsString.addAll(helper.getChildrenNames());
commandsCache.handleCommands(commandsAsString, serverName);
List<String> playerCommands = new ArrayList<>();
List<String> playerCommands = commandsCache.getPlayerCommands(commandsAsString, player, player.getUniqueId(), serverName);
if (!ignore) {
helper.removeIf(str -> !playerCommands.contains(str));
Map<String, CommandsCache> cache = Storage.getLoader().getCommandsCacheMap();
if (!cache.containsKey(serverName)) {
cache.put(serverName, new CommandsCache());
}
CommandsCache commandsCache = cache.get(serverName);
commandsCache.handleCommands(commandsAsString, serverName);
List<String> tmpPlayerCommands = commandsCache.getPlayerCommands(commandsAsString, player, serverName);
helper.removeIf(str -> !tmpPlayerCommands.contains(str));
if (Storage.ConfigSections.Settings.CUSTOM_VERSION.ALWAYS_TAB_COMPLETABLE) {
Storage.ConfigSections.Settings.CUSTOM_VERSION.COMMANDS.getLines().forEach(input -> helper.add(input, false));
}
if (Storage.ConfigSections.Settings.CUSTOM_PLUGIN.ALWAYS_TAB_COMPLETABLE) {
Storage.ConfigSections.Settings.CUSTOM_PLUGIN.COMMANDS.getLines().forEach(input -> helper.add(input, false));
}
playerCommands = tmpPlayerCommands;
}
for (Map.Entry<String, Command> command : ProxyServer.getInstance().getPluginManager().getCommands()) {
@@ -163,33 +190,49 @@ public class BungeePacketAnalyzer {
if (commands.getRoot().getChild(command.getKey()) != null)
continue;
if (!command.getValue().hasPermission(player))
if (!command.getValue().hasPermission(player)) {
continue;
}
String commandName = command.getKey();
commandName = commandName.startsWith("/") ? commandName.substring(1) : commandName;
if (!playerCommands.contains(commandName))
continue;
if (!ignore) {
boolean tabablePluginCommand = Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isTabCompletable(commandName);
boolean tabableVersionCommand = Storage.ConfigSections.Settings.CUSTOM_VERSION.isTabCompletable(commandName);
CommandNode dummy = createDummyCommandNode(command.getKey());
if (!tabablePluginCommand && !tabableVersionCommand && !playerCommands.contains(commandName)) {
continue;
}
}
CommandNode dummy = CommandNodeHelper.createDummyCommandNode(command.getKey());
commands.getRoot().addChild(dummy);
}
// Disabled temporarily
// PROXY_COMMANDS.stream().filter(playerCommands::contains).forEach(helper::add);
// SubArgsModule.handleCommandNode(player.getUniqueId(), helper);
for (String command : PROXY_COMMANDS) {
if (ignore || playerCommands.contains(command)) {
helper.add(command, true);
}
}
if (!ignore) {
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();
public static void sendCommandsPacket() {
for (ProxiedPlayer player : ProxyServer.getInstance().getPlayers()) {
if (player.getPendingConnection().getVersion() < 754)
continue;
RootCommandNode root = new RootCommandNode();
Commands packet = new Commands(root);
modifyCommands(player, packet);
player.unsafe().sendPacket(packet);
}
}
private static class PacketDecoder extends MessageToMessageDecoder<PacketWrapper> {
@@ -207,7 +250,7 @@ public class BungeePacketAnalyzer {
return;
}
if(wrapper.packet instanceof PluginMessage) {
if (wrapper.packet instanceof PluginMessage) {
PluginMessage pluginMessage = (PluginMessage) wrapper.packet;
if(CustomServerBrand.isEnabled() && CustomServerBrand.isBrandTag(pluginMessage.getTag()))
return;
@@ -219,29 +262,37 @@ public class BungeePacketAnalyzer {
player.unsafe().sendPacket(response);
return;
/*
} else if (wrapper.packet instanceof TabCompleteResponse) {
TabCompleteResponse response = (TabCompleteResponse) wrapper.packet;
String serverName = player.getServer().getInfo().getName();
if(player.getPendingConnection().getVersion() < 754) {
if(!PermissionUtil.hasBypassPermission(player)) {
System.out.println("damn");
ClientInfo clientInfo = Communicator.getClientByName(player.getServer().getInfo().getName());
if (clientInfo == null || !PLAYER_INPUT_CACHE.containsKey(player))
if (!Storage.Blacklist.isDisabledServer(serverName) && player.getPendingConnection().getVersion() < 754) {
if (!PermissionUtil.hasBypassPermission(player)) {
System.out.println("Further!");
System.out.println("Got: " + PLAYER_INPUT_CACHE.get(player.getUniqueId()));
if (!PLAYER_INPUT_CACHE.contains(player.getUniqueId()))
return;
boolean cancelsBeforeHand = false;
String rawPlayerInput = getPlayerInput(player);
String rawPlayerInput = PLAYER_INPUT_CACHE.get(player.getUniqueId());
int spaces = rawPlayerInput.contains(" ") ? rawPlayerInput.split(" ").length : 0;
String playerInput = StringUtils.getFirstArg(rawPlayerInput),
server = player.getServer().getInfo().getName();
System.out.println("NETTY -> " + playerInput);
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, "/", ""));
cancelsBeforeHand = !Storage.ConfigSections.Settings.CUSTOM_VERSION.isTabCompletable(StringUtils.replaceFirst(playerInput, "/", "")) || Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isTabCompletable(StringUtils.replaceFirst(playerInput, "/", ""));
}
final String cursor = playerInput;
@@ -294,7 +345,7 @@ public class BungeePacketAnalyzer {
player.unsafe().sendPacket(new TabCompleteResponse(response.getCommands()));
}
}
}
}*/
}
list.add(wrapper);
@@ -1,10 +1,7 @@
package de.rayzs.pat.api.netty.proxy;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import com.velocitypowered.api.proxy.Player;
@@ -73,20 +70,27 @@ public class VelocityPacketAnalyzer {
channel = (Channel) Reflection.getMethodsByName(minecraftConnectionClass, "getChannel").get(0).invoke(minecraftConnectionObj);
if(channel == null) {
if (channel == null) {
Logger.warning("Failed to inject " + player.getUsername() + "! Channel is null.");
return false;
}
if(channel.pipeline().names().contains(VelocityPacketAnalyzer.PIPELINE_NAME))
if (channel.pipeline().names().contains(VelocityPacketAnalyzer.PIPELINE_NAME))
uninject(player);
channel.pipeline().addBefore(VelocityPacketAnalyzer.HANDLER_NAME, VelocityPacketAnalyzer.PIPELINE_NAME, new PacketDecoder(player));
VelocityPacketAnalyzer.INJECTED_PLAYERS.put(player, channel);
} catch (NoSuchElementException e) {
Logger.warning("Failed to find 'handler' inside player pipeline! (name=" + player.getUsername() + ", uuid=" + player.getUniqueId() + ", version=" + player.getProtocolVersion() + ", brand=" + player.getClientBrand() + " )");
return false;
} catch (Throwable throwable) {
throwable.printStackTrace();
return false;
} return true;
}
return true;
}
public static void uninject(Player player) {
@@ -190,6 +194,13 @@ public class VelocityPacketAnalyzer {
} else if (packet instanceof TabCompleteResponsePacket) {
String serverName = player.getCurrentServer().get().getServer().getServerInfo().getName();
if (Storage.Blacklist.isDisabledServer(serverName)) {
super.write(ctx, msg, promise);
return;
}
if (!PermissionUtil.hasBypassPermission(player) && player.getCurrentServer().isPresent()) {
TabCompleteResponsePacket response = (TabCompleteResponsePacket) packet;
@@ -213,7 +224,6 @@ public class VelocityPacketAnalyzer {
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.");
return;
}
@@ -223,6 +233,10 @@ public class VelocityPacketAnalyzer {
String command = offer.getText();
if (command.startsWith("/")) command = StringUtils.replaceFirst(command, "/", "");
if (Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isTabCompletable(command) || Storage.ConfigSections.Settings.CUSTOM_VERSION.isTabCompletable(command)) {
return false;
}
return !Storage.Blacklist.canPlayerAccessTab(player, command, player.getCurrentServer().get().getServerInfo().getName());
});
} else {
@@ -238,6 +252,7 @@ public class VelocityPacketAnalyzer {
}
response.getOffers().removeIf(offer -> !filteredTabCompletionEvent.getCompletion().contains(offer.getText()));
if (response.getOffers().isEmpty()) return;
}
}
@@ -246,10 +261,17 @@ public class VelocityPacketAnalyzer {
} else if (packet instanceof AvailableCommandsPacket) {
if (!PermissionUtil.hasBypassPermission(player) && player.getCurrentServer().isPresent()) {
String serverName = player.getCurrentServer().get().getServer().getServerInfo().getName();
if (Storage.Blacklist.isDisabledServer(serverName)) {
super.write(ctx, msg, promise);
return;
}
AvailableCommandsPacket commands = (AvailableCommandsPacket) packet;
if(!commands.getRootNode().getChildren().isEmpty()) {
String serverName = player.getCurrentServer().get().getServer().getServerInfo().getName();
Map<String, CommandsCache> cache = Storage.getLoader().getCommandsCacheMap();
if (!cache.containsKey(serverName))
@@ -264,7 +286,7 @@ public class VelocityPacketAnalyzer {
if (PermissionUtil.hasBypassPermission(player)) return;
final boolean newer = player.getProtocolVersion().getProtocol() > 340;
final List<String> playerCommands = commandsCache.getPlayerCommands(commandsAsString, player, player.getUniqueId(), serverName);
final List<String> playerCommands = commandsCache.getPlayerCommands(commandsAsString, player, serverName);
if (commands.getRootNode().getChildren().size() == 1 && newer
&& commands.getRootNode().getChild("args") != null
@@ -281,6 +303,10 @@ public class VelocityPacketAnalyzer {
if (command.getName().equals("args"))
return false;
if (Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isTabCompletable(command.getName()) || Storage.ConfigSections.Settings.CUSTOM_VERSION.isTabCompletable(command.getName())) {
return false;
}
return !playerCommands.contains(command.getName());
});
}
@@ -3,44 +3,23 @@ package de.rayzs.pat.api.storage;
import java.util.*;
import java.util.concurrent.TimeUnit;
import de.rayzs.pat.api.brand.CustomServerBrand;
import de.rayzs.pat.api.communication.BackendUpdater;
import de.rayzs.pat.api.communication.Communicator;
import de.rayzs.pat.api.netty.proxy.BungeePacketAnalyzer;
import de.rayzs.pat.api.storage.config.messages.*;
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 de.rayzs.pat.utils.configuration.updater.ConfigUpdater;
import de.rayzs.pat.utils.permission.PermissionPlugin;
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.config.settings.AutoLowercaseCommandsSection;
import de.rayzs.pat.api.storage.config.settings.BlockNamespaceCommandsSection;
import de.rayzs.pat.api.storage.config.settings.CancelCommandSection;
import de.rayzs.pat.api.storage.config.settings.CustomBrandSection;
import de.rayzs.pat.api.storage.config.settings.CustomPluginsSection;
import de.rayzs.pat.api.storage.config.settings.CustomProtocolPingSection;
import de.rayzs.pat.api.storage.config.settings.CustomUnknownCommandSection;
import de.rayzs.pat.api.storage.config.settings.CustomVersionSection;
import de.rayzs.pat.api.storage.config.settings.DisableSyncSection;
import de.rayzs.pat.api.storage.config.settings.HandleThroughProxySection;
import de.rayzs.pat.api.storage.config.settings.PatchExploitSection;
import de.rayzs.pat.api.storage.config.settings.TurnBlacklistToWhitelistSection;
import de.rayzs.pat.api.storage.config.settings.UpdateSection;
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;
@@ -82,14 +61,37 @@ public class Storage {
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_PLACEHOLDERAPI = false, USE_PAPIPROXYBRIDGE = false, USE_VIAVERSION = false, USE_VELOCITY = false, USE_SIMPLECLOUD;
public static long LAST_SYNC = System.currentTimeMillis();
private static PermissionPlugin PERMISSION_PLUGIN = PermissionPlugin.NONE;
public static void initialize(PluginLoader loader, String currentVersion) {
LOADER = loader;
CURRENT_VERSION = currentVersion;
}
public static void setPermissionPlugin(PermissionPlugin permissionPlugin) {
if (PERMISSION_PLUGIN == PermissionPlugin.LUCKPERMS) {
return;
}
PERMISSION_PLUGIN = permissionPlugin;
}
public static void broadcastPermissionsPluginNotice() {
if (Storage.getPermissionPlugin() != PermissionPlugin.NONE) {
return;
}
Logger.warning("No known permissions plugin found, so some features may be disabled.");
Logger.warning("Read more about it here: http://rayzs.de/products/proantitab/nkppf");
}
public static PermissionPlugin getPermissionPlugin() {
return PERMISSION_PLUGIN;
}
public static void loadAll(boolean loadBlacklist) {
loadConfig();
loadToken();
@@ -106,6 +108,7 @@ public class Storage {
}
public static void loadToken() {
Files.TOKEN.reload();
boolean invalidEnv = false;
@@ -161,6 +164,30 @@ public class Storage {
ConfigSections.PLACEHOLDERS.forEach(PlaceholderStorage::load);
}
public static void reload() {
boolean proxy = Reflection.isProxyServer();
boolean backend = Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED && !proxy;
ConfigUpdater.initialize();
Storage.loadAll(Reflection.isProxyServer() || !backend);
CustomServerBrand.initialize();
GroupManager.clearAllGroups();
GroupManager.initialize();
if (!proxy) {
BackendUpdater.stop();
BackendUpdater.start();
}
if (!backend) {
Storage.handleChange();
}
ConfigUpdater.broadcastMissingParts();
Storage.getLoader().handleReload();
}
public static void handleChange() {
handleChange(null);
}
@@ -204,6 +231,8 @@ public class Storage {
} else {
Storage.Blacklist.Experimental.forceCacheReset();
if (isVelocity) {
List<UUID> playerIds = Storage.getLoader().getPlayerIds();
@@ -222,16 +251,40 @@ public class Storage {
Storage.getLoader().updateCommandCache();
Communicator.sendPermissionReset();
if (!Reflection.isVelocityServer()) {
BungeePacketAnalyzer.sendCommandsPacket();
}
return;
}
getLoader().handleReload();
PermissionUtil.reloadPermissions();
if (Reflection.getMinor() >= 13) {
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();
}
}
// Quickly updates all player subarguments.
public static void quickSubArgumentUpdate(UUID uuid) {
List<String> playerCommands = new ArrayList<>(SubArgsModule.getServerCommands(uuid));
playerCommands.addAll(SubArgsModule.getGroupCommands(uuid));
PATEventHandler.callUpdatePlayerCommandsEvents(uuid, playerCommands, false);
}
public static PluginLoader getLoader() {
return LOADER;
}
@@ -288,6 +341,7 @@ public class Storage {
public static class Settings {
public static AllowGroupOverrulingSection ALLOW_GROUP_OVERRULING = new AllowGroupOverrulingSection();
public static AutoLowercaseCommandsSection AUTO_LOWERCASE_COMMANDS = new AutoLowercaseCommandsSection();
public static BlockNamespaceCommandsSection BLOCK_NAMESPACE_COMMANDS = new BlockNamespaceCommandsSection();
public static HandleThroughProxySection HANDLE_THROUGH_PROXY = new HandleThroughProxySection();
@@ -300,6 +354,10 @@ public class Storage {
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 UpdateGroupsPerWorldSection UPDATE_GROUPS_PER_WORLD = new UpdateGroupsPerWorldSection();
public static UpdateGroupsPerServerSection UPDATE_GROUPS_PER_SERVER = new UpdateGroupsPerServerSection();
public static UpdateSection UPDATE = new UpdateSection();
public static void initialize() {}
@@ -310,6 +368,8 @@ public class Storage {
public static PrefixSection PREFIX = new PrefixSection();
public static BlacklistSection BLACKLIST = new BlacklistSection();
public static CommandFailedSection COMMAND_FAILED = new CommandFailedSection();
public static ConvertSection CONVERT = new ConvertSection();
public static ExtractSection EXTRACT = new ExtractSection();
public static GroupSection GROUP = new GroupSection();
public static HelpSection HELP = new HelpSection();
public static InfoSection INFO = new InfoSection();
@@ -384,6 +444,19 @@ public class Storage {
public static class Blacklist {
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]"),
@@ -428,14 +501,9 @@ public class Storage {
BLACKLIST.getConfig().getKeys("global.servers", true).forEach(key -> {
GeneralBlacklist blacklist = BlacklistCreator.createGeneralBlacklist(key);
blacklist.load();
SERVER_BLACKLISTS.put(key, blacklist);
});
loadAllCachedServerBlacklists();
}
private static void loadAllCachedServerBlacklists() {
getServers().forEach(Blacklist::loadCachedServerBlacklists);
}
@@ -443,9 +511,7 @@ public class Storage {
List<GeneralBlacklist> blacklists = SERVER_BLACKLISTS.entrySet().stream()
.filter(entry ->
isServer(entry.getKey(), server)
).map(entry ->
entry.getValue()
).toList();
).map(Map.Entry::getValue).toList();
CACHED_SERVER_BLACKLIST.put(server, blacklists);
}
@@ -513,18 +579,69 @@ public class Storage {
}
public static boolean canPlayerAccess(Object player, String command, BlockType type, String server) {
boolean blocked = isBlocked(command, type, server);
final boolean allowGroupOverruling = ConfigSections.Settings.ALLOW_GROUP_OVERRULING.ENABLED;
final boolean blocked = isBlocked(command, type, server);
if (allowGroupOverruling) {
GroupManager.AccessResult groupResult = GroupManager.canAccessCommand(player, command, type, server);
if (groupResult == GroupManager.AccessResult.NEGATED) {
return false;
}
if (!blocked) {
return true;
}
if (Storage.getPermissionPlugin() != PermissionPlugin.NONE) {
if (PermissionUtil.hasBypassPermission(player, command)) {
return true;
}
}
return groupResult.asBoolean();
}
if (!blocked) {
return true;
}
if (PermissionUtil.hasBypassPermission(player, command)) {
if (Storage.getPermissionPlugin() != PermissionPlugin.NONE) {
if (PermissionUtil.hasBypassPermission(player, command)) {
return true;
}
}
return GroupManager.canAccessCommand(player, command, type, server).asBoolean();
}
/*
Experimental:
It allows to negate commands inside a PAT group to block them off,
even though it is allowed inside the global section.
public static boolean canPlayerAccess(Object player, String command, BlockType type, String server) {
boolean blocked = isBlocked(command, type, server);
GroupManager.AccessResult groupResult = GroupManager.canAccessCommand(player, command, type, server);
if (groupResult == GroupManager.AccessResult.NEGATED) {
return false;
}
if (!blocked) {
return true;
}
return GroupManager.canAccessCommand(player, command, type, server);
if (Storage.getPermissionPlugin() != PermissionPlugin.NONE) {
if (PermissionUtil.hasBypassPermission(player, command)) {
return true;
}
}
return groupResult.asBoolean();
}
*/
public static boolean isBlockedChat(String command) {
return isBlocked(command, BlockType.CHAT, null);
@@ -547,31 +664,56 @@ public class Storage {
}
public static boolean isBlocked(String command, BlockType type, String server) {
boolean listed = isListed(command, type, server),
BlockType negation = BlockType.NEGATE;
String negatedCommand = negation + command;
boolean all = isListed("*", type, server),
listed = isListed(command, type, server),
negatedListed = isListed(negatedCommand, type, server),
turn = ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED;
return !(listed && turn);
if (all) {
// Only listens to negated commands
if (negatedListed) {
return turn;
}
return !turn;
}
/*
if (turn) {
return !listed;
} else {
return listed;
}
*/
return turn != listed; // Shorter version of above's code
}
private static boolean isListed(String unmodifiedCommand, BlockType type, String server) {
if (server != null && isDisabledServer(server))
if (server != null && isDisabledServer(server)) {
return false;
}
boolean turn = Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED;
boolean listed = false;
if (type == BlockType.NEGATE)
turn = !turn;
String command = type.toString() + unmodifiedCommand;
if (server == null || !isIgnoredServer(server))
listed = BLACKLIST.isListed(command, !turn);
if (server == null || !isIgnoredServer(server)) {
listed = BLACKLIST.isListed(command, false);
}
if (server == null) {
if (!listed && type != BlockType.BOTH)
if (!listed && type != BlockType.BOTH) {
return isListed(unmodifiedCommand, BlockType.BOTH, null);
}
return listed;
}
@@ -581,11 +723,11 @@ public class Storage {
blacklists.add(BLACKLIST);
for (GeneralBlacklist blacklist : blacklists) {
if (listed && turn) {
if (listed) {
break;
}
listed = blacklist.isListed(command, turn);
listed = blacklist.isListed(command, false);
}
if (!listed && type != BlockType.BOTH) {
@@ -0,0 +1,25 @@
package de.rayzs.pat.api.storage.config.messages;
import de.rayzs.pat.api.storage.storages.ConfigStorage;
import de.rayzs.pat.utils.configuration.helper.ConfigSectionHelper;
import de.rayzs.pat.utils.configuration.helper.MultipleMessagesHelper;
public class ConvertSection extends ConfigStorage {
public MultipleMessagesHelper MESSAGE;
public ConvertSection() {
super("convert");
}
public String INVALID_CONVERTER, SUCCESS;
@Override
public void load() {
super.load();
INVALID_CONVERTER = new ConfigSectionHelper<String>(this, "converter-not-found", "&cConverter or necessary files could not be found!").getOrSet();
SUCCESS = new ConfigSectionHelper<String>(this, "success", "&aSuccessfully converted &e%converter% &ainto the PAT storage.yml!").getOrSet();
}
}
@@ -0,0 +1,31 @@
package de.rayzs.pat.api.storage.config.messages;
import de.rayzs.pat.api.storage.storages.ConfigStorage;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.configuration.helper.ConfigSectionHelper;
import de.rayzs.pat.utils.configuration.helper.MultipleMessagesHelper;
public class ExtractSection extends ConfigStorage {
public MultipleMessagesHelper MESSAGE;
public ExtractSection() {
super("extract");
}
public String USAGE, PLUGIN_NOT_FOUND, SUCCESS;
@Override
public void load() {
super.load();
if (Reflection.isProxyServer()) {
return;
}
USAGE = new ConfigSectionHelper<String>(this, "usage", "&7Usage: &f/pat extract [plugin] <use-colon> &7or &f<group> <use-colon>").getOrSet();
PLUGIN_NOT_FOUND = new ConfigSectionHelper<String>(this, "plugin-not-found", "&cPlugin %plugin% not found!").getOrSet();
SUCCESS = new ConfigSectionHelper<String>(this, "success", "&aSuccessfully extracted &e%amount% &anew commands from %plugin%!").getOrSet();
}
}
@@ -16,6 +16,7 @@ public class HelpSection extends ConfigStorage {
@Override
public void load() {
super.load();
MESSAGE = new MultipleMessagesHelper(this, null, Reflection.isProxyServer() ?
Arrays.asList(
"&7Available commands are: &f/%label%&7..."
@@ -26,6 +27,8 @@ public class HelpSection extends ConfigStorage {
, "&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 extract (plugin) &7to extract all plugin commands"
, "&f convert (plugin) &7converts into a PAT storage.yml"
, "&f creategroup (group) &7Create a group"
, "&f deletegroup (group) &7Delete a group"
, "&f setpriority (group) (priority) &7to set the priority"
@@ -44,6 +47,7 @@ public class HelpSection extends ConfigStorage {
, "&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 extract (plugin) &7to extract all plugin commands"
, "&f creategroup (group) &7Create a group"
, "&f deletegroup (group) &7Delete a group"
, "&f setpriority (group) (priority) &7to set the priority"
@@ -0,0 +1,19 @@
package de.rayzs.pat.api.storage.config.settings;
import de.rayzs.pat.api.storage.storages.ConfigStorage;
import de.rayzs.pat.utils.configuration.helper.ConfigSectionHelper;
public class AllowGroupOverrulingSection extends ConfigStorage {
public boolean ENABLED;
public AllowGroupOverrulingSection() {
super("allow-group-overruling");
}
@Override
public void load() {
super.load();
ENABLED = new ConfigSectionHelper<Boolean>(this, null, false).getOrSet();
}
}
@@ -1,6 +1,5 @@
package de.rayzs.pat.api.storage.config.settings;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.api.storage.storages.ConfigStorage;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.StringUtils;
@@ -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,6 +1,5 @@
package de.rayzs.pat.api.storage.config.settings;
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;
@@ -8,7 +7,7 @@ import de.rayzs.pat.utils.permission.PermissionUtil;
public class BlockNamespaceCommandsSection extends ConfigStorage {
public boolean ENABLED;
public boolean ENABLED, ALWAYS_BLOCK_COMMAND;
public BlockNamespaceCommandsSection() {
super("block-namespace-commands");
@@ -18,15 +17,22 @@ public class BlockNamespaceCommandsSection extends ConfigStorage {
public void load() {
super.load();
ENABLED = new ConfigSectionHelper<Boolean>(this, "enabled", true).getOrSet();
ALWAYS_BLOCK_COMMAND = new ConfigSectionHelper<Boolean>(this, "always-block-command", true).getOrSet();
}
public boolean doesAlwaysBlock(String command) {
return ALWAYS_BLOCK_COMMAND && isCommand(command);
}
public boolean isCommand(String command) {
if(!ENABLED || Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED) return false;
if (!ENABLED) {
return false;
}
return StringUtils.getFirstArg(command).contains(":");
}
public boolean doesBypass(Object targetObj) {
return !ENABLED || PermissionUtil.hasPermission(targetObj, "namespace");
}
}
@@ -1,6 +1,7 @@
package de.rayzs.pat.api.storage.config.settings;
import de.rayzs.pat.api.storage.storages.ConfigStorage;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.configuration.helper.*;
import java.util.*;
@@ -31,13 +32,8 @@ public class CustomPluginsSection extends ConfigStorage {
public boolean isCommand(String command) {
if(!ENABLED) return false;
command = StringUtils.getFirstArg(command);
if (command.contains(" ")) {
String[] split = command.split(" ");
if (split.length > 0)
command = split[0];
command = command.split(" ")[0];
}
for (String currentCommand : COMMANDS.getLines()) {
if (currentCommand.equalsIgnoreCase(command))
return true;
@@ -26,6 +26,6 @@ public class HandleThroughProxySection extends ConfigStorage {
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();
ENV_NAME = new ConfigSectionHelper<String>(this, "load-from-env.name", "PAT_TOKEN").getOrSet();
}
}
@@ -0,0 +1,27 @@
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 UpdateGroupsPerServerSection extends ConfigStorage {
// Disabled for now
public boolean ENABLED = false;
public UpdateGroupsPerServerSection() {
super("update-groups-per-server");
}
@Override
public void load() {
super.load();
/*
if (!Reflection.isProxyServer())
return;
ENABLED = new ConfigSectionHelper<Boolean>(this, null, false).getOrSet();
*/
}
}
@@ -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 UpdateGroupsPerWorldSection extends ConfigStorage {
public boolean ENABLED;
public UpdateGroupsPerWorldSection() {
super("update-groups-per-world");
}
@Override
public void load() {
super.load();
if (Reflection.isProxyServer())
return;
ENABLED = new ConfigSectionHelper<Boolean>(this, null, false).getOrSet();
}
}
@@ -1,8 +1,6 @@
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;
@@ -11,36 +9,55 @@ import java.util.*;
public class BlacklistStorage extends StorageTemplate implements Serializable {
private List<String> commands = new ArrayList<>();
private List<String> hiddenCommands = new ArrayList<>();
public BlacklistStorage(String navigatePath) {
super(Storage.Files.STORAGE, navigatePath);
}
public boolean isListed(String command) {
return isListed(command, !Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED);
return isListed(command, false);
}
public boolean isListed(String command, boolean ignoreCollons) {
if(commands == null) {
public boolean isListed(String command, boolean ignoreColons) {
final boolean caseSensitive = Storage.ConfigSections.Settings.BASE_COMMAND_CASE_SENSITIVE.ENABLED;
if (commands == null || command.isEmpty()) {
return false;
}
if (commands.contains("*"))
/*
if (!isNegated(command) && commands.contains("*")) {
return true;
}
*/
for (String listedCommand : commands) {
if(listedCommand == null)
boolean isNegated = isNegated(command);
if (!isNegated) {
command = StringUtils.getFirstArg(command);
}
for (String listedCommand : hiddenCommands) {
if (listedCommand == null)
continue;
if (ignoreCollons) {
if (ignoreColons) {
command = StringUtils.getFirstArg(command);
if (command.contains(":"))
command = command.substring(command.indexOf(':'));
}
if (StringUtils.getFirstArg(listedCommand).equalsIgnoreCase(StringUtils.getFirstArg(command)))
if (!isNegated) {
listedCommand = StringUtils.getFirstArg(listedCommand);
}
if (caseSensitive && listedCommand.equals(command)) {
return true;
} else if (!caseSensitive && listedCommand.equalsIgnoreCase(command)) {
return true;
}
}
return false;
@@ -51,14 +68,17 @@ public class BlacklistStorage extends StorageTemplate implements Serializable {
}
public BlacklistStorage add(String command) {
if (!commands.contains(command))
if (!commands.contains(command)) {
commands.add(command);
hiddenCommands.add(command);
}
return this;
}
public BlacklistStorage remove(String command) {
commands.remove(command);
hiddenCommands.remove(command);
return this;
}
@@ -71,6 +91,10 @@ public class BlacklistStorage extends StorageTemplate implements Serializable {
return commands;
}
public List<String> getHiddenCommands() {
return hiddenCommands;
}
@Override
public void save() {
getConfig().setAndSave(getNavigatePath(), commands);
@@ -79,6 +103,47 @@ public class BlacklistStorage extends StorageTemplate implements Serializable {
@Override
public void load() {
getConfig().reload();
commands = (ArrayList<String>) getConfig().getOrSet(getNavigatePath(), commands);
List<String> tmpCommands = commands != null ? new ArrayList<>(commands) : new ArrayList<>();
Set<String> pluginListCommands = new HashSet<>();
final String pluginCommandPrefix = "plugin=";
for (String command : tmpCommands) {
if (command.startsWith(pluginCommandPrefix)) {
pluginListCommands.add(command);
}
}
tmpCommands.removeAll(pluginListCommands);
for (String pluginListCommand : pluginListCommands) {
pluginListCommand = pluginListCommand.substring(pluginCommandPrefix.length());
List<String> pluginCommands = Storage.getLoader().getPluginCommands(pluginListCommand, false);
for (String pluginCommand : pluginCommands) {
if (!commands.contains(Storage.Blacklist.BlockType.NEGATE + pluginCommand)) {
tmpCommands.add(pluginCommand);
}
}
}
hiddenCommands = tmpCommands;
}
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;
}
}
@@ -17,8 +17,11 @@ public class DisabledServersStorage extends StorageTemplate {
public DisabledServersStorage add(String server) {
server = server.toLowerCase();
if(!servers.contains(server))
if (!servers.contains(server)) {
servers.add(server);
}
return this;
}
@@ -29,7 +32,10 @@ public class DisabledServersStorage extends StorageTemplate {
}
public boolean isListed(String server) {
if(servers.isEmpty()) return false;
if (servers.isEmpty()) {
return false;
}
return Storage.isServer(server, servers);
}
@@ -42,7 +48,11 @@ public class DisabledServersStorage extends StorageTemplate {
@Override
public void load() {
if(!Reflection.isProxyServer()) return;
if (!Reflection.isProxyServer()) {
return;
}
getConfig().reload();
servers = (ArrayList<String>) getConfig().getOrSet(getNavigatePath(), servers);
}
@@ -1,10 +1,12 @@
package de.rayzs.pat.plugin;
import de.rayzs.pat.api.brand.CustomServerBrand;
import de.rayzs.pat.plugin.converter.StorageConverter;
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;
@@ -21,7 +23,10 @@ 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 de.rayzs.pat.utils.sender.CommandSender;
import de.rayzs.pat.utils.sender.CommandSenderHandler;
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.*;
@@ -32,15 +37,23 @@ 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 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 PATSchedulerTask updaterTask;
private final List<String> offlinePlayerNames = new ArrayList<>();
private long lastCommandsLoad = -1;
@Override
public void onLoad() {
Configurator.createResourcedFile("files\\bukkit-config.yml", "config.yml", false);
@@ -54,6 +67,10 @@ public class BukkitLoader extends JavaPlugin implements PluginLoader {
plugin = this;
logger = getLogger();
for (OfflinePlayer offlinePlayerName : Bukkit.getOfflinePlayers()) {
offlinePlayerNames.add(offlinePlayerName.getName());
}
loadCommandMap();
CommandProcess.initialize();
@@ -61,7 +78,7 @@ public class BukkitLoader extends JavaPlugin implements PluginLoader {
ConfigUpdater.initialize();
Storage.initialize(this, getDescription().getVersion());
VersionComparer.setCurrentVersion(Storage.CURRENT_VERSION);
VersionComparer.get().setCurrentVersion(Storage.CURRENT_VERSION);
Storage.loadAll(true);
@@ -80,7 +97,7 @@ public class BukkitLoader extends JavaPlugin implements PluginLoader {
BukkitPacketAnalyzer.injectAll();
} else BackendUpdater.handle();
manager.registerEvents(new BukkitPlayerConnectionListener(), this);
manager.registerEvents(new BukkitPlayerListener(), this);
manager.registerEvents(new BukkitBlockCommandListener(), this);
if (Reflection.getMinor() >= 13) {
@@ -99,17 +116,33 @@ public class BukkitLoader extends JavaPlugin implements PluginLoader {
if (getServer().getPluginManager().getPlugin("LuckPerms") != null) {
LuckPermsAdapter.initialize();
Bukkit.getOnlinePlayers().forEach(player -> PermissionUtil.setPlayerPermissions(player.getUniqueId()));
} else {
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)
if (Storage.USE_SIMPLECLOUD) {
Logger.warning("Detected SimpleCloud. Therefore, MiniMessages are disabled!");
}
Storage.broadcastPermissionsPluginNotice();
ConfigUpdater.broadcastMissingParts();
ActionHandler.initialize();
SubArgsModule.initialize();
StorageConverter.initialize();
PATScheduler.createScheduler(() -> {
Storage.reload();
loadAllCommands();
});
}
@Override
@@ -128,6 +161,21 @@ public class BukkitLoader extends JavaPlugin implements PluginLoader {
}
}
@Override
public void handleReload() {
loadAllCommands();
}
@Override
public boolean doesCommandExist(String command) {
if (commandsMap == null)
return false;
loadAllCommands();
return getAllCommands().contains(command);
}
@Override
public Object getConsoleSender() {
return Bukkit.getConsoleSender();
@@ -158,7 +206,7 @@ public class BukkitLoader extends JavaPlugin implements PluginLoader {
@Override
public boolean doesPlayerExist(String playerName) {
return getOfflinePlayerNames().contains(playerName);
return isPlayerOnline(playerName) || ArrayUtils.containsIgnoreCase(getPlayerNames(), playerName);
}
@Override
@@ -178,7 +226,7 @@ public class BukkitLoader extends JavaPlugin implements PluginLoader {
@Override
public List<UUID> getPlayerIds() {
return null;
return Bukkit.getOnlinePlayers().stream().map(Entity::getUniqueId).collect(Collectors.toList());
}
@Override
@@ -188,15 +236,14 @@ public class BukkitLoader extends JavaPlugin implements PluginLoader {
@Override
public List<String> getOfflinePlayerNames() {
return new ArrayList<>(List.of(Bukkit.getOfflinePlayers())).stream().map(OfflinePlayer::getName).toList();
return offlinePlayerNames;
}
@Override
public List<String> getPlayerNames() {
List<String> playerNames = new ArrayList<>();
List<String> playerNames = new ArrayList<>(offlinePlayerNames);
playerNames.addAll(getOnlinePlayerNames());
playerNames.addAll(getOfflinePlayerNames());
return playerNames;
}
@@ -218,46 +265,36 @@ public class BukkitLoader extends JavaPlugin implements PluginLoader {
return List.of();
}
@Override
public void delayedPermissionsReload() {
PATScheduler.createScheduler(PermissionUtil::reloadPermissions, 40);
}
public void startUpdaterTask() {
if (!Storage.ConfigSections.Settings.UPDATE.ENABLED) return;
if (!Storage.ConfigSections.Settings.UPDATE.ENABLED)
return;
updaterTask = PATScheduler.createAsyncScheduler(() -> {
String result = new ConnectionBuilder().setUrl("https://www.rayzs.de/proantitab/api/version.php")
.setProperties("ProAntiTab", "4654").connect().getResponse();
if (result == null)
result = "/";
if (!result.equals("/")) {
Storage.NEWER_VERSION = result;
VersionComparer.setNewestVersion(Storage.NEWER_VERSION);
if (VersionComparer.isDeveloperVersion()) {
updaterTask.cancelTask();
Logger.info("§8[§fPAT | Bukkit§8] §7Please be aware that you are currently using a §bdeveloper §7version of ProAntiTab. Bugs, errors and a lot of debug messages might be included.");
} else if (!checkUpdate && (VersionComparer.isNewest() || VersionComparer.isUnreleased())) {
updaterTask.cancelTask();
checkUpdate = true;
if (VersionComparer.isUnreleased()) {
Logger.info("§8[§fPAT | Bukkit§8] §7Please be aware that you are currently using an §eunreleased §7version of ProAntiTab.");
return;
}
Storage.ConfigSections.Settings.UPDATE.UPDATED.getLines().forEach(Logger::warning);
} else if (VersionComparer.isOutdated()) {
updaterTask.cancelTask();
Storage.OUTDATED = true;
Storage.ConfigSections.Settings.UPDATE.OUTDATED.getLines().forEach(Logger::warning);
}
} else {
Logger.warning("Failed to connect to plugin page! Version comparison cannot be made. (No internet?)");
}
if (VersionComparer.get().computeComparison())
updaterTask.cancelTask();
}, 20L, 20L * Storage.ConfigSections.Settings.UPDATE.PERIOD);
}
public static void handleUpdateCommandsPacket(CommunicationPackets.UpdateCommandsPacket packet) {
if (!packet.hasTargetUUID()) {
Bukkit.getOnlinePlayers().forEach(Player::updateCommands);
return;
}
Player player = Bukkit.getPlayer(packet.getTargetUUID());
if (player != null) {
player.updateCommands();
}
}
public static void synchronize(CommunicationPackets.PacketBundle packetBundle) {
Storage.LAST_SYNC = System.currentTimeMillis();
Communicator.sendFeedback();
@@ -317,27 +354,70 @@ public class BukkitLoader extends JavaPlugin implements PluginLoader {
if (Storage.ConfigSections.Settings.CUSTOM_UNKNOWN_COMMAND.ENABLED != unknownCommandPacket.isEnabled())
Storage.ConfigSections.Settings.CUSTOM_UNKNOWN_COMMAND.ENABLED = unknownCommandPacket.isEnabled();
if (!loaded)
if (!loaded) {
loaded = true;
Bukkit.getOnlinePlayers().forEach(player -> {
CommandSender sender = CommandSenderHandler.from(player);
sender.updateGroups();
});
}
if (Reflection.getMinor() >= 13) {
if (updatedList) {
BukkitAntiTabListener.updateCommands();
Logger.debug("Force server to load all players tab-completion due to received sync!");
}
if (Reflection.getMinor() >= 13 && updatedList) {
BukkitAntiTabListener.updateCommands();
}
PATEventHandler.callReceiveSyncEvents(packetBundle);
}
public static boolean doesCommandExist(String command, boolean replace) {
if (commandsMap == null)
return false;
public static List<String> getAllCommands() {
return new ArrayList<>(commands);
}
if (replace) command = StringUtils.replaceFirst(command, "/", "");
return getAllCommands().contains(command);
public static List<String> getAllowedCommands() {
return new ArrayList<>(allowedCommands);
}
public static List<String> getDisallowedCommands() {
return disallowedCommands;
}
@Override
public List<String> getPluginNames(String format) {
List<String> pluginNames = new ArrayList<>();
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
PluginDescriptionFile description = plugin.getDescription();
pluginNames.add(
format.replace("%n", description.getName())
.replace("%v", description.getVersion())
);
}
return pluginNames;
}
@Override
public List<String> getPluginCommands(String pluginName, boolean useColons) {
List<String> commands = new ArrayList<>();
if (pluginName.isBlank()) return commands;
pluginName = pluginName.toLowerCase();
for (Map.Entry<String, Command> entry : BukkitLoader.getCommandsMap().entrySet()) {
if (entry.getKey().toLowerCase().startsWith(pluginName + ":")) {
String command = entry.getKey().substring(pluginName.length() + 1);
commands.add(command);
if (useColons) {
commands.add(entry.getKey());
}
}
}
return commands;
}
private void loadCommandMap() {
@@ -348,45 +428,65 @@ public class BukkitLoader extends JavaPlugin implements PluginLoader {
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) { }
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() {
public static List<String> getAllCommands() {
if (commandsMap == null) return getNotBlockedCommands();
if (lastCommandsLoad != -1 && System.currentTimeMillis() - lastCommandsLoad < 1000)
return;
List<String> result = new LinkedList<>();
for (String command : commandsMap.keySet()) if(!result.contains(command)) result.add(command);
List<String> result = new ArrayList<>();
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);
}
if (commandsMap == null) {
result.addAll(
Bukkit.getHelpMap().getHelpTopics().stream()
.map(topic -> {
String name = topic.getName();
} else if (Bukkit.getServer().getCommandAliases().get(s) != null)
for (String alias : Bukkit.getServer().getCommandAliases().get(s))
if (!result.contains(alias)) result.add(alias);
}
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());
}
});
return result;
boolean turn = Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED;
List<String> allowedCommands = new ArrayList<>(result).stream().filter(command -> {
boolean contains = Storage.Blacklist.getBlacklist().getCommands().contains(command);
return turn == contains;
}).toList();
lastCommandsLoad = System.currentTimeMillis();
BukkitLoader.commands = result;
BukkitLoader.allowedCommands = allowedCommands;
BukkitLoader.disallowedCommands = commands.stream().filter(command -> !allowedCommands.contains(command)).toList();
}
public static Map<String, Command> getCommandsMap() {
return commandsMap;
}
public static boolean useSuggestions() {
return suggestions;
@@ -2,6 +2,7 @@ package de.rayzs.pat.plugin;
import de.rayzs.pat.api.brand.CustomServerBrand;
import de.rayzs.pat.plugin.converter.StorageConverter;
import de.rayzs.pat.plugin.process.CommandProcess;
import de.rayzs.pat.plugin.modules.SubArgsModule;
import de.rayzs.pat.api.netty.proxy.BungeePacketAnalyzer;
@@ -10,6 +11,7 @@ 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 de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.utils.response.action.ActionHandler;
import net.md_5.bungee.api.scheduler.ScheduledTask;
import de.rayzs.pat.plugin.commands.BungeeCommand;
@@ -33,7 +35,6 @@ public class BungeeLoader extends Plugin implements PluginLoader {
private static Plugin plugin;
private static java.util.logging.Logger logger;
private static boolean checkUpdate = false;
private static final HashMap<String, CommandsCache> commandsCacheMap = new HashMap<>();
@Override
@@ -56,7 +57,7 @@ public class BungeeLoader extends Plugin implements PluginLoader {
Storage.USE_SIMPLECLOUD = Reflection.doesClassExist("eu.thesimplecloud.plugin.startup.CloudPlugin");
Storage.initialize(this, getDescription().getVersion());
VersionComparer.setCurrentVersion(Storage.CURRENT_VERSION);
VersionComparer.get().setCurrentVersion(Storage.CURRENT_VERSION);
Storage.loadAll(true);
@@ -95,9 +96,19 @@ public class BungeeLoader extends Plugin implements PluginLoader {
Logger.warning("Detected SimpleCloud and therefore MiniMessages by Kyori are disabled!");
BungeePacketAnalyzer.injectAll();
Storage.broadcastPermissionsPluginNotice();
ConfigUpdater.broadcastMissingParts();
ActionHandler.initialize();
SubArgsModule.initialize();
StorageConverter.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
@@ -113,6 +124,26 @@ public class BungeeLoader extends Plugin implements PluginLoader {
}
}
@Override
public void handleReload() {
BungeePacketAnalyzer.loadProxyCommands();
}
@Override
public void delayedPermissionsReload() {
getProxy().getScheduler().schedule(this, () -> {
PermissionUtil.reloadPermissions();
Storage.getLoader().updateCommandCache();
Communicator.sendRequest();
}, 1, TimeUnit.SECONDS);
}
@Override
public boolean doesCommandExist(String command) {
return false;
}
@Override
public Object getConsoleSender() {
return ProxyServer.getInstance().getConsole();
@@ -225,44 +256,36 @@ public class BungeeLoader extends Plugin implements PluginLoader {
return new ArrayList<>(ProxyServer.getInstance().getServers().keySet().stream().toList());
}
@Override
public List<String> getPluginNames(String format) {
List<String> pluginNames = new ArrayList<>();
for (Plugin plugin : ProxyServer.getInstance().getPluginManager().getPlugins()) {
PluginDescription description = plugin.getDescription();
pluginNames.add(
format.replace("%n", description.getName())
.replace("%v", description.getVersion())
);
}
return pluginNames;
}
@Override
public List<String> getPluginCommands(String pluginName, boolean useColons) {
return List.of();
}
public void startUpdaterTask() {
if (!Storage.ConfigSections.Settings.UPDATE.ENABLED) return;
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();
if (result == null)
result = "/";
if (VersionComparer.get().computeComparison())
getProxy().getScheduler().cancel(updaterTask);
if (!result.equals("/")) {
Storage.NEWER_VERSION = result;
VersionComparer.setNewestVersion(Storage.NEWER_VERSION);
if(VersionComparer.isDeveloperVersion()) {
getProxy().getScheduler().cancel(updaterTask);
Logger.info("§8[§fPAT | Proxy§8] §7Please be aware that you are currently using a §bdeveloper §7version of ProAntiTab. Bugs, errors and a lot of debug messages might be included.");
} else if(!checkUpdate && (VersionComparer.isNewest() || VersionComparer.isUnreleased())) {
getProxy().getScheduler().cancel(updaterTask);
checkUpdate = true;
if(VersionComparer.isUnreleased()) {
Logger.info("§8[§fPAT | Proxy§8] §7Please be aware that you are currently using an §eunreleased §7version of ProAntiTab.");
return;
}
checkUpdate = true;
Storage.ConfigSections.Settings.UPDATE.UPDATED.getLines().forEach(Logger::warning);
} else if(VersionComparer.isOutdated()) {
Storage.OUTDATED = true;
Storage.ConfigSections.Settings.UPDATE.OUTDATED.getLines().forEach(Logger::warning);
}
} else {
Logger.warning("Failed to connect to plugin page! Version comparison cannot be made. (No internet?)");
}
}, 20L, Storage.ConfigSections.Settings.UPDATE.PERIOD, TimeUnit.MILLISECONDS);
}
@@ -8,8 +8,13 @@ import java.util.UUID;
public interface PluginLoader {
void handleReload();
boolean doesCommandExist(String command);
HashMap<String, CommandsCache> getCommandsCacheMap();
void delayedPermissionsReload();
void updateCommandCache();
List<String> getServerNames();
@@ -35,4 +40,13 @@ public interface PluginLoader {
List<String> getPlayerNames();
List<String> getOnlinePlayerNames();
List<String> getOfflinePlayerNames();
List<String> getPluginCommands(String pluginName, boolean useColons);
/**
* <pre>
* %n = Plugin name
* %v = Plugin version
*/
List<String> getPluginNames(String format);
}
@@ -6,6 +6,7 @@ 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.converter.StorageConverter;
import de.rayzs.pat.plugin.modules.SubArgsModule;
import de.rayzs.pat.plugin.process.CommandProcess;
import de.rayzs.pat.utils.CommandsCache;
@@ -21,7 +22,6 @@ import de.rayzs.pat.utils.adapter.LuckPermsAdapter;
import com.velocitypowered.api.proxy.ProxyServer;
import de.rayzs.pat.plugin.listeners.velocity.*;
import de.rayzs.pat.utils.group.GroupManager;
import de.rayzs.pat.utils.ConnectionBuilder;
import de.rayzs.pat.utils.VersionComparer;
import de.rayzs.pat.plugin.logger.Logger;
import com.velocitypowered.api.plugin.*;
@@ -38,7 +38,7 @@ import java.util.*;
@Plugin(name = "ProAntiTab",
id = "proantitab",
version = "2.0.3",
version = "2.2.0",
authors = "Rayzs_YT",
description = "Hide more than just your plugins. Hide almost everything!",
url = "https://www.rayzs.de/products/proantitab/page",
@@ -58,7 +58,6 @@ public class VelocityLoader implements PluginLoader {
private ScheduledTask updaterTask;
private static final HashMap<String, CommandsCache> commandsCacheMap = new HashMap<>();
private static boolean checkUpdate = false;
@Inject
public VelocityLoader(ProxyServer server, org.slf4j.Logger logger, VelocityMetrics.Factory metricsFactory) {
@@ -85,7 +84,7 @@ public class VelocityLoader implements PluginLoader {
Storage.USE_SIMPLECLOUD = Reflection.doesClassExist("eu.thesimplecloud.plugin.startup.CloudPlugin");
Storage.initialize(this, pluginContainer.getDescription().getVersion().get());
VersionComparer.setCurrentVersion(Storage.CURRENT_VERSION);
VersionComparer.get().setCurrentVersion(Storage.CURRENT_VERSION);
Storage.loadAll(true);
MessageTranslator.initialize();
@@ -95,7 +94,7 @@ public class VelocityLoader implements PluginLoader {
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));
@@ -118,16 +117,21 @@ public class VelocityLoader implements PluginLoader {
if(Storage.USE_SIMPLECLOUD)
Logger.warning("Detected SimpleCloud and therefore MiniMessages by Kyori are disabled!");
Storage.broadcastPermissionsPluginNotice();
ConfigUpdater.broadcastMissingParts();
ActionHandler.initialize();
SubArgsModule.initialize();
StorageConverter.initialize();
}
public static org.slf4j.Logger getPluginLogger() {
return logger;
}
public static void delayedPermissionsReload() {
@Override
public void delayedPermissionsReload() {
server.getScheduler().buildTask(VelocityLoader.instance, () -> {
PermissionUtil.reloadPermissions();
Storage.getLoader().updateCommandCache();
@@ -145,6 +149,14 @@ public class VelocityLoader implements PluginLoader {
}).delay(1, TimeUnit.SECONDS).schedule();
}
@Override
public void handleReload() {}
@Override
public boolean doesCommandExist(String command) {
return false;
}
@Override
public Object getConsoleSender() {
return server.getConsoleCommandSource();
@@ -267,63 +279,40 @@ public class VelocityLoader implements PluginLoader {
return new ArrayList<>(server.getAllServers().stream().map(registeredServer -> registeredServer.getServerInfo().getName()).toList());
}
@Override
public List<String> getPluginNames(String format) {
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(
format.replace("%n", pluginName)
.replace("%v", version)
);
}
return pluginNames;
}
@Override
public List<String> getPluginCommands(String pluginName, boolean useColons) {
return List.of();
}
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();
if (result == null)
result = "/";
if (VersionComparer.get().computeComparison())
updaterTask.cancel();
if (!result.equals("/")) {
Storage.NEWER_VERSION = result;
VersionComparer.setNewestVersion(Storage.NEWER_VERSION);
if (VersionComparer.isDeveloperVersion()) {
updaterTask.cancel();
MessageTranslator.send(server.getConsoleCommandSource(), "<dark_gray>[</dark_gray><white>PAT | Proxy</white><dark_gray>]</dark_gray> <gray>Please be aware that you are currently using a</gray> <aqua>developer</aqua> <gray>version of ProAntiTab. Bugs, errors and a lot of debug messages might be included.</gray>");
} else if (!checkUpdate && (VersionComparer.isNewest() || VersionComparer.isUnreleased())) {
updaterTask.cancel();
checkUpdate = true;
if (VersionComparer.isUnreleased()) {
MessageTranslator.send(server.getConsoleCommandSource(), "<dark_gray>[</dark_gray><white>PAT | Proxy</white><dark_gray>]</dark_gray> <gray>Please be aware that you are currently using an</gray> <yellow>unreleased</yellow> <gray>version of ProAntiTab.</gray>");
return;
}
checkUpdate = true;
MessageTranslator.send(server.getConsoleCommandSource(), Storage.ConfigSections.Settings.UPDATE.UPDATED.getLines());
} else if (VersionComparer.isOutdated()) {
Storage.OUTDATED = true;
MessageTranslator.send(server.getConsoleCommandSource(), Storage.ConfigSections.Settings.UPDATE.OUTDATED.getLines());
}
} else {
Logger.warning("Failed to connect to plugin page! Version comparison cannot be made. (No internet?)");
}
}).delay(1, TimeUnit.SECONDS).repeat(Storage.ConfigSections.Settings.UPDATE.PERIOD, TimeUnit.SECONDS).schedule();
}
public static String getServerNameByPlayerUUID(UUID uuid) {
Optional<Player> optPlayer = server.getPlayer(uuid);
if(!optPlayer.isPresent()) return null;
Player player = optPlayer.get();
Optional<ServerConnection> optServer = player.getCurrentServer();
if(!optServer.isPresent()) return null;
ServerConnection server = optServer.get();
if(server.getServerInfo() == null) return null;
return server.getServerInfo().getName();
}
public static ProxyServer getServer() {
return server;
}
@@ -0,0 +1,46 @@
package de.rayzs.pat.plugin.converter;
import de.rayzs.pat.api.storage.storages.BlacklistStorage;
import de.rayzs.pat.utils.configuration.ConfigurationBuilder;
import de.rayzs.pat.utils.configuration.Configurator;
import de.rayzs.pat.utils.sender.CommandSender;
import java.io.File;
import java.util.List;
public abstract class Converter {
private final String pluginName, fileName, folderPath;
protected final ConfigurationBuilder config;
public Converter(String pluginName, String folderName, String fileName) {
this.pluginName = pluginName;
this.fileName = fileName;
this.folderPath = "./plugins/" + folderName;
this.config = exists() ? Configurator.get(fileName, folderPath) : null;
}
public String getPluginName() {
return pluginName;
}
public boolean exists() {
return new File(folderPath, fileName + ".yml").exists();
}
protected void applyStorage(BlacklistStorage storage, List<String> commands) {
for (String command : commands) {
boolean exist = command.contains(" ")
? storage.getCommands().contains(command)
: storage.isListed(command);
if (exist) continue;
storage.add(command);
}
storage.save();
}
public abstract void apply(CommandSender sender);
}
@@ -0,0 +1,40 @@
package de.rayzs.pat.plugin.converter;
import de.rayzs.pat.plugin.converter.converters.*;
import org.jetbrains.annotations.NotNull;
import java.util.*;
public class StorageConverter {
private StorageConverter() {}
private static final Map<String, Converter> converters = new HashMap<>();
public static void initialize() {
if (!converters.isEmpty()) {
return;
}
registerConverter(new AdvancedPlHideConverter());
registerConverter(new CommandWhitelistConverter());
registerConverter(new PluginHiderPlus());
registerConverter(new PlHideFree());
registerConverter(new PlHidePro());
}
public static Set<String> getConverters() {
return converters.keySet();
}
public static Converter getConverter(@NotNull String name) {
return converters.get(name);
}
public static void registerConverter(@NotNull Converter converter) {
if (!converter.exists()) return;
converters.putIfAbsent(converter.getPluginName(), converter);
}
}
@@ -0,0 +1,40 @@
package de.rayzs.pat.plugin.converter.converters;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.api.storage.storages.BlacklistStorage;
import de.rayzs.pat.plugin.converter.Converter;
import de.rayzs.pat.utils.group.Group;
import de.rayzs.pat.utils.group.GroupManager;
import de.rayzs.pat.utils.sender.CommandSender;
import java.util.ArrayList;
import java.util.List;
public class AdvancedPlHideConverter extends Converter {
public AdvancedPlHideConverter() {
super("AdvancedPlHide", "AdvancedPlHide", "config");
}
@Override
public void apply(CommandSender sender) {
List<String> groups = config.getKeys("groups", false).stream().toList();
for (String groupName : groups) {
List<String> commands = (ArrayList<String>) config.get("groups."+ groupName + ".tabcomplete");
BlacklistStorage storage;
if (groupName.equalsIgnoreCase("default")) {
storage = Storage.Blacklist.getBlacklist();
} else {
Group group = GroupManager.registerAndGetGroup(groupName);
storage = group.getGeneralGroupBlacklist();
}
applyStorage(storage, commands);
}
sender.sendMessage("&e&lNotice: &7AdvanedPlHide works based on permissions whether to whitelist or blacklist commands from a group. Due to the fact that this cannot be detected by PAT and formatted in the exact way, all commands have been interpreted as whitelisted commands instead. Also, since PAT groups are only intended to whitelist commands, all created groups based on AdvancedPlHide have been created with the intention of whitelisting commands instead. If you wish to change that, please check out the GitHub wiki on how to use the storage.yml of PAT the intended way. (https://github.com/RayzsYT/ProAntiTab/wiki/How-to#introduction)");
}
}
@@ -0,0 +1,44 @@
package de.rayzs.pat.plugin.converter.converters;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.api.storage.storages.BlacklistStorage;
import de.rayzs.pat.plugin.converter.Converter;
import de.rayzs.pat.utils.group.Group;
import de.rayzs.pat.utils.group.GroupManager;
import de.rayzs.pat.utils.sender.CommandSender;
import java.util.ArrayList;
import java.util.List;
public class CommandWhitelistConverter extends Converter {
public CommandWhitelistConverter() {
super("CommandWhitelist", "CommandWhitelist", "config");
}
@Override
public void apply(CommandSender sender) {
List<String> groups = config.getKeys("groups", false).stream().toList();
for (String groupName : groups) {
List<String> commands = new ArrayList<>();
final List<String> l1 = (ArrayList<String>) config.get("groups." + groupName + ".commands");
final List<String> l2 = (ArrayList<String>) config.get("groups." + groupName + ".subcommands");
commands.addAll(l1);
commands.addAll(l2);
BlacklistStorage storage;
if (groupName.equalsIgnoreCase("default")) {
storage = Storage.Blacklist.getBlacklist();
} else {
Group group = GroupManager.registerAndGetGroup(groupName);
storage = group.getGeneralGroupBlacklist();
}
applyStorage(storage, commands);
}
}
}
@@ -0,0 +1,58 @@
package de.rayzs.pat.plugin.converter.converters;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.api.storage.storages.BlacklistStorage;
import de.rayzs.pat.plugin.converter.Converter;
import de.rayzs.pat.utils.group.Group;
import de.rayzs.pat.utils.group.GroupManager;
import de.rayzs.pat.utils.sender.CommandSender;
import java.util.ArrayList;
import java.util.List;
public class PlHideFree extends Converter {
public PlHideFree() {
super("PlHide", "Pl-Hide-Free", "config");
}
@Override
public void apply(CommandSender sender) {
List<String> groups = config.getKeys("groups", false).stream().toList();
for (String groupName : groups) {
List<String> execution = (ArrayList<String>) config.get("groups." + groupName + ".commands");
List<String> commands = execution.stream().filter(s -> !s.startsWith("!") && !s.equalsIgnoreCase("*")).map(this::translate).toList();
BlacklistStorage storage;
if (groupName.equalsIgnoreCase("default")) {
storage = Storage.Blacklist.getBlacklist();
} else {
Group group = GroupManager.registerAndGetGroup(groupName);
storage = group.getGeneralGroupBlacklist();
}
applyStorage(storage, commands);
}
sender.sendMessage("§e§lNotice: §7Since PAT is mainly focussed on either blocking or whitelisting commands entirely, PAT is viewing and converting the file such that commands are only working in whitelist mode. If you wish to use ProAntiTab in blacklist mode instead, then please checkout the wiki! (https://github.com/RayzsYT/ProAntiTab/wiki/How-to#introduction)");
}
private String translate(String input) {
if (input.contains(" ")) {
if (input.endsWith("~")) {
return translate(input.substring(0, input.length() - 1) + "_-");
}
if (input.endsWith("*")) {
return input.substring(0, input.length() - 2);
} else if (input.contains("*")) {
return input.substring(0, input.indexOf('*') - 1);
}
}
return input;
}
}
@@ -0,0 +1,99 @@
package de.rayzs.pat.plugin.converter.converters;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.api.storage.storages.BlacklistStorage;
import de.rayzs.pat.plugin.converter.Converter;
import de.rayzs.pat.utils.group.Group;
import de.rayzs.pat.utils.group.GroupManager;
import de.rayzs.pat.utils.sender.CommandSender;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class PlHidePro extends Converter {
public PlHidePro() {
super("PlHidePro", "Pl-Hide-Pro", "config");
}
@Override
public void apply(CommandSender sender) {
boolean updateGroupPerWorld = (boolean) config.get("per_world_group_updates");
Storage.ConfigSections.Settings.UPDATE_GROUPS_PER_WORLD.getConfig().setAndSave("update-groups-per-world", updateGroupPerWorld);
boolean autoLowercaseCommands = (boolean) config.get("auto_lowercase_base_commands");
Storage.ConfigSections.Settings.AUTO_LOWERCASE_COMMANDS.getConfig().setAndSave("auto-lowercase-commands.enabled", autoLowercaseCommands);
boolean f3brand = (boolean) config.get("replace-f3-server-brand");
String f3brandString = (String) config.get("f3-server-brand");
Storage.ConfigSections.Settings.CUSTOM_BRAND.getConfig().setAndSave("custom-server-brand.enabled", f3brand);
if (f3brand) {
Storage.ConfigSections.Settings.CUSTOM_BRAND.getConfig().setAndSave("custom-server-brand.repeat-delay", -1);
Storage.ConfigSections.Settings.CUSTOM_BRAND.getConfig().setAndSave("custom-server-brand.brands", new ArrayList<>(Collections.singletonList(f3brandString.replace("§", "&"))));
}
List<String> groups = config.getKeys("groups", false).stream().toList();
for (String groupName : groups) {
List<String> commands = new ArrayList<>();
final List<String> execution = (ArrayList<String>) config.get("groups." + groupName + ".commands");
final List<String> tabCompletion = (ArrayList<String>) config.get("groups." + groupName + ".tabcomplete");
for (String s : execution) {
if (s.equalsIgnoreCase("*")) {
tabCompletion.remove("*");
continue;
}
if (!s.contains(" ") && s.startsWith("!")) {
tabCompletion.remove(s);
continue;
}
if (tabCompletion.contains(s)) {
commands.add(s);
tabCompletion.remove(s);
continue;
}
commands.add("[CMD]" + s);
}
commands.addAll(tabCompletion.stream().map(s -> "[TAB]" + s).toList());
commands = commands.stream().map(this::translate).toList();
BlacklistStorage storage;
if (groupName.equalsIgnoreCase("default")) {
storage = Storage.Blacklist.getBlacklist();
} else {
Group group = GroupManager.registerAndGetGroup(groupName);
storage = group.getGeneralGroupBlacklist();
}
applyStorage(storage, commands);
}
sender.sendMessage("§e§lNotice: §7Since PAT is mainly focussed on either blocking or whitelisting commands entirely, PAT is viewing and converting the file such that commands are only working in whitelist mode. If you wish to use ProAntiTab in blacklist mode instead, then please checkout the wiki! (https://github.com/RayzsYT/ProAntiTab/wiki/How-to#introduction)");
}
private String translate(String input) {
if (input.contains(" ")) {
if (input.endsWith("~")) {
return translate(input.substring(0, input.length() - 1) + "_-");
}
if (input.endsWith("*")) {
return input.substring(0, input.length() - 2);
} else if (input.contains("*")) {
return input.substring(0, input.indexOf('*') - 1);
}
}
return input;
}
}
@@ -0,0 +1,32 @@
package de.rayzs.pat.plugin.converter.converters;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.converter.Converter;
import de.rayzs.pat.utils.sender.CommandSender;
import java.util.ArrayList;
import java.util.List;
public class PluginHiderPlus extends Converter {
public PluginHiderPlus() {
super("PluginHider+", "PluginHiderPlus", "config");
}
@Override
public void apply(CommandSender sender) {
boolean blacklist = (boolean) config.get("reverse-suggestionsWhitelist");
Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.getConfig().setAndSave("turn-blacklist-to-whitelist", !blacklist);
List<String> commands = (ArrayList<String>) config.get("suggestionsWhitelist");
if (blacklist) {
List<String> blockedCommands = (ArrayList<String>) config.get("blockedCommands.everyone.commands");
commands.addAll(blockedCommands);
}
applyStorage(Storage.Blacklist.getBlacklist(), commands);
sender.sendMessage("&e&lNotice: &7Since PluginHider+ both blocks certain commands and whitelist a few, the conversion into PAT's storage.yml format won't be accurate. Only whitelisted commands have been added, and blocked commands for everyone if the plugin was used in blacklist mode.");
}
}
@@ -1,68 +1,88 @@
package de.rayzs.pat.plugin.listeners.bukkit;
import de.rayzs.pat.api.event.events.FilteredSuggestionEvent;
import de.rayzs.pat.utils.sender.CommandSender;
import de.rayzs.pat.utils.sender.CommandSenderHandler;
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;
import de.rayzs.pat.utils.*;
import org.bukkit.event.*;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.*;
public class BukkitAntiTabListener implements Listener {
private static final CommandsCache COMMANDS_CACHE = new CommandsCache();
private static final List<UUID> knownOperators = new ArrayList<>();
@EventHandler (priority = EventPriority.LOWEST)
public void onPlayerCommandSend(PlayerCommandSendEvent event) {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
String uuidSubstring = uuid.toString().substring(uuid.toString().length() - 5);
final Player player = event.getPlayer();
final UUID uuid = player.getUniqueId();
if (Storage.USE_VELOCITY) {
return;
}
if (player.isOp()) {
if (!knownOperators.contains(uuid)) {
knownOperators.add(uuid);
}
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() + ")");
return;
}
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 (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED)
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
return;
}
if (event.getCommands().isEmpty()) {
Logger.debug("No available commands to filter! Ignoring rest of the code until at least one command is listed in there.");
return;
}
List<String> allCommands = getCommands();
List<String> allCommands = getCommands();
COMMANDS_CACHE.handleCommands(allCommands);
if (!player.isOp() && knownOperators.contains(uuid)) {
knownOperators.remove(uuid);
CommandSender sender = CommandSenderHandler.getSenderFromUUID(uuid);
PermissionUtil.reloadPermissions(sender);
}
if (PermissionUtil.hasBypassPermission(player)) {
Logger.debug("Player with uuid " + uuidSubstring + " skipped the commands-list creation due to its permissions.");
return;
}
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(new ArrayList<>(event.getCommands()), player);
final FilteredSuggestionEvent filteredSuggestionEvent = PATEventHandler.callFilteredSuggestionEvents(player, playerCommands);
event.getCommands().clear();
if (filteredSuggestionEvent.isCancelled())
if (filteredSuggestionEvent.isCancelled()) {
return;
}
event.getCommands().addAll(filteredSuggestionEvent.getSuggestions());
Logger.debug("Player with uuid " + uuidSubstring + " has a total of " + playerCommands.size() + " commands.");
if (Storage.ConfigSections.Settings.CUSTOM_PLUGIN.ALWAYS_TAB_COMPLETABLE) {
event.getCommands().addAll(Storage.ConfigSections.Settings.CUSTOM_PLUGIN.COMMANDS.getLines());
}
if (Storage.ConfigSections.Settings.CUSTOM_VERSION.ALWAYS_TAB_COMPLETABLE) {
event.getCommands().addAll(Storage.ConfigSections.Settings.CUSTOM_VERSION.COMMANDS.getLines());
}
}
public static List<String> getCommands() {
@@ -77,14 +97,6 @@ public class BukkitAntiTabListener implements Listener {
// --------------- LUCKPERMS SECTIONS --------------- //
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 updateCommands() {
Bukkit.getOnlinePlayers().forEach(BukkitAntiTabListener::updateCommands);
}
@@ -104,10 +116,12 @@ public class BukkitAntiTabListener implements Listener {
public static void handleTabCompletion(UUID uuid) {
Player player = Bukkit.getPlayer(uuid);
if (player == null)
return;
handleTabCompletion(player);
if (player == null) {
return;
}
handleTabCompletion(player, getCommands());
}
public static void handleTabCompletion(Player player) {
@@ -2,6 +2,8 @@ package de.rayzs.pat.plugin.listeners.bukkit;
import java.util.List;
import de.rayzs.pat.utils.sender.CommandSender;
import de.rayzs.pat.utils.sender.CommandSenderHandler;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Player;
@@ -13,7 +15,6 @@ 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.BukkitLoader;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.message.MessageTranslator;
@@ -25,14 +26,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 = rawCommand.substring(1);
if (!Storage.ConfigSections.Settings.CUSTOM_UNKNOWN_COMMAND.ENABLED || event.isCancelled()) return;
if (PermissionUtil.hasBypassPermission(player)) return;
//if (BukkitLoader.doesCommandExist(command, false)) return;
if (Bukkit.getHelpMap().getHelpTopic(rawCommand) != null) 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());
@@ -40,9 +47,12 @@ public class BukkitBlockCommandListener implements Listener {
@EventHandler (priority = EventPriority.LOWEST)
public void onPlayerCommandProcess(PlayerCommandPreprocessEvent event) {
Player player = event.getPlayer();
final Player player = event.getPlayer();
final CommandSender sender = CommandSenderHandler.from(player);
if (Storage.ConfigSections.Settings.AUTO_LOWERCASE_COMMANDS.isCommand(StringUtils.getFirstArg(event.getMessage()))) {
final String commandFirstArg = StringUtils.getFirstArg(event.getMessage());
if (Storage.ConfigSections.Settings.AUTO_LOWERCASE_COMMANDS.isCommand(commandFirstArg)) {
String command = event.getMessage();
if (command.contains(" ")) {
@@ -51,47 +61,109 @@ public class BukkitBlockCommandListener implements Listener {
command = String.join(" ", args);
} else command = command.toLowerCase();
player.chat(command);
event.setCancelled(true);
return;
if (!commandFirstArg.equals(command)) {
player.chat(command);
event.setCancelled(true);
return;
}
}
World world = player.getWorld();
String command = event.getMessage(),
worldName = world.getName();
boolean bypassPermission = PermissionUtil.hasBypassPermission(player, command);
command = command.substring(1);
command = StringUtils.getFirstArg(command);
final String displayName = command;
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
return;
}
command = StringUtils.replaceTriggers(command, "", "\\", "<", ">", "&");
command = command.toLowerCase();
if (PermissionUtil.hasBypassPermission(player, command)) {
return;
}
final String displayCommand = StringUtils.replaceTriggers(command, "", "\\", "<", ">", "&");
List<String> notificationMessage = MessageTranslator.replaceMessageList(
Storage.ConfigSections.Messages.NOTIFICATION.ALERT,
"%player%", player.getName(),
"%command%", displayName,
"%command%", displayCommand,
"%world%", worldName);
if (bypassPermission)
return;
if (Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isCommand(command)) {
if (!Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED)
return;
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED)
return;
MessageTranslator.send(
player,
Storage.ConfigSections.Settings.CUSTOM_PLUGIN.MESSAGE,
"%command%", StringUtils.getFirstArg(displayCommand)
);
if (!Storage.Blacklist.canPlayerAccessChat(player, command)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, event.getMessage(), true);
if (Storage.SEND_CONSOLE_NOTIFICATION)
Logger.info(notificationMessage);
Storage.NOTIFY_PLAYERS.forEach(uuid -> {
Object p = Storage.getLoader().getPlayerObjByUUID(uuid);
if (p != null) {
MessageTranslator.send(p, notificationMessage);
}
});
event.setCancelled(true);
return;
}
if (Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(command)) {
MessageTranslator.send(
player,
Storage.ConfigSections.Settings.CUSTOM_VERSION.MESSAGE,
"%command%", StringUtils.getFirstArg(displayCommand)
);
if (Storage.SEND_CONSOLE_NOTIFICATION)
Logger.info(notificationMessage);
Storage.NOTIFY_PLAYERS.forEach(uuid -> {
Object p = Storage.getLoader().getPlayerObjByUUID(uuid);
if (p != null) {
MessageTranslator.send(p, notificationMessage);
}
});
event.setCancelled(true);
return;
}
final boolean cancelBlockedCommand = Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED;
boolean allowed = Storage.Blacklist.canPlayerAccessChat(player, command);
boolean blockedNamespace = false;
if (!Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesBypass(sender)) {
blockedNamespace = cancelBlockedCommand
? Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.isCommand(command)
: Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesAlwaysBlock(command);
if (blockedNamespace) allowed = false;
}
if (!Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED && !blockedNamespace) {
return;
}
if (!allowed) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(
player,
event.getMessage(),
true,
!Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED
);
if (executeCommandEvent.isBlocked()) {
event.setCancelled(true);
if (Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED)
if (!executeCommandEvent.doesNotify())
return;
if (Storage.SEND_CONSOLE_NOTIFICATION)
@@ -108,7 +180,7 @@ public class BukkitBlockCommandListener implements Listener {
return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, event.getMessage(), false);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, event.getMessage(), false, false);
if (executeCommandEvent.isBlocked())
event.setCancelled(true);
}
@@ -1,61 +0,0 @@
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.utils.message.MessageTranslator;
import de.rayzs.pat.utils.permission.PermissionUtil;
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();
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(!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();
PATEventHandler.callServerPlayersChangeEvents(player, ServerPlayersChangeEvent.Type.LEFT);
BukkitPacketAnalyzer.uninject(player.getUniqueId());
PermissionUtil.resetPermissions(player.getUniqueId());
if(Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1) return;
}
@EventHandler (priority = EventPriority.LOWEST)
public void onPlayerChangedWorld(PlayerChangedWorldEvent event) {
Player player = event.getPlayer();
if(Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1) return;
CustomServerBrand.sendBrandToPlayer(player);
}
}
@@ -0,0 +1,121 @@
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.PermissionPlugin;
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();
final CommandSender sender = CommandSenderHandler.from(player);
sender.updateSenderObject(player);
PATEventHandler.callServerPlayersChangeEvents(player, ServerPlayersChangeEvent.Type.JOINED);
if (Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
BackendUpdater.handle();
}
CustomServerBrand.preparePlayer(player);
PermissionUtil.reloadPermissions(sender);
if (CustomServerBrand.isEnabled()) {
CustomServerBrand.sendBrandToPlayer(player);
}
if (!Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
if (Storage.getPermissionPlugin() != PermissionPlugin.LUCKPERMS) {
PATScheduler.createScheduler(() -> {
if (Storage.getPermissionPlugin() == PermissionPlugin.GROUPMANAGER) {
PermissionUtil.reloadPermissions(sender);
} else {
sender.updateGroups();
}
if (Reflection.getMinor() >= 13) {
BukkitAntiTabListener.handleTabCompletion(player);
}
}, 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);
}
// Update sub arguments for <1.12.2 servers.
if (Reflection.getMinor() < 13) {
Storage.quickSubArgumentUpdate(uuid);
}
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_GROUPS_PER_WORLD.ENABLED) {
CommandSender sender = CommandSenderHandler.from(player);
assert sender != null;
PermissionUtil.reloadPermissions(sender);
if (Reflection.getMinor() >= 13) {
BukkitAntiTabListener.handleTabCompletion(player);
}
}
}
}
@@ -2,7 +2,9 @@ package de.rayzs.pat.plugin.listeners.bungee;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.event.events.FilteredTabCompletionEvent;
import de.rayzs.pat.api.netty.proxy.BungeePacketAnalyzer;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.permission.PermissionUtil;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
@@ -10,19 +12,32 @@ 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;
import java.util.ArrayList;
public class BungeeAntiTabListener implements Listener {
@EventHandler
public void onTabComplete(TabCompleteEvent event) {
if(!(event.getSender() instanceof ProxiedPlayer)) return;
public void onTabCompleteResponse(TabCompleteResponseEvent event) {
ProxiedPlayer player = (ProxiedPlayer) event.getSender();
if(!(event.getReceiver() instanceof ProxiedPlayer)) return;
ProxiedPlayer player = (ProxiedPlayer) event.getReceiver();
ServerInfo serverInfo = player.getServer().getInfo();
String serverName = serverInfo.getName();
String cursor = event.getCursor().substring(1);
String rawCursor = BungeePacketAnalyzer.getPlayerInput(player);
if (rawCursor == null) {
return;
}
if (!rawCursor.startsWith("/")) {
return;
}
String cursor = rawCursor.substring(1);
if (event.getSuggestions().isEmpty())
return;
@@ -33,35 +48,59 @@ public class BungeeAntiTabListener implements Listener {
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));
final boolean doesBypassNamespace = Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesBypass(player);
final boolean spaces = cursor.contains(" ");
boolean cancelsBeforeHand = false;
if (Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.isCommand(cursor) && !doesBypassNamespace) {
cancelsBeforeHand = true;
}
if (!cancelsBeforeHand && !cursor.isEmpty()) {
cancelsBeforeHand = !Storage.Blacklist.canPlayerAccessTab(player, StringUtils.getFirstArg(cursor), serverName);
}
if (!cancelsBeforeHand) {
cancelsBeforeHand = Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isCommand(cursor) || Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(cursor);
}
if (spaces) {
if (cancelsBeforeHand) {
event.getSuggestions().clear();
return;
}
FilteredTabCompletionEvent filteredTabCompletionEvent = PATEventHandler.callFilteredTabCompletionEvents(player.getUniqueId(), rawCursor, new ArrayList<>(event.getSuggestions()));
if (filteredTabCompletionEvent.isCancelled()) {
event.getSuggestions().clear();
} else {
event.getSuggestions().removeIf(s -> !filteredTabCompletionEvent.getCompletion().contains(s));
}
return;
}
event.getSuggestions().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, serverName);
});
}
@EventHandler
public void onTabComplete(TabCompleteResponseEvent event) {
// Ignoring this at first, due to transfer to the packet-based solution only. Hehe
/*
if (!(event.getSender() instanceof ProxiedPlayer))
return;
public void onTabComplete(TabCompleteEvent event) {
ProxiedPlayer player = (ProxiedPlayer) event.getSender();
ServerInfo serverInfo = player.getServer().getInfo();
String serverName = serverInfo.getName();
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();
*/
BungeePacketAnalyzer.setPlayerInput(player, event.getCursor());
}
}
@@ -3,6 +3,8 @@ 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 de.rayzs.pat.utils.sender.CommandSender;
import de.rayzs.pat.utils.sender.CommandSenderHandler;
import net.md_5.bungee.api.event.ChatEvent;
import net.md_5.bungee.api.plugin.Listener;
import de.rayzs.pat.plugin.logger.Logger;
@@ -20,26 +22,24 @@ public class BungeeBlockCommandListener implements Listener {
public void onChat(ChatEvent event) {
if (event.isCancelled()) return;
Connection connection = event.getSender();
final Connection connection = event.getSender();
if (! (connection instanceof ProxiedPlayer) || !event.getMessage().startsWith("/"))
return;
ProxiedPlayer player = (ProxiedPlayer) connection;
String serverName = player.getServer().getInfo().getName();
final ProxiedPlayer player = (ProxiedPlayer) connection;
final CommandSender sender = CommandSenderHandler.from(player);
final String serverName = player.getServer().getInfo().getName();
String command = event.getMessage();
boolean bypassPermission = PermissionUtil.hasBypassPermission(player, command);
if (bypassPermission)
if (PermissionUtil.hasBypassPermission(player, command) || Storage.Blacklist.isDisabledServer(serverName))
return;
command = command.startsWith("/") ? command.substring(1) : command;
command = StringUtils.getFirstArg(command);
final String displayCommand = command;
final String displayCommand = StringUtils.replaceTriggers(command, "", "\\", "<", ">", "&");
command = StringUtils.replaceTriggers(command, "", "\\", "<", ">", "&");
command = command.toLowerCase();
List<String> notificationMessage = MessageTranslator.replaceMessageList(
Storage.ConfigSections.Messages.NOTIFICATION.ALERT,
@@ -47,16 +47,79 @@ public class BungeeBlockCommandListener implements Listener {
"%command%", displayCommand,
"%server%", serverName);
if (!Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED)
return;
if (Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isCommand(command)) {
if (!Storage.Blacklist.canPlayerAccessChat(player, command, serverName)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, event.getMessage(), true);
MessageTranslator.send(
player,
Storage.ConfigSections.Settings.CUSTOM_PLUGIN.MESSAGE,
"%command%", StringUtils.getFirstArg(displayCommand)
);
if (Storage.SEND_CONSOLE_NOTIFICATION)
Logger.info(notificationMessage);
Storage.NOTIFY_PLAYERS.stream().forEach(uuid -> {
Object p = Storage.getLoader().getPlayerObjByUUID(uuid);
if (p != null) {
MessageTranslator.send(p, notificationMessage);
}
});
event.setCancelled(true);
return;
}
if (Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(command)) {
MessageTranslator.send(
player,
Storage.ConfigSections.Settings.CUSTOM_VERSION.MESSAGE,
"%command%", StringUtils.getFirstArg(displayCommand)
);
if (Storage.SEND_CONSOLE_NOTIFICATION)
Logger.info(notificationMessage);
Storage.NOTIFY_PLAYERS.forEach(uuid -> {
Object p = Storage.getLoader().getPlayerObjByUUID(uuid);
if (p != null) {
MessageTranslator.send(p, notificationMessage);
}
});
event.setCancelled(true);
return;
}
final boolean cancelBlockedCommand = Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED;
boolean allowed = Storage.Blacklist.canPlayerAccessChat(player, command, serverName);
boolean blockedNamespace = false;
if (!Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesBypass(sender)) {
blockedNamespace = cancelBlockedCommand
? Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.isCommand(command)
: Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesAlwaysBlock(command);
if (blockedNamespace) allowed = false;
}
if (!Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED && !blockedNamespace) {
return;
}
if (!allowed) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(
player,
event.getMessage(),
true,
!Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED
);
if (executeCommandEvent.isBlocked()) {
event.setCancelled(true);
if (Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED)
if (!executeCommandEvent.doesNotify())
return;
if (Storage.SEND_CONSOLE_NOTIFICATION)
@@ -76,7 +139,7 @@ public class BungeeBlockCommandListener implements Listener {
return;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, event.getMessage(), false);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, event.getMessage(), false, false);
if (executeCommandEvent.isBlocked())
event.setCancelled(true);
}
@@ -24,7 +24,7 @@ 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();
@@ -6,6 +6,8 @@ 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 de.rayzs.pat.utils.sender.CommandSender;
import de.rayzs.pat.utils.sender.CommandSenderHandler;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Listener;
import de.rayzs.pat.api.storage.Storage;
@@ -19,7 +21,10 @@ public class BungeePlayerConnectionListener implements Listener {
@EventHandler (priority = EventPriority.LOWEST)
public void onPostLogin(PostLoginEvent event) {
ProxiedPlayer player = event.getPlayer();
final ProxiedPlayer player = event.getPlayer();
final CommandSender sender = CommandSenderHandler.from(player);
sender.updateSenderObject(player);
PATEventHandler.callServerPlayersChangeEvents(player, ServerPlayersChangeEvent.Type.JOINED);
if(CustomServerBrand.isEnabled())
@@ -27,7 +32,8 @@ public class BungeePlayerConnectionListener implements Listener {
if (player.isConnected()) CustomServerBrand.sendBrandToPlayer(player);
}, 500, TimeUnit.MILLISECONDS);
PermissionUtil.setPlayerPermissions(player.getUniqueId());
PermissionUtil.setPlayerPermissions(sender);
sender.updateGroups();
if(Storage.OUTDATED && PermissionUtil.hasPermission(player, "joinupdate")) {
ProxyServer.getInstance().getScheduler().schedule(BungeeLoader.getPlugin(), () -> {
@@ -44,8 +50,16 @@ public class BungeePlayerConnectionListener implements Listener {
BungeePacketAnalyzer.inject(player);
if (Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1)
if (Storage.ConfigSections.Settings.UPDATE_GROUPS_PER_SERVER.ENABLED) {
CommandSender sender = CommandSenderHandler.from(player);
assert sender != null;
PermissionUtil.reloadPermissions(sender);
}
if (Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1) {
return;
}
CustomServerBrand.sendBrandToPlayer(player);
}
@@ -58,8 +72,9 @@ public class BungeePlayerConnectionListener implements Listener {
PermissionUtil.resetPermissions(player.getUniqueId());
BungeePacketAnalyzer.uninject(player);
if (Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1)
if (Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1) {
return;
}
CustomServerBrand.sendBrandToPlayer(player);
}
@@ -21,15 +21,12 @@ public class WaterfallAntiTabListener implements Listener {
@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 (Storage.Blacklist.isDisabledServer(serverName))
if (Storage.Blacklist.isDisabledServer(serverName) || PermissionUtil.hasBypassPermission(player))
return;
Map<String, CommandsCache> cache = Storage.getLoader().getCommandsCacheMap();
@@ -44,13 +41,18 @@ public class WaterfallAntiTabListener implements Listener {
event.getCommands().forEach((key, value) -> commandsAsString.add(key));
commandsCache.handleCommands(commandsAsString, serverName);
if(PermissionUtil.hasBypassPermission(player)) return;
List<String> playerCommands = commandsCache.getPlayerCommands(commandsAsString, player, serverName);
event.getCommands().entrySet().removeIf(command -> {
List<String> playerCommands = commandsCache.getPlayerCommands(commandsAsString, player, player.getUniqueId(), serverName);
event.getCommands().entrySet().removeIf(command -> playerCommands.contains(command.getKey()));
if (Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isTabCompletable(command.getKey()) || Storage.ConfigSections.Settings.CUSTOM_VERSION.isTabCompletable(command.getKey())) {
return false;
}
return playerCommands.contains(command.getKey());
});
FilteredSuggestionEvent filteredSuggestionEvent = PATEventHandler.callFilteredSuggestionEvents(player, new ArrayList<>(event.getCommands().keySet()));
if(filteredSuggestionEvent.isCancelled()) event.getCommands().clear();
if (filteredSuggestionEvent.isCancelled()) event.getCommands().clear();
for (String commandName : filteredSuggestionEvent.getSuggestions()) {
@@ -1,7 +1,6 @@
package de.rayzs.pat.plugin.listeners.velocity;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -15,6 +14,7 @@ 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.plugin.logger.Logger;
import de.rayzs.pat.utils.CommandsCache;
import de.rayzs.pat.utils.permission.PermissionUtil;
@@ -29,6 +29,11 @@ public class VelocityAntiTabListener {
@Subscribe (order = PostOrder.LAST)
public void onTabComplete(TabCompleteEvent event) {
Player player = event.getPlayer();
if (!event.getPartialMessage().startsWith("/")) {
return;
}
String serverName = player.getCurrentServer().isPresent() ? player.getCurrentServer().get().getServerInfo().getName() : "unknown";
if (Storage.Blacklist.isDisabledServer(serverName))
@@ -36,53 +41,78 @@ public class VelocityAntiTabListener {
if (PermissionUtil.hasBypassPermission(player) || event.getSuggestions().isEmpty() || !player.getCurrentServer().isPresent()) return;
event.getSuggestions().removeIf(command -> !Storage.Blacklist.canPlayerAccessTab(player, command, serverName));
event.getSuggestions().removeIf(command -> {
if (Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isTabCompletable(command) || Storage.ConfigSections.Settings.CUSTOM_VERSION.isTabCompletable(command)) {
return false;
}
return !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();
try {
Player player = event.getPlayer();
if(event.getRootNode().getChildren().isEmpty() || !player.getCurrentServer().isPresent())
return;
if (event.getRootNode().getChildren().isEmpty() || !player.getCurrentServer().isPresent()) {
return;
}
String serverName = player.getCurrentServer().get().getServer().getServerInfo().getName();
if (PermissionUtil.hasBypassPermission(player)) {
return;
}
Map<String, CommandsCache> cache = Storage.getLoader().getCommandsCacheMap();
String serverName = player.getCurrentServer().get().getServer().getServerInfo().getName();
if(!cache.containsKey(serverName))
cache.put(serverName, new CommandsCache());
if (Storage.Blacklist.isDisabledServer(serverName)) {
return;
}
CommandsCache commandsCache = cache.get(serverName);
Map<String, CommandsCache> cache = Storage.getLoader().getCommandsCacheMap();
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 (!cache.containsKey(serverName)) {
cache.put(serverName, new CommandsCache());
}
if (PermissionUtil.hasBypassPermission(player))
return;
CommandsCache commandsCache = cache.get(serverName);
final boolean newer = player.getProtocolVersion().getProtocol() > 340, argsChildrenExist = event.getRootNode().getChild("args") != null;
final List<String> playerCommands = commandsCache.getPlayerCommands(commandsAsString, player, player.getUniqueId(), 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 (event.getRootNode().getChildren().size() == 1
&& newer && argsChildrenExist
&& event.getRootNode().getChild("args").getChildren().isEmpty()) {
return;
final boolean newer = player.getProtocolVersion().getProtocol() > 340, argsChildrenExist = event.getRootNode().getChild("args") != null;
final List<String> playerCommands = commandsCache.getPlayerCommands(commandsAsString, player, 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;
if (Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isTabCompletable(command.getName()) || Storage.ConfigSections.Settings.CUSTOM_VERSION.isTabCompletable(command.getName())) {
return false;
}
return !playerCommands.contains(command.getName());
});
} catch (Exception exception) {
Logger.warning("An error occurred while processing commands in PAT: " + exception.getMessage());
exception.printStackTrace();
}
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());
});
}
}
@@ -1,5 +1,6 @@
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;
@@ -9,10 +10,18 @@ import com.velocitypowered.api.proxy.Player;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.api.event.*;
import de.rayzs.pat.utils.sender.CommandSender;
import de.rayzs.pat.utils.sender.CommandSenderHandler;
import java.util.List;
public class VelocityBlockCommandListener {
@Subscribe
public void onCommandExecute(CommandExecuteEvent event) {
handleCommand(event);
}
public static CommandExecuteEvent handleCommand(Player player, String command) {
return handleCommand(new CommandExecuteEvent(player, command));
}
@@ -21,28 +30,24 @@ public class VelocityBlockCommandListener {
if(!event.getResult().isAllowed())
return event;
CommandSource commandSource = event.getCommandSource();
Object consoleSender = Storage.getLoader().getConsoleSender();
final CommandSource commandSource = event.getCommandSource();
final Object consoleSender = Storage.getLoader().getConsoleSender();
if(! (commandSource instanceof Player))
return event;
Player player = (Player) commandSource;
String command = StringUtils.getFirstArg(event.getCommand());
String serverName = player.getCurrentServer().isPresent()
final Player player = (Player) commandSource;
final CommandSender sender = CommandSenderHandler.from(player);
final String serverName = player.getCurrentServer().isPresent()
? player.getCurrentServer().get().getServerInfo().getName()
: "unknown";
boolean bypassPermission = PermissionUtil.hasBypassPermission(player, command);
String command = StringUtils.getFirstArg(event.getCommand());
if (bypassPermission)
if (PermissionUtil.hasBypassPermission(player, command) || Storage.Blacklist.isDisabledServer(serverName))
return event;
final String displayCommand = command;
command = StringUtils.replaceTriggers(command, "", "\\", "<", ">", "&");
command = command.toLowerCase();
final String displayCommand = StringUtils.replaceTriggers(command, "", "\\", "<", ">", "&");
List<String> notificationMessage = MessageTranslator.replaceMessageList(
@@ -52,22 +57,84 @@ public class VelocityBlockCommandListener {
"%server%", serverName
);
if (!Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED)
return event;
if (Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isCommand(command)) {
if (!Storage.Blacklist.canPlayerAccessChat(player, command, serverName)) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, event.getCommand(), true);
MessageTranslator.send(
player,
Storage.ConfigSections.Settings.CUSTOM_PLUGIN.MESSAGE,
"%command%", StringUtils.getFirstArg(displayCommand)
);
if (Storage.SEND_CONSOLE_NOTIFICATION)
MessageTranslator.send(consoleSender, notificationMessage);
Storage.NOTIFY_PLAYERS.forEach(uuid -> {
Object p = Storage.getLoader().getPlayerObjByUUID(uuid);
if (p != null) {
MessageTranslator.send(p, notificationMessage);
}
});
event.setResult(CommandExecuteEvent.CommandResult.denied());
return event;
}
if (Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(command)) {
MessageTranslator.send(
player,
Storage.ConfigSections.Settings.CUSTOM_VERSION.MESSAGE,
"%command%", StringUtils.getFirstArg(displayCommand)
);
if (Storage.SEND_CONSOLE_NOTIFICATION)
MessageTranslator.send(consoleSender, notificationMessage);
Storage.NOTIFY_PLAYERS.forEach(uuid -> {
Object p = Storage.getLoader().getPlayerObjByUUID(uuid);
if (p != null) {
MessageTranslator.send(p, notificationMessage);
}
});
event.setResult(CommandExecuteEvent.CommandResult.denied());
return event;
}
final boolean cancelBlockedCommand = Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED;
boolean allowed = Storage.Blacklist.canPlayerAccessChat(player, command, serverName);
boolean blockedNamespace = false;
if (!Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesBypass(sender)) {
blockedNamespace = cancelBlockedCommand
? Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.isCommand(command)
: Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesAlwaysBlock(command);
if (blockedNamespace) allowed = false;
}
if (!Storage.ConfigSections.Settings.CANCEL_COMMAND.ENABLED && !blockedNamespace) {
return event;
}
if (!allowed) {
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(
player,
event.getCommand(),
true,
!Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED);
if (executeCommandEvent.isBlocked()) {
event.setResult(CommandExecuteEvent.CommandResult.denied());
if (Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED)
if (!executeCommandEvent.doesNotify())
return event;
if (Storage.SEND_CONSOLE_NOTIFICATION)
MessageTranslator.send(consoleSender, notificationMessage);
Storage.NOTIFY_PLAYERS.stream().forEach(uuid -> {
Storage.NOTIFY_PLAYERS.forEach(uuid -> {
Object p = Storage.getLoader().getPlayerObjByUUID(uuid);
if (p != null) {
MessageTranslator.send(p, notificationMessage);
@@ -79,7 +146,7 @@ public class VelocityBlockCommandListener {
return event;
}
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, event.getCommand(), false);
ExecuteCommandEvent executeCommandEvent = PATEventHandler.callExecuteCommandEvents(player, event.getCommand(), false, false);
if (executeCommandEvent.isBlocked())
event.setResult(CommandExecuteEvent.CommandResult.denied());
@@ -5,6 +5,7 @@ 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.plugin.logger.Logger;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.utils.permission.PermissionUtil;
import com.velocitypowered.api.event.Subscribe;
@@ -12,6 +13,10 @@ import com.velocitypowered.api.event.player.*;
import de.rayzs.pat.plugin.VelocityLoader;
import de.rayzs.pat.api.storage.Storage;
import com.velocitypowered.api.proxy.*;
import de.rayzs.pat.utils.sender.CommandSender;
import de.rayzs.pat.utils.sender.CommandSenderHandler;
import net.kyori.adventure.text.Component;
import java.util.concurrent.TimeUnit;
public class VelocityConnectionListener {
@@ -26,7 +31,10 @@ public class VelocityConnectionListener {
@Subscribe
public void onServerPreConnect(ServerPreConnectEvent event) {
Player player = event.getPlayer();
final Player player = event.getPlayer();
final CommandSender sender = CommandSenderHandler.from(player);
sender.updateSenderObject(player);
PATEventHandler.callServerPlayersChangeEvents(player, ServerPlayersChangeEvent.Type.JOINED);
if(CustomServerBrand.isEnabled())
@@ -34,7 +42,8 @@ public class VelocityConnectionListener {
if (player.isActive()) CustomServerBrand.sendBrandToPlayer(player);
}).delay(500, TimeUnit.MILLISECONDS).schedule();
PermissionUtil.setPlayerPermissions(player.getUniqueId());
PermissionUtil.setPlayerPermissions(sender);
sender.updateGroups();
if(Storage.OUTDATED && PermissionUtil.hasPermission(player, "joinupdate")) {
server.getScheduler().buildTask(loader, () -> {
@@ -48,10 +57,32 @@ public class VelocityConnectionListener {
public void onServerSwitch(ServerConnectedEvent event) {
Player player = event.getPlayer();
if(!VelocityPacketAnalyzer.isInjected(player))
VelocityPacketAnalyzer.inject(player);
if (!VelocityPacketAnalyzer.isInjected(player)) {
if (!VelocityPacketAnalyzer.inject(player)) {
Logger.warning("Attempting delayed injection for " + player.getUsername());
server.getScheduler().buildTask(loader, () -> {
if (!VelocityPacketAnalyzer.inject(player)) {
Logger.warning("Second injection for " + player.getUsername() + " failed as well!");
player.disconnect(Component.text("Failed to inject player!"));
}
}).delay(1, TimeUnit.SECONDS).schedule();
}
}
if (Storage.ConfigSections.Settings.UPDATE_GROUPS_PER_SERVER.ENABLED) {
CommandSender sender = CommandSenderHandler.from(player);
assert sender != null;
PermissionUtil.reloadPermissions(sender);
}
if (Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1) {
return;
}
if(Storage.ConfigSections.Settings.CUSTOM_BRAND.REPEAT_DELAY != -1) return;
CustomServerBrand.sendBrandToPlayer(player);
}
@@ -1,21 +1,42 @@
package de.rayzs.pat.plugin.logger;
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 de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.*;
import de.rayzs.pat.utils.group.Group;
import de.rayzs.pat.utils.group.GroupManager;
import de.rayzs.pat.utils.permission.PermissionPlugin;
import java.net.URL;
import java.util.*;
import java.io.*;
public class Logger {
private static final String LOG_HEADER;
static {
final String software = Reflection.isProxyServer()
? Reflection.isVelocityServer() ? "Velocity" : "Bungeecord"
: (Reflection.isPaper() ? "Paper" : Reflection.isFoliaServer() ? "Folia" : "Spigot/Bukkit");
final String version = Reflection.isProxyServer() ? "" : " " + Reflection.getRawVersionName().replace("_", ".");
LOG_HEADER = "> ProAntiTab v" + Storage.CURRENT_VERSION + " [" + software + version + "]";
}
private final static LoggerTemplate LOGGER =
Reflection.isVelocityServer() ? new VelocityLogger()
: Reflection.isProxyServer() ? new BungeeLogger()
: new BukkitLogger();
public static void info(List<String> messages) {
LOGGER.info(messages);
}
@@ -24,10 +45,6 @@ public class Logger {
LOGGER.warn(messages);
}
public static void debug(List<String> messages) {
LOGGER.debug(messages);
}
public static void info(String message) {
LOGGER.info(message);
}
@@ -36,25 +53,9 @@ public class Logger {
LOGGER.warn(message);
}
public static void debug(String message) {
LOGGER.debug(message);
}
public static String post() throws IOException {
ArrayList<String> clonedLogs = new ArrayList<>(LOGGER.getLogs());
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();
@@ -77,4 +78,102 @@ public class Logger {
response = response.substring(response.indexOf(":") + 2, response.length() - 2);
return "https://haste.rayzs.de/" + response + ".txt";
}
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: ");
if (Reflection.isProxyServer()) {
builder.append(Reflection.isPaper() ? "Waterfall" : Reflection.isVelocityServer() ? "Velocity" : "Bungeecord");
} else {
builder.append(Reflection.isFoliaServer() ? "Folia" : Reflection.isPaper() ? "Paper" : "Spigot");
}
builder.append("\n");
builder.append("Installed plugins: \n ")
.append(String.join("\n ", Storage.getLoader().getPluginNames("%n (%v)")))
.append("\n\n");
builder.append("Detected supported plugins:")
.append("\n");
builder.append(" LuckPerms: ")
.append(Storage.getPermissionPlugin() == PermissionPlugin.LUCKPERMS)
.append("\n");
if (!Reflection.isProxyServer()) {
builder.append(" GroupManager: ")
.append(Storage.getPermissionPlugin() == PermissionPlugin.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 ? TimeConverter.calcAndGetTime(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" : (TimeConverter.calcAndGetTime(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();
}
}
@@ -1,3 +1,3 @@
package de.rayzs.pat.plugin.logger;
public enum LoggerPriority { INFO, WARNING, DEBUG }
public enum LoggerPriority { INFO, WARNING }
@@ -1,23 +1,16 @@
package de.rayzs.pat.plugin.logger;
import java.text.SimpleDateFormat;
import java.util.List;
public interface LoggerTemplate {
SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss:SS");
List<String> getLogs();
void info(List<String> messages);
void warn(List<String> messages);
void debug(List<String> messages);
void send(LoggerPriority priority, List<String> messages);
void info(String message);
void warn(String message);
void debug(String message);
void send(LoggerPriority priority, String message);
}
@@ -1,25 +1,15 @@
package de.rayzs.pat.plugin.logger.impl;
import de.rayzs.pat.plugin.BukkitLoader;
import de.rayzs.pat.plugin.logger.LoggerPriority;
import de.rayzs.pat.plugin.logger.LoggerTemplate;
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.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;
public class BukkitLogger implements LoggerTemplate {
private final List<String> LOGS = new ArrayList<>();
private final java.util.logging.Logger logger = BukkitLoader.getPluginLogger();
@Override
public List<String> getLogs() {
return LOGS;
}
@Override
public void info(List<String> messages) {
messages.forEach(this::info);
@@ -30,11 +20,6 @@ public class BukkitLogger implements LoggerTemplate {
messages.forEach(this::warn);
}
@Override
public void debug(List<String> messages) {
messages.forEach(this::debug);
}
@Override
public void send(LoggerPriority priority, List<String> messages) {
messages.forEach(message -> send(priority, message));
@@ -50,22 +35,10 @@ public class BukkitLogger implements LoggerTemplate {
send(LoggerPriority.WARNING, message);
}
@Override
public void debug(String message) {
send(LoggerPriority.DEBUG, message);
}
@Override
public void send(LoggerPriority priority, String message) {
message = MessageTranslator.replaceMessage(message);
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(message));
if (priority == LoggerPriority.DEBUG)
return;
if (message.contains("§")) {
MessageTranslator.send(Bukkit.getServer().getConsoleSender(), message);
return;
@@ -1,25 +1,15 @@
package de.rayzs.pat.plugin.logger.impl;
import de.rayzs.pat.plugin.BungeeLoader;
import de.rayzs.pat.plugin.logger.LoggerPriority;
import de.rayzs.pat.plugin.logger.LoggerTemplate;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.plugin.BungeeLoader;
import net.md_5.bungee.api.ProxyServer;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import de.rayzs.pat.plugin.logger.*;
import java.util.*;
public class BungeeLogger implements LoggerTemplate {
private final List<String> LOGS = new ArrayList<>();
private final java.util.logging.Logger logger = BungeeLoader.getPluginLogger();
@Override
public List<String> getLogs() {
return LOGS;
}
@Override
public void info(List<String> messages) {
messages.forEach(this::info);
@@ -30,11 +20,6 @@ public class BungeeLogger implements LoggerTemplate {
messages.forEach(this::warn);
}
@Override
public void debug(List<String> messages) {
messages.forEach(this::debug);
}
@Override
public void send(LoggerPriority priority, List<String> messages) {
messages.forEach(message -> send(priority, message));
@@ -50,22 +35,10 @@ public class BungeeLogger implements LoggerTemplate {
send(LoggerPriority.WARNING, message);
}
@Override
public void debug(String message) {
send(LoggerPriority.DEBUG, message);
}
@Override
public void send(LoggerPriority priority, String message) {
message = MessageTranslator.replaceMessage(message);
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(message));
if (priority == LoggerPriority.DEBUG)
return;
if (message.contains("§")) {
MessageTranslator.send(ProxyServer.getInstance().getConsole(), message);
return;
@@ -1,25 +1,15 @@
package de.rayzs.pat.plugin.logger.impl;
import de.rayzs.pat.plugin.VelocityLoader;
import de.rayzs.pat.plugin.logger.LoggerPriority;
import de.rayzs.pat.plugin.logger.LoggerTemplate;
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.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;
public class VelocityLogger implements LoggerTemplate {
private final List<String> LOGS = new ArrayList<>();
private final Logger logger = VelocityLoader.getPluginLogger();
@Override
public List<String> getLogs() {
return LOGS;
}
@Override
public void info(List<String> messages) {
messages.forEach(this::info);
@@ -30,11 +20,6 @@ public class VelocityLogger implements LoggerTemplate {
messages.forEach(this::warn);
}
@Override
public void debug(List<String> messages) {
messages.forEach(this::debug);
}
@Override
public void send(LoggerPriority priority, List<String> messages) {
messages.forEach(message -> send(priority, message));
@@ -50,22 +35,10 @@ public class VelocityLogger implements LoggerTemplate {
send(LoggerPriority.WARNING, message);
}
@Override
public void debug(String message) {
send(LoggerPriority.DEBUG, message);
}
@Override
public void send(LoggerPriority priority, String message) {
message = MessageTranslator.replaceMessage(message);
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(message));
if (priority == LoggerPriority.DEBUG)
return;
if (message.contains("§")) {
MessageTranslator.send(VelocityLoader.getServer().getConsoleCommandSource(), message);
return;
@@ -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
@@ -5,9 +5,12 @@ 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.permission.PermissionPlugin;
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.sender.CommandSender;
import de.rayzs.pat.utils.sender.CommandSenderHandler;
import de.rayzs.pat.utils.subargs.*;
import java.util.stream.Collectors;
import de.rayzs.pat.utils.group.*;
@@ -72,11 +75,11 @@ public class SubArgsModule {
ArgumentSource source = arguments.TAB_ARGUMENTS;
if (source == null) return;
List<String> inputs = source.getAllInputs().stream().filter(str -> !str.contains("%")).toList();
List<String> inputs = source.getAllInputs();
List<String> allEntries = inputs.stream().map(StringUtils::getFirstArg).toList();
helper.removeIf(allEntries::contains);
inputs.forEach(helper::add);
inputs.forEach(input -> helper.add(input, true));
}
public static List<String> getServerCommands(UUID uuid) {
@@ -104,7 +107,14 @@ public class SubArgsModule {
public static List<String> getGroupCommands(UUID uuid, String serverName) {
List<String> commands = new ArrayList<>();
List<Group> groups = GroupManager.getPlayerGroups(uuid);
List<Group> groups;
if (Storage.getPermissionPlugin() == PermissionPlugin.NONE) {
CommandSender sender = CommandSenderHandler.getSenderFromUUID(uuid);
groups = GroupManager.getPlayerGroups(sender);
} else {
groups = GroupManager.getPlayerGroups(uuid);
}
if (serverName == null) {
groups.forEach(group -> commands.addAll(group.getCommands()));
@@ -124,4 +134,36 @@ public class SubArgsModule {
});
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);
}
}
@@ -23,7 +23,10 @@ public class ExecuteCommand extends ExecuteCommandEvent {
? command.substring(1)
: command;
final String displayCommand = StringUtils.getFirstArg(command);
final String displayCommand = StringUtils.replaceTriggers(
command, "",
"\\", "<", ">", "&"
);
CommandSender sender = CommandSenderHandler.from(event.getSenderObj());
@@ -32,39 +35,13 @@ public class ExecuteCommand extends ExecuteCommandEvent {
UUID uuid = sender.getUniqueId();
if (Storage.ConfigSections.Settings.CUSTOM_PLUGIN.isCommand(command)) {
MessageTranslator.send(
event.getSenderObj(),
Storage.ConfigSections.Settings.CUSTOM_PLUGIN.MESSAGE,
"%command%", displayCommand
);
event.setBlocked(true);
event.setCancelled(true);
return;
}
if (Storage.ConfigSections.Settings.CUSTOM_VERSION.isCommand(command)) {
MessageTranslator.send(
event.getSenderObj(),
Storage.ConfigSections.Settings.CUSTOM_VERSION.MESSAGE,
"%command%", displayCommand
);
event.setBlocked(true);
event.setCancelled(true);
return;
}
if (command.contains(" ") && !canPlayerExecute(sender, command)) {
if (isBlocked(sender, command)) {
event.setBlocked(true);
event.setCancelled(true);
MessageTranslator.send(event.getSenderObj(),
ResponseHandler.getResponse(uuid, event.getCommand()),
"%command%", command);
"%command%", displayCommand);
return;
}
@@ -77,22 +54,57 @@ public class ExecuteCommand extends ExecuteCommandEvent {
MessageTranslator.send(
event.getSenderObj(),
ResponseHandler.getResponse(uuid, event.getCommand(), Storage.ConfigSections.Settings.CANCEL_COMMAND.BASE_COMMAND_RESPONSE.getLines()),
"%command%", displayCommand
"%command%", StringUtils.getFirstArg(displayCommand)
);
}
private boolean canPlayerExecute(CommandSender sender, String command) {
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;
Arguments arguments = SubArgsModule.PLAYER_COMMANDS.getOrDefault(sender.getUniqueId(), Arguments.ARGUMENTS);
List<String> commands = new ArrayList<>(arguments.CHAT_ARGUMENTS.getGeneralArgument().getInputs());
final String unmodifiable = command;
if (commands.stream().noneMatch(c -> StringUtils.getFirstArg(c).equalsIgnoreCase(StringUtils.getFirstArg(unmodifiable)))) {
return true;
}
final String firstArgUnmodifiable = StringUtils.getFirstArg(unmodifiable);
commands = commands.stream().map(c -> {
if (c.contains("%hidden")) {
@@ -102,10 +114,13 @@ public class ExecuteCommand extends ExecuteCommandEvent {
return c;
}).toList();
List<String> placeholderCommands = commands.stream().filter(s -> s.contains("%")).toList();
List<String> placeholderCommands = commands.stream().filter(s ->
StringUtils.getFirstArg(s).equalsIgnoreCase(firstArgUnmodifiable) && s.contains("%")
).toList();
if (!placeholderCommands.isEmpty())
command = replacePlaceholders(command, placeholderCommands);
if (!placeholderCommands.isEmpty()) {
command = SubArgsModule.replacePlaceholders(command);
}
String cpyCommand;
for (String c : commands) {
@@ -137,38 +152,6 @@ public class ExecuteCommand extends ExecuteCommandEvent {
}
}
return turn == listed;
}
private String replacePlaceholders(String input, List<String> abnormalCommands) {
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);
return listed;
}
}
@@ -13,23 +13,56 @@ public class TabCompletion extends FilteredTabCompletionEvent {
@Override
public void handle(FilteredTabCompletionEvent event) {
String cursor = StringUtils.replaceFirst(event.getCursor(), "/", "");
final String cursor = event.getCursor().substring(1);
if (event.getCompletion().isEmpty()) return;
UUID uuid = event.getSenderObj() instanceof UUID
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();
Arguments arguments = SubArgsModule.PLAYER_COMMANDS.getOrDefault(uuid, Arguments.ARGUMENTS);
List<String> possibilities = event.getCompletion(), result = new ArrayList<>(arguments.getResultTab(cursor));
final Arguments arguments = SubArgsModule.PLAYER_COMMANDS.getOrDefault(uuid, Arguments.ARGUMENTS);
if (Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED) {
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(possibilities.stream().filter(NumberUtils::isDigit).toList());
possibilities.addAll(event.getCompletion().stream().filter(NumberUtils::isDigit).toList());
if (possibilities.isEmpty())
possibilities.add("///////////");
}
if (result.contains("%players%")) {
@@ -67,11 +100,11 @@ public class TabCompletion extends FilteredTabCompletionEvent {
return result.contains(completion);
}).toList());
if (possibilities.isEmpty()) possibilities.add("///////////");
if (possibilities.isEmpty())
possibilities.add("///////////");
}
} else {
if (result.contains("%numbers%"))
possibilities.removeIf(NumberUtils::isDigit);
@@ -81,11 +114,20 @@ public class TabCompletion extends FilteredTabCompletionEvent {
if (result.contains("%online_players%"))
possibilities.removeIf(possibility -> SubArgsModule.getOnlinePlayerNames().contains(possibility));
possibilities.removeAll(result);
possibilities.removeIf(s -> {
if (negated.contains(s)) {
return false;
}
return result.contains(s);
});
}
cursor = StringUtils.getFirstArg(cursor.toLowerCase());
if(possibilities.isEmpty() && !SubArgsModule.GENERAL_LIST.contains(cursor)) return;
String firstCursorArg = StringUtils.getFirstArg(cursor.toLowerCase());
if (possibilities.isEmpty() && !SubArgsModule.GENERAL_LIST.contains(firstCursorArg)) {
return;
}
event.setCompletion(possibilities);
}
@@ -48,11 +48,26 @@ public class UpdateList {
for (String command : event.getCommands())
argument.buildArgumentStacks(command);
for (String command : argument.CHAT_ARGUMENTS.getGeneralArgument().getInputs())
argument.CHAT_ARGUMENTS.buildArguments(Storage.Blacklist.BlockTypeFetcher.modify(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 : argument.TAB_ARGUMENTS.getGeneralArgument().getInputs())
argument.TAB_ARGUMENTS.buildArguments(Storage.Blacklist.BlockTypeFetcher.modify(command));
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);
@@ -9,6 +9,7 @@ import de.rayzs.pat.plugin.process.impl.local.modify.list.ListPrioritiesCommand;
import de.rayzs.pat.plugin.process.impl.local.system.NotifyCommand;
import de.rayzs.pat.plugin.process.impl.local.system.PostDebugCommand;
import de.rayzs.pat.plugin.process.impl.local.system.ReloadCommand;
import de.rayzs.pat.plugin.process.impl.local.system.UpdateCommand;
import de.rayzs.pat.plugin.process.impl.server.ServAddCommand;
import de.rayzs.pat.plugin.process.impl.server.ServClearCommand;
import de.rayzs.pat.plugin.process.impl.server.ServRemoveCommand;
@@ -34,6 +35,12 @@ public class CommandProcess {
COMMANDS.add(new RemoveCommand());
COMMANDS.add(new ClearCommand());
COMMANDS.add(new ConvertCommand());
if (!Reflection.isProxyServer()) {
COMMANDS.add(new ExtractCommand());
}
COMMANDS.add(new CreateGroupCommand());
COMMANDS.add(new DeleteGroupCommand());
@@ -1,53 +0,0 @@
package de.rayzs.pat.plugin.process.impl.local.info;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.api.command.ProCommand;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.sender.CommandSender;
import java.util.*;
public class UpdateCommand extends ProCommand {
public UpdateCommand() {
super(
"update",
""
);
}
@Override
public boolean execute(CommandSender sender, String[] args) {
if (args.length == 0) {
PermissionUtil.reloadPermissions();
sender.sendMessage(Storage.ConfigSections.Messages.UPDATE_PERMISSIONS.UPDATE_ALL);
return true;
}
String name = args[0];
UUID uuid = Storage.getLoader().getUUIDByName(name);
boolean exist = uuid != null;
if (exist) {
name = Storage.getLoader().getNameByUUID(uuid);
}
String message = exist
? Storage.ConfigSections.Messages.UPDATE_PERMISSIONS.UPDATE_SPECIFIC
: Storage.ConfigSections.Messages.UPDATE_PERMISSIONS.PLAYER_NOT_ONLINE;
message = message.replace("%target%", name);
if (exist) {
PermissionUtil.reloadPermissions(uuid);
}
sender.sendMessage(message);
return true;
}
@Override
public List<String> tabComplete(CommandSender sender, String[] args) {
return args.length < 2 ? Storage.getLoader().getPlayerNames() : null;
}
}
@@ -58,6 +58,7 @@ public class AddCommand extends ProCommand {
if (command.isEmpty())
return false;
final boolean loadBlacklist = command.startsWith("plugin=") || command.startsWith("!");
final int length = args.length;
if (length == 1) {
@@ -67,6 +68,8 @@ public class AddCommand extends ProCommand {
if (!exist) {
Storage.Blacklist.getBlacklist().add(command).save();
if (loadBlacklist) Storage.Blacklist.getBlacklist().load();
Storage.handleChange();
}
@@ -107,7 +110,9 @@ public class AddCommand extends ProCommand {
if (Reflection.isProxyServer())
return null;
return BukkitLoader.getNotBlockedCommands();
return Storage.ConfigSections.Settings.TURN_BLACKLIST_TO_WHITELIST.ENABLED
? BukkitLoader.getDisallowedCommands()
: BukkitLoader.getAllowedCommands();
}
String fullString = String.join(" ", args);
@@ -34,6 +34,7 @@ public class ClearCommand extends ProCommand {
}
Storage.Blacklist.getBlacklist().clear().save();
Storage.Blacklist.getBlacklist().load();
Storage.handleChange();
CONFIRMATION.remove(sender.getUniqueId());
@@ -0,0 +1,51 @@
package de.rayzs.pat.plugin.process.impl.local.modify;
import de.rayzs.pat.api.command.ProCommand;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.converter.Converter;
import de.rayzs.pat.plugin.converter.StorageConverter;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.sender.CommandSender;
import java.util.List;
public class ConvertCommand extends ProCommand {
public ConvertCommand() {
super(
"convert",
""
);
}
@Override
public boolean execute(CommandSender sender, String[] args) {
if (args.length != 1)
return false;
String converterName = args[0];
Converter converter = StorageConverter.getConverter(converterName);
if (converter == null) {
sender.sendMessage(StringUtils.replace(Storage.ConfigSections.Messages.CONVERT.INVALID_CONVERTER,
"%converter%", converterName)
);
return true;
}
converterName = converter.getPluginName();
sender.sendMessage(StringUtils.replace(Storage.ConfigSections.Messages.CONVERT.SUCCESS,
"%converter%", converterName)
);
converter.apply(sender);
Storage.reload();
return true;
}
@Override
public List<String> tabComplete(CommandSender sender, String[] args) {
return StorageConverter.getConverters().stream().toList();
}
}
@@ -8,6 +8,7 @@ import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.group.Group;
import de.rayzs.pat.utils.group.GroupManager;
import java.util.Collections;
import java.util.List;
public class CreateGroupCommand extends ProCommand {
@@ -50,6 +51,6 @@ public class CreateGroupCommand extends ProCommand {
@Override
public List<String> tabComplete(CommandSender sender, String[] args) {
return args.length < 2 ? GroupManager.getGroupNames() : null;
return Collections.emptyList();
}
}
@@ -0,0 +1,137 @@
package de.rayzs.pat.plugin.process.impl.local.modify;
import de.rayzs.pat.api.command.ProCommand;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.api.storage.storages.BlacklistStorage;
import de.rayzs.pat.plugin.BukkitLoader;
import de.rayzs.pat.plugin.converter.Converter;
import de.rayzs.pat.plugin.converter.StorageConverter;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.group.Group;
import de.rayzs.pat.utils.group.GroupManager;
import de.rayzs.pat.utils.sender.CommandSender;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import java.util.*;
public class ExtractCommand extends ProCommand {
public ExtractCommand() {
super(
"extract",
""
);
}
@Override
public boolean execute(CommandSender sender, String[] args) {
if (args.length < 1) {
sender.sendMessage(Storage.ConfigSections.Messages.EXTRACT.USAGE);
return true;
}
String pluginName = args[0].toLowerCase();
boolean failed = false, useColons = false;
Group group = null;
if (args.length == 2) {
group = GroupManager.getGroupByName(args[1]);
if (group == null) {
useColons = Boolean.parseBoolean(args[1]);
if (!useColons && !args[1].equalsIgnoreCase("false")) {
failed = true;
}
}
try {
useColons = Boolean.parseBoolean(args[1]);
} catch (Exception exception) {
group = GroupManager.getGroupByName(args[1]);
failed = group == null;
}
} else if (args.length == 3) {
group = GroupManager.getGroupByName(args[1]);
if (group == null) {
failed = true;
} else {
try {
useColons = Boolean.parseBoolean(args[2]);
} catch (Exception exception) {
failed = true;
}
}
}
if (failed) {
sender.sendMessage(Storage.ConfigSections.Messages.EXTRACT.USAGE);
return true;
}
List<String> pluginNames = Storage.getLoader().getPluginNames("%n");
boolean pluginFound = false;
for (String name : pluginNames) {
if (name.equalsIgnoreCase(pluginName)) {
pluginFound = true;
break;
}
}
if (!pluginFound) {
sender.sendMessage(StringUtils.replace(Storage.ConfigSections.Messages.EXTRACT.PLUGIN_NOT_FOUND,
"%plugin%", pluginName)
);
return true;
}
List<String> commands = Storage.getLoader().getPluginCommands(args[0], useColons);
BlacklistStorage storage = group == null
? Storage.Blacklist.getBlacklist()
: group.getGeneralGroupBlacklist();
commands = commands.stream().filter(command -> !storage.isListed(command)).toList();
commands.forEach(storage::add);
storage.save();
sender.sendMessage(StringUtils.replace(Storage.ConfigSections.Messages.EXTRACT.SUCCESS,
"%amount%", String.valueOf(commands.size()),
"%plugin%", pluginName
));
return true;
}
@Override
public List<String> tabComplete(CommandSender sender, String[] args) {
final int length = args.length;
if (length <= 1) {
return Storage.getLoader().getPluginNames("%n");
}
List<String> result = new ArrayList<>();
if (length == 2 || length == 3 && GroupManager.getGroupByName(args[1]) != null) {
result.add("true");
result.add("false");
}
if (length == 2) {
result.addAll(GroupManager.getGroupNames());
}
return result;
}
}
@@ -57,15 +57,16 @@ public class RemoveCommand extends ProCommand {
if (command.isEmpty())
return false;
final boolean loadBlacklist = command.startsWith("plugin=") || command.startsWith("!");
final int length = args.length;
if (length == 1) {
boolean exist = command.contains(" ")
? Storage.Blacklist.getBlacklist().getCommands().contains(command)
: Storage.Blacklist.getBlacklist().isListed(command);
boolean exist = Storage.Blacklist.getBlacklist().getCommands().contains(command);
if (exist) {
Storage.Blacklist.getBlacklist().remove(command).save();
if (loadBlacklist) Storage.Blacklist.getBlacklist().load();
Storage.handleChange();
}
@@ -51,7 +51,7 @@ public class ListCommand extends ProCommand {
String message = Storage.ConfigSections.Messages.GROUP.LIST_MESSAGE;
message = StringUtils.replace(message,
"%group%", groupName,
"%size%", String.valueOf(Storage.Blacklist.getBlacklist().getCommands().size()),
"%size%", String.valueOf(group.getCommands().size()),
"%commands%", commandsListMessage
);
@@ -26,7 +26,7 @@ public class ListGroupsCommand extends ProCommand {
String message = Storage.ConfigSections.Messages.GROUP.LIST_GROUP_MESSAGE;
message = StringUtils.replace(message,
"%size%", String.valueOf(Storage.Blacklist.getBlacklist().getCommands().size()),
"%size%", String.valueOf(GroupManager.getGroups().size()),
"%groups%", groupsListMessage
);
@@ -2,6 +2,7 @@ package de.rayzs.pat.plugin.process.impl.local.system;
import de.rayzs.pat.api.communication.BackendUpdater;
import de.rayzs.pat.api.brand.CustomServerBrand;
import de.rayzs.pat.api.storage.blacklist.impl.GeneralBlacklist;
import de.rayzs.pat.utils.configuration.updater.ConfigUpdater;
import de.rayzs.pat.utils.group.GroupManager;
import de.rayzs.pat.api.command.ProCommand;
@@ -21,28 +22,8 @@ public class ReloadCommand extends ProCommand {
@Override
public boolean execute(CommandSender sender, String[] args) {
boolean proxy = Reflection.isProxyServer();
boolean backend = Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED && !proxy;
sender.sendMessage(Storage.ConfigSections.Messages.RELOAD.LOADING);
Storage.loadAll(Reflection.isProxyServer() || !backend);
CustomServerBrand.initialize();
GroupManager.clearAllGroups();
GroupManager.initialize();
if (!proxy) {
BackendUpdater.stop();
BackendUpdater.start();
}
ConfigUpdater.broadcastMissingParts();
if (!backend) {
Storage.handleChange();
}
ConfigUpdater.initialize();
Storage.reload();
sender.sendMessage(Storage.ConfigSections.Messages.RELOAD.DONE);
return true;
}
@@ -0,0 +1,81 @@
package de.rayzs.pat.plugin.process.impl.local.system;
import de.rayzs.pat.plugin.listeners.bukkit.BukkitAntiTabListener;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.api.command.ProCommand;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.sender.CommandSender;
import de.rayzs.pat.utils.sender.CommandSenderHandler;
import java.util.*;
public class UpdateCommand extends ProCommand {
public UpdateCommand() {
super(
"update",
""
);
}
@Override
public boolean execute(CommandSender sender, String[] args) {
if (args.length == 0) {
PermissionUtil.reloadPermissions();
Storage.getLoader().getOnlinePlayerNames().forEach(name -> {
Object playerObj = Storage.getLoader().getPlayerObjByName(name);
if (playerObj != null) {
CommandSender s = CommandSenderHandler.from(playerObj);
assert s != null;
PermissionUtil.reloadPermissions(s);
}
});
if (!Reflection.isProxyServer() && Reflection.getMinor() >= 13) {
BukkitAntiTabListener.handleTabCompletion();
}
sender.sendMessage(Storage.ConfigSections.Messages.UPDATE_PERMISSIONS.UPDATE_ALL);
return true;
}
String name = args[0];
UUID uuid = Storage.getLoader().getUUIDByName(name);
Object playerObj = Storage.getLoader().getPlayerObjByUUID(uuid);
CommandSender targetSender = CommandSenderHandler.from(playerObj);
boolean exist = targetSender != null;
if (exist) {
name = targetSender.getName();
}
String message = exist
? Storage.ConfigSections.Messages.UPDATE_PERMISSIONS.UPDATE_SPECIFIC
: Storage.ConfigSections.Messages.UPDATE_PERMISSIONS.PLAYER_NOT_ONLINE;
message = message.replace("%target%", name);
if (exist) {
PermissionUtil.reloadPermissions(targetSender);
if (!Reflection.isProxyServer() && Reflection.getMinor() >= 13) {
BukkitAntiTabListener.handleTabCompletion(uuid);
}
}
sender.sendMessage(message);
return true;
}
@Override
public List<String> tabComplete(CommandSender sender, String[] args) {
return args.length < 2 ? Storage.getLoader().getOnlinePlayerNames() : null;
}
}
@@ -90,7 +90,15 @@ public class ServAddCommand extends ProCommand {
Group group = GroupManager.getGroupByName(groupName);
if (group == null) {
sender.sendMessage(Storage.ConfigSections.Messages.GROUP.DOES_NOT_EXIST_SERVER.replace("%group%", groupName));
String message = Storage.ConfigSections.Messages.GROUP.DOES_NOT_EXIST_SERVER;
message = StringUtils.replace(message,
"%group%", groupName,
"%server%", serverName
);
sender.sendMessage(message);
return true;
}
@@ -2,6 +2,7 @@ package de.rayzs.pat.plugin.process.impl.server;
import de.rayzs.pat.api.command.ProCommand;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.sender.CommandSender;
import de.rayzs.pat.utils.ExpireCache;
import de.rayzs.pat.utils.group.Group;
@@ -66,12 +67,14 @@ public class ServClearCommand extends ProCommand {
if (group == null) {
sender.sendMessage(
Storage.ConfigSections.Messages.GROUP.DOES_NOT_EXIST_SERVER
.replace("%group%", groupName)
.replace("%server%", serverName)
String message = Storage.ConfigSections.Messages.GROUP.DOES_NOT_EXIST_SERVER;
message = StringUtils.replace(message,
"%group%", groupName,
"%server%", serverName
);
sender.sendMessage(message);
return true;
}
@@ -95,12 +95,14 @@ public class ServRemoveCommand extends ProCommand {
if (group == null) {
sender.sendMessage(
Storage.ConfigSections.Messages.GROUP.DOES_NOT_EXIST_SERVER
.replace("%group%", groupName)
.replace("%server%", serverName)
String message = Storage.ConfigSections.Messages.GROUP.DOES_NOT_EXIST_SERVER;
message = StringUtils.replace(message,
"%group%", groupName,
"%server%", serverName
);
sender.sendMessage(message);
return true;
}
@@ -43,6 +43,7 @@ public class ServListCommand extends ProCommand {
);
String message = Storage.ConfigSections.Messages.BLACKLIST.LIST_SERVER_MESSAGE;
message = StringUtils.replace(message,
"%size%", String.valueOf(blacklist.getCommands().size()),
"%commands%", commandsListMessage,
@@ -57,7 +58,15 @@ public class ServListCommand extends ProCommand {
Group group = GroupManager.getGroupByName(groupName);
if (group == null) {
sender.sendMessage(Storage.ConfigSections.Messages.GROUP.DOES_NOT_EXIST_SERVER.replace("%group%", groupName));
String message = Storage.ConfigSections.Messages.GROUP.DOES_NOT_EXIST_SERVER;
message = StringUtils.replace(message,
"%group%", groupName,
"%server%", serverName
);
sender.sendMessage(message);
return true;
}
@@ -5,9 +5,18 @@ import java.util.*;
import de.rayzs.pat.api.event.PATEventHandler;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.permission.PermissionUtil;
public class CommandsCache {
/**
*
*
* RECODE PLANNED
*
*
*/
private List<String> filteredCommands = null, allCommands = null;
private boolean change = false;
@@ -15,7 +24,7 @@ public class CommandsCache {
if (change || !isOutdated(commands))
return;
filteredCommands = new LinkedList<>();
LinkedList<String> tmpFilteredCommands = new LinkedList<>();
allCommands = new ArrayList<>(commands);
for (String command : allCommands) {
@@ -36,65 +45,81 @@ public class CommandsCache {
}
filteredCommands = tmpFilteredCommands;
change = true;
}
public void handleCommands(List<String> commands, String server) {
if(!isOutdated(commands))
if (!isOutdated(commands))
return;
filteredCommands = new LinkedList<>();
allCommands = new ArrayList<>(commands);
LinkedList<String> tmpFilteredCommands = new LinkedList<>();
List<String> tmpAllCommands = new ArrayList<>(commands);
allCommands = tmpAllCommands;
for (String command : allCommands) {
command = StringUtils.getFirstArg(command);
final int length = allCommands.size();
for (int i = 0; i < length; i++) {
if (i >= tmpAllCommands.size())
break;
String command = StringUtils.getFirstArg(tmpAllCommands.get(i));
Storage.Blacklist.BlockType type = Storage.Blacklist.BlockTypeFetcher.getType(command);
if (type != Storage.Blacklist.BlockType.BOTH && type != Storage.Blacklist.BlockType.TAB)
continue;
if (isFilterListAvailable(server)) {
if (filteredCommands.contains(command))
if (isFilterListAvailable()) {
if (filteredCommands.contains(command))
continue;
if (!Storage.Blacklist.isBlockedTab(command, server))
filteredCommands.add(command);
tmpFilteredCommands.add(command);
}
}
filteredCommands = tmpFilteredCommands;
}
public List<String> getPlayerCommands(Collection<String> unfilteredCommands, Object targetObj, UUID uuid) {
return getPlayerCommands(unfilteredCommands, targetObj, uuid, null);
public List<String> getPlayerCommands(Collection<String> unfilteredCommands, Object targetObj) {
return getPlayerCommands(unfilteredCommands, targetObj, null);
}
public List<String> getPlayerCommands(Collection<String> unfilteredCommands, Object targetObj, UUID uuid, String serverName) {
public List<String> getPlayerCommands(Collection<String> unfilteredCommands, Object targetObj, String serverName) {
List<String> playerCommands = new LinkedList<>(unfilteredCommands);
List<String> localFilteredCommands = filteredCommands == null ? null : new LinkedList<>(filteredCommands);
List<String> localFilteredCommands = filteredCommands == null ? null : new LinkedList<>();
if (localFilteredCommands == null)
return playerCommands;
boolean hasNamespaceBypass = Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesBypass(targetObj);
playerCommands.removeIf(command -> {
if (!hasNamespaceBypass && Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.isCommand(command)) {
return true;
final int max = filteredCommands.size();
for (int i = 0; i < max; i++) {
try {
String command = filteredCommands.get(i);
localFilteredCommands.add(command);
} catch (IndexOutOfBoundsException indexOutOfBoundsException) {
Logger.warning("Array is out of bounds " + i + "/" + max + "! " + indexOutOfBoundsException.getMessage());
break;
}
}
if (localFilteredCommands.contains(command)) {
return false;
}
return !Storage.Blacklist.canPlayerAccessTab(targetObj, command, serverName);
});
if (!PermissionUtil.hasBypassPermission(targetObj)) {
boolean hasNamespaceBypass = Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.doesBypass(targetObj);
String uuidSubstring = uuid.toString().substring(uuid.toString().length() - 5);
if(playerCommands.isEmpty())
Logger.debug("Commands list for player with uuid " + uuidSubstring + " is empty! (" + (filteredCommands != null ? filteredCommands.size() : "null") + " | " + (unfilteredCommands != null ? unfilteredCommands.size() : "null") + ")");
else
Logger.debug("Created list of commands for player with uuid " + uuidSubstring + " with a total of " + playerCommands.size() + " commands!");
playerCommands.removeIf(command -> {
if (!hasNamespaceBypass && Storage.ConfigSections.Settings.BLOCK_NAMESPACE_COMMANDS.isCommand(command)) {
return true;
}
if (localFilteredCommands.contains(command)) {
return false;
}
return !Storage.Blacklist.canPlayerAccessTab(targetObj, command, serverName);
});
}
PATEventHandler.callUpdatePlayerCommandsEvents(targetObj, playerCommands, serverName != null);
@@ -111,15 +136,7 @@ public class CommandsCache {
}
public boolean isFilterListAvailable() {
return isFilterListAvailable(null);
}
public boolean isFilterListAvailable(String server) {
boolean available = this.filteredCommands != null;
if(!available)
Logger.debug("FilterList didn't exist during built!" + (server != null ? "(server: " + server + ")" : ""));
return available;
return this.filteredCommands != null;
}
public void updateChangeState() {
@@ -58,6 +58,33 @@ public class CommunicationPackets {
}
}
public static class UpdateCommandsPacket implements CommunicationPacket, Serializable {
private final String proxyToken;
private final UUID targetUUID;
public UpdateCommandsPacket(String proxyToken) {
this.proxyToken = proxyToken;
this.targetUUID = null;
}
public UpdateCommandsPacket(String proxyToken, UUID targetUUID) {
this.proxyToken = proxyToken;
this.targetUUID = targetUUID;
}
public boolean hasTargetUUID() {
return targetUUID != null;
}
public UUID getTargetUUID() {
return targetUUID;
}
public boolean isToken(String token) {
return proxyToken.equals(token);
}
}
public static class FeedbackPacket implements CommunicationPacket, Serializable {
private final String proxyToken, serverId;
@@ -37,16 +37,21 @@ public class ConnectionBuilder {
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
connection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
if(parameters != null && parameters.length > 0) {
Object firstParam = null, secondParam = null;
for (Object parameter : parameters) {
if(firstParam == null) firstParam = parameter;
else if(secondParam == null) secondParam = parameter;
else {
connection.setRequestProperty((String) firstParam, (String) secondParam);
firstParam = null;
secondParam = null;
if (firstParam == null) {
firstParam = parameter;
continue;
}
secondParam = parameter;
connection.setRequestProperty((String) firstParam, (String) secondParam);
firstParam = null;
}
}
@@ -16,13 +16,19 @@ public class ExpireCache<T, K> {
}
public boolean put(T t, K k) {
if(contains(t)) return false;
if (contains(t)) {
return false;
}
cache.put(t, k);
return true;
}
public boolean remove(T t) {
if(!contains(t)) return false;
if (!contains(t)) {
return false;
}
cache.invalidate(t);
return true;
}
@@ -0,0 +1,43 @@
package de.rayzs.pat.utils;
import java.util.ArrayDeque;
import java.util.function.Consumer;
public class LimitedList<T> {
private ArrayDeque<T> list = new ArrayDeque<>();
private final int maxCapacity;
public LimitedList(int maxCapacity) {
this.maxCapacity = maxCapacity;
}
public LimitedList(LimitedList<T> list) {
this.maxCapacity = list.maxCapacity;
this.list = new ArrayDeque<>(list.getList());
}
public void add(T element) {
if (list.size() == maxCapacity) {
list.removeFirst();
}
list.add(element);
}
public void iterate(Consumer<T> action) {
list.forEach(action);
}
public int getSize() {
return list.size();
}
public int getMaxCapacity() {
return maxCapacity;
}
private ArrayDeque<T> getList() {
return list;
}
}
@@ -2,6 +2,8 @@ package de.rayzs.pat.utils;
public class NumberUtils {
private static final char[] EXCEPTIONS = {'.', ',', 'k', 'm', 'b'};
public static boolean isBetween(int n, int l, int r) {
int min = Math.min(l, r);
int max = Math.max(l, r);
@@ -16,10 +18,9 @@ public class NumberUtils {
int length = str.length();
for (int i = 0; i < length; i++) {
char c = str.charAt(i);
if (c == '.' || c == ',')
if (isExceptionalDigit(c))
continue;
if (!Character.isDigit(c))
@@ -28,4 +29,17 @@ public class NumberUtils {
return true;
}
private static boolean isExceptionalDigit(char c) {
for (char q : EXCEPTIONS) {
if (c == q) {
return true;
}
if (Character.isAlphabetic(c) && c == Character.toUpperCase(q)) {
return true;
}
}
return false;
}
}
@@ -25,10 +25,10 @@ public class Reflection {
proxy = false;
} catch (Throwable ignored) { proxy = true; }
if(!proxy) {
if (!proxy) {
try {
Class.forName("com.destroystokyo.paper.proxy.VelocityProxy");
folia = versionName.toLowerCase().contains("folia");
Class.forName("io.papermc.paper.threadedregions.RegionizedServer");
folia = true;
} catch (Throwable throwable) {
folia = false;
}
@@ -46,7 +46,7 @@ public class Reflection {
}
}
if(proxy) {
if (proxy) {
try {
Class.forName("com.velocitypowered.api.proxy.ProxyServer");
velocity = true;
@@ -58,6 +58,10 @@ public class Reflection {
oldChannelMethod = folia || paper && Reflection.isWeird();
}
public static void toggleInjectionMethod() {
oldChannelMethod = !oldChannelMethod;
}
public static String getVersionPackageName() {return versionPackageName;}
public static int[] getAges() { return new int[]{major, minor, release}; }
@@ -1,121 +1,179 @@
package de.rayzs.pat.utils;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.logger.Logger;
import java.util.Arrays;
import java.util.List;
public class VersionComparer {
private static Version CURRENT_VERSION, NEWEST_VERSION;
public enum VersionState { NEWER, UPDATED, OUTDATED }
public static void setCurrentVersion(String versionName) {
if(CURRENT_VERSION != null && CURRENT_VERSION.getVersionName().equals(versionName)) return;
CURRENT_VERSION = new Version(versionName);
private static final VersionComparer instance = new VersionComparer();
public static VersionComparer get() {
return instance;
}
public static void setNewestVersion(String versionName) {
if(NEWEST_VERSION != null && NEWEST_VERSION.getVersionName().equals(versionName))
private VersionComparer() {}
private final List<String> ignoreVersions = Arrays.asList("1.9.1", "1.9.2");
private final String versionUrl = "https://www.rayzs.de/proantitab/api/version.php";
private final int versionLength = 3;
private Version currentVersion, newestVersion;
private VersionState versionState = VersionState.UPDATED;
private boolean shouldAnnounce = true;
public boolean computeComparison() {
String result = new ConnectionBuilder().setUrl(versionUrl)
.setProperties("ProAntiTab", "4454")
.connect()
.getResponse();
if (result == null)
result = "/";
if (result.equals("/")) {
Logger.warning("Failed to connect to plugin page! Version comparison cannot be made. (No internet?)");
return false;
}
Storage.NEWER_VERSION = result;
VersionComparer.get().setNewestVersion(Storage.NEWER_VERSION);
if (VersionComparer.get().isNewer()) {
if (shouldAnnounce) {
shouldAnnounce = false;
Logger.info("§8[§fPAT | Bukkit§8] §7Please be aware that you are currently using a §bdeveloper §7version of ProAntiTab. Bugs, errors and a lot of debug messages might be included.");
}
return true;
}
if (VersionComparer.get().isUpdated()) {
if (shouldAnnounce) {
shouldAnnounce = false;
Storage.ConfigSections.Settings.UPDATE.UPDATED.getLines().forEach(Logger::warning);
}
return false;
}
if (VersionComparer.get().isOutdated()) {
if (shouldAnnounce) {
shouldAnnounce = false;
Storage.OUTDATED = true;
Storage.ConfigSections.Settings.UPDATE.OUTDATED.getLines().forEach(Logger::warning);
}
return true;
}
return false;
}
public void setCurrentVersion(String version) {
if (version == null)
return;
NEWEST_VERSION = new Version(versionName);
currentVersion = new Version(version);
}
public static Version getCurrentVersion() {
return CURRENT_VERSION;
public void setNewestVersion(String version) {
if (version == null)
return;
if (ignoreVersions.contains(version))
return;
newestVersion = new Version(version);
compute();
}
public static Version getNewestVersion() {
return NEWEST_VERSION;
public VersionState getVersionState() {
return versionState;
}
public static boolean isNewest() {
if(CURRENT_VERSION == null || NEWEST_VERSION == null) return true;
return CURRENT_VERSION.isSame(NEWEST_VERSION);
public boolean isUpdated() {
return versionState == VersionState.UPDATED;
}
public static boolean isUnreleased() {
if(CURRENT_VERSION == null || NEWEST_VERSION == null) return true;
return CURRENT_VERSION.isNewer(NEWEST_VERSION);
public boolean isOutdated() {
return versionState == VersionState.OUTDATED;
}
public static boolean isOutdated() {
if(CURRENT_VERSION == null || NEWEST_VERSION == null) return false;
return CURRENT_VERSION.isOlder(NEWEST_VERSION);
public boolean isNewer() {
return versionState == VersionState.NEWER;
}
public static boolean isDeveloperVersion() {
return CURRENT_VERSION.getState() == State.DEV;
}
private void compute() {
if (currentVersion == null || newestVersion == null)
return;
public static class Version {
private final String versionName;
private int release = -1, major = -1, patch = -1;
private State state = State.RELEASE;
int[] crntNum = currentVersion.getVersionNums();
int[] newNum = newestVersion.getVersionNums();
public Version(String version) {
this.versionName = version;
for (int i = 0; i < versionLength; i++) {
try {
String[] versionSplit = version.split("\\.");
release = Integer.parseInt(versionSplit[0]);
major = Integer.parseInt(versionSplit[1]);
String patchAsString = versionSplit[2];
patchAsString = patchAsString.contains("-") ? patchAsString.split("-")[0] : patchAsString;
patch = Integer.parseInt(patchAsString);
if(!version.contains("-")) return;
String stateName = version.split("-")[1].toUpperCase();
state = State.valueOf(stateName);
} catch (Throwable throwable) {
Logger.warning("Failed to read version name! [" + version + "]");
throwable.printStackTrace();
if (crntNum[i] > newNum[i]) {
versionState = VersionState.NEWER;
return;
}
if (crntNum[i] < newNum[i]) {
versionState = VersionState.OUTDATED;
return;
}
}
}
private class Version {
private final int[] versionNums = new int[versionLength];
private final String versionString;
public Version(String versionString) {
this.versionString = versionString;
setVersionNums();
}
public String getVersionName() {
return versionName;
return versionString;
}
public boolean isSame(Version version) {
return version.getVersionName().equals(versionName);
public int[] getVersionNums() {
return versionNums;
}
public boolean isNewer(Version comparedVersion) {
return !isSame(comparedVersion) && !isOlder(comparedVersion);
private void setVersionNums() {
if (!versionString.contains("."))
return;
String[] details = versionString.split("\\.");
for (int i = 0; i < details.length; i++) {
if (i >= versionLength)
break;
String detailString = details[i];
if (!NumberUtils.isDigit(detailString))
continue;
int detail = Integer.parseInt(detailString);
versionNums[i] = detail;
}
}
public boolean isOlder(Version comparedVersion) {
if(release > comparedVersion.getRelease()) return false;
if(major > comparedVersion.getMajor()) return false;
return patch < comparedVersion.getPatch();
}
public int getRelease() {
return release;
}
public int getMajor() {
return major;
}
public int getPatch() {
return patch;
}
public State getState() {
return state;
}
public boolean isInvalid() {
return release == -1 || major == -1 || patch == -1;
}
}
public enum State {
RELEASE, DEV, ALPHA, BETA
}
}
@@ -0,0 +1,73 @@
package de.rayzs.pat.utils.adapter;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.BukkitLoader;
import de.rayzs.pat.plugin.listeners.bukkit.BukkitAntiTabListener;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.permission.PermissionPlugin;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.utils.scheduler.PATScheduler;
import org.anjocaido.groupmanager.GroupManager;
import org.anjocaido.groupmanager.events.GMGroupEvent;
import org.anjocaido.groupmanager.events.GMSystemEvent;
import org.anjocaido.groupmanager.events.GMUserEvent;
import org.anjocaido.groupmanager.permissions.AnjoPermissionsHandler;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import java.util.UUID;
public class GroupManagerAdapter implements Listener {
private static GroupManager manager;
public static void initialize(Plugin plugin) {
Logger.info("Successfully hooked into GroupManager for easier usage.");
Storage.setPermissionPlugin(PermissionPlugin.GROUPMANAGER);
manager = (GroupManager) plugin;
Bukkit.getServer().getPluginManager().registerEvents(new GroupManagerListener(), BukkitLoader.getPlugin());
}
public static void setPermissions(UUID uuid) {
final Player player = Bukkit.getPlayer(uuid);
if (player == null) {
return;
}
final AnjoPermissionsHandler handler = manager.getWorldsHolder().getWorldPermissions(player);
handler.getAllPlayersPermissions(player.getName()).stream()
.filter(permission -> permission.startsWith("proantitab."))
.forEach(permission -> PermissionUtil.setPermission(uuid, permission, true));
if (Reflection.getMinor() >= 13) {
BukkitAntiTabListener.handleTabCompletion(uuid);
}
}
private static class GroupManagerListener implements Listener {
@EventHandler
public void onGMUser(GMUserEvent event) {
PATScheduler.createScheduler(() -> {
PermissionUtil.reloadPermissions(event.getUser().getBukkitPlayer().getUniqueId());
}, 10);
}
@EventHandler
public void onGMGroup(GMGroupEvent event) {
PATScheduler.createScheduler(PermissionUtil::reloadPermissions, 10);
}
@EventHandler
public void onGMSystem(GMSystemEvent event) {
PATScheduler.createScheduler(PermissionUtil::reloadPermissions, 10);
}
}
}
@@ -1,13 +1,15 @@
package de.rayzs.pat.utils.adapter;
import de.rayzs.pat.api.communication.Communicator;
import de.rayzs.pat.plugin.listeners.bukkit.BukkitAntiTabListener;
import de.rayzs.pat.utils.permission.PermissionPlugin;
import de.rayzs.pat.utils.scheduler.PATScheduler;
import net.luckperms.api.event.sync.PreNetworkSyncEvent;
import de.rayzs.pat.utils.permission.PermissionUtil;
import de.rayzs.pat.plugin.VelocityLoader;
import net.luckperms.api.model.user.User;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.BukkitLoader;
import net.luckperms.api.event.EventBus;
import net.luckperms.api.event.node.*;
import de.rayzs.pat.utils.Reflection;
@@ -22,30 +24,22 @@ public class LuckPermsAdapter {
public static void initialize() {
Logger.info("Successfully hooked into LuckPerms for easier usage.");
Storage.USE_LUCKPERMS = true;
Storage.setPermissionPlugin(PermissionPlugin.LUCKPERMS);
PROVIDER = LuckPermsProvider.get();
EventBus eventBus = PROVIDER.getEventBus();
eventBus.subscribe(Storage.PLUGIN_OBJECT, NodeMutateEvent.class, LuckPermsAdapter::onNoteMutate);
if (!Reflection.isProxyServer()) {
if (BukkitLoader.useSuggestions())
eventBus.subscribe(Storage.PLUGIN_OBJECT, PreNetworkSyncEvent.class, event -> BukkitAntiTabListener.luckpermsNetworkSync());
} else {
if (Reflection.isVelocityServer()) {
eventBus.subscribe(Storage.PLUGIN_OBJECT, PreNetworkSyncEvent.class, event -> VelocityLoader.delayedPermissionsReload());
}
Storage.getLoader().updateCommandCache();
}
eventBus.subscribe(Storage.PLUGIN_OBJECT, PreNetworkSyncEvent.class, event -> Storage.getLoader().delayedPermissionsReload());
}
public static User getUser(UUID uuid) {
if (uuid == null) {
Logger.warning("Attempted to get LuckPerms user with null UUID!");
return null;
}
return PROVIDER.getUserManager().getUser(uuid);
}
@@ -56,13 +50,6 @@ public class LuckPermsAdapter {
return user.getCachedData().getPermissionData().getPermissionMap();
}
public static boolean hasAnyPermissions(UUID uuid) {
Map<String, Boolean> permissions = getPermissions(uuid);
if (permissions == null) return false;
return !permissions.isEmpty();
}
public static void setPermissions(UUID uuid) {
Map<String, Boolean> permissions = getPermissions(uuid);
if (permissions == null) return;
@@ -106,18 +93,20 @@ public class LuckPermsAdapter {
User user = (User) event.getTarget();
UUID uuid = user.getUniqueId();
if (!Reflection.isProxyServer()) {
if (Reflection.getMinor() >= 13)
BukkitAntiTabListener.luckpermsNetworkUserSync(user.getUniqueId());
return;
}
if (Reflection.isVelocityServer()) {
if (Reflection.isProxyServer()) {
PermissionUtil.reloadPermissions(user.getUniqueId());
VelocityLoader.delayedPlayerReload(uuid);
Communicator.sendUpdateCommand(uuid);
if (Reflection.isVelocityServer()) {
VelocityLoader.delayedPlayerReload(uuid);
}
} else {
PATScheduler.createScheduler(() -> {
PermissionUtil.reloadPermissions(user.getUniqueId());
});
}
}
}
}
@@ -1,6 +1,6 @@
package de.rayzs.pat.utils.adapter;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.api.storage.Storage;
import com.viaversion.viaversion.api.*;
import java.util.UUID;
@@ -9,8 +9,7 @@ public class ViaVersionAdapter {
private static ViaAPI API;
public static void initialize() {
Logger.info("Successfully hooked into ViaVersion for easier usage.");
Storage.USE_VIAVERSION = true;
API = Via.getAPI();
}
@@ -81,14 +81,9 @@ public class BukkitConfigurationBuilder implements ConfigurationBuilder {
if (result != null)
return result;
if (fileName.equals("config")) {
if (!ConfigUpdater.shouldAutoUpdate()) {
ConfigUpdater.addMissingPart(path + "." + target);
return object;
}
set(path, target, object);
return get(path, target);
if (fileName.equals("config") && !ConfigUpdater.shouldAutoUpdate()) {
ConfigUpdater.addMissingPart((!path.isBlank() ? path + "." : "") + target);
return object;
}
set(path, target, object);
@@ -103,14 +98,9 @@ public class BukkitConfigurationBuilder implements ConfigurationBuilder {
if (result != null)
return result;
if (fileName.equals("config")) {
if (!ConfigUpdater.shouldAutoUpdate()) {
ConfigUpdater.addMissingPart(target);
return object;
}
set(target, object);
return get(target);
if (fileName.equals("config") && !ConfigUpdater.shouldAutoUpdate()) {
ConfigUpdater.addMissingPart(target);
return object;
}
set(target, object);
@@ -88,14 +88,9 @@ public class ProxyConfigurationBuilder implements ConfigurationBuilder {
if (result != null)
return result;
if (fileName.equals("config")) {
if (!ConfigUpdater.shouldAutoUpdate()) {
ConfigUpdater.addMissingPart(path + "." + target);
return object;
}
set(path, target, object);
return get(path, target);
if (fileName.equals("config") && !ConfigUpdater.shouldAutoUpdate()) {
ConfigUpdater.addMissingPart((!path.isBlank() ? path + "." : "") + target);
return object;
}
set(path, target, object);
@@ -110,14 +105,9 @@ public class ProxyConfigurationBuilder implements ConfigurationBuilder {
if (result != null)
return result;
if (fileName.equals("config")) {
if (!ConfigUpdater.shouldAutoUpdate()) {
ConfigUpdater.addMissingPart(target);
return object;
}
set(target, object);
return get(target);
if (fileName.equals("config") && !ConfigUpdater.shouldAutoUpdate()) {
ConfigUpdater.addMissingPart(target);
return object;
}
set(target, object);
@@ -13,8 +13,7 @@ import java.util.*;
public class ConfigUpdater {
private static List<String> NEWEST_CONFIG_INPUT = new ArrayList<>(),
MISSING_PARTS = new ArrayList<>();
private static final List<String> MISSING_PARTS = new ArrayList<>();
private static boolean LOADED = false, AUTO_UPDATE = false, ANNOUNCE = false;
@@ -22,19 +21,19 @@ public class ConfigUpdater {
HOW_TO_READ_FILE_NAME = "How-To-Read.txt";
public static void initialize() {
try {
MISSING_PARTS.clear();
LOADED = false;
MISSING_PARTS.clear();
try {
ConfigurationBuilder config = Configurator.get("config");
ANNOUNCE = (boolean) config.getOrSet("updater.announce-missing-parts", true);
AUTO_UPDATE = (boolean) config.getOrSet("updater.auto-update-config", false);
LOADED = true;
} catch (Exception exception) {
Logger.warning("Failed to find section 'updater.auto-config-updater' in config.yml!");
}
LOADED = true;
}
public static boolean shouldAutoUpdate() {
@@ -69,9 +68,6 @@ public class ConfigUpdater {
if (!ANNOUNCE)
return;
List<String> configInput = new LinkedList<>(Arrays.asList("# WARNING: This file is auto generated and its sole purpose is to be used as comparison!\n# WARNING: It will be deleted once this file is no longer needed.", " ", " "));
configInput.addAll(NEWEST_CONFIG_INPUT);
Configurator.createResourcedFile(
"files\\" + (Reflection.isProxyServer() ? "proxy" : "bukkit") + "-config.yml",
COMPARABLE_FILE_NAME,
@@ -105,13 +101,20 @@ public class ConfigUpdater {
}
Logger.warning(" ");
Logger.warning("The config.yml is missing a few parts.");
Logger.warning("What can be done to solve this issue? There are two options:");
Logger.warning("Hey, the config.yml is missing a few parts.");
Logger.warning("This most likely happened because PAT added a new feature or message.");
Logger.warning(" ");
Logger.warning("No worries though! This isn't a bad or dangerous thing.");
Logger.warning("You can even ignore or disable this warning entirely by disabling 'announce-missing-parts'.");
Logger.warning(" ");
Logger.warning("But more importantly. If you want to fill the missing parts,");
Logger.warning("then you would have three options on how to do so:");
Logger.warning(" ");
Logger.warning("Option 1: Delete your current config.yml and restart the server.");
Logger.warning("Option 2: Set the missing parts/sections yourself in the config.yml.");
Logger.warning("Option 3: Enable 'auto-update-config'. But *please* read the warning message above that option.");
Logger.warning(" ");
Logger.warning("To simplify that process, a new file with the newest config.yml content has been created as comparison. (plugins/ProAntiTab/comparable-config.yml)");
Logger.warning("To simplify this process, a new file with the newest config.yml content has been created as comparison. (plugins/ProAntiTab/comparable-config.yml)");
Logger.warning(" ");
Logger.warning("Following parts are missing:");
@@ -120,7 +123,9 @@ public class ConfigUpdater {
});
Logger.warning(" ");
Logger.warning("How to read? Check out the newly generated " + HOW_TO_READ_FILE_NAME + " file. ^^");
Logger.warning("You don't know how to interpret the missing parts? No worries.");
Logger.warning("A new file has been created which explains with examples on how to read and apply the missing parts.");
Logger.warning("-> ./plugins/ProAntiTab/" + HOW_TO_READ_FILE_NAME);
Logger.warning(" ");
}
}
@@ -1,16 +1,14 @@
package de.rayzs.pat.utils.group;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.api.storage.blacklist.BlacklistCreator;
import de.rayzs.pat.api.storage.blacklist.impl.GroupBlacklist;
import de.rayzs.pat.utils.ExpireCache;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.configuration.ConfigurationBuilder;
import de.rayzs.pat.utils.permission.PermissionUtil;
@@ -58,6 +56,37 @@ public class Group implements Serializable {
loadServerBlacklist();
}
public String getGroupInfo() {
StringBuilder builder = new StringBuilder();
builder.append(" groupName: ")
.append(groupName).append("\n")
.append(" priority: ")
.append(priority).append("\n");
builder.append(" commands: ")
.append(String.join(", ", getCommands()))
.append("\n");
if (Reflection.isProxyServer()) {
builder.append(" servers:\n");
for (Map.Entry<String, GroupBlacklist> entry : groupServerBlacklist.entrySet()) {
builder.append(" ")
.append(entry.getKey())
.append(": ");
for (GroupBlacklist blacklist : getAllServerGroupBlacklist(entry.getKey())) {
builder.append(String.join(", ", blacklist.getCommands()));
builder.append(", ");
}
builder.append("\n");
}
}
return builder.toString();
}
private void loadServerBlacklist() {
String path = "groups." + groupName + ".servers";
@@ -79,6 +108,10 @@ public class Group implements Serializable {
public void add(String command) {
this.generalGroupBlacklist.add(command).save();
if (command.startsWith("plugin=") || command.startsWith("!")) {
this.generalGroupBlacklist.load();
}
}
public void add(String command, String server) {
@@ -89,6 +122,10 @@ public class Group implements Serializable {
public void remove(String command) {
this.generalGroupBlacklist.remove(command).save();
if (command.startsWith("plugin=") || command.startsWith("!")) {
this.generalGroupBlacklist.load();
}
}
public void remove(String command, String server) {
@@ -99,6 +136,7 @@ public class Group implements Serializable {
public void clear() {
this.generalGroupBlacklist.clear().save();
this.generalGroupBlacklist.load();
}
public void clear(String server) {
@@ -152,15 +190,16 @@ public class Group implements Serializable {
GroupBlacklist groupBlacklist;
if (this.groupServerBlacklist.containsKey(server) && this.groupServerBlacklist.get(server) != null)
if (this.groupServerBlacklist.get(server) != null)
groupBlacklist = this.groupServerBlacklist.get(server);
else {
groupBlacklist = BlacklistCreator.createGroupBlacklist(this.groupName, server, ignoreExist);
this.groupServerBlacklist.put(server, groupBlacklist);
}
if (groupBlacklist != null)
groupBlacklist.load();
if (groupBlacklist != null) {
groupBlacklist.load();
this.groupServerBlacklist.put(server, groupBlacklist);
}
}
return groupBlacklist;
}
@@ -6,7 +6,10 @@ import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.api.storage.Storage.Blacklist.BlockType;
import de.rayzs.pat.api.storage.blacklist.BlacklistCreator;
import de.rayzs.pat.api.storage.blacklist.impl.GroupBlacklist;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.sender.CommandSender;
import de.rayzs.pat.utils.sender.CommandSenderHandler;
public class GroupManager {
@@ -52,39 +55,78 @@ public class GroupManager {
return playerGroups;
}
public static boolean canAccessCommand(Object targetObj, String unmodifiedCommand, Storage.Blacklist.BlockType type) {
public static AccessResult canAccessCommand(Object targetObj, String unmodifiedCommand, Storage.Blacklist.BlockType type) {
return canAccessCommand(targetObj, unmodifiedCommand, type, null);
}
public static boolean canAccessCommand(Object targetObj, String unmodifiedCommand, Storage.Blacklist.BlockType type, String server) {
final List<Group> playerGroups = getPlayerGroups(targetObj);
public static AccessResult
canAccessCommand(Object targetObj, String unmodifiedCommand, Storage.Blacklist.BlockType type, String server) {
final CommandSender sender = CommandSenderHandler.from(targetObj);
if(playerGroups.isEmpty()) {
return false;
if (sender == null) {
Logger.warning("Failed to load player! (GroupManager#66)");
return AccessResult.UNKNOWN;
}
String command = type.toString() + unmodifiedCommand;
boolean permitted = playerGroups.stream().anyMatch(group -> {
if (group == null)
return false;
final List<Group> playerGroups = sender.getGroups();
if (playerGroups == null || playerGroups.isEmpty()) {
return AccessResult.NO_GROUPS;
}
String command = type.toString() + unmodifiedCommand;
String allCommand = type + "*";
String negatedCommand = type.toString() + BlockType.NEGATE + unmodifiedCommand;
boolean all = false,
permitted = false,
negated = false;
for (Group group : playerGroups) {
all = group.contains(allCommand);
permitted = group.contains(command);
negated = group.contains(negatedCommand);
if (permitted) {
break;
}
if (server != null) {
List<String> servers = group.getBlacklistServerNames(server);
for (String s : servers) {
if (group.contains(command, s))
return true;
if (!all) {
all = group.contains(allCommand, s);
}
if (!permitted) {
permitted = group.contains(command, s);
}
if (!negated) {
negated = group.contains(negatedCommand, s);
}
}
}
return group.contains(command);
});
}
if (negated) {
return AccessResult.NEGATED;
}
if (all) {
return AccessResult.ALLOWED;
}
if (!permitted && type != BlockType.BOTH)
return canAccessCommand(targetObj, unmodifiedCommand, Storage.Blacklist.BlockType.BOTH, server);
return permitted;
return permitted ? AccessResult.ALLOWED : AccessResult.NOT_LISTED;
}
public static void setGroup(String groupName, List<String> commands) {
@@ -231,4 +273,19 @@ public class GroupManager {
public static boolean isGroupRegistered(String groupName) {
return getGroupByName(groupName) != null;
}
public enum AccessResult {
ALLOWED(true), NEGATED(false),
NO_GROUPS(false), NOT_LISTED(false),
UNKNOWN(false);
private final boolean bool;
AccessResult(boolean bool) {
this.bool = bool;
}
public boolean asBoolean() {
return this.bool;
}
}
}
@@ -1,13 +1,48 @@
package de.rayzs.pat.utils.node;
import com.mojang.brigadier.Command;
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.suggestion.SuggestionProvider;
import com.mojang.brigadier.tree.*;
import net.md_5.bungee.protocol.packet.Commands;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class CommandNodeHelper<T> {
private static final Command DUMMY_COMMAND = (context) -> 0;
private static SuggestionProvider DEFAULT_SUGGESTION_PROVIDER;
public static void setDefaultSuggestionProvider(SuggestionProvider<?> suggestionProvider) {
DEFAULT_SUGGESTION_PROVIDER = suggestionProvider;
}
public static CommandNode createDummyCommandNode(String command) {
return LiteralArgumentBuilder
.literal(command)
.executes(DUMMY_COMMAND)
.then(RequiredArgumentBuilder
.argument("args", (ArgumentType) StringArgumentType.greedyString())
.suggests(DEFAULT_SUGGESTION_PROVIDER)
.executes(DUMMY_COMMAND))
.build();
}
public static CommandNode createEmptyDummyCommandNode(String command) {
return LiteralArgumentBuilder
.literal(command)
.executes(DUMMY_COMMAND)
.then(RequiredArgumentBuilder
.argument("args", (ArgumentType) StringArgumentType.greedyString())
.executes(DUMMY_COMMAND))
.build();
}
private final RootCommandNode<T> rootNode;
public CommandNodeHelper(RootCommandNode<T> rootNode) {
@@ -76,27 +111,56 @@ public class CommandNodeHelper<T> {
return this;
}
public CommandNodeHelper<T> add(String commandPath) {
if (commandPath.endsWith("_-"))
commandPath = commandPath.substring(0, commandPath.length() - 3);
public CommandNodeHelper<T> add(String commandPath, boolean autoSuggestions) {
String[] args = commandPath.split(" ");
add(rootNode, args, 0);
add(rootNode, args, 0, autoSuggestions);
return this;
}
private void add(CommandNode<T> parent, String[] args, int index) {
private void add(CommandNode<T> parent, String[] args, int index, boolean autoSuggestions) {
if (index >= args.length) return;
String part = args[index];
String next = index + 1 >= args.length ? null : args[index + 1];
CommandNode<T> childNode = parent.getChild(part);
if (childNode == null) {
LiteralCommandNode<T> newNode = LiteralArgumentBuilder.<T>literal(part).build();
LiteralCommandNode newNode;
boolean cancel = next != null && (next.equals("_-"));
boolean stop = next != null && next.startsWith("%") && next.endsWith("%");
boolean skip = part.equals("-_");
if (index == 0 && part.charAt(0) == '!' && part.length() > 1) {
return;
}
if (skip) {
return;
}
if (!autoSuggestions || cancel || !stop && index != args.length - 1) {
newNode = LiteralArgumentBuilder.literal(part)
.then(RequiredArgumentBuilder
.argument("args", StringArgumentType.string()))
.build();
} else {
newNode = LiteralArgumentBuilder.literal(part)
.then(RequiredArgumentBuilder
.argument("args", (ArgumentType) StringArgumentType.greedyString())
.suggests(Commands.SuggestionRegistry.ASK_SERVER))
.build();
}
parent.addChild(newNode);
if (stop || cancel) {
return;
}
childNode = newNode;
}
add(childNode, args, index + 1);
add(childNode, args, index + 1, autoSuggestions);
}
}
@@ -41,8 +41,13 @@ public class PermissionMap {
}
public PermissionState getPermissionState(String permission) {
if(!hasPermissionState(permission)) return PermissionState.EMPTY;
return permissionMap.get(permission) ? PermissionState.PERMITTED : PermissionState.DENIED;
if (!hasPermissionState(permission)) {
return PermissionState.EMPTY;
}
return permissionMap.get(permission)
? PermissionState.PERMITTED
: PermissionState.DENIED;
}
public boolean hasPermissionState(String permission) {
@@ -0,0 +1,5 @@
package de.rayzs.pat.utils.permission;
public enum PermissionPlugin {
LUCKPERMS, GROUPMANAGER, NONE
}
@@ -1,11 +1,12 @@
package de.rayzs.pat.utils.permission;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Set;
import java.util.UUID;
import java.util.*;
import de.rayzs.pat.api.storage.Storage;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.adapter.GroupManagerAdapter;
import de.rayzs.pat.utils.group.GroupManager;
import de.rayzs.pat.utils.sender.CommandSender;
import de.rayzs.pat.utils.sender.CommandSenderHandler;
import de.rayzs.pat.utils.adapter.LuckPermsAdapter;
@@ -19,39 +20,77 @@ public class PermissionUtil {
}
public static void reloadPermissions() {
MAP.keySet().forEach(PermissionUtil::reloadPermissions);
List<UUID> uuids = new ArrayList<>(MAP.keySet());
uuids.forEach(PermissionUtil::reloadPermissions);
}
public static void reloadPermissions(UUID uuid) {
if (!MAP.containsKey(uuid))
if (uuid == null) {
return;
}
MAP.get(uuid).clear();
resetPermissions(uuid);
setPlayerPermissions(uuid);
CommandSender sender = CommandSenderHandler.getSenderFromUUID(uuid);
if (sender != null) {
sender.updateGroups();
}
}
public static void reloadPermissions(CommandSender sender) {
resetPermissions(sender.getUniqueId());
setPlayerPermissions(sender);
sender.updateGroups();
}
public static String getPermissionsAsString(UUID uuid) {
if (Storage.getPermissionPlugin() == PermissionPlugin.NONE) {
return "No permission plugin detected. Therefore, no permissions have been cached.";
}
PermissionMap permissionMap = MAP.get(uuid);
if (permissionMap == null)
if (permissionMap == null) {
return "";
}
return Arrays.toString(permissionMap.getHashedPermissions().toArray()).replace("[", "").replace("]", "");
}
public static Set<String> getPermissions(UUID uuid) {
PermissionMap permissionMap = MAP.get(uuid);
if(permissionMap == null) return null;
if(permissionMap == null)
return null;
return permissionMap.getHashedPermissions();
}
public static void setPlayerPermissions(CommandSender sender) {
if (Storage.getPermissionPlugin() == PermissionPlugin.LUCKPERMS) {
LuckPermsAdapter.setPermissions(sender.getUniqueId());
} else if (Storage.getPermissionPlugin() == PermissionPlugin.GROUPMANAGER) {
GroupManagerAdapter.setPermissions(sender.getUniqueId());
} else {
GroupManager.getGroups().forEach(group -> group.hasPermission(sender));
}
}
public static void setPlayerPermissions(UUID uuid) {
if (Storage.USE_LUCKPERMS)
if (Storage.getPermissionPlugin() == PermissionPlugin.LUCKPERMS) {
LuckPermsAdapter.setPermissions(uuid);
} else if (Storage.getPermissionPlugin() == PermissionPlugin.GROUPMANAGER) {
GroupManagerAdapter.setPermissions(uuid);
} else {
GroupManager.getGroups().forEach(group -> group.hasPermission(uuid));
}
}
public static void resetPermissions(UUID uuid) {
if(!MAP.containsKey(uuid)) return;
if (!MAP.containsKey(uuid))
return;
MAP.get(uuid).clear();
}
@@ -79,6 +118,29 @@ public class PermissionUtil {
else
sender = CommandSenderHandler.from(targetObj);
// No permission plugin found!
if (Storage.getPermissionPlugin() == PermissionPlugin.NONE) {
if (sender == null) {
try {
throw new Exception("Unknown sender!");
} catch (Exception exception) {
exception.printStackTrace();
}
return true;
}
if (sender.isConsole()) {
return true;
}
return sender.isOperator()
|| sender.hasPermission("*")
|| sender.hasPermission("proantitab.*")
|| sender.hasPermission("proantitab." + permission);
}
if (uuid == null) {
if (sender == null || sender.isConsole())
return true;
@@ -86,49 +148,70 @@ public class PermissionUtil {
uuid = sender.getUniqueId();
}
if(!MAP.containsKey(uuid)) {
MAP.put(uuid, new PermissionMap(uuid));
return false;
}
permissionMap = MAP.get(uuid);
if (permissionMap == null) {
permissionMap = new PermissionMap(uuid);
MAP.put(uuid, permissionMap);
}
if (sender != null) {
if (!Storage.USE_LUCKPERMS) {
if (permissionMap.hasPermissionState("*"))
if (Storage.getPermissionPlugin() != PermissionPlugin.LUCKPERMS) {
if (!permissionMap.hasPermissionState("*"))
permissionMap.setState("*", sender.hasPermission("*"));
if (permissionMap.hasPermissionState("proantitab.*"))
if (!permissionMap.hasPermissionState("proantitab.*"))
permissionMap.setState("proantitab.*", sender.hasPermission("proantitab.*"));
if (permissionMap.hasPermissionState("proantitab." + permission))
if (!permissionMap.hasPermissionState("proantitab." + permission))
permissionMap.setState("proantitab." + permission, sender.hasPermission("proantitab." + permission));
}
if (sender.isOperator())
if (!Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED)
return true;
if (sender.isOperator()) {
return true;
}
}
return permissionMap.isPermitted("*") || permissionMap.isPermitted("proantitab.*") || permissionMap.isPermitted("proantitab." + permission);
}
public static boolean hasBypassPermission(Object targetObj) {
if (!Reflection.isProxyServer() && Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
return false;
}
return hasPermission(targetObj, "bypass");
}
public static boolean hasBypassPermission(Object targetObj, String command) {
return hasBypassPermission(targetObj) || hasPermission(targetObj, "bypass." + command);
if (!Reflection.isProxyServer() && Storage.ConfigSections.Settings.HANDLE_THROUGH_PROXY.ENABLED) {
return false;
}
if (hasBypassPermission(targetObj)) {
return true;
}
if (Storage.getPermissionPlugin() == PermissionPlugin.NONE) {
return false;
}
return hasPermission(targetObj, "bypass." + command);
}
public static boolean hasPermissionWithResponse(Object targetObj, String command) {
boolean permitted = hasPermission(targetObj, command);
if (!permitted && targetObj instanceof CommandSender) {
((CommandSender) targetObj).sendMessage(
Storage.ConfigSections.Messages.NO_PERMISSION.MESSAGE
.replace("%permission%", "proantitab." + command)
);
String message = Storage.ConfigSections.Messages.NO_PERMISSION.MESSAGE;
message = message.replace("%permission%", "proantitab." + command);
((CommandSender) targetObj).sendMessage(message);
}
@@ -7,6 +7,7 @@ import de.rayzs.pat.utils.*;
import de.rayzs.pat.utils.response.action.ActionHandler;
import java.util.*;
import java.util.stream.Collectors;
public class ResponseHandler {
@@ -23,12 +24,67 @@ public class ResponseHandler {
});
}
public static String replaceArgsVariables(String input, String command) {
final String[] commandSplit = command.contains(" ") ? command.split(" ") : new String[] { command };
final String[] inputSplit = input.contains(" ") ? input.split(" ") : new String[] { input };
final StringBuilder output = new StringBuilder();
final int commandLength = commandSplit.length;
for (int i = 0; i < inputSplit.length; i++) {
String part = inputSplit[i];
if (i > 0) {
output.append(" ");
}
if (! (part.startsWith("%args[") && part.endsWith("]%"))) {
output.append(part);
continue;
}
part = part.substring(part.indexOf('[') + 1, part.lastIndexOf(']'));
int fromIndex, toIndex;
try {
if (part.contains("-")) {
final String[] partSplit = part.split("-");
fromIndex = Integer.parseInt(partSplit[0]);
toIndex = Integer.parseInt(partSplit[1]);
} else if (part.startsWith("_")) {
final String[] partSplit = part.split("_");
fromIndex = 0;
toIndex = Integer.parseInt(partSplit[1]);
} else if (part.endsWith("_")) {
final String[] partSplit = part.split("_");
fromIndex = Integer.parseInt(partSplit[0]);
toIndex = commandLength + 1;
} else {
fromIndex = Integer.parseInt(part);
toIndex = fromIndex;
}
fromIndex = Math.max(0, fromIndex - 1);
toIndex = Math.min(commandLength, toIndex);
output.append(String.join(" ", Arrays.copyOfRange(commandSplit, fromIndex, toIndex)));
} catch (NumberFormatException exception) {
Logger.warning("Failed to convert number! (" + part + ")");
}
}
return output.toString();
}
public static List<String> getResponse(UUID uuid, String input) {
return getResponse(uuid, input, Storage.ConfigSections.Settings.CANCEL_COMMAND.SUB_COMMAND_RESPONSE.getLines());
}
public static List<String> getResponse(UUID uuid, String input, List<String> defaultMessage) {
final String finalInput = input.startsWith("/") ? StringUtils.replaceFirst(input, "/", "") : input;
final String finalInput = input.startsWith("/") && input.length() > 1
? input.substring(1)
: input;
final Optional<Response> optionalResponse = RESPONSES.stream().filter(response -> {
for (String trigger : response.triggers)
@@ -39,8 +95,11 @@ public class ResponseHandler {
}).findFirst();
if (uuid != null && optionalResponse.isPresent()) {
optionalResponse.get().executeAction(uuid);
return optionalResponse.get().message;
optionalResponse.get().executeAction(uuid, finalInput);
return new ArrayList<>(optionalResponse.get().message)
.stream().map(s -> replaceArgsVariables(s, finalInput))
.collect(Collectors.toList());
}
return defaultMessage;
@@ -56,7 +115,7 @@ public class ResponseHandler {
this.actions = (List<String>) Storage.Files.CUSTOM_RESPONSES.getOrSet(key + ".actions", new ArrayList<>());
}
public void executeAction(UUID uuid) {
public void executeAction(UUID uuid, String command) {
String[] split;
for (String action : actions) {
@@ -142,7 +201,7 @@ public class ResponseHandler {
continue;
}
ActionHandler.sendTitle(action, uuid, split[1], split[2], fadeIn, stay, fadeOut);
ActionHandler.sendTitle(action, uuid, command, split[1], split[2], fadeIn, stay, fadeOut);
continue;
case "sound":
@@ -192,7 +251,7 @@ public class ResponseHandler {
Logger.warning(" > e.g: console::say Hello world!");
}
ActionHandler.executeConsoleCommand(action, uuid, split[1]);
ActionHandler.executeConsoleCommand(action, uuid, command, split[1]);
case "execute":
if (split.length == 1) {
@@ -203,7 +262,7 @@ public class ResponseHandler {
Logger.warning(" > e.g: execute::help");
}
ActionHandler.executePlayerCommand(action, uuid, split[1]);
ActionHandler.executePlayerCommand(action, uuid, command, split[1]);
case "actionbar":
if (split.length == 1) {
@@ -214,7 +273,7 @@ public class ResponseHandler {
Logger.warning(" > e.g: actionbar::I like COOKIES");
}
ActionHandler.sendActionbar(action, uuid, split[1]);
ActionHandler.sendActionbar(action, uuid, command, split[1]);
}
}
@@ -4,11 +4,11 @@ import java.util.UUID;
public interface Action {
void executeConsoleCommand(String action, UUID uuid, String command);
void executePlayerCommand(String action, UUID uuid, String command);
void sendTitle(String action, UUID uuid, String title, String subTitle, int fadeIn, int stay, int fadeOut);
void executeConsoleCommand(String action, UUID uuid, String command, String message);
void executePlayerCommand(String action, UUID uuid, String command, String message);
void sendTitle(String action, UUID uuid, String command, String title, String subTitle, int fadeIn, int stay, int fadeOut);
void addPotionEffect(String action, UUID uuid, String potionEffectTypeName, int duration, int amplifier);
void playSound(String action, UUID uuid, String soundName, float volume, float pitch);
void sendActionbar(String action, UUID uuid, String text);
void sendActionbar(String action, UUID uuid, String command, String message);
}
@@ -6,20 +6,23 @@ import java.util.UUID;
public class ActionHandler {
private static final Action ACTION = Reflection.isProxyServer() ? Reflection.isVelocityServer() ? new VelocityAction() : new BungeeAction() : Reflection.getMinor() <= 16 ? new OldBukkitAction() : new ModernBukkitAction();
private static final Action ACTION = Reflection.isProxyServer() ? Reflection.isVelocityServer()
? new VelocityAction() : new BungeeAction()
: Reflection.getMinor() <= 16
? new OldBukkitAction() : new ModernBukkitAction();
public static void initialize() {}
public static void executeConsoleCommand(String action, UUID uuid, String command) {
ACTION.executeConsoleCommand(action, uuid, command);
public static void executeConsoleCommand(String action, UUID uuid, String command, String message) {
ACTION.executeConsoleCommand(action, uuid, command, message);
}
public static void executePlayerCommand(String action, UUID uuid, String command) {
ACTION.executePlayerCommand(action, uuid, command);
public static void executePlayerCommand(String action, UUID uuid, String command, String message) {
ACTION.executePlayerCommand(action, uuid, command, message);
}
public static void sendTitle(String action, UUID uuid, String title, String subTitle, int fadeIn, int stay, int fadeOut) {
ACTION.sendTitle(action, uuid, title, subTitle, fadeIn, stay, fadeOut);
public static void sendTitle(String action, UUID uuid, String command, String title, String subTitle, int fadeIn, int stay, int fadeOut) {
ACTION.sendTitle(action, uuid, command, title, subTitle, fadeIn, stay, fadeOut);
}
public static void addPotionEffect(String action, UUID uuid, String potionEffectType, int duration, int amplifier) {
@@ -30,7 +33,7 @@ public class ActionHandler {
ACTION.playSound(action, uuid, soundName, volume, pitch);
}
public static void sendActionbar(String action, UUID uuid, String text) {
ACTION.sendActionbar(action, uuid, text);
public static void sendActionbar(String action, UUID uuid, String command, String message) {
ACTION.sendActionbar(action, uuid, command, message);
}
}
@@ -2,6 +2,7 @@ package de.rayzs.pat.utils.response.action.impl;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.response.ResponseHandler;
import de.rayzs.pat.utils.response.action.Action;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.ProxyServer;
@@ -14,28 +15,32 @@ import java.util.UUID;
public class BungeeAction implements Action {
@Override
public void executeConsoleCommand(String action, UUID uuid, String command) {
public void executeConsoleCommand(String action, UUID uuid, String command, String message) {
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid);
message = ResponseHandler.replaceArgsVariables(message, command);
if (player != null)
command = command.replace("%player%", player.getName());
message = message.replace("%player%", player.getName());
ProxyServer.getInstance().getPluginManager().dispatchCommand(ProxyServer.getInstance().getConsole(), command);
ProxyServer.getInstance().getPluginManager().dispatchCommand(ProxyServer.getInstance().getConsole(), message);
}
@Override
public void executePlayerCommand(String action, UUID uuid, String command) {
public void executePlayerCommand(String action, UUID uuid, String command, String message) {
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid);
message = ResponseHandler.replaceArgsVariables(message, command);
if (player != null)
command = command.replace("%player%", player.getName());
message = command.replace("%player%", player.getName());
ProxyServer.getInstance().getPluginManager().dispatchCommand(player, command);
ProxyServer.getInstance().getPluginManager().dispatchCommand(player, message);
}
@Override
public void sendTitle(String action, UUID uuid, String title, String subTitle, int fadeIn, int stay, int fadeOut) {
public void sendTitle(String action, UUID uuid, String command, String title, String subTitle, int fadeIn, int stay, int fadeOut) {
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid);
title = ResponseHandler.replaceArgsVariables(title, command);
subTitle = ResponseHandler.replaceArgsVariables(subTitle, command);
if (player == null)
return;
@@ -58,12 +63,13 @@ public class BungeeAction implements Action {
}
@Override
public void sendActionbar(String action, UUID uuid, String text) {
public void sendActionbar(String action, UUID uuid, String command, String message) {
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid);
message = ResponseHandler.replaceArgsVariables(message, command);
if (player == null)
return;
player.sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(StringUtils.replace(text, "%player%", player.getName())));
player.sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(StringUtils.replace(message, "%player%", player.getName())));
}
}
@@ -3,6 +3,7 @@ package de.rayzs.pat.utils.response.action.impl;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.message.replacer.PlaceholderReplacer;
import de.rayzs.pat.utils.response.ResponseHandler;
import de.rayzs.pat.utils.response.action.Action;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
@@ -17,35 +18,39 @@ import java.util.UUID;
public class ModernBukkitAction implements Action {
@Override
public void executeConsoleCommand(String action, UUID uuid, String command) {
public void executeConsoleCommand(String action, UUID uuid, String command, String message) {
Player player = Bukkit.getPlayer(uuid);
message = ResponseHandler.replaceArgsVariables(message, command);
if (player != null)
command = command.replace("%player%", player.getName());
message = message.replace("%player%", player.getName());
if (command.contains("%"))
command = PlaceholderReplacer.replace(player, command);
if (message.contains("%"))
message = PlaceholderReplacer.replace(player, message);
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), message);
}
@Override
public void executePlayerCommand(String action, UUID uuid, String command) {
public void executePlayerCommand(String action, UUID uuid, String command, String message) {
Player player = Bukkit.getPlayer(uuid);
message = ResponseHandler.replaceArgsVariables(message, command);
if(player != null)
command = command.replace("%player%", player.getName());
message = message.replace("%player%", player.getName());
if (command.contains("%"))
command = PlaceholderReplacer.replace(player, command);
if (message.contains("%"))
message = PlaceholderReplacer.replace(player, message);
if (player != null)
Bukkit.dispatchCommand(player, command);
Bukkit.dispatchCommand(player, message);
}
@Override
public void sendTitle(String action, UUID uuid, String title, String subTitle, int fadeIn, int stay, int fadeOut) {
public void sendTitle(String action, UUID uuid, String command, String title, String subTitle, int fadeIn, int stay, int fadeOut) {
Player player = Bukkit.getPlayer(uuid);
title = ResponseHandler.replaceArgsVariables(title, command);
subTitle = ResponseHandler.replaceArgsVariables(subTitle, command);
if (player == null)
return;
@@ -98,14 +103,15 @@ public class ModernBukkitAction implements Action {
}
@Override
public void sendActionbar(String action, UUID uuid, String text) {
public void sendActionbar(String action, UUID uuid, String command, String message) {
Player player = Bukkit.getPlayer(uuid);
message = ResponseHandler.replaceArgsVariables(message, command);
if (player == null)
return;
text = PlaceholderReplacer.replace(player, StringUtils.replace(text, "&", "§", "%player%", player.getName()));
message = PlaceholderReplacer.replace(player, StringUtils.replace(message, "&", "§", "%player%", player.getName()));
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(text));
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(message));
}
}
@@ -4,6 +4,7 @@ import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.Reflection;
import de.rayzs.pat.utils.StringUtils;
import de.rayzs.pat.utils.message.replacer.PlaceholderReplacer;
import de.rayzs.pat.utils.response.ResponseHandler;
import de.rayzs.pat.utils.response.action.Action;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
@@ -21,33 +22,40 @@ public class OldBukkitAction implements Action {
private String versionPackage = null;
@Override
public void executeConsoleCommand(String action, UUID uuid, String command) {
public void executeConsoleCommand(String action, UUID uuid, String command, String message) {
Player player = Bukkit.getPlayer(uuid);
if(player != null) command = command.replace("%player%", player.getName());
message = ResponseHandler.replaceArgsVariables(message, command);
if (command.contains("%"))
command = PlaceholderReplacer.replace(player, command);
if(player != null)
message = message.replace("%player%", player.getName());
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
if (message.contains("%"))
message = PlaceholderReplacer.replace(player, message);
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), message);
}
@Override
public void executePlayerCommand(String action, UUID uuid, String command) {
public void executePlayerCommand(String action, UUID uuid, String command, String message) {
Player player = Bukkit.getPlayer(uuid);
message = ResponseHandler.replaceArgsVariables(message, command);
if (player != null)
command = command.replace("%player%", player.getName());
message = message.replace("%player%", player.getName());
if (command.contains("%"))
command = PlaceholderReplacer.replace(player, command);
if (message.contains("%"))
message = PlaceholderReplacer.replace(player, message);
if (player != null)
Bukkit.dispatchCommand(player, command);
Bukkit.dispatchCommand(player, message);
}
@Override
public void sendTitle(String action, UUID uuid, String title, String subTitle, int fadeIn, int stay, int fadeOut) {
public void sendTitle(String action, UUID uuid, String command, String title, String subTitle, int fadeIn, int stay, int fadeOut) {
Player player = Bukkit.getPlayer(uuid);
title = ResponseHandler.replaceArgsVariables(title, command);
subTitle = ResponseHandler.replaceArgsVariables(subTitle, command);
if (player == null) return;
title = PlaceholderReplacer.replace(player, StringUtils.replace(title, "&", "§", "%player%", player.getName()));
@@ -98,13 +106,14 @@ public class OldBukkitAction implements Action {
}
@Override
public void sendActionbar(String action, UUID uuid, String text) {
public void sendActionbar(String action, UUID uuid, String command, String message) {
Player player = Bukkit.getPlayer(uuid);
message = ResponseHandler.replaceArgsVariables(message, command);
if (player == null)
return;
text = PlaceholderReplacer.replace(player, StringUtils.replace(text, "&", "§", "%player%", player.getName()));
message = PlaceholderReplacer.replace(player, StringUtils.replace(message, "&", "§", "%player%", player.getName()));
try {
if (versionPackage == null)
@@ -112,7 +121,7 @@ public class OldBukkitAction implements Action {
Object entityPlayer = player.getClass().getMethod("getHandle").invoke(player);
Constructor<?> constructor = (Objects.<Class<?>>requireNonNull(Class.forName("net.minecraft.server." + versionPackage + ".PacketPlayOutChat"))).getConstructor(Class.forName("net.minecraft.server." + versionPackage + ".IChatBaseComponent"), byte.class);
Object iChatBaseComponent = (Objects.requireNonNull(Class.forName("net.minecraft.server." + versionPackage + ".IChatBaseComponent"))).getDeclaredClasses()[0].getMethod("a", String.class).invoke(null, "{\"text\":\"" + text + "\"}");
Object iChatBaseComponent = (Objects.requireNonNull(Class.forName("net.minecraft.server." + versionPackage + ".IChatBaseComponent"))).getDeclaredClasses()[0].getMethod("a", String.class).invoke(null, "{\"text\":\"" + message + "\"}");
Object actionbarPacket = constructor.newInstance(iChatBaseComponent, (byte) 2);
Object playerConnection = entityPlayer.getClass().getField("playerConnection").get(entityPlayer);
playerConnection.getClass().getMethod("sendPacket", Class.forName("net.minecraft.server." + versionPackage + ".Packet")).invoke(playerConnection, actionbarPacket);
@@ -123,6 +132,7 @@ public class OldBukkitAction implements Action {
| InvocationTargetException
| NoSuchFieldException
| InstantiationException exception) {
Logger.warning("! Failed to run action: " + action);
Logger.warning(" > Actionbars are not supported in this server version!");
}
@@ -2,6 +2,7 @@ package de.rayzs.pat.utils.response.action.impl;
import de.rayzs.pat.plugin.logger.Logger;
import de.rayzs.pat.utils.message.MessageTranslator;
import de.rayzs.pat.utils.response.ResponseHandler;
import net.kyori.adventure.text.minimessage.MiniMessage;
import de.rayzs.pat.utils.response.action.Action;
import com.velocitypowered.api.proxy.Player;
@@ -14,22 +15,33 @@ import java.time.*;
public class VelocityAction implements Action {
@Override
public void executeConsoleCommand(String action, UUID uuid, String command) {
public void executeConsoleCommand(String action, UUID uuid, String command, String message) {
Optional<Player> optPlayer = VelocityLoader.getServer().getPlayer(uuid);
if (optPlayer.isPresent()) command = command.replace("%player%", optPlayer.get().getUsername());
VelocityLoader.getServer().getCommandManager().executeAsync(VelocityLoader.getServer().getConsoleCommandSource(), command);
message = ResponseHandler.replaceArgsVariables(message, command);
if (optPlayer.isPresent())
message = message.replace("%player%", optPlayer.get().getUsername());
VelocityLoader.getServer().getCommandManager().executeAsync(VelocityLoader.getServer().getConsoleCommandSource(), message);
}
@Override
public void executePlayerCommand(String action, UUID uuid, String command) {
public void executePlayerCommand(String action, UUID uuid, String command, String message) {
Optional<Player> optPlayer = VelocityLoader.getServer().getPlayer(uuid);
if (optPlayer.isPresent()) command = command.replace("%player%", optPlayer.get().getUsername());
VelocityLoader.getServer().getCommandManager().executeAsync(optPlayer.get(), command);
message = ResponseHandler.replaceArgsVariables(message, command);
if (optPlayer.isPresent())
message = command.replace("%player%", optPlayer.get().getUsername());
VelocityLoader.getServer().getCommandManager().executeAsync(optPlayer.get(), message);
}
@Override
public void sendTitle(String action, UUID uuid, String title, String subTitle, int fadeIn, int stay, int fadeOut) {
public void sendTitle(String action, UUID uuid, String command, String title, String subTitle, int fadeIn, int stay, int fadeOut) {
Optional<Player> optPlayer = VelocityLoader.getServer().getPlayer(uuid);
title = ResponseHandler.replaceArgsVariables(title, command);
subTitle = ResponseHandler.replaceArgsVariables(subTitle, command);
if (!optPlayer.isPresent()) return;
Player player = optPlayer.get();
@@ -51,11 +63,14 @@ public class VelocityAction implements Action {
}
@Override
public void sendActionbar(String action, UUID uuid, String text) {
public void sendActionbar(String action, UUID uuid, String command, String message) {
Optional<Player> optPlayer = VelocityLoader.getServer().getPlayer(uuid);
if (!optPlayer.isPresent()) return;
message = ResponseHandler.replaceArgsVariables(message, command);
if (!optPlayer.isPresent())
return;
Player player = optPlayer.get();
player.sendActionBar(MiniMessage.miniMessage().deserialize(MessageTranslator.replaceMessage(StringUtils.replace(text, "%player%", player.getUsername()))));
player.sendActionBar(MiniMessage.miniMessage().deserialize(MessageTranslator.replaceMessage(StringUtils.replace(message, "%player%", player.getUsername()))));
}
}
Loaded 100 of 116 files, more files were not shown because too many files have changed in this diff. Show more