Compare commits

...
229 Commits
Author SHA1 Message Date
NotAlexNoyle 2d5b6beef3 Point submodules at canonical Gitea repositories 2026-11-01 12:49:12 -05:00
NotAlexNoyle 2f91860ad9 Update canonical Gitea links 2026-10-31 11:49:12 -04:00
NotAlexNoyle 4ae8786e8e Update canonical Gitea links 2026-10-29 09:18:40 -04:00
NotAlexNoyle 60e0b41186 Exclude CODEOWNERS from language statistics 2026-10-28 15:32:13 -04:00
NotAlexNoyle 4632d61b96 Add CODEOWNERS (one staff approval) 2026-10-28 15:32:13 -04:00
NotAlexNoyle 03b955fd2a Update Utilities-OG API 2026-10-18 15:02:25 -04:00
NotAlexNoyle 8d04fc0cf7 Update Utilities-OG 2026-09-14 02:01:35 -04:00
NotAlexNoyle 64d652a676 Remove Dynamap 2026-08-11 14:33:00 -04:00
NotAlexNoyle 31bc05689d Fix Dynmap repo 2026-08-11 14:28:50 -04:00
NotAlexNoyle 3dee6ed808 Update Utilities-OG API 2026-07-20 00:50:02 -04:00
NotAlexNoyle 280063a609 Remove Template-OG artifact 2026-06-21 21:03:20 -04:00
NotAlexNoyle 8a84095afe Update Utilities-OG API 2026-05-20 11:22:37 -04:00
NotAlexNoyle 3fcdfee824 Update Utilities-OG 2026-05-10 14:19:57 -04:00
NotAlexNoyle eb4f80f467 Fix ProtocolLib vanishing 2026-04-22 15:00:28 -04:00
NotAlexNoyle 055e4393d4 Update Vanish-OG 2026-04-22 13:38:35 -04:00
NotAlexNoyle 14e784a7ea Fix vanish persistence 2026-04-22 11:20:07 -04:00
NotAlexNoyle ad2af065f4 Revert failed keydb migration 2026-04-22 08:29:35 -04:00
NotAlexNoyle 34ff8e7443 Force clear past vanish states in other plugins 2026-04-22 07:58:44 -04:00
NotAlexNoyle d56c34fdd6 Fix stale keydb entries on login 2026-04-22 06:48:56 -04:00
NotAlexNoyle f697333710 Fix stale vanish states 2026-04-21 16:09:17 -04:00
NotAlexNoyle a01c07f641 Fix invalid vanish states 2026-04-21 15:13:48 -04:00
NotAlexNoyle 74bda649a5 Fix old invalid vanish states 2026-04-21 15:01:38 -04:00
NotAlexNoyle c685d4ccfa Fix TAB-OG compatibility 2026-04-21 14:30:36 -04:00
NotAlexNoyle 40ef184e3a Fix TAB-OG vanished hook 2026-04-21 14:17:10 -04:00
NotAlexNoyle aadf6cc622 Fix everyone being invisible 2026-04-21 13:53:32 -04:00
NotAlexNoyle e2947d30db Update OpenInv hook 2026-04-21 11:34:14 -04:00
NotAlexNoyle fc9afdf09a Fix TAB-OG support with ViaSuite and forge clients 2026-04-21 10:53:48 -04:00
NotAlexNoyle d1d0fd2eb2 Fix TAB-OG Hooks 2026-04-21 06:03:20 -04:00
NotAlexNoyle a3a118ee11 Use TAB-OG API instead of playerdata for setting vanish status 2026-04-20 12:46:25 -04:00
NotAlexNoyle 6f6296971d Add TAB-OG Compatibility 2026-04-20 11:10:15 -04:00
NotAlexNoyle a8f257ae62 Update Utilities-OG API 2026-04-20 02:14:15 -04:00
NotAlexNoyle c0107a99d4 Fix runtime exception 2026-04-15 05:57:02 -04:00
NotAlexNoyle cf4db3f5ba Fix ProtocolLib 1.19.4 compatibility 2026-04-14 15:07:50 -04:00
NotAlexNoyle dfffb9c154 Fix SLF4J errors 2026-04-14 14:08:01 -04:00
NotAlexNoyle 98bd470968 Fix SLF4J warning 2026-04-13 04:32:26 -04:00
NotAlexNoyle 0abb3fcb9a Fix gradle placeholder expansion 2026-04-13 04:28:31 -04:00
NotAlexNoyle c3b22df4f6 Avoid keydb parsing bugs 2026-04-13 03:37:52 -04:00
NotAlexNoyle 5bf3e2def8 1.1 - Store data using lettuce instead of data.yml 2026-04-13 03:29:35 -04:00
NotAlexNoyle ff4118bb4e Make directories generic 2026-04-08 13:31:38 -04:00
NotAlexNoyle 5b11813ff7 Release Vanish-OG 2026-04-08 07:53:46 -04:00
Leon Mangler 84627afee6 6.2.21:
- Improve player hiding API and performance
- Add OpenInv hook
- Various improvements and fixes
2025-08-19 21:26:25 +09:00
Leon Mangler 46b0581005 Update README.md 2024-08-03 07:31:14 +02:00
Leon Mangler aaa15b93c3 Merge pull request #88 from Learting/patch-1
Support Purpur
2024-08-03 07:22:57 +02:00
Leon Mangler e2526f8f01 6.2.20:
- Only display warning for failed tab-complete interceptions
2024-08-03 14:15:45 +09:00
Learting b6c44164f6 Support Purpur 2024-07-10 09:16:40 +02:00
Learting d960e23fc5 Support Purpur 2024-07-10 09:05:10 +02:00
Leon Mangler bcf10d0688 6.2.19:
- Redo night vision module without packets
- Fix version util on latest paper
2024-06-26 00:10:26 +09:00
Leon Mangler acf4242ab8 Update Lombok and fix compile 2024-03-25 15:38:30 +09:00
Leon Mangler 5bfd192d97 Fix compile 2024-03-25 15:33:42 +09:00
Leon Mangler e133f70b86 Avoid storing the player reference in VanishPlayer 2024-03-25 15:31:47 +09:00
Leon Mangler fbc303bbee Increase java version to 17 to fulfill paper dependency requirements 2023-11-06 15:53:22 +09:00
Leon Mangler df72b954c4 Fix maven build by changing spigot to paper repo 2023-11-06 15:41:11 +09:00
Leon Mangler 086278d662 Merge branch 'crazycat256-paper' 2023-08-13 18:22:38 +09:00
Leon Mangler a9b9770233 Bump version to 6.2.18 2023-08-13 18:18:56 +09:00
Leon Mangler 9065c44d9e Improve performance of NoMobSpawn 2023-08-13 18:14:15 +09:00
Leon Mangler 794d34d0df Improve error logging in new features 2023-08-13 18:07:10 +09:00
Leon Mangler d5777add02 Fix typo 2023-08-13 18:00:46 +09:00
Leon Mangler 77653f48c2 Add PaperServerPingListener 2023-08-13 18:00:31 +09:00
Leon Mangler 843e4d6ee1 Fix server list ping write position and improve error messages 2023-08-13 17:51:26 +09:00
Leon Mangler 48fd17a36d Merge branch 'paper' of github.com:crazycat256/SuperVanish into crazycat256-paper 2023-08-13 17:45:37 +09:00
Leon Mangler d846cd5519 Merge pull request #79 from crazycat256/externalinvisibility
Bug fixes
2023-08-04 11:22:34 +02:00
crazycat256 5da1b96e20 Create NoMobSpawn.java 2023-08-01 23:57:55 +02:00
crazycat256 9e60483c78 Create HideAdvancementMessages.java 2023-08-01 23:57:52 +02:00
crazycat256 f5c20777eb Add features to config.yml 2023-08-01 23:57:48 +02:00
crazycat256 6b36ea7d8f Add paperServer featureInfo 2023-08-01 23:57:10 +02:00
crazycat256 7fdfde4523 Switch to PaperMC API 2023-08-01 23:56:24 +02:00
crazycat256 5a51918af1 Add CALIBRATED_SCULK_SENSOR 2023-08-01 19:25:09 +02:00
crazycat256 696e762fbd Fix External Invisibility 2023-07-30 22:36:21 +02:00
Leon Mangler 8d7f3d6da5 6.2.17: Update for MC 1.20.1 2023-06-29 18:31:59 +09:00
Leon Mangler bf765d8055 Bump version to 6.2.16 2023-05-18 19:31:31 +09:00
Leon Mangler ee6ad93f5c Only log errors once in TabCompleteListener to prevent spam 2023-05-18 18:50:21 +09:00
Leon Mangler b2e39dd9af Remove Citizens dependency to resolve circular dependency issues 2023-04-19 20:49:59 +09:00
Leon Mangler b649d0f1e2 Increase teleport distance when closing chest silently 2023-02-06 20:13:09 +01:00
Leon Mangler f67dd7bce3 Fix comment 2023-01-28 21:33:55 +01:00
Leon Mangler 5671730d22 Bump version to 6.2.15 2023-01-28 21:30:29 +01:00
Leon Mangler ef49346fca Merge pull request #71 from crazycat256/master
Add check for sculk sensors, sculk shrieker and turtle eggs
2023-01-28 21:28:20 +01:00
Leon Mangler 4954745ceb Prevent falling into the ground when opening chests silently 2023-01-28 21:14:38 +01:00
crazycat256 215b2dbe83 Merge branch 'LeonMangler:master' into master 2023-01-19 21:45:54 +01:00
Leon Mangler 19d82a11d9 Bump version to 6.2.14 2023-01-19 18:21:10 +01:00
Leon Mangler 23f3952a6b Fix hex colors again 2023-01-19 18:15:47 +01:00
Leon Mangler 12ddb16175 6.2.13:
- 1.19.3 update
- Disabled some unstable features
- Added vanish prefix and suffix placeholders
2023-01-19 18:08:49 +01:00
crazycat256 cb41cfe553 Merge branch 'LeonMangler:master' into master 2022-12-04 12:27:52 +01:00
Leon Mangler 4f0612b338 Fix &#FFFFFF chat color format 2022-11-28 23:19:56 +01:00
Leon Mangler e9e50e2b5e Fix null pointer exception in sendMessage(..) 2022-11-28 23:18:57 +01:00
crazycat256 4f48b825f6 Removed debug message 2022-11-15 21:49:49 +01:00
crazycat256 91019a2c40 Added NoRaidTrigger feature 2022-11-15 21:45:36 +01:00
crazycat256 29e082dc94 Added NoTurtleEggBreaking feature 2022-11-03 17:20:45 +01:00
crazycat256 91999ea0ce Update NoSculkSensorDetection.java 2022-11-03 10:54:52 +01:00
Leon Mangler afbb1348ae Bump version to 6.2.12 2022-08-29 23:59:14 +02:00
Leon Mangler d1f579894d Add TabCompleteModule to intercept tab complete packets 2022-08-29 23:58:49 +02:00
Leon Mangler 937d14a08d git push origin masterMerge branch 'ARR4NN-master' 2022-08-19 22:48:12 +02:00
Leon Mangler bc1231cd81 Bump version to 6.2.11 2022-08-19 22:47:49 +02:00
Leon Mangler 3c5afcc030 Fix oneDotSeventeenOrHigher feature requirement 2022-08-19 22:46:53 +02:00
Leon Mangler b79d4bd628 Add some more checks and fix formatting in drip leaf feature 2022-08-19 22:46:35 +02:00
ARR4NN b41a82d533 Simplify 2022-08-17 10:31:26 +01:00
ARR4NN 48f2f6f3c8 Add check for tilting of DripLeaves. 2022-08-17 10:22:34 +01:00
Leon Mangler c4c889d432 Remove double isSneaking check 2022-08-12 04:42:09 +02:00
Leon Mangler 620a98d1cf Merge pull request #67 from BetTD/pr
Remove unnecessary checks and enable resource filtering
2022-08-12 04:40:04 +02:00
Leon Mangler e1702994b0 Fix config version number change 2022-08-12 04:35:47 +02:00
Leon Mangler 5cb1c11f0e Use lambda expressions in FeatureMgr 2022-08-12 04:34:21 +02:00
Leon Mangler 4f7cc7bad7 Update sculk sensor config setting name 2022-08-12 04:32:26 +02:00
Leon Mangler f61cdd6b0e Merge pull request #68 from BetTD/no-sculk-sensor-detect
Add ability to disable sculk sensor detection for vanished players
2022-08-12 04:29:11 +02:00
Raúl M 9212ad99ff Re-added nullcheck for p.getItemInHand() 2022-08-12 04:05:35 +02:00
Raúl M 5d7b4c09d6 Merge branch 'master' of https://github.com/LeonMangler/SuperVanish into pr
 Conflicts:
	src/main/resources/config.yml
	src/main/resources/messages.yml
	src/main/resources/plugin.yml
2022-08-12 04:02:08 +02:00
Raúl M 3eb9e625ea Undo changes in 6.2.10 2022-08-12 03:59:48 +02:00
Raúl M 96ac8d63a6 Merge branch 'master' of https://github.com/LeonMangler/SuperVanish into no-sculk-sensor-detect
 Conflicts:
	src/main/resources/config.yml
2022-08-12 03:58:14 +02:00
Leon Mangler 0f6728220a 6.2.10: Add sculk sensor activate listener 2022-08-02 23:56:28 +02:00
Leon Mangler e3270fbc51 Turn night vision back on again 2022-08-02 23:55:36 +02:00
Raúl M 2555593fa6 Enable resource filtering for config.yml and messages.yml 2022-07-10 20:37:22 +02:00
Raúl M 2781e3d599 Merge branch 'master' of https://github.com/LeonMangler/SuperVanish into pr
 Conflicts:
	src/main/resources/plugin.yml
2022-07-10 20:36:36 +02:00
Leon Mangler 205e7a2d4d 6.2.9: Fix NightVision 2022-07-09 00:35:27 +02:00
Raúl M a93764355f Add ability to disable sculk sensor detection for vanished players 2022-07-07 20:49:15 +02:00
Raúl M 62c095d9a2 Implement resource filtering 2022-07-07 20:20:25 +02:00
Raúl M c7b983c1ff Remove unnecessary checks 2022-07-07 20:02:36 +02:00
Leon Mangler 65ceba4708 6.2.8: Experimental 1.19 update 2022-06-30 22:27:32 +02:00
Leon Mangler 333837ccea Improve TabCompleteListener performance 2022-05-17 19:50:14 +02:00
Leon Mangler 85d20e17d3 Merge remote-tracking branch 'svgithubrepo/master' 2022-03-15 22:31:00 +01:00
Leon Mangler 1ad76d43dc Update NightVision and bump to 6.2.7 2022-03-15 22:30:43 +01:00
Leon Mangler c2366d3013 Bump version to 6.2.7 2022-03-15 22:22:02 +01:00
Leon Mangler f57056a13a Update ProtocolLib dependency 2022-01-18 16:10:30 +01:00
Leon Mangler 2ccec38b65 Remove SuperTrails hook from plugin.yml and config.yml 2022-01-18 16:02:11 +01:00
Leon Mangler ca4287dcf5 Update maven repo info in README 2022-01-18 15:59:29 +01:00
Leon Mangler b1c3cf280f Update dynmap hook and pom.xml to remove local dependencies 2022-01-18 15:57:36 +01:00
Leon Mangler a1cc8e9cfb Remove SuperTrails hook 2022-01-18 15:57:07 +01:00
Leon Mangler b2873319dc Update maven repository info in README.md 2021-10-04 20:00:22 +02:00
Leon Mangler 1effcc0d87 Bump version in maven 2021-10-04 19:58:04 +02:00
Leon Mangler bf05c51d3d Merge pull request #62 from montlikadani/patch-1
Changing repository urls from HTTP to HTTPS for security reasons
2021-10-04 19:48:01 +02:00
montlikadani 6c3adbcd40 Changing from HTTP to HTTPS for security reasons 2021-09-04 21:05:46 +02:00
Leon Mangler 24d6d2d2b2 Accept '&' before HEX color placeholders 2021-08-13 19:57:26 +02:00
Leon Mangler f1eea4626e Update Lombok dependency as well 2021-08-13 19:56:42 +02:00
Leon Mangler 6e637ca5c8 Merge pull request #61 from Iaiao/patch-2
Bump lombok version to 1.18.20
2021-08-13 19:55:40 +02:00
Iaiao eb3145daa6 Bemp lombok version to 1.18.20 2021-08-07 20:46:27 +03:00
Leon Mangler 4f8e5bbaf2 Bump version to 6.2.6 2021-05-03 21:29:55 +02:00
Leon Mangler 505f9876a2 Deal with NoSuchMethodErrors in ActionBarMgr on outdated servers 2021-05-03 16:22:05 +02:00
Leon Mangler 99b3a958bf Readd copyright headers to updated files 2021-04-27 01:59:13 +02:00
Leon Mangler c0b5d5dffb Fix missing bracket in VanishIndication 2021-04-27 01:38:14 +02:00
Leon Mangler 70be2c8b2e Add info about new sv.silentchest permission 2021-04-27 01:36:40 +02:00
Leon Mangler 6887d1b1ed Add HEX color tutorial to messages.yml file 2021-04-27 01:24:13 +02:00
Leon Mangler c3fa548841 6.2.5:
- Improve action bar method
- Prevent error spam by suppressing subsequent errors
- Add info on how to fix common problems to the error messages
- Add HEX colors
- New SilentOpenChest strategy
2021-04-27 01:21:30 +02:00
Leon Mangler 16c6f70c66 Bump version to 6.2.4 2021-04-20 01:56:52 +02:00
Leon Mangler 846d72de85 Rename event listeners 2021-04-20 01:19:32 +02:00
Leon Mangler 64b6c24213 Move MC 1.10 or higher TabCompleteEvent to its own class 2021-04-20 01:17:51 +02:00
Leon Mangler d7cb1c9523 Filter tab-completions with the TabCompleteEvent 2021-04-20 00:46:44 +02:00
Leon Mangler 4117b44984 Bump version to 6.2.3 2021-04-12 07:45:05 +02:00
Leon Mangler 6d6b228801 Update MVdWPlaceholderAPI maven dependency 2021-04-12 06:06:51 +02:00
Leon Mangler e6e3782b04 Fix Mob NoClassDefFoundError for 1.12 and below 2021-04-12 05:46:54 +02:00
Leon Mangler ae0e8db57a Fix Mob NoClassDefFoundError for 1.12 and below 2021-04-12 05:40:36 +02:00
Leon Mangler 1d00e73a75 Update license to MIT
I believe anyone should be allowed to modify SV to their server's needs without having to disclose the source. Hence the license is now the MIT license. It's still a requirement to give credit however, which means servers using modified versions of SV should mention SuperVanish and where they got SV from somewhere on the server (e.g. in a custom command known by players or in the standard "/plugins" and "/version SuperVanish" commands).
2021-04-05 19:33:24 +02:00
Leon Mangler fc054f4896 Bump version to 6.2.2 2021-04-05 19:25:49 +02:00
Leon Mangler 2940a7b3bd Remove vanished players as a mob target from all entities on vanish 2021-04-05 18:59:09 +02:00
Leon Mangler 36b85109d6 Use Java 8 2021-04-05 18:59:01 +02:00
Leon Mangler 3a8627863f Bump version to 6.2.1 2021-03-29 19:30:41 +02:00
Leon Mangler 41d774258a Merge remote-tracking branch 'svgithubrepo/master' 2021-03-29 19:14:35 +02:00
Leon Mangler 0d535aed72 Let sub commands override equally-named players 2021-03-29 19:14:30 +02:00
Leon Mangler f3532f703c Update maven repo exampel code 2021-02-08 13:56:50 +01:00
Leon Mangler 9c4a6046b8 Dont tab-complete if player doesnt have any SV permissions 2020-09-14 10:47:07 +02:00
Leon Mangler fde7fdb090 Only activate PlayerInfoModule on MC 1.8+ 2020-08-31 22:41:51 +02:00
Leon Mangler 289dd486c8 6.2.0: Added PlayerInfoModule for tab packet interception 2020-08-31 22:31:32 +02:00
Leon Mangler 5bb09887f5 Update maven instructions 2020-08-03 04:29:09 +02:00
Leon Mangler 1fc5a836dd Downgrade broken PlaceholderAPI dependency 2020-08-03 04:15:48 +02:00
Leon Mangler e9443a35da Bump version to 6.1.8 2020-08-03 04:03:04 +02:00
Leon Mangler 23b12d945f Update PlaceholderAPI hook for PlaceholderAPI 2.10.8 2020-08-03 02:35:44 +02:00
Leon Mangler 6e20f5c2dd Bump version to 6.1.6 2020-07-28 00:17:39 +02:00
Leon Mangler 0da0a5709e Update PlaceholderAPI hook to use the new expansion system 2020-07-28 00:17:23 +02:00
Leon Mangler d42082b05c Use JitPack as maven repository 2020-07-15 08:57:37 +02:00
Leon Mangler c2b0fef9b1 Use the new Essentials repository 2020-07-14 12:55:40 +02:00
Leon Mangler a352a07fdb Hide players in join event too to avoid simultaneous login edge-cases 2020-07-14 12:43:34 +02:00
Leon Mangler 22bc0ce8a6 Workaround for SilentOpenChest issues 2020-06-30 23:02:26 +02:00
Leon Mangler ce3d058e65 Add death message placeholder 2020-06-30 22:43:29 +02:00
Leon Mangler 8529b0d472 Bump version to 6.1.5 2020-06-30 22:17:57 +02:00
Leon Mangler 8f208d7352 Remove unnecessary instanceof check and fix punctuation 2020-06-30 22:16:59 +02:00
Leon Mangler 8efb8b495d Merge pull request #56 from Ashesh3/master
Add an option to suppress death messages
2020-06-30 22:08:46 +02:00
Ashesh 0c3001d1d7 fix imports 2020-06-24 14:55:56 +05:30
Ashesh a6bdb5614a fix a syntax error 2020-06-24 14:36:44 +05:30
Ashesh3 ed578c3400 Add an option to suppress death messages 2020-06-23 10:15:27 +05:30
Leon Mangler b07dc76605 Merge pull request #55 from Luracasmus/patch-3
Update spigot-api to 1.15.2-R0.1-SNAPSHOT
2020-06-23 06:12:50 +02:00
Luracasmus 682c615504 Update spigot-api to 1.15.2-R0.1-SNAPSHOT 2020-06-11 11:38:51 +02:00
Leon Mangler 5827c022ff Bump version to v6.1.5 2020-05-04 16:15:41 +02:00
Leon Mangler 2185913c20 Fix temporary players error in VanishIndication 2020-04-27 21:56:14 +02:00
Leon Mangler 5e2dcbafa3 Bump version to 6.1.4 2020-04-04 06:49:23 +02:00
Leon Mangler 2a94d729a6 Update SilentOpenChest for 1.15 2020-04-04 06:27:44 +02:00
Leon Mangler 51aed96ba8 Improve join/quit announcements comments in config 2020-03-10 23:36:57 +01:00
Leon Mangler 3ae7933015 Update README.md 2019-11-11 15:57:16 +01:00
Leon Mangler 51152f61fd Merge remote-tracking branch 'svgithubrepo/master' 2019-10-25 16:57:45 +02:00
Leon Mangler ac4a81340c Fix out of bounds in EssentialsHook 2019-10-25 16:57:32 +02:00
Leon Mangler f92754d37b Bump version to 6.1.3 2019-07-24 18:03:03 +02:00
Leon Mangler dcae65f1c5 Add barrel support to SilentOpenChest feature 2019-07-24 18:02:46 +02:00
Leon Mangler 87aa8069e4 Merge pull request #46 from lekro/patch-1
Add '%l' to ListMessagePrefix
2019-06-29 22:15:53 +02:00
kapurai 73340ed882 Add '%l' to ListMessagePrefix
This allows the list of players to actually appear when /sv list is called.
2019-06-29 13:13:35 -05:00
Leon Mangler 2a3dd0abc1 Bump version to 6.1.2 2019-06-12 11:56:12 +02:00
Leon Mangler addb564e37 Improve dynmap hook and update dynmap dependency 2019-06-12 11:55:10 +02:00
Leon Mangler 105d34afb4 Add null check to PlaceholderAPIHook 2019-06-12 10:49:37 +02:00
Leon Mangler 1d2879b6bf Bump version to 6.1.1 2019-06-05 19:30:28 +02:00
Leon Mangler 24998b99d4 Code cleanup 2019-06-05 19:26:57 +02:00
Leon Mangler e8b130c15a Update dependencies 2019-06-05 19:03:15 +02:00
Leon Mangler f329bddb6c Release v6.1.0 2018-09-30 11:24:34 +02:00
Leon Mangler 201fc9aa2c Set sleeping-ignored state while vanished (#35) 2018-09-30 11:15:35 +02:00
Leon Mangler 7a4ee61f8e Update spigot-api usage to be pre and post 1.13 compatible 2018-09-29 20:00:09 +02:00
Leon Mangler 1c5b00262e Update spigot dependency to 1.13.1 2018-09-29 19:51:58 +02:00
Leon Mangler f5dd1a7cc2 Fix copy-paste error in config file comments 2018-09-29 19:51:38 +02:00
Stephen 474672b004 Remove periods after {Player} Joined the game (#33)
This is a dead give away to when players vanish vs leave normally.
2018-09-29 19:48:18 +02:00
Leon 0db5d970d5 Fix missing versions of previous commit 2018-01-31 18:55:14 +01:00
Leon f393eb5033 Bump version to v6.0.5 2018-01-31 18:47:02 +01:00
Leon 29b1ad28e9 Ensure that there are always wrapped Players available 2018-01-31 18:46:13 +01:00
Leon 2e2f252afe Adjust and remove some useless comments 2017-12-30 17:40:30 +01:00
Leon a99148a379 Bump version to v6.0.4 2017-12-30 17:03:04 +01:00
Leon 885f285c5b Add feature requirement system to FeatureMgr
Change the dependency list to a requirement list to allow
for different feature requirements as well and add MC-1.8
requirements to features which require MC-1.8.
2017-12-30 17:03:04 +01:00
Leon a24731fa55 Bump version to v6.0.3 2017-12-30 17:03:04 +01:00
Leon 743ba83a40 Revert use of new Player hiding API
Not using the new player#hidePlayer(otherPlayer, plugin) API anymore
since its use breaks SVs functionality. More testing is required for
implementing it.
2017-12-30 17:02:15 +01:00
Leon 105ec009a9 Bump version to v6.0.2 2017-12-23 14:27:12 +01:00
Leon 77d42e6fea Fix UnsupportedOperationException in Vault placeholder replacer 2017-12-23 14:26:19 +01:00
Leon 22aa85bb15 Bump version to v6.0.1 2017-12-23 13:37:53 +01:00
Leon e4b4596d26 Remove deprecated API usage in MVdWPlaceholderHook 2017-12-23 13:27:17 +01:00
Leon a5956f6ed8 Fix placeholder replacer being broken by placeholder plugins
Add a null check to the placeholder converter to ensure that the message cannot be null.
2017-12-23 13:27:17 +01:00
Leon 4672cce95c Change README maven dependency version 2017-12-23 13:27:17 +01:00
Leon ebb936ba56 v6.0.0: Rewrite and expansion of everything:
- Improved SilentOpenChest
- Expanded API
- Added help action
- Added tab-completion to command
- Added MVdWPlaceholderAPI and PlaceholderAPI hooks and placeholder support
- Added update checker and notifier
- Now using new Spigot 1.12.2 hiding API
- Improved MarkVanishedPlayersAsSpectators
- Restructured config files and improved placeholder format
- Now using Lombok
- Huge code clean-up, improved encapsulation, improved naming, etc
2017-12-23 13:27:17 +01:00
MyzelYam ac17d7086b Update README.md 2017-12-23 13:27:17 +01:00
Foorack 25cc5efdd5 Add Cubekrowd CI (#24) 2017-12-23 13:27:17 +01:00
Leon 33dc8058fd Clean-up serverlist packet listener 2017-12-23 13:25:55 +01:00
Leon 9e2cab4b18 Improve language of config.yml comments 2017-12-23 13:24:58 +01:00
Leon f16742641a Adjust config file to recent hook changes 2017-08-16 01:41:49 +02:00
Leon 8d94ce8aae Final touches for the actual v5.10.1 release:
- Removed LibsDisguises and DisguiseCraft hooks since their use was very limited
- Replaced PermissionsEx hook with Vault hook
- Fixed maven compilation
2017-08-16 01:30:22 +02:00
Leon ff791b660b Merge remote-tracking branch 'svgithubrepo/master'
# Conflicts:
#	pom.xml
2017-08-16 00:45:09 +02:00
CDAGaming 0c4fcc87cd Updates Dependencies to fix some Issues (#20)
* Updates Dependencies to fix some Issues

* Fix Repository Links
2017-08-16 00:44:36 +02:00
Leon 715e2725a1 Update to v5.10.1: Fixed some NPEs 2017-08-16 00:37:33 +02:00
Leon bc0a06fdc2 Fix duplicate uuids in playerdata 2017-08-07 19:15:31 +02:00
Leon 7ccdcac5bf Update to v5.10.0:
- Replaced some legacy code which caused issues
- Removed legacy API which has been deprecated for a very long time
- Improved /sv reload effect
- Improved PlugMan and /reload compatibility
- Added a toggle of the layered permissions to the config (they are now turned off by default)
- Added AutoVanishOnJoin feature
- Fixed TrailGUI hook
2017-08-07 19:08:29 +02:00
Leon f831860e39 Update to v5.9.8: New way of sending action bars to prevent issues 2017-07-18 19:31:01 +02:00
Leon aa4771a7dc Update to v5.9.7: Fix NoSuchMethodError for MC1.8 in TablistPacketMgr 2017-07-09 22:42:17 +02:00
140 changed files with 10667 additions and 3778 deletions

No files matched your search

+1
View File
@@ -0,0 +1 @@
.gitea/CODEOWNERS linguist-detectable=false
+3
View File
@@ -0,0 +1,3 @@
# Pull requests request review from the eligible staff team(s).
# One approval from either an Admin or Developer satisfies branch protection.
* @trueog/Admins @trueog/Developers
+6 -1
View File
@@ -1,6 +1,12 @@
*.class
target/
out/
build/
.gradle/
bin/
.classpath
.project
.checkstyle
# Mobile Tools for Java (J2ME)
.mtj.tmp/
@@ -10,7 +16,6 @@ out/
*.eml
*.iml
# Eclipse files
.settings
+3
View File
@@ -0,0 +1,3 @@
[submodule "libs/Utilities-OG"]
path = libs/Utilities-OG
url = https://git.trueog.net/trueog/Utilities-OG
+21 -373
View File
@@ -1,373 +1,21 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.
MIT License
Copyright (c) 2021 Leon Mangler
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+160 -4
View File
@@ -1,6 +1,162 @@
# SuperVanish
Website: https://www.spigotmc.org/resources/supervanish.1331/
# Vanish-OG
Source of my Bukkit-Plugin SuperVanish for the spigot/craftbukkit minecraft server-software.
A fork of [SuperVanish](https://www.spigotmc.org/resources/supervanish-be-invisible.1331/) for [TrueOG Network](https://trueog.net). Lets staff become completely invisible so they can quietly observe and moderate.
Feel free to create Pull Requests if you think that you can improve SuperVanish!
Built for **Purpur 1.19.4**. Clients from **Minecraft 1.8 through 1.21.11** can connect through ViaSuite (ViaVersion / ViaBackwards / ViaRewind) and vanish works correctly across the board.
### What's different from SuperVanish?
- **Tab list hiding works on 1.19+** Upstream switched it off after a Mojang change broke it. Vanish-OG handles the new format so vanished staff stay hidden from the tab list.
- **Spectator indication works on 1.19.4 again.** `MarkVanishedPlayersAsSpectators` now uses the native 1.19.4 player info update packet, so staff who can see vanished players still get the dark-gray/head-only tab list cue across Via-served 1.8-1.21.11 clients.
- **Silent chest opening works on 1.19.4 again.** Peeking into containers looks completely invisible to other players if vanished.
- **All connected clients see the same thing.** Whether someone joins from 1.8 or the latest 1.21.11 release through ViaSuite, vanish behaves identically.
- **[Chat-OG](https://git.trueog.net/trueog/Chat-OG) owns announcement visibility.** Vanish-OG no longer rewrites join/quit, death, or advancement messages and no longer emits fake join/quit broadcasts on vanish toggles. Chat-OG is responsible for hiding vanished-player activity from Discord-facing announcements.
- **OpenInv support.** If installed, Vanish-OG hands off chest viewing to OpenInv so staff never enter spectator mode and can't get stuck there after a crash.
- **MiniPlaceholders support** (via Utilities-OG) for use in chat, tab, and hologram plugins.
- **Safer chest peeking.** Staff no longer occasionally fall through the floor when finishing a peek. Pair with [WGamemode](https://github.com/true-og/WGamemode) to auto-restore gamemodes after crashes if OpenInv is not installed.
- **Flat-file storage again.** Vanish state and player preferences are stored locally in `plugins/Vanish-OG/data.yml`, which keeps the runtime path simple and removes the external KeyDB dependency.
- **Rejoin state is persisted, not permission-driven.** Players only reconnect vanished if `data.yml` still marks them vanished from last time; there is no "always join vanished" permission path anymore.
- **TAB-OG compatibility via TAB API.** When [TAB-OG](https://git.trueog.net/trueog/TAB-OG) is installed, Vanish-OG registers a `VanishIntegration` handler with TAB's API so TAB consults Vanish-OG's state manager directly for its `canSee()` / `isVanished()` checks instead of depending solely on the `"vanished"` player metadata key. This closes the join-time race where Forge clients crashed because TAB evaluated tab-list visibility before the metadata was set. The metadata key is still set during `PlayerLoginEvent` so TAB's placeholder-level `isVanished` fallback and any other plugin using the convention keep working.
- **Removed old clutter.** Deprecated functions are removed and the code is updated for java 17 conventions.
### Chat-OG handles some events that used to be handled by SuperVanish
If your stack includes [Chat-OG](https://git.trueog.net/trueog/Chat-OG), think of the split like this:
- Vanish-OG manages vanish state, player/entity visibility, tab list hiding, spectator indication, and silent chest behavior.
- Chat-OG manages whether vanished-player join/quit, kick, advancement, death, and Discord bridge announcements are surfaced.
This avoids two plugins trying to suppress or fake the same announcement events.
### API
Vanish-OG ships the same Bukkit-facing API package as SuperVanish: `de.myzelyam.api.vanish`.
### Main entry point
Use [`VanishAPI`](src/main/java/de/myzelyam/api/vanish/VanishAPI.java) for all direct integrations.
```java
import de.myzelyam.api.vanish.VanishAPI;
import net.trueog.utilitiesog.UtilitiesOG;
```
### Commands
Main command: `/vanish` (also `/v`, `/sv`, `/supervanish`).
### State queries
- `VanishAPI.getInvisiblePlayers()`
Returns the UUIDs of all online vanished players.
- `VanishAPI.getAllInvisiblePlayers()`
Returns the UUIDs of all vanished players, including offline players stored in `data.yml`.
- `VanishAPI.isVanished(Player player)`
Checks if a player is vanished. Returns `boolean`.
- `VanishAPI.isVanished(UUID uuid)`
Checks if a player is vanished. Returns `boolean`.
Java:
```java
if (VanishAPI.isVanished(player) || VanishAPI.isVanished(player.getUniqueId())) {
UtilitiesOG.trueogMessage(player, "You are vanished.");
}
```
Kotlin:
```kotlin
if (VanishAPI.isVanished(player) || VanishAPI.isVanished(player.uniqueId)) {
UtilitiesOG.trueogMessage(player, "You are vanished.")
}
```
### Visibility control
- `VanishAPI.hidePlayer(Player player)`
Vanishes the player through the normal SuperVanish pipeline and fires the related events. Main thread only.
- `VanishAPI.showPlayer(Player player)`
Reveals the player through the normal SuperVanish pipeline and fires the related events. Main thread only.
- `VanishAPI.canSee(Player viewer, Player viewed)`
Returns whether `viewer` should currently be able to see `viewed`. Main thread only.
Java:
```java
if (!VanishAPI.canSee(viewer, target)) {
UtilitiesOG.trueogMessage(viewer, "<red>That player is hidden from you.");
}
VanishAPI.hidePlayer(target);
VanishAPI.showPlayer(target);
```
Kotlin:
```kotlin
if (!VanishAPI.canSee(viewer, target)) {
UtilitiesOG.trueogMessage(viewer, "<red>That player is hidden from you.")
}
VanishAPI.hidePlayer(target)
VanishAPI.showPlayer(target)
```
### Configuration access
- `VanishAPI.getConfiguration()`
Returns `config.yml`. Main thread only; treat the returned `FileConfiguration` as Bukkit-owned mutable state.
- `VanishAPI.getMessages()`
Returns `messages.yml`. Main thread only; treat the returned `FileConfiguration` as Bukkit-owned mutable state.
- `VanishAPI.reloadConfig()`
Reloads the plugin. Main thread only.
- `VanishAPI.getPlugin()`
Returns the active `SuperVanish` plugin instance. Fetching the reference is cheap, but any interaction with the plugin or Bukkit APIs should stay on the main thread.
### Events
The API exposes the following Bukkit events in `de.myzelyam.api.vanish`:
All of these are normal Bukkit events and should be handled on the main server thread. Do not assume they fire asynchronously.
- [`PlayerHideEvent`](src/main/java/de/myzelyam/api/vanish/PlayerHideEvent.java)
Fired before a player is hidden. Cancellable. Includes `isSilent()` / `setSilent(boolean)`.
- [`PostPlayerHideEvent`](src/main/java/de/myzelyam/api/vanish/PostPlayerHideEvent.java)
Fired after a player has been hidden. Not cancellable. Includes `isSilent()`.
- [`PlayerShowEvent`](src/main/java/de/myzelyam/api/vanish/PlayerShowEvent.java)
Fired before a player is shown. Cancellable. Includes `isSilent()` / `setSilent(boolean)`.
- [`PostPlayerShowEvent`](src/main/java/de/myzelyam/api/vanish/PostPlayerShowEvent.java)
Fired after a player has been shown. Not cancellable. Includes `isSilent()`.
- [`PlayerVanishStateChangeEvent`](src/main/java/de/myzelyam/api/vanish/PlayerVanishStateChangeEvent.java)
Fired when persisted vanish state changes for a UUID. Cancellable. Exposes `isVanishing()`, `getUUID()`, `getPlayer()` (returns the Bukkit `Player` or `null` if offline), `getName()`, and `getCause()`. Constructible via `(UUID, String, boolean, String)` or `(Player, boolean, String)`.
### Example listener
Java:
```java
@EventHandler
public void onPlayerHide(PlayerHideEvent event) {
if (!event.getPlayer().hasPermission("myplugin.allowvanish")) {
UtilitiesOG.trueogMessage(event.getPlayer(), "<red>You are not allowed to vanish.");
event.setCancelled(true);
}
}
```
Kotlin:
```kotlin
@EventHandler
fun onPlayerHide(event: PlayerHideEvent) {
if (!event.player.hasPermission("myplugin.allowvanish")) {
UtilitiesOG.trueogMessage(event.player, "<red>You are not allowed to vanish.")
event.isCancelled = true
}
}
```
## Reporting issues
Open an issue on the [Vanish-OG Gitea repository](https://git.trueog.net/trueog/Vanish-OG/issues).
Executable
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/bash
# Fetch all submodule content.
git submodule update --force --recursive --init
+157
View File
@@ -0,0 +1,157 @@
/* ------------------------------ Plugins ------------------------------ */
plugins {
id("java") // Import Java plugin.
id("java-library") // Import Java Library plugin.
id("com.diffplug.spotless") version "8.1.0" // Import Spotless plugin.
id("com.gradleup.shadow") version "8.3.9" // Import Shadow plugin.
id("checkstyle") // Import Checkstyle plugin.
eclipse // Import Eclipse plugin.
}
/* --------------------------- JDK / Kotlin ---------------------------- */
java {
sourceCompatibility = JavaVersion.VERSION_17 // Compile with JDK 17 compatibility.
toolchain { // Select Java toolchain.
languageVersion.set(JavaLanguageVersion.of(17)) // Use JDK 17.
vendor.set(JvmVendorSpec.GRAAL_VM) // Use GraalVM CE.
}
}
/* ----------------------------- Metadata ------------------------------ */
group = "de.myzelyam.vanishog" // Declare bundle identifier.
version = "1.1" // Declare plugin version (will be in .jar).
val apiVersion = "1.13" // Declare minecraft server target version.
/* ----------------------------- Resources ----------------------------- */
tasks.named<ProcessResources>("processResources") {
val props = mapOf("version" to version, "apiVersion" to apiVersion)
inputs.properties(props) // Indicates to rerun if version changes.
filesMatching(listOf("plugin.yml", "config.yml", "messages.yml")) {
expand(props) { escapeBackslash.set(true) } // Keep literal '\n' etc. intact in YAML comments/values.
}
from("LICENSE") { into("/") } // Bundle main GPLv2 license at jar root.
from("libs/License.txt") { // Bundle ProtocolLib GPLv2 license.
into("META-INF/licenses/ProtocolLib")
rename { "LICENSE" }
}
from("libs/TAB-OG/LICENSE") { // Bundle TAB-OG license.
into("META-INF/licenses/TAB-OG")
}
}
/* ---------------------------- Repos ---------------------------------- */
repositories {
mavenCentral() // Import the Maven Central Maven Repository.
gradlePluginPortal() // Import the Gradle Plugin Portal Maven Repository.
maven { url = uri("https://repo.purpurmc.org/snapshots") } // Import the PurpurMC Maven Repository.
maven { url = uri("https://repo.papermc.io/repository/maven-public/") } // PaperMC.
maven { url = uri("https://repo.essentialsx.net/releases/") } // EssentialsX.
maven { url = uri("https://jitpack.io") } // JitPack (VaultAPI, TrailGUI, OpenInv, Dynmap).
maven { url = uri("https://repo.citizensnpcs.co/") } // Citizens.
maven { url = uri("https://libraries.minecraft.net") } // Mojang Brigadier.
}
/* ---------------------- Java project deps ---------------------------- */
dependencies {
// Purpur API (server target).
compileOnly("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT")
// Import TrueOG Network Utilities-OG Java API (from source).
compileOnlyApi(project(":libs:Utilities-OG"))
// EssentialsX API.
compileOnly("net.essentialsx:EssentialsX:2.21.0") {
exclude(group = "org.bstats", module = "bstats-bukkit") // Exclude bstats.
}
// LuckPerms API (group, prefix, suffix lookups).
compileOnly("net.luckperms:api:5.5") // Import the LuckPerms API.
// ProtocolLib (local jar in libs/ProtocolLib/).
compileOnly(files("libs/ProtocolLib/ProtocolLib-5.0.jar"))
// TAB-OG API (local jar in libs/TAB-OG/).
compileOnly(files("libs/TAB-OG/tab-api-4.2.0.jar"))
// Citizens API.
compileOnly("net.citizensnpcs:citizensapi:2.0.28-SNAPSHOT")
// TrailGUI (via JitPack).
compileOnly("com.github.SinnDevelopment:TrailGUI:37659dda03")
// Import MiniPlaceholders API.
compileOnly("io.github.miniplaceholders:miniplaceholders-api:2.2.3")
// Mojang Brigadier (provided at runtime by Purpur).
compileOnly("com.mojang:brigadier:1.0.18")
}
apply(from = "eclipse.gradle.kts") // Import eclipse classpath support script.
/* ---------------------- Reproducible jars ---------------------------- */
tasks.withType<AbstractArchiveTask>().configureEach { // Ensure reproducible .jars
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}
/* ----------------------------- Shadow -------------------------------- */
tasks.shadowJar {
exclude("io.github.miniplaceholders.*") // Exclude the MiniPlaceholders package from being shadowed.
isEnableRelocation = true
relocationPrefix = "${project.group}.shadow"
mergeServiceFiles()
archiveClassifier.set("") // Use empty string instead of null.
archiveBaseName.set(rootProject.name) // Vanish-OG-${version}.jar
}
tasks.jar { archiveClassifier.set("part") } // Applies to root jarfile only.
tasks.build { dependsOn(tasks.spotlessApply, tasks.shadowJar) } // Build depends on spotless and shadow.
/* --------------------------- Javac opts ------------------------------- */
tasks.withType<JavaCompile>().configureEach {
options.compilerArgs.add("-parameters") // Enable reflection for java code.
options.isFork = true // Run javac in its own process.
options.compilerArgs.add("-Xlint:deprecation") // Trigger deprecation warning messages.
options.encoding = "UTF-8" // Use UTF-8 file encoding.
}
/* ----------------------------- Auto Formatting ------------------------ */
spotless {
java {
eclipse().configFile("config/formatter/eclipse-java-formatter.xml") // Eclipse java formatting.
leadingTabsToSpaces() // Convert leftover leading tabs to spaces.
removeUnusedImports() // Remove imports that aren't being called.
}
kotlinGradle {
ktfmt().kotlinlangStyle().configure { it.setMaxWidth(120) } // JetBrains Kotlin formatting.
target("build.gradle.kts", "settings.gradle.kts") // Gradle files to format.
}
}
checkstyle {
toolVersion = "10.18.1" // Declare checkstyle version to use.
configFile = file("config/checkstyle/checkstyle.xml") // Point checkstyle to config file.
isIgnoreFailures = true // Don't fail the build if checkstyle does not pass.
isShowViolations = true // Show the violations in any IDE with the checkstyle plugin.
}
tasks.named("compileJava") {
dependsOn("spotlessApply") // Run spotless before compiling with the JDK.
}
tasks.named("spotlessCheck") {
dependsOn("spotlessApply") // Run spotless before checking if spotless ran.
}
/* ------------------------------ Eclipse SHIM ------------------------- */
// This can't be put in eclipse.gradle.kts because Gradle is weird.
subprojects {
apply(plugin = "java-library")
apply(plugin = "eclipse")
eclipse.project.name = "${project.name}-${rootProject.name}"
tasks.withType<Jar>().configureEach { archiveBaseName.set("${project.name}-${rootProject.name}") }
}
+34
View File
@@ -0,0 +1,34 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="TreeWalker">
<module name="FinalLocalVariable"/>
<module name="AvoidStarImport"/>
<module name="Indentation">
<property name="severity" value="ignore"/>
</module>
</module>
<module name="RegexpSingleline">
<property name="format" value="\borg\.junit\.jupiter\.api\.Assertions\.fail\s*\(\s*&quot;Not yet implemented&quot;\s*\)\s*;"/>
<property name="message" value="Remove placeholder fail() and implement the test."/>
<property name="ignoreCase" value="true"/>
<property name="severity" value="warning"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="(?&lt;!\w)fail\s*\(\s*&quot;Not yet implemented&quot;\s*\)\s*;"/>
<property name="message" value="Remove placeholder fail() and implement the test."/>
<property name="severity" value="warning"/>
</module>
</module>
+404
View File
@@ -0,0 +1,404 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="23">
<profile kind="CodeFormatterProfile" name="TrueOG Network Formatting" version="23">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_switch_case_arrow_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_permitted_types" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_annotations" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.javadoc_do_not_separate_block_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case_after_arrow" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_switch_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_arrow" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.align_arrows_in_switch_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_switch_case_with_arrow_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_colon" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_switch_case_with_arrow" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assertion_message" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_permitted_types" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
+158
View File
@@ -0,0 +1,158 @@
/* This is free and unencumbered software released into the public domain */
import org.gradle.api.tasks.bundling.Jar
import org.gradle.plugins.ide.eclipse.model.EclipseModel
import java.nio.file.Files
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.transform.OutputKeys
import javax.xml.transform.TransformerFactory
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
val sourcePluginProjects =
configurations
.getByName("compileClasspath")
.allDependencies
.filterIsInstance<ProjectDependency>()
.map { it.path }
.filter { it.startsWith(":libs:") }
.distinct()
val sourcePluginProjectNames = sourcePluginProjects.map { it.substringAfterLast(":") }.toSet()
sourcePluginProjects.forEach { evaluationDependsOn(it) }
val ideLibs: Configuration by
configurations.creating {
isCanBeResolved = true
isCanBeConsumed = false
}
configure<EclipseModel> {
project {
name = "${rootProject.name}-Plugin"
}
classpath {
plusConfigurations.add(ideLibs)
}
}
val ideLibDir = layout.buildDirectory.dir("ide-libs")
val hashRegex = Regex("-[0-9a-fA-F]{10}(?=\\.jar$)") // Black magic.
val copyTasks = mutableListOf<TaskProvider<Copy>>()
sourcePluginProjects.forEach { path ->
val sub = project(path)
val archiveTaskName = if ("shadowJar" in sub.tasks.names) "shadowJar" else "jar"
val archiveTask = sub.tasks.named<Jar>(archiveTaskName)
val copyTask =
tasks.register<Copy>("ideCopy${sub.name.replaceFirstChar(Char::titlecase)}") {
dependsOn(archiveTask)
from(archiveTask.flatMap { it.archiveFile })
into(ideLibDir)
rename { it.replace(hashRegex, "") } // Remove git commit hash from jarfile.
}
copyTasks += copyTask
}
/* Ensure the jars exist before .classpath is generated */
tasks.named("eclipseClasspath").configure { dependsOn(copyTasks) }
/* Supply those jars to the ideLibs configuration (after evaluation) */
afterEvaluate { dependencies { add("ideLibs", fileTree(ideLibDir) { include("*.jar") }) } }
val injectIdeLibs =
tasks.register("injectIdeLibs") {
dependsOn("eclipse") // run after all eclipse files are generated
doLast {
val cpFile = file(".classpath")
if (!cpFile.exists()) return@doLast
val jars = fileTree(ideLibDir.get()) { include("*.jar") }.files.sortedBy { it.name }
if (jars.isEmpty()) return@doLast
// Parse DOM
val dbf = DocumentBuilderFactory.newInstance()
val doc = dbf.newDocumentBuilder().parse(cpFile)
val root = doc.documentElement
// Helper to see if an entry already exists
fun exists(path: String): Boolean =
root.getElementsByTagName("classpathentry").let { list ->
(0 until list.length).any { i ->
val n = list.item(i)
val kind = n.attributes?.getNamedItem("kind")?.nodeValue
val p = n.attributes?.getNamedItem("path")?.nodeValue
kind == "lib" && p == path
}
}
// Remove any entry that points to ide-libs dir or unresolved :libs: project refs.
val toRemove = mutableListOf<org.w3c.dom.Node>()
val list = root.getElementsByTagName("classpathentry")
val dirPath = ideLibDir.get().asFile.absolutePath
for (i in 0 until list.length) {
val n = list.item(i)
val kind = n.attributes?.getNamedItem("kind")?.nodeValue
val p = n.attributes?.getNamedItem("path")?.nodeValue ?: ""
val isIdeLibEntry = kind == "lib" && (p == dirPath || p.startsWith("$dirPath/"))
val sourceProjectPath = p.removePrefix("/")
val isHalfImportedSourceModule = kind == "src" && p.startsWith("/libs:")
val isSourcePluginModule = kind == "src" && sourceProjectPath in sourcePluginProjectNames
if (isIdeLibEntry || isHalfImportedSourceModule || isSourcePluginModule) {
toRemove += n
}
}
toRemove.forEach { root.removeChild(it) }
// Append our jar entries LAST
jars.forEach { f ->
val abs = f.absolutePath
if (!exists(abs)) {
val entry = doc.createElement("classpathentry")
entry.setAttribute("kind", "lib")
entry.setAttribute("path", abs)
root.appendChild(entry)
}
}
// Write back pretty
val tf =
TransformerFactory.newInstance().newTransformer().apply {
setOutputProperty(OutputKeys.INDENT, "yes")
setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "1")
setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no")
setOutputProperty(OutputKeys.ENCODING, "UTF-8")
}
Files.newBufferedWriter(cpFile.toPath()).use { w -> tf.transform(DOMSource(doc), StreamResult(w)) }
}
}
tasks.named("eclipse").configure { finalizedBy(injectIdeLibs) }
val eclipseModel = extensions.getByType<EclipseModel>()
fun Project.addResolvableEclipseConfigs() {
val jarAttr =
objects.named(org.gradle.api.attributes.LibraryElements::class, org.gradle.api.attributes.LibraryElements.JAR)
val apiAttr = objects.named(org.gradle.api.attributes.Usage::class, org.gradle.api.attributes.Usage.JAVA_API)
val compileOnlyRes =
configurations.create("eclipseCompileOnly") {
extendsFrom(configurations.getByName("compileOnly"))
isCanBeResolved = true
isCanBeConsumed = false
attributes.attribute(org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE, apiAttr)
attributes.attribute(org.gradle.api.attributes.LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, jarAttr)
}
val compileOnlyApiRes =
configurations.create("eclipseCompileOnlyApi") {
extendsFrom(configurations.getByName("compileOnlyApi"))
isCanBeResolved = true
isCanBeConsumed = false
attributes.attribute(org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE, apiAttr)
attributes.attribute(org.gradle.api.attributes.LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, jarAttr)
}
eclipseModel.classpath.plusConfigurations.addAll(listOf(compileOnlyRes, compileOnlyApiRes))
}
addResolvableEclipseConfigs()
Binary file not shown.
+7
View File
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored Executable
+251
View File
@@ -0,0 +1,251 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
+94
View File
@@ -0,0 +1,94 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
+339
View File
@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
Binary file not shown.
+174
View File
@@ -0,0 +1,174 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
Binary file not shown.
+1
Submodule libs/Utilities-OG added at 8b5c86cc9c.
-119
View File
@@ -1,119 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.myzelyam</groupId>
<artifactId>SuperVanish</artifactId>
<version>5.9.4</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>ess-repo</id>
<url>http://repo.ess3.net/content/groups/essentials</url>
</repository>
<repository>
<id>dmulloy2-repo</id>
<url>http://repo.dmulloy2.net/nexus/repository/public/</url>
</repository>
<repository>
<id>md_5-public</id>
<url>http://repo.md-5.net/content/groups/public/</url>
</repository>
<repository>
<id>pex-repo</id>
<url>http://pex-repo.aoeu.xyz</url>
</repository>
<repository>
<id>everything</id>
<url>http://repo.citizensnpcs.co</url>
</repository>
</repositories>
<dependencies>
<!--Spigot API-->
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!--Essentials API-->
<dependency>
<groupId>net.ess3</groupId>
<artifactId>Essentials</artifactId>
<version>2.13-SNAPSHOT</version>
</dependency>
<!--ProtocolLib-->
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib-API</artifactId>
<version>4.2.1</version>
</dependency>
<!--LibsDisguises-->
<dependency>
<groupId>LibsDisguises</groupId>
<artifactId>LibsDisguises</artifactId>
<version>9.0.7</version>
</dependency>
<!--PermissionsEx-->
<dependency>
<groupId>ru.tehkode</groupId>
<artifactId>PermissionsEx</artifactId>
<version>1.23.2-SNAPSHOT</version>
</dependency>
<!--Citizens API-->
<dependency>
<groupId>net.citizensnpcs</groupId>
<artifactId>citizensapi</artifactId>
<version>2.0.18-SNAPSHOT</version>
<type>jar</type>
</dependency>
<!--TrailGUI-->
<dependency>
<groupId>ca.jamiesinn.trailgui</groupId>
<artifactId>TrailGUI</artifactId>
<scope>system</scope>
<systemPath>${basedir}/dependencies/TrailGUI-5.2-SNAPSHOT.jar</systemPath>
</dependency>
<!--DisguiseCraft-->
<dependency>
<groupId>pgDev.bukkit</groupId>
<artifactId>DisguiseCraft</artifactId>
<scope>system</scope>
<systemPath>${basedir}/dependencies/DisguiseCraft.jar</systemPath>
</dependency>
<!--Dynmap-->
<dependency>
<groupId>org.dynmap</groupId>
<artifactId>Dynmap</artifactId>
<scope>system</scope>
<systemPath>${basedir}/dependencies/dynmap-2.4.jar</systemPath>
</dependency>
<!--SuperTrails-->
<dependency>
<groupId>me.kvq.plugin.trails</groupId>
<artifactId>SuperTrails</artifactId>
<scope>system</scope>
<systemPath>${basedir}/dependencies/SuperTrails.jar</systemPath>
</dependency>
</dependencies>
</project>
+13
View File
@@ -0,0 +1,13 @@
rootProject.name = "Vanish-OG"
ProcessBuilder("sh", "bootstrap.sh").directory(rootDir).inheritIO().start().let {
if (it.waitFor() != 0) throw GradleException("bootstrap.sh failed")
}
file("libs")
.listFiles()
?.filter { it.isDirectory && !it.name.startsWith(".") }
?.forEach { dir ->
include(":libs:${dir.name}")
project(":libs:${dir.name}").projectDir = dir
}
@@ -1,52 +1,68 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.api.vanish;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
public class PlayerHideEvent extends Event implements Cancellable {
public class PlayerHideEvent extends PlayerEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean silent;
private boolean isCancelled = false;
private Player player;
public PlayerHideEvent(Player p, boolean silent) {
super(p);
this.silent = silent;
public PlayerHideEvent(Player player) {
this.player = player;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* @return The player
*/
public Player getPlayer() {
return player;
public boolean isSilent() {
return silent;
}
public void setSilent(boolean silent) {
this.silent = silent;
}
@Override
public boolean isCancelled() {
return this.isCancelled;
return isCancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.isCancelled = cancel;
isCancelled = cancel;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}
@@ -1,52 +1,68 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.api.vanish;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
public class PlayerShowEvent extends Event implements Cancellable {
public class PlayerShowEvent extends PlayerEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean silent;
private boolean isCancelled = false;
private Player player;
public PlayerShowEvent(Player p, boolean silent) {
super(p);
this.silent = silent;
public PlayerShowEvent(Player player) {
this.player = player;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* @return The player
*/
public Player getPlayer() {
return player;
public boolean isSilent() {
return silent;
}
public void setSilent(boolean silent) {
this.silent = silent;
}
@Override
public boolean isCancelled() {
return this.isCancelled;
return isCancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.isCancelled = cancel;
isCancelled = cancel;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}
@@ -0,0 +1,123 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.api.vanish;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import java.util.UUID;
public class PlayerVanishStateChangeEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private final boolean vanishing;
private final UUID uuid;
private final String name;
private final String cause;
private boolean isCancelled = false;
public PlayerVanishStateChangeEvent(UUID uuid, String name, boolean vanishing, String cause) {
this.vanishing = vanishing;
this.uuid = uuid;
this.name = name;
this.cause = cause;
}
public PlayerVanishStateChangeEvent(Player player, boolean vanishing, String cause) {
this(player.getUniqueId(), player.getName(), vanishing, cause);
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public boolean isCancelled() {
return isCancelled;
}
/**
* Cancels the operation, it's recommended to send a message to the cause
*/
@Override
public void setCancelled(boolean cancel) {
isCancelled = cancel;
}
/**
* @return TRUE if the player is vanishing, FALSE if the player is reappearing
*/
public boolean isVanishing() {
return vanishing;
}
/**
* @return The name of the player who is vanishing/reappearing
*/
public String getName() {
return name;
}
/**
* @return The UUID of the player who is vanishing/reappearing
*/
public UUID getUUID() {
return uuid;
}
/**
* @return The Bukkit Player who is vanishing/reappearing, or null if the player
* is not currently online
*/
public Player getPlayer() {
return Bukkit.getPlayer(uuid);
}
/**
* @return The name of the command sender who caused the vanish state change or
* null if the cause is either not specified or it's SuperVanish itself,
* please note that if this returns 'CONSOLE' then it's the console
* which caused this state change
*/
public String getCause() {
return cause;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}
@@ -0,0 +1,46 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.api.vanish;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
public class PostPlayerHideEvent extends PlayerEvent {
private static final HandlerList handlers = new HandlerList();
private final boolean silent;
public PostPlayerHideEvent(Player p, boolean silent) {
super(p);
this.silent = silent;
}
public static HandlerList getHandlerList() {
return handlers;
}
public boolean isSilent() {
return silent;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}
@@ -0,0 +1,46 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.api.vanish;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
public class PostPlayerShowEvent extends PlayerEvent {
private static final HandlerList handlers = new HandlerList();
private final boolean silent;
public PostPlayerShowEvent(Player p, boolean silent) {
super(p);
this.silent = silent;
}
public static HandlerList getHandlerList() {
return handlers;
}
public boolean isSilent() {
return silent;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}
@@ -1,16 +1,16 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.api.vanish;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.config.MessagesFile;
import de.myzelyam.supervanish.config.SettingsFile;
import de.myzelyam.supervanish.utils.Validation;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
@@ -18,42 +18,57 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* Static API for SuperVanish on Bukkit
*/
@SuppressWarnings("unused")
public class VanishAPI {
private static SuperVanish plugin;
private static SuperVanish PLUGIN;
/**
* @return A list of the UUIDs of all online vanished players
* @return A collection of the UUIDs of all online vanished players
*/
public static List<UUID> getInvisiblePlayers() {
List<UUID> uuids = new ArrayList<>();
for (String uuidStr : plugin.playerData.getStringList("InvisiblePlayers")) {
UUID uuid = UUID.fromString(uuidStr);
if (Bukkit.getPlayer(uuid) != null)
uuids.add(uuid);
}
return uuids;
return new ArrayList<>(PLUGIN.getVanishStateMgr().getOnlineVanishedPlayers());
}
/**
* @return A list of the UUIDs of all vanished players, both online and offline
* @return A collection of the UUIDs of all vanished players, both online and
* offline players
*/
public static List<UUID> getAllInvisiblePlayers() {
List<UUID> uuids = new ArrayList<>();
for (String uuidStr : plugin.playerData.getStringList("InvisiblePlayers")) {
UUID uuid = UUID.fromString(uuidStr);
uuids.add(uuid);
}
return uuids;
return new ArrayList<>(PLUGIN.getVanishStateMgr().getVanishedPlayers());
}
/**
* @param p - the player.
* @return TRUE if the player is invisible, FALSE otherwise.
* Checks if a player is vanished.
*
* @param uuid - the player's UUID.
* @return TRUE if the player is vanished, FALSE otherwise.
*/
public static boolean isInvisible(Player p) {
if (p == null) throw new IllegalArgumentException("player cannot be null");
return plugin.playerData.getStringList("InvisiblePlayers").contains(p.getUniqueId().toString());
public static boolean isVanished(UUID uuid) {
Validation.checkNotNull("UUID cannot be null!", uuid);
return PLUGIN.getVanishStateMgr().isVanished(uuid);
}
/**
* Checks if a player is vanished.
*
* @param player - the player.
* @return TRUE if the player is vanished, FALSE otherwise.
*/
public static boolean isVanished(Player player) {
Validation.checkNotNull("Player cannot be null!", player);
return PLUGIN.getVanishStateMgr().isVanished(player);
}
/**
@@ -62,59 +77,66 @@ public class VanishAPI {
* @param p - the player.
*/
public static void hidePlayer(Player p) {
if (p == null) throw new IllegalArgumentException("player cannot be null");
plugin.getVisibilityAdjuster().hidePlayer(p);
Validation.checkNotNull("Player cannot be null!", p);
PLUGIN.getVisibilityChanger().hidePlayer(p);
}
/**
* * Shows a player using SuperVanish
* Shows a player using SuperVanish
*
* @param p - the player.
*/
public static void showPlayer(Player p) {
if (p == null) throw new IllegalArgumentException("player cannot be null");
plugin.getVisibilityAdjuster().showPlayer(p);
Validation.checkNotNull("Player cannot be null!", p);
PLUGIN.getVisibilityChanger().showPlayer(p);
}
/**
* * Checks if a player is allowed to see another player
* Checks if a player is allowed to see another player
*
* @param viewer - the viewer
* @param viewed - the viewed player
* @return TRUE if viewed is not vanished or viewer has the permission to see viewed
* @return TRUE if viewed is not vanished or viewer has the permission to see
* viewed
*/
public static boolean canSee(Player viewer, Player viewed) {
return plugin.canSee(viewer, viewed);
return PLUGIN.canSee(viewer, viewed);
}
public static FileConfiguration getConfiguration() {
return plugin.settings;
return PLUGIN.getSettings();
}
public static FileConfiguration getMessages() {
return plugin.messages;
}
public static FileConfiguration getPlayerData() {
return plugin.playerData;
return PLUGIN.getMessages();
}
public static void reloadConfig() {
// messages
plugin.messagesFile = new MessagesFile();
plugin.messagesFile.saveDefaultConfig();
plugin.messages = plugin.messagesFile.getConfig();
// config
plugin.settingsFile = new SettingsFile();
plugin.settingsFile.saveDefaultConfig();
plugin.settings = plugin.settingsFile.getConfig();
PLUGIN.reload();
}
public static SuperVanish getPlugin() {
return plugin;
return PLUGIN;
}
public static void setPlugin(SuperVanish plugin) {
VanishAPI.plugin = plugin;
VanishAPI.PLUGIN = plugin;
}
}
}
@@ -0,0 +1,90 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
public class LayeredPermissionChecker {
private final SuperVanish plugin;
private final FileConfiguration settings;
public LayeredPermissionChecker(SuperVanish plugin) {
this.plugin = plugin;
settings = plugin.getSettings();
}
/**
* @return TRUE if sender has *permission* to use /sv on, else FALSE; TRUE
* doesn't mean that sender can actually use /sv on
*/
public boolean hasPermissionToVanish(CommandSender sender) {
if (settings.getBoolean("IndicationFeatures.LayeredPermissions.LayeredSeeAndUsePermissions", false)) {
if (sender.hasPermission("sv.use"))
return true;
int permissionLevel;
if (sender instanceof Player)
permissionLevel = plugin.getVanishPlayer((Player) sender).getUsePermissionLevel();
else
permissionLevel = getLayeredPermissionLevel(sender, "use");
return permissionLevel > 0 && sender.hasPermission("sv.use.level" + permissionLevel);
} else
return sender.hasPermission("sv.use");
}
public boolean hasPermissionToSee(Player viewer, Player viewed) {
if (viewer == null)
throw new IllegalArgumentException("viewer cannot be null");
if (viewer == viewed)
return true;
if (settings.getBoolean("IndicationFeatures.LayeredPermissions.LayeredSeeAndUsePermissions", false)) {
VanishPlayer vanishViewer = plugin.getVanishPlayer(viewer);
VanishPlayer vanishViewed = plugin.getVanishPlayer(viewed);
int viewerLevel = vanishViewer.getSeePermissionLevel();
if (viewerLevel == 0)
return false;
int viewedLevel = Math.max(1, vanishViewed.getUsePermissionLevel());
return viewerLevel >= viewedLevel;
} else {
boolean enableSeePermission = settings
.getBoolean("IndicationFeatures.LayeredPermissions.EnableSeePermission", true);
return enableSeePermission && viewer.hasPermission("sv.see");
}
}
public int getLayeredPermissionLevel(CommandSender sender, String permission) {
boolean enableSeePermission = settings.getBoolean("IndicationFeatures.LayeredPermissions.EnableSeePermission",
true);
if (!enableSeePermission && permission.equalsIgnoreCase("see"))
return 0;
int maxLevel = settings.getInt("IndicationFeatures.LayeredPermissions.MaxLevel", 100);
int level = sender.hasPermission("sv." + permission) ? 1 : 0;
for (int i = 1; i <= maxLevel; i++)
if (sender.hasPermission("sv." + permission + ".level" + i))
level = i;
return level;
}
}
@@ -0,0 +1,304 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.User;
import de.myzelyam.supervanish.utils.Validation;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.luckperms.api.LuckPerms;
import net.luckperms.api.LuckPermsProvider;
import net.luckperms.api.cacheddata.CachedMetaData;
import net.trueog.utilitiesog.UtilitiesOG;
public class PlaceholderConverter {
private static final LegacyComponentSerializer LEGACY_SERIALIZER = LegacyComponentSerializer.legacySection();
public PlaceholderConverter(SuperVanish plugin) {
}
public String replacePlaceholders(String msg, Object... additionalPlayerInfo) {
return LEGACY_SERIALIZER.serialize(expandPlaceholders(msg, additionalPlayerInfo));
}
public Component expandPlaceholders(String msg, Object... additionalPlayerInfo) {
return expandPlaceholders(null, msg, additionalPlayerInfo);
}
public Component expandPlaceholders(CommandSender recipient, String msg, Object... additionalPlayerInfo) {
Validation.checkNotNull("Failed to replace variables (Illegal arguments)", msg, additionalPlayerInfo);
final PlaceholderContext context = parseContext(additionalPlayerInfo);
final String preparedMessage = applyInlinePlaceholders(msg.replace("\\n", "\n"), context);
if (recipient instanceof Player player) {
if (context.primaryPlayer != null) {
return UtilitiesOG.trueogExpand(preparedMessage, player, context.primaryPlayer);
}
return UtilitiesOG.trueogExpand(preparedMessage, player);
}
if (context.primaryPlayer != null) {
return UtilitiesOG.trueogExpand(preparedMessage, context.primaryPlayer);
}
return UtilitiesOG.trueogExpand(preparedMessage);
}
public static MessagePlaceholder placeholder(String name, Object value) {
return new MessagePlaceholder(name, value == null ? "" : String.valueOf(value));
}
private PlaceholderContext parseContext(Object... additionalPlayerInfo) {
final PlaceholderContext context = new PlaceholderContext();
if (additionalPlayerInfo == null) {
return context;
}
for (Object entry : additionalPlayerInfo) {
if (entry instanceof MessagePlaceholder messagePlaceholder) {
context.inlinePlaceholders.add(messagePlaceholder);
continue;
}
if (context.primaryObject == null) {
context.primaryObject = entry;
if (entry instanceof Player player) {
context.primaryPlayer = player;
}
continue;
}
if (context.otherName == null && (entry instanceof Player || entry instanceof String)) {
if (entry instanceof Player player) {
context.otherName = player.getName();
} else {
context.otherName = String.valueOf(entry);
}
}
}
return context;
}
private String applyInlinePlaceholders(String message, PlaceholderContext context) {
message = replaceTag(message, "sv_player_name", getPrimaryName(context.primaryObject));
message = replaceTag(message, "sv_player_display_name", getPrimaryDisplayName(context.primaryObject));
message = replaceTag(message, "sv_player_tab_name", getPrimaryTabName(context.primaryObject));
message = replaceTag(message, "sv_player_prefix", getPrimaryPrefix(context.primaryObject));
message = replaceTag(message, "sv_player_suffix", getPrimarySuffix(context.primaryObject));
message = replaceTag(message, "sv_player_group", getPrimaryGroup(context.primaryObject));
message = replaceTag(message, "sv_player_nick", getPrimaryNick(context.primaryObject));
message = replaceTag(message, "sv_other_name", context.otherName != null ? context.otherName : "UNKNOWN");
for (MessagePlaceholder inlinePlaceholder : context.inlinePlaceholders) {
message = replaceTag(message, inlinePlaceholder.name(), inlinePlaceholder.value());
}
return message;
}
private String getPrimaryName(Object primaryObject) {
if (primaryObject instanceof OfflinePlayer offlinePlayer) {
return offlinePlayer.getName();
}
if (primaryObject instanceof CommandSender) {
return "Console";
}
return "";
}
private String getPrimaryDisplayName(Object primaryObject) {
if (primaryObject instanceof Player player) {
return LEGACY_SERIALIZER.serialize(player.displayName());
}
return getPrimaryName(primaryObject);
}
private String getPrimaryTabName(Object primaryObject) {
if (primaryObject instanceof Player player) {
return LEGACY_SERIALIZER.serialize(player.playerListName());
}
return getPrimaryName(primaryObject);
}
private String getPrimaryNick(Object primaryObject) {
if (!(primaryObject instanceof Player player) || Bukkit.getPluginManager().getPlugin("Essentials") == null) {
return getPrimaryName(primaryObject);
}
final Essentials essentials = (Essentials) Bukkit.getServer().getPluginManager().getPlugin("Essentials");
final User user = essentials.getUser(player);
if (user == null || user.getNickname() == null) {
return player.getName();
}
return user.getNickname();
}
private String getPrimaryGroup(Object primaryObject) {
if (!(primaryObject instanceof OfflinePlayer offlinePlayer)) {
return "";
}
if (Bukkit.getPluginManager().getPlugin("LuckPerms") == null) {
return "";
}
try {
final LuckPerms luckPerms = LuckPermsProvider.get();
final net.luckperms.api.model.user.User user = luckPerms.getUserManager()
.getUser(offlinePlayer.getUniqueId());
return user == null ? "" : user.getPrimaryGroup();
} catch (IllegalStateException ignored) {
return "";
}
}
private String getPrimaryPrefix(Object primaryObject) {
final CachedMetaData metaData = getPrimaryMetaData(primaryObject);
return metaData == null || metaData.getPrefix() == null ? "" : metaData.getPrefix();
}
private String getPrimarySuffix(Object primaryObject) {
final CachedMetaData metaData = getPrimaryMetaData(primaryObject);
return metaData == null || metaData.getSuffix() == null ? "" : metaData.getSuffix();
}
private CachedMetaData getPrimaryMetaData(Object primaryObject) {
if (!(primaryObject instanceof OfflinePlayer offlinePlayer)
|| Bukkit.getPluginManager().getPlugin("LuckPerms") == null)
{
return null;
}
try {
final LuckPerms luckPerms = LuckPermsProvider.get();
final net.luckperms.api.model.user.User user = luckPerms.getUserManager()
.getUser(offlinePlayer.getUniqueId());
return user == null ? null : user.getCachedData().getMetaData();
} catch (IllegalStateException ignored) {
return null;
}
}
private String replaceTag(String message, String tagName, String value) {
return message.replace("<" + tagName + ">", value == null ? "" : value);
}
public record MessagePlaceholder(String name, String value) {
}
private static final class PlaceholderContext {
private Object primaryObject;
private Player primaryPlayer;
private String otherName;
private final List<MessagePlaceholder> inlinePlaceholders = new ArrayList<>();
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,28 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish;
import de.myzelyam.supervanish.visibility.VanishStateMgr;
import java.util.logging.Level;
import java.util.logging.Logger;
public interface SuperVanishPlugin {
void log(Level level, String msg);
void log(Level level, String msg, Throwable ex);
Logger getLogger();
void logException(Throwable e);
VanishStateMgr getVanishStateMgr();
}
@@ -0,0 +1,97 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish;
import org.bukkit.entity.Player;
import java.util.Objects;
import java.util.UUID;
/**
* Holds additional information about players in the context of vanishing
*/
public class VanishPlayer {
private final SuperVanish plugin;
private final UUID playerUUID;
private boolean itemPickUps;
private int seePermissionLevel, usePermissionLevel;
VanishPlayer(Player player, SuperVanish plugin, boolean itemPickUps) {
this.plugin = plugin;
this.playerUUID = player.getUniqueId();
this.itemPickUps = itemPickUps;
if (plugin.getSettings().getBoolean("IndicationFeatures.LayeredPermissions.LayeredSeeAndUsePermissions",
false))
{
seePermissionLevel = plugin.getLayeredPermissionLevel(player, "see");
usePermissionLevel = plugin.getLayeredPermissionLevel(player, "use");
}
}
public boolean isOnlineVanished() {
return plugin.getVanishStateMgr().isVanished(playerUUID);
}
public boolean hasItemPickUpsEnabled() {
return itemPickUps;
}
public UUID getPlayerUUID() {
return playerUUID;
}
public void setItemPickUps(boolean itemPickUps) {
this.itemPickUps = itemPickUps;
}
public int getSeePermissionLevel() {
return seePermissionLevel;
}
public int getUsePermissionLevel() {
return usePermissionLevel;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
VanishPlayer that = (VanishPlayer) o;
return Objects.equals(playerUUID, that.playerUUID);
}
@Override
public int hashCode() {
return Objects.hash(playerUUID);
}
}
@@ -1,43 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.cmd;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import java.util.List;
import java.util.UUID;
public class CmdList extends SubCommand {
public CmdList(SuperVanish plugin, CommandSender p, String[] args, String label) {
super(plugin);
if (canDo(p, CommandAction.LIST)) {
String listMessage = getMsg("ListMessage");
StringBuffer stringBuffer = new StringBuffer();
List<String> allInvisiblePlayers = getAllInvisiblePlayers();
if (allInvisiblePlayers.size() == 0) {
stringBuffer = stringBuffer.append("none");
}
for (int i = 0; i < allInvisiblePlayers.size(); i++) {
String uuidString = allInvisiblePlayers.get(i);
UUID playerUUID = UUID.fromString(uuidString);
String name = Bukkit.getOfflinePlayer(playerUUID).getName();
if (Bukkit.getPlayer(playerUUID) == null) {
name = name + ChatColor.RED + "[offline]" + ChatColor.WHITE;
}
stringBuffer = stringBuffer.append(name);
if (i != (allInvisiblePlayers.size() - 1))
stringBuffer = stringBuffer.append(ChatColor.GREEN).append(", ").append(ChatColor.WHITE);
}
listMessage = listMessage.replace("%l", stringBuffer.toString());
p.sendMessage(convertString(listMessage, p));
}
}
}
@@ -1,21 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.cmd;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
public class CmdLogin extends SubCommand {
public CmdLogin(SuperVanish plugin, CommandSender p, String[] args, String label) {
super(plugin);
if (canDo(p, CommandAction.LOGIN)) {
Bukkit.broadcastMessage(convertString(getMsg("ReappearMessage"), p));
}
}
}
@@ -1,21 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.cmd;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
public class CmdLogout extends SubCommand {
public CmdLogout(SuperVanish plugin, CommandSender p, String[] args, String label) {
super(plugin);
if (canDo(p, CommandAction.LOGOUT)) {
Bukkit.broadcastMessage(convertString(getMsg("VanishMessage"), p));
}
}
}
@@ -1,30 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.cmd;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.config.MessagesFile;
import de.myzelyam.supervanish.config.SettingsFile;
import org.bukkit.command.CommandSender;
public class CmdReload extends SubCommand {
public CmdReload(SuperVanish plugin, CommandSender p, String[] args, String label) {
super(plugin);
if (canDo(p, CommandAction.RELOAD)) {
// messages
plugin.messagesFile = new MessagesFile();
plugin.messagesFile.saveDefaultConfig();
plugin.messages = plugin.messagesFile.getConfig();
// config
plugin.settingsFile = new SettingsFile();
plugin.settingsFile.saveDefaultConfig();
plugin.settings = plugin.settingsFile.getConfig();
p.sendMessage(convertString(getMsg("ConfigReloadedMessage"), p).split("\\n"));
}
}
}
@@ -1,32 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.cmd;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class CmdToggleItemPickups extends SubCommand {
public CmdToggleItemPickups(SuperVanish plugin, CommandSender sender, String[] args, String label) {
super(plugin);
if (canDo(sender, CommandAction.TOGGLE_ITEM_PICKUPS)) {
Player p = (Player) sender;
p.sendMessage(convertString(getMsg("ToggledPickingUpItems"
+ (toggleState(p) ? "On" : "Off")), p));
}
}
private boolean toggleState(Player player) {
boolean hasEnabled = playerData.getBoolean("PlayerData."
+ player.getUniqueId().toString() + ".itemPickUps");
playerData.set("PlayerData." + player.getUniqueId().toString() + ".itemPickUps",
!hasEnabled);
plugin.savePlayerData();
return !hasEnabled;
}
}
@@ -1,79 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.cmd;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import java.io.File;
public class CmdUpdateCfg extends SubCommand {
public CmdUpdateCfg(SuperVanish plugin, CommandSender player, String[] args, String label) {
super(plugin);
if (canDo(player, CommandAction.UPDATE_CFG)) {
// get changes and updates
String updates;
String changes;
if (plugin.requiresCfgUpdate && plugin.requiresMsgUpdate) {
updates = "the config and the messages";
changes = "all settings and messages";
} else if (plugin.requiresCfgUpdate) {
updates = "the config";
changes = "all settings";
} else {
updates = "the messages";
changes = "all messages";
}
if (args.length != 2) {
if ((!plugin.requiresCfgUpdate) && (!plugin.requiresMsgUpdate)) {
player.sendMessage(convertString(
getMsg("NoConfigUpdateAvailableMessage"), player));
return;
}
player.sendMessage(convertString(getMsg("UpdateWarningMessage"), player)
.replace("%changes", changes).replace("%updates",
updates));
return;
}
if (args[1].equalsIgnoreCase("confirm")) {
if (!plugin.requiresCfgUpdate && !plugin.requiresMsgUpdate) {
player.sendMessage(convertString(
getMsg("NoConfigUpdateAvailableMessage"), player));
return;
}
// delete necessary files
boolean success = true;
if (plugin.requiresCfgUpdate) {
File configFile = new File(plugin.getDataFolder().getPath()
+ File.separator + "config.yml");
success = configFile.delete();
plugin.settingsFile.saveDefaultConfig();
plugin.settingsFile.reloadConfig();
plugin.settings = plugin.settingsFile.getConfig();
}
if (plugin.requiresMsgUpdate) {
File messagesFile = new File(plugin.getDataFolder().getPath()
+ File.separator + "messages.yml");
success &= messagesFile.delete();
plugin.messagesFile.saveDefaultConfig();
plugin.messagesFile.reloadConfig();
plugin.messages = plugin.messagesFile.getConfig();
}
if (success)
player.sendMessage(convertString(getMsg("UpdatedConfigMessage"), player)
.replace("%changes", changes).replace("%updates",
updates));
else
player.sendMessage(ChatColor.DARK_RED + "[PV] ERROR: Failed to delete old config file.");
// update update-information
plugin.checkConfig();
}
}
}
}
@@ -1,55 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.cmd;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.utils.PlayerCache;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Collection;
public class CmdVanish extends SubCommand {
public CmdVanish(SuperVanish plugin, CommandSender sender, String[] args, String label) {
super(plugin);
if (hasLayeredAccess(sender) || canDo(sender, CommandAction.VANISH_SELF)) {
Player p = (Player) sender;
Collection<Player> onlineInvisiblePlayers = getOnlineInvisiblePlayers();
if (args.length == 0) {
if (onlineInvisiblePlayers.contains(p))
showPlayer(p);
else
hidePlayer(p);
} else if (args.length == 1) {
if (args[0].equalsIgnoreCase("off")) {
if (!onlineInvisiblePlayers.contains(p)) {
p.sendMessage(convertString(
getMsg("OnReappearWhileVisible"), p));
return;
}
showPlayer(p);
} else if (args[0].equalsIgnoreCase("on")) {
if (onlineInvisiblePlayers.contains(p)) {
p.sendMessage(convertString(
getMsg("OnVanishWhileInvisible"), p));
return;
}
hidePlayer(p);
}
}
}
}
private boolean hasLayeredAccess(CommandSender sender) {
if (!(sender instanceof Player)) return false;
Player p = (Player) sender;
int level = PlayerCache.fromPlayer(p).getUsePermissionLevel();
return level > 0 && p.hasPermission("sv.use.level" + level);
}
}
@@ -1,58 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.cmd;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Collection;
public class CmdVanishOther extends SubCommand {
public CmdVanishOther(SuperVanish plugin, CommandSender sender, String[] args, String label) {
super(plugin);
if (canDo(sender, CommandAction.VANISH_OTHER)) {
if (args.length < 2) {
sender.sendMessage(convertString(getMsg("InvalidUsageMessage"), sender));
return;
}
Collection<Player> onlineInvisiblePlayers = getOnlineInvisiblePlayers();
boolean hide = false;
switch (args[0]) {
case "on":
hide = true;
}
Player p = Bukkit.getPlayer(args[1]);
if (p == null) {
sender.sendMessage(
convertString(getMsg("PlayerNotOnlineMessage"), sender));
return;
}
// check
if (hide && onlineInvisiblePlayers.contains(p)) {
sender.sendMessage(
convertString(getMsg("AlreadyInvisibleMessage"), p));
return;
} else if (!hide && !onlineInvisiblePlayers.contains(p)) {
sender.sendMessage(
convertString(getMsg("AlreadyVisibleMessage"), p));
return;
}
// hide
if (hide) {
hidePlayer(p);
sender.sendMessage(convertString(getMsg("HideOtherMessage"), p));
// show
} else {
showPlayer(p);
sender.sendMessage(convertString(getMsg("ShowOtherMessage"), p));
}
}
}
}
@@ -1,93 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.cmd;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class CommandMgr {
public CommandMgr(SuperVanish plugin, Command cmd, CommandSender sender, String[] args,
String label) {
try {
if (label.equalsIgnoreCase("vlist")) {
new CmdList(plugin, sender, args, label);
return;
}
if (cmd.getName().equalsIgnoreCase("sv")) {
if (args.length == 0) {
if (sender instanceof Player)
new CmdVanish(plugin, sender, args, label);
else
sender.sendMessage(plugin.convertString(
plugin.getMsg("InvalidUsageMessage"), sender));
return;
}
if (args[0].equalsIgnoreCase("updateCfg")) {
new CmdUpdateCfg(plugin, sender, args, label);
return;
}
if (args.length == 1) {
if (args[0].equalsIgnoreCase("reload")
|| args[0].equalsIgnoreCase("rl")) {
new CmdReload(plugin, sender, args, label);
return;
}
if (args[0].equalsIgnoreCase("list")) {
new CmdList(plugin, sender, args, label);
return;
}
if (args[0].equalsIgnoreCase("on")
|| args[0].equalsIgnoreCase("off")) {
new CmdVanish(plugin, sender, args, label);
return;
}
if (args[0].equalsIgnoreCase("toggleitempickups")
|| args[0].equalsIgnoreCase("toggleitempickup")
|| args[0].equalsIgnoreCase("toggleitem")
|| args[0].equalsIgnoreCase("toggleitems")
|| args[0].equalsIgnoreCase("togglepickup")
|| args[0].equalsIgnoreCase("togglepickups")
|| args[0].equalsIgnoreCase("pickup")
|| args[0].equalsIgnoreCase("pickups")
|| args[0].equalsIgnoreCase("tipu")
|| args[0].equalsIgnoreCase("tip")) {
new CmdToggleItemPickups(plugin, sender, args, label);
return;
}
sender.sendMessage(plugin.convertString(
plugin.getMsg("InvalidUsageMessage"), sender));
return;
}
if (args.length == 2) {
if (args[0].equalsIgnoreCase("on")
|| args[0].equalsIgnoreCase("off")) {
new CmdVanishOther(plugin, sender, args, label);
return;
}
sender.sendMessage(plugin.convertString(
plugin.getMsg("InvalidUsageMessage"), sender));
return;
}
sender.sendMessage(
plugin.convertString(plugin.getMsg("InvalidUsageMessage"), sender));
return;
}
if (cmd.getName().equalsIgnoreCase("vlogin")) {
new CmdLogin(plugin, sender, args, label);
return;
}
if (cmd.getName().equalsIgnoreCase("vlogout")) {
new CmdLogout(plugin, sender, args, label);
}
} catch (Exception e) {
plugin.printException(e);
}
}
}
@@ -1,97 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.cmd;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import java.util.Collection;
import java.util.List;
public abstract class SubCommand {
protected final SuperVanish plugin;
protected final FileConfiguration settings;
protected final FileConfiguration playerData;
public SubCommand(SuperVanish plugin) {
this.plugin = plugin;
settings = plugin.settings;
playerData = plugin.playerData;
}
protected List<String> getAllInvisiblePlayers() {
return plugin.getAllInvisiblePlayers();
}
protected Collection<Player> getOnlineInvisiblePlayers() {
return plugin.getOnlineInvisiblePlayers();
}
public void hidePlayer(Player p) {
plugin.getVisibilityAdjuster().hidePlayer(p);
}
public void showPlayer(Player p) {
plugin.getVisibilityAdjuster().showPlayer(p);
}
public void showPlayer(Player p, boolean hideJoinMsg) {
plugin.getVisibilityAdjuster().showPlayer(p, hideJoinMsg);
}
protected boolean isVanished(Player p) {
return getOnlineInvisiblePlayers().contains(p);
}
protected boolean canDo(CommandSender p, CommandAction cmd) {
if (!(p instanceof Player))
if (!cmd.canConsole()) {
p.sendMessage(convertString(getMsg("InvalidSenderMessage"), p));
return false;
}
if (!p.hasPermission(cmd.getPerm())) {
p.sendMessage(convertString(getMsg("NoPermissionMessage"), p));
return false;
}
return true;
}
protected String getMsg(String msg) {
return plugin.getMsg(msg);
}
protected String convertString(String message, CommandSender p) {
return plugin.convertString(message, p);
}
protected enum CommandAction {
VANISH_SELF("sv.use", false), VANISH_OTHER("sv.others", true), LIST(
"sv.list", true), LOGIN("sv.login", false), LOGOUT("sv.logout",
false), TOGGLE_ITEM_PICKUPS("sv.toggleitempickups", false), UPDATE_CFG(
"sv.updatecfg", true), RELOAD("sv.reload", true);
private String perm;
private boolean console;
CommandAction(String perm, boolean console) {
this.perm = perm;
this.console = console;
}
String getPerm() {
return perm;
}
boolean canConsole() {
return console;
}
}
}
@@ -0,0 +1,145 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.utils.Validation;
import org.bukkit.command.CommandSender;
import java.util.ArrayList;
import java.util.List;
public enum CommandAction {
VANISH_SELF("sv.use", false, "/sv [on|off]", "Toggles your visibility") {
@Override
public boolean checkPermission(CommandSender sender, SuperVanish plugin) {
Validation.checkNotNull(plugin, "plugin cannot be null");
return plugin.hasPermissionToVanish(sender);
}
},
VANISH_OTHER("sv.others", true, "/sv [on|off] <player>", "Shows or hides a player"),
VANISHED_LIST("sv.list", true, "/sv list", "Shows a list of vanished players"),
BROADCAST_LOGIN("sv.login", false, "/sv login", "Broadcasts a fake login message"),
BROADCAST_LOGOUT("sv.logout", false, "/sv logout", "Broadcasts a fake logout message"),
TOGGLE_ITEM_PICKUPS("sv.toggleitems", false, "/sv tipu", "Toggles picking up items")
{
@Override
public boolean checkPermission(CommandSender sender, SuperVanish plugin) {
return sender.hasPermission(getMainPermission()) || sender.hasPermission("sv.toggleitempickups");
}
},
RECREATE_FILES("sv.recreatefiles", true, "/sv recreatefiles", "Recreates the config")
{
@Override
public boolean checkPermission(CommandSender sender, SuperVanish plugin) {
return sender.hasPermission(getMainPermission()) || sender.hasPermission("sv.updatecfg");
}
},
RELOAD("sv.reload", true, "/sv reload", "Reloads all settings and messages"),
CLEANUP("sv.cleanup", true, "/sv cleanup", "Clears all vanish state and forces everyone visible"),
PRINT_STACKTRACE("sv.stacktrace", true, "/sv stacktrace", "Logs info for a bug report"),
SHOW_HELP("sv.help", true, "/sv help", "Shows this help page");
/**
* Use {@link #checkPermission(CommandSender, SuperVanish)} to check whether a
* {@link CommandSender} has permission to perform an action or not
*/
private final String mainPermission;
private final boolean console;
private final String usage, description;
CommandAction(String mainPermission, boolean console, String usage, String description) {
this.mainPermission = mainPermission;
this.console = console;
this.usage = usage;
this.description = description;
}
static List<String> getAvailableFirstArguments(CommandSender sender, SuperVanish plugin) {
Validation.checkNotNull(plugin, "plugin cannot be null");
List<String> list = new ArrayList<>();
if (SHOW_HELP.checkPermission(sender, plugin))
list.add("help");
if (RECREATE_FILES.checkPermission(sender, plugin))
list.add("recreatefiles");
if (RELOAD.checkPermission(sender, plugin))
list.add("reload");
if (CLEANUP.checkPermission(sender, plugin))
list.add("cleanup");
if (VANISHED_LIST.checkPermission(sender, plugin))
list.add("list");
if (VANISH_SELF.checkPermission(sender, plugin))
list.add("on");
if (VANISH_SELF.checkPermission(sender, plugin))
list.add("off");
if (TOGGLE_ITEM_PICKUPS.checkPermission(sender, plugin))
list.add("tipu");
if (PRINT_STACKTRACE.checkPermission(sender, plugin))
list.add("stacktrace");
return list;
}
public static boolean hasAnyCmdPermission(CommandSender sender, SuperVanish plugin) {
for (CommandAction action : CommandAction.values())
if (action.checkPermission(sender, plugin))
return true;
return false;
}
public boolean checkPermission(CommandSender sender, SuperVanish plugin) {
return sender.hasPermission(getMainPermission());
}
public boolean usableByConsole() {
return console;
}
public String getMainPermission() {
return mainPermission;
}
public String getUsage() {
return usage;
}
public String getDescription() {
return description;
}
}
@@ -0,0 +1,18 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public interface Executable {
void execute(Command cmd, CommandSender sender, String[] args, String label);
}
@@ -0,0 +1,81 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Collection;
import java.util.UUID;
public abstract class SubCommand implements Executable {
protected final SuperVanish plugin;
public SubCommand(SuperVanish plugin) {
this.plugin = plugin;
}
protected Collection<UUID> getAllVanishedPlayers() {
return plugin.getVanishStateMgr().getVanishedPlayers();
}
protected Collection<UUID> getOnlineVanishedPlayers() {
return plugin.getVanishStateMgr().getOnlineVanishedPlayers();
}
public void hidePlayer(Player player) {
plugin.getVisibilityChanger().hidePlayer(player);
}
public void showPlayer(Player player) {
plugin.getVisibilityChanger().showPlayer(player);
}
public boolean isVanished(UUID uuid) {
return plugin.getVanishStateMgr().isVanished(uuid);
}
public boolean canDo(CommandSender sender, CommandAction action, boolean sendErrors) {
if (!(sender instanceof Player))
if (!action.usableByConsole()) {
if (sendErrors)
plugin.sendMessage(sender, "InvalidSender", sender);
return false;
}
if (!action.checkPermission(sender, plugin)) {
if (sendErrors)
plugin.sendMessage(sender, "NoPermission", sender);
return false;
}
return true;
}
}
@@ -0,0 +1,222 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.commands.subcommands.*;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
public class SubCommandMgr {
private SuperVanish plugin;
public SubCommandMgr(SuperVanish plugin) {
this.plugin = plugin;
}
public void execute(Command cmd, CommandSender sender, String[] args, String label) {
try {
// invalid usage by default
Executable executable = new InvalidUsage(plugin);
// vanish self #1
if (args.length == 0) {
if (sender instanceof Player)
executable = new VanishSelf(plugin);
executable.execute(cmd, sender, args, label);
return;
}
// vanish other
if ((args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("off") || args[0].equalsIgnoreCase("vanish")
|| args[0].equalsIgnoreCase("reappear") || args[0].equalsIgnoreCase("enable")
|| args[0].equalsIgnoreCase("disable")) && args.length > 1 || Bukkit.getPlayer(args[0]) != null)
{
executable = Bukkit.getPlayer(args[0]) != null
&& !(args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("off")
|| args[0].equalsIgnoreCase("vanish") || args[0].equalsIgnoreCase("reappear")
|| args[0].equalsIgnoreCase("enable") || args[0].equalsIgnoreCase("disable"))
? new VanishOther(Bukkit.getPlayer(args[0]), plugin)
: new VanishOther(plugin);
}
// vanish self #2
if ((args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("off") || args[0].equalsIgnoreCase("vanish")
|| args[0].equalsIgnoreCase("reappear") || args[0].equalsIgnoreCase("enable")
|| args[0].equalsIgnoreCase("disable") || args[0].equalsIgnoreCase("-s")) && args.length == 1)
{
executable = new VanishSelf(plugin);
}
//
if (args[0].equalsIgnoreCase("help") || args[0].equalsIgnoreCase("commands")
|| args[0].equalsIgnoreCase("?"))
{
executable = new ShowHelp(plugin);
}
if (args[0].equalsIgnoreCase("printstacktrace") || args[0].equalsIgnoreCase("logstacktrace")
|| args[0].equalsIgnoreCase("dumpstacktrace") || args[0].equalsIgnoreCase("stacktrace"))
{
executable = new PrintStacktrace(plugin);
}
if (args[0].equalsIgnoreCase("toggleitempickups") || args[0].equalsIgnoreCase("toggleitempickup")
|| args[0].equalsIgnoreCase("toggleitem") || args[0].equalsIgnoreCase("toggleitems")
|| args[0].equalsIgnoreCase("togglepickup") || args[0].equalsIgnoreCase("togglepickups")
|| args[0].equalsIgnoreCase("pickup") || args[0].equalsIgnoreCase("pickups")
|| args[0].equalsIgnoreCase("tipu") || args[0].equalsIgnoreCase("tip"))
{
executable = new ToggleItemPickups(plugin);
}
if (args[0].equalsIgnoreCase("recreatecfg") || args[0].equalsIgnoreCase("rccfg")
|| args[0].equalsIgnoreCase("recreateconfig") || args[0].equalsIgnoreCase("rcconfig")
|| args[0].equalsIgnoreCase("updatecfg") || args[0].equalsIgnoreCase("recreate")
|| args[0].equalsIgnoreCase("recreatefiles") || args[0].equalsIgnoreCase("rf")
|| args[0].equalsIgnoreCase("rcf") || args[0].equalsIgnoreCase("refi"))
{
executable = new RecreateFiles(plugin);
}
if (args[0].equalsIgnoreCase("reload") || args[0].equalsIgnoreCase("rl") || args[0].equalsIgnoreCase("re")
|| args[0].equalsIgnoreCase("rlc") || args[0].equalsIgnoreCase("rlcfg")
|| args[0].equalsIgnoreCase("reloadconfig") || args[0].equalsIgnoreCase("rlp")
|| args[0].equalsIgnoreCase("rlpl") || args[0].equalsIgnoreCase("reloadplugin"))
{
executable = new Reload(plugin);
}
if (args[0].equalsIgnoreCase("list")) {
executable = new VanishedList(plugin);
}
if (args[0].equalsIgnoreCase("cleanup") || args[0].equalsIgnoreCase("clearall")
|| args[0].equalsIgnoreCase("flush"))
{
executable = new Cleanup(plugin);
}
if (args[0].equalsIgnoreCase("login")) {
executable = new BroadcastLogin(plugin);
}
if (args[0].equalsIgnoreCase("logout")) {
executable = new BroadcastLogout(plugin);
}
executable.execute(cmd, sender, args, label);
} catch (Exception e) {
plugin.logException(e);
}
}
public List<String> onTabComplete(Command command, CommandSender sender, String alias, String[] args) {
// don't provide any help at all if user doesn't have permission to
// execute '/sv help'
if (!CommandAction.hasAnyCmdPermission(sender, plugin)) {
return Collections.emptyList();
}
if (args.length == 1) {
String toComplete = args[0];
// didn't start to type first argument
if (toComplete.equalsIgnoreCase(""))
return CommandAction.getAvailableFirstArguments(sender, plugin);
// started to type it, only show args that start with given argument
List<String> matchingFirstArguments = new ArrayList<>();
for (String arg : CommandAction.getAvailableFirstArguments(sender, plugin)) {
if (arg.toLowerCase(Locale.ENGLISH).startsWith(toComplete.toLowerCase(Locale.ENGLISH)))
matchingFirstArguments.add(arg);
}
if (matchingFirstArguments.isEmpty())
return getOnlinePlayerNameTabCompletions(toComplete);
return matchingFirstArguments;
// extra commands
} else if (args.length == 2) {
// vanish other player tab completion
if ((args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("off") || args[0].equalsIgnoreCase("vanish")
|| args[0].equalsIgnoreCase("reappear") || args[0].equalsIgnoreCase("enable")
|| args[0].equalsIgnoreCase("disable"))
&& CommandAction.VANISH_OTHER.checkPermission(sender, plugin))
{
return getOnlinePlayerNameTabCompletions(args[1]);
}
}
return Collections.emptyList();
}
private List<String> getOnlinePlayerNameTabCompletions(String arg) {
List<String> playerNames = new ArrayList<>();
for (Player p : plugin.getServer().getOnlinePlayers()) {
if (p.getName().toLowerCase(Locale.ENGLISH).startsWith(arg.toLowerCase(Locale.ENGLISH)))
playerNames.add(p.getName());
}
return playerNames;
}
}
@@ -0,0 +1,40 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands;
import java.util.List;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import de.myzelyam.supervanish.SuperVanish;
public class VanishCommand {
private final SubCommandMgr subCommandMgr;
public VanishCommand(SuperVanish plugin) {
subCommandMgr = new SubCommandMgr(plugin);
}
public void execute(Command command, CommandSender sender, String commandLabel, String[] args) {
subCommandMgr.execute(command, sender, args, commandLabel);
}
public List<String> tabComplete(Command command, CommandSender sender, String alias, String[] args) {
return subCommandMgr.onTabComplete(command, sender, alias, args);
}
}
@@ -0,0 +1,40 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands.subcommands;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.commands.CommandAction;
import de.myzelyam.supervanish.commands.SubCommand;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class BroadcastLogin extends SubCommand {
public BroadcastLogin(SuperVanish plugin) {
super(plugin);
}
@Override
public void execute(Command cmd, CommandSender p, String[] args, String label) {
if (canDo(p, CommandAction.BROADCAST_LOGIN, true)) {
for (Player onlinePlayer : Bukkit.getOnlinePlayers())
plugin.sendMessage(onlinePlayer, "ReappearMessage", p, onlinePlayer);
}
}
}
@@ -0,0 +1,40 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands.subcommands;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.commands.CommandAction;
import de.myzelyam.supervanish.commands.SubCommand;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class BroadcastLogout extends SubCommand {
public BroadcastLogout(SuperVanish plugin) {
super(plugin);
}
@Override
public void execute(Command cmd, CommandSender p, String[] args, String label) {
if (canDo(p, CommandAction.BROADCAST_LOGOUT, true)) {
for (Player onlinePlayer : Bukkit.getOnlinePlayers())
plugin.sendMessage(onlinePlayer, "VanishMessage", p, onlinePlayer);
}
}
}
@@ -0,0 +1,90 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands.subcommands;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.commands.CommandAction;
import de.myzelyam.supervanish.commands.SubCommand;
import net.trueog.utilitiesog.UtilitiesOG;
public class Cleanup extends SubCommand {
public Cleanup(SuperVanish plugin) {
super(plugin);
}
@Override
public void execute(Command cmd, CommandSender p, String[] args, String label) {
if (!canDo(p, CommandAction.CLEANUP, true)) {
return;
}
plugin.getVanishStateMgr().clearAllVanishState();
// Must run before forceShowAllPlayers: Essentials' setVanished(false)
// internally calls the deprecated showPlayer(Player) for every online
// user, and we want our aggressive pass to finish after that so nothing
// sneaks back in.
if (plugin.getPluginHookMgr() != null) {
plugin.getPluginHookMgr().onCleanup();
}
if (plugin.getVisibilityChanger() != null) {
// Aggressive mode also drops the null-plugin-ref hide that Essentials
// and other deprecated-API users leave in CraftPlayer's
// invertedVisibilityEntities. Without it, CraftPlayer#canSee still
// returns false because the set for the target UUID is non-empty.
plugin.forceShowAllPlayers(true);
plugin.getVisibilityChanger().getHider().clearHiddenState();
}
for (Player online : Bukkit.getOnlinePlayers()) {
for (Plugin other : Bukkit.getPluginManager().getPlugins()) {
// Each plugin owns its own "vanished" metadata entry; leaving any
// of them populated keeps TAB-OG and other consumers treating the
// player as vanished even though Vanish-OG has been wiped.
online.removeMetadata("vanished", other);
}
}
plugin.reconcileAllVisibilities();
final String msg = "&aVanish state cleared. All players should now be visible and mutually damageable again.";
if (p instanceof Player player) {
UtilitiesOG.trueogMessage(player, msg);
} else {
p.sendMessage(msg);
}
}
}
@@ -0,0 +1,40 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands.subcommands;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.commands.CommandAction;
import de.myzelyam.supervanish.commands.SubCommand;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public class InvalidUsage extends SubCommand {
public InvalidUsage(SuperVanish plugin) {
super(plugin);
}
@Override
public void execute(Command cmd, CommandSender sender, String[] args, String label) {
if (!CommandAction.hasAnyCmdPermission(sender, plugin)) {
plugin.sendMessage(sender, "NoPermission", sender);
return;
}
plugin.sendMessage(sender, "InvalidUsage", sender);
}
}
@@ -0,0 +1,38 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands.subcommands;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.commands.CommandAction;
import de.myzelyam.supervanish.commands.SubCommand;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public class PrintStacktrace extends SubCommand {
public PrintStacktrace(SuperVanish plugin) {
super(plugin);
}
@Override
public void execute(Command cmd, CommandSender sender, String[] args, String label) {
if (canDo(sender, CommandAction.PRINT_STACKTRACE, true)) {
plugin.sendMessage(sender, "PrintedStacktrace", sender);
plugin.logException(null);
}
}
}
@@ -0,0 +1,143 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands.subcommands;
import java.io.File;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import de.myzelyam.supervanish.PlaceholderConverter;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.commands.CommandAction;
import de.myzelyam.supervanish.commands.SubCommand;
import net.trueog.utilitiesog.UtilitiesOG;
public class RecreateFiles extends SubCommand {
public RecreateFiles(SuperVanish plugin) {
super(plugin);
}
@Override
public void execute(Command cmd, CommandSender p, String[] args, String label) {
if (!canDo(p, CommandAction.RECREATE_FILES, true)) {
return;
}
String files = "the messages file";
String changes = "all messages";
if (args.length != 2) {
if (!plugin.getConfigMgr().isMessagesUpdateRequired()) {
plugin.sendMessage(p, "NoConfigUpdateAvailable", p);
return;
}
plugin.sendMessage(p, plugin.getMessage("UpdateWarning"), p,
PlaceholderConverter.placeholder("changes", changes),
PlaceholderConverter.placeholder("files", files));
return;
}
if (StringUtils.equalsIgnoreCase("confirm", args[1]) || StringUtils.equalsIgnoreCase(args[1], "force")) {
if (!plugin.getConfigMgr().isMessagesUpdateRequired() && !StringUtils.equalsIgnoreCase(args[1], "force")) {
plugin.sendMessage(p, "NoConfigUpdateAvailable", p);
return;
}
if (StringUtils.equalsIgnoreCase(args[1], "force")) {
files = "the config and the messages file";
changes = "all settings and messages";
}
// Delete necessary files.
boolean success = true;
if (StringUtils.equalsIgnoreCase(args[1], "force")) {
final File file = new File(plugin.getDataFolder().getPath() + File.separator + "config.yml");
success = file.delete();
plugin.getConfigMgr().getSettingsFile().save();
plugin.getConfigMgr().getSettingsFile().reload();
plugin.getConfigMgr().setSettings(plugin.getConfigMgr().getSettingsFile().getConfig());
}
if (plugin.getConfigMgr().isMessagesUpdateRequired() || StringUtils.equalsIgnoreCase(args[1], "force")) {
final File file2 = new File(plugin.getDataFolder().getPath() + File.separator + "messages.yml");
success &= file2.delete();
plugin.getConfigMgr().getMessagesFile().save();
plugin.getConfigMgr().getMessagesFile().reload();
plugin.getConfigMgr().setMessages(plugin.getConfigMgr().getMessagesFile().getConfig());
}
if (!success) {
final String failMsg = "&cERROR: Cannot recreate files because one of them could not be deleted. Are the file permissions valid?";
if (p instanceof Player player) {
UtilitiesOG.trueogMessage(player, failMsg);
} else {
p.sendMessage(failMsg);
}
return;
}
plugin.sendMessage(p, plugin.getMessage("RecreatedConfig"), p,
PlaceholderConverter.placeholder("changes", changes),
PlaceholderConverter.placeholder("files", files));
// Refresh recreation status after regenerating the files.
plugin.getConfigMgr().checkFilesForLeftOvers();
} else if (StringUtils.equalsIgnoreCase("dismiss", args[1])) {
final String currentVersion = plugin.getPluginMeta().getVersion();
final String dismissId = p instanceof Player ? ((Player) p).getUniqueId().toString() : "CONSOLE";
final boolean isDismissed = plugin.getVanishStateMgr().isDismissed(dismissId, currentVersion);
plugin.getVanishStateMgr().setDismissed(dismissId, currentVersion, !isDismissed);
if (!isDismissed) {
plugin.sendMessage(p, "DismissedRecreationWarning", p);
} else {
plugin.sendMessage(p, "UndismissedRecreationWarning", p);
}
}
}
}
@@ -0,0 +1,64 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands.subcommands;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import de.myzelyam.supervanish.PlaceholderConverter;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.commands.CommandAction;
import de.myzelyam.supervanish.commands.SubCommand;
import net.trueog.utilitiesog.UtilitiesOG;
public class Reload extends SubCommand {
public Reload(SuperVanish plugin) {
super(plugin);
}
@Override
public void execute(Command cmd, CommandSender p, String[] args, String label) {
if (!canDo(p, CommandAction.RELOAD, true)) {
return;
}
final long before = System.currentTimeMillis();
plugin.reload();
if (!Bukkit.getPluginManager().isPluginEnabled(plugin)) {
final String failMsg = "&cERROR: Failed to reload Vanish-OG since it failed to restart itself. "
+ "More information is in the console. (" + (System.currentTimeMillis() - before) + "ms)";
if (p instanceof Player player) {
UtilitiesOG.trueogMessage(player, failMsg);
} else {
p.sendMessage(failMsg);
}
return;
}
plugin.sendMessage(p, plugin.getMessage("PluginReloaded"), p,
PlaceholderConverter.placeholder("time", System.currentTimeMillis() - before));
}
}
@@ -0,0 +1,50 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* license, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands.subcommands;
import de.myzelyam.supervanish.PlaceholderConverter;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.commands.CommandAction;
import de.myzelyam.supervanish.commands.SubCommand;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public class ShowHelp extends SubCommand {
public ShowHelp(SuperVanish plugin) {
super(plugin);
}
@Override
public void execute(Command cmd, CommandSender sender, String[] args, String label) {
if (canDo(sender, CommandAction.SHOW_HELP, true)) {
plugin.sendMessage(sender, "HelpHeader", sender);
for (CommandAction action : CommandAction.values()) {
if (canDo(sender, action, false)) {
plugin.sendMessage(sender, plugin.getMessage("HelpFormat"), sender,
PlaceholderConverter.placeholder("usage", action.getUsage()),
PlaceholderConverter.placeholder("description", action.getDescription()),
PlaceholderConverter.placeholder("permission", action.getMainPermission()));
}
}
}
}
}
@@ -0,0 +1,50 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands.subcommands;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.VanishPlayer;
import de.myzelyam.supervanish.commands.CommandAction;
import de.myzelyam.supervanish.commands.SubCommand;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class ToggleItemPickups extends SubCommand {
public ToggleItemPickups(SuperVanish plugin) {
super(plugin);
}
@Override
public void execute(Command cmd, CommandSender sender, String[] args, String label) {
if (canDo(sender, CommandAction.TOGGLE_ITEM_PICKUPS, true)) {
Player p = (Player) sender;
plugin.sendMessage(p, plugin
.getMessage("ToggledPickingUpItems" + (toggleState(plugin.getVanishPlayer(p)) ? "On" : "Off")), p);
}
}
private boolean toggleState(VanishPlayer vp) {
boolean hasEnabled = plugin.getVanishStateMgr().getItemPickUps(vp.getPlayerUUID(), false);
plugin.getVanishStateMgr().setItemPickUps(vp.getPlayerUUID(), !hasEnabled);
vp.setItemPickUps(!hasEnabled);
return !hasEnabled;
}
}
@@ -0,0 +1,149 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands.subcommands;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.commands.CommandAction;
import de.myzelyam.supervanish.commands.SubCommand;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.UUID;
public class VanishOther extends SubCommand {
private Player specifiedPlayer;
public VanishOther(SuperVanish plugin) {
this(null, plugin);
}
public VanishOther(Player specifiedPlayer, SuperVanish plugin) {
super(plugin);
this.specifiedPlayer = specifiedPlayer;
}
@Override
public void execute(Command cmd, CommandSender sender, String[] args, String label) {
if (canDo(sender, CommandAction.VANISH_OTHER, true)) {
boolean hide = false, offline = false, silent = false;
Player target;
String name;
UUID uuid;
if (specifiedPlayer == null) {
if (args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("enable")
|| args[0].equalsIgnoreCase("vanish"))
hide = true;
target = Bukkit.getPlayer(args[1]);
name = target == null ? args[1] : target.getName();
} else {
target = specifiedPlayer;
name = specifiedPlayer.getName();
hide = !isVanished(target.getUniqueId());
}
if (target == null) {
offline = true;
uuid = plugin.getVanishStateMgr().getVanishedUUIDFromName(name);
if (uuid == null) {
plugin.sendMessage(sender, "PlayerNonExistent", sender, name);
return;
}
} else {
name = target.getName();
uuid = target.getUniqueId();
}
if (!offline && sender instanceof Player && sender != target && target.hasPermission("sv.notoggle")) {
plugin.sendMessage(sender, "CannotHideOtherPlayer", sender, name);
return;
}
if (plugin.getSettings().getBoolean("IndicationFeatures.LayeredPermissions.HideInvisibleInCommands", false)
&& target != null && sender instanceof Player
&& !plugin.hasPermissionToSee((Player) sender, target))
{
plugin.sendMessage(sender, "PlayerNonExistent", sender, name);
return;
}
if (hide && (offline ? isVanished(uuid) : isVanished(uuid))) {
plugin.sendMessage(sender, "AlreadyInvisibleMessage", sender, name);
return;
} else if (!hide && !(offline ? isVanished(uuid) : isVanished(uuid))) {
plugin.sendMessage(sender, "AlreadyVisibleMessage", sender, name);
return;
}
if (args.length == 3)
silent = args[2].equalsIgnoreCase("-s");
else if (args.length == 2)
silent = args[1].equalsIgnoreCase("-s");
if (!offline) {
if (hide) {
plugin.getVisibilityChanger().hidePlayer(target, sender.getName(), silent);
plugin.sendMessage(sender, "HideOtherMessage", sender, name);
} else {
plugin.getVisibilityChanger().showPlayer(target, sender.getName());
plugin.sendMessage(sender, "ShowOtherMessage", sender, name, silent);
}
} else {
if (hide) {
plugin.getVanishStateMgr().setVanishedState(uuid, name, true, sender.getName());
plugin.sendMessage(sender, "HideOtherMessage", sender, name);
} else {
plugin.getVanishStateMgr().setVanishedState(uuid, name, false, sender.getName());
plugin.sendMessage(sender, "ShowOtherMessage", sender, name);
}
}
}
}
}
@@ -0,0 +1,81 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands.subcommands;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.commands.CommandAction;
import de.myzelyam.supervanish.commands.SubCommand;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class VanishSelf extends SubCommand {
public VanishSelf(SuperVanish plugin) {
super(plugin);
}
@Override
public void execute(Command cmd, CommandSender s, String[] args, String label) {
if (canDo(s, CommandAction.VANISH_SELF, true)) {
Player p = (Player) s;
if (args.length == 0) {
if (isVanished(p.getUniqueId()))
showPlayer(p);
else
hidePlayer(p);
} else if (args.length == 1) {
if (args[0].equalsIgnoreCase("off") || args[0].equalsIgnoreCase("reappear")
|| args[0].equalsIgnoreCase("disable"))
{
if (!isVanished(p.getUniqueId())) {
plugin.sendMessage(p, "NotVanishedError", p);
return;
}
showPlayer(p);
} else if (args[0].equalsIgnoreCase("-s")) {
if (isVanished(p.getUniqueId()))
plugin.getVisibilityChanger().showPlayer(p, null, true);
else
plugin.getVisibilityChanger().hidePlayer(p, null, true);
} else {
if (isVanished(p.getUniqueId())) {
plugin.sendMessage(p, "AlreadyVanishedError", p);
return;
}
hidePlayer(p);
}
}
}
}
}
@@ -0,0 +1,79 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.commands.subcommands;
import com.google.common.collect.ImmutableList;
import de.myzelyam.supervanish.PlaceholderConverter;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.commands.CommandAction;
import de.myzelyam.supervanish.commands.SubCommand;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.util.List;
import java.util.UUID;
public class VanishedList extends SubCommand {
public VanishedList(SuperVanish plugin) {
super(plugin);
}
@Override
public void execute(Command cmd, final CommandSender sender, final String[] args, String label) {
if (!canDo(sender, CommandAction.VANISHED_LIST, true)) {
return;
}
String listMessage = plugin.getMessage("ListMessagePrefix");
final StringBuilder stringBuilder = new StringBuilder();
final List<UUID> allInvisiblePlayerUUIDs = ImmutableList.copyOf(getAllVanishedPlayers());
if (allInvisiblePlayerUUIDs.isEmpty()) {
stringBuilder.append("none");
}
for (int i = 0; i < allInvisiblePlayerUUIDs.size(); i++) {
final UUID playerUUID = allInvisiblePlayerUUIDs.get(i);
String name = Bukkit.getOfflinePlayer(playerUUID).getName();
if (Bukkit.getPlayer(playerUUID) == null) {
name = LegacyComponentSerializer.legacySection()
.serialize(MiniMessage.miniMessage().deserialize(name + "<red>[offline]<white>"));
}
stringBuilder.append(name);
if (i != allInvisiblePlayerUUIDs.size() - 1) {
stringBuilder.append(LegacyComponentSerializer.legacySection()
.serialize(MiniMessage.miniMessage().deserialize("<green>, <white>")));
}
}
plugin.sendMessage(sender, listMessage, sender,
PlaceholderConverter.placeholder("vanished_list", stringBuilder.toString()));
}
}
@@ -0,0 +1,137 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.config;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.configuration.file.FileConfiguration;
import java.util.logging.Level;
import static de.myzelyam.supervanish.SuperVanish.*;
public class ConfigMgr {
private final SuperVanish plugin;
private final FileMgr fileMgr;
private boolean messagesUpdateRequired;
private FileConfiguration settings;
private FileConfiguration messages;
private ConfigurableFile messagesFile;
private ConfigurableFile settingsFile;
public ConfigMgr(SuperVanish plugin) {
this.plugin = plugin;
fileMgr = new FileMgr(plugin);
}
public void prepareFiles() {
// messages
messagesFile = (ConfigurableFile) fileMgr.addFile("messages");
messages = messagesFile.getConfig();
// settings
settingsFile = (ConfigurableFile) fileMgr.addFile("config");
settings = settingsFile.getConfig();
}
public void checkFilesForLeftOvers() {
try {
String newestVersion = plugin.getPluginMeta().getVersion();
String currentMessagesVersion = messages.getString("MessagesVersion");
messagesUpdateRequired = fileRequiresRecreation(currentMessagesVersion);
if (newestVersion.equals(currentMessagesVersion))
messagesUpdateRequired = false;
if (messagesUpdateRequired) {
String currentVersion = plugin.getPluginMeta().getVersion();
boolean isDismissed = plugin.getVanishStateMgr().isDismissed("CONSOLE", currentVersion);
if (!isDismissed)
plugin.log(Level.WARNING,
"Messages file needs to be recreated. " + "Use '/sv recreatefiles' to regenerate it.");
}
} catch (Exception e) {
plugin.logException(e);
}
}
private boolean fileRequiresRecreation(String currentVersion) {
if (currentVersion == null)
return true;
for (String ignoredVersion : NON_REQUIRED_MESSAGES_UPDATES) {
if (currentVersion.equalsIgnoreCase(ignoredVersion))
return false;
}
return true;
}
public FileMgr getFileMgr() {
return fileMgr;
}
public boolean isMessagesUpdateRequired() {
return messagesUpdateRequired;
}
public FileConfiguration getSettings() {
return settings;
}
public FileConfiguration getMessages() {
return messages;
}
public void setSettings(FileConfiguration settings) {
this.settings = settings;
}
public void setMessages(FileConfiguration messages) {
this.messages = messages;
}
public ConfigurableFile getMessagesFile() {
return messagesFile;
}
public ConfigurableFile getSettingsFile() {
return settingsFile;
}
}
@@ -0,0 +1,98 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.config;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
public class ConfigurableFile implements PluginFile<FileConfiguration> {
private final SuperVanish plugin;
private String name;
private File file;
private FileConfiguration fileConfiguration;
private FileConfiguration defaultFileConfiguration;
public ConfigurableFile(String name, SuperVanish plugin) {
this.name = name + ".yml";
this.plugin = plugin;
setup();
}
@Override
public String getName() {
return name;
}
private void setup() {
file = new File(plugin.getDataFolder(), name);
try (Reader reader = new InputStreamReader(plugin.getResource(name))) {
defaultFileConfiguration = YamlConfiguration.loadConfiguration(reader);
} catch (IOException e) {
e.printStackTrace();
}
save();
}
@Override
public void reload() {
fileConfiguration = YamlConfiguration.loadConfiguration(file);
}
@Override
public FileConfiguration getConfig() {
if (fileConfiguration == null) {
reload();
}
return fileConfiguration;
}
@Override
public void save() {
if (!file.exists()) {
plugin.saveResource(name, false);
}
}
public FileConfiguration getDefaultConfig() {
return defaultFileConfiguration;
}
}
@@ -0,0 +1,56 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.config;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.SuperVanishPlugin;
import java.util.HashMap;
import java.util.Map;
public class FileMgr {
private final SuperVanishPlugin plugin;
private Map<String, PluginFile<?>> files;
public FileMgr(SuperVanishPlugin plugin) {
this.plugin = plugin;
files = new HashMap<>();
}
public PluginFile<?> addFile(String name) {
if (name == null)
throw new IllegalArgumentException("The file name cannot be null!");
ConfigurableFile file = new ConfigurableFile(name, (SuperVanish) plugin);
files.put(name, file);
return file;
}
public void reloadFile(String fileName) {
PluginFile<?> file = files.get(fileName);
if (file != null)
file.reload();
else
throw new IllegalArgumentException("Specified file doesn't exist!");
}
public void reloadAll() {
for (String fileName : files.keySet())
reloadFile(fileName);
}
}
@@ -1,69 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.config;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
public class MessagesFile {
private final String fileName;
private SuperVanish plugin = (SuperVanish) Bukkit.getPluginManager()
.getPlugin("SuperVanish");
private File messages;
private FileConfiguration fileConfiguration, defaultFileConfiguration;
public MessagesFile() {
this.fileName = "messages.yml";
File dataFolder = plugin.getDataFolder();
if (dataFolder == null)
throw new IllegalStateException();
this.messages = new File(plugin.getDataFolder(), fileName);
try (Reader reader = new InputStreamReader(plugin.getResource(fileName))) {
defaultFileConfiguration = YamlConfiguration.loadConfiguration(reader);
} catch (IOException e) {
e.printStackTrace();
}
}
public void reloadConfig() {
fileConfiguration = YamlConfiguration.loadConfiguration(messages);
InputStream defConfigStream = plugin.getResource(fileName);
if (defConfigStream != null) {
YamlConfiguration defConfig = YamlConfiguration
.loadConfiguration(new InputStreamReader(defConfigStream));
fileConfiguration.setDefaults(defConfig);
}
}
public FileConfiguration getConfig() {
if (fileConfiguration == null) {
this.reloadConfig();
}
return fileConfiguration;
}
public FileConfiguration getDefaultConfig() {
return defaultFileConfiguration;
}
public void saveDefaultConfig() {
if (!messages.exists()) {
this.plugin.saveResource(fileName, false);
}
}
}
@@ -0,0 +1,21 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.config;
public interface PluginFile<CT> {
String getName();
void reload();
CT getConfig();
void save();
}
@@ -1,57 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.config;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
public class SettingsFile {
private final String fileName;
private SuperVanish plugin = (SuperVanish) Bukkit.getPluginManager()
.getPlugin("SuperVanish");
private File config;
private FileConfiguration fileConfiguration;
public SettingsFile() {
this.fileName = "config.yml";
File dataFolder = plugin.getDataFolder();
if (dataFolder == null)
throw new IllegalStateException();
this.config = new File(dataFolder, fileName);
}
public void reloadConfig() {
fileConfiguration = YamlConfiguration.loadConfiguration(config);
InputStream defConfigStream = plugin.getResource(fileName);
if (defConfigStream != null) {
YamlConfiguration defConfig = YamlConfiguration
.loadConfiguration(new InputStreamReader(defConfigStream));
fileConfiguration.setDefaults(defConfig);
}
}
public FileConfiguration getConfig() {
if (fileConfiguration == null) {
this.reloadConfig();
}
return fileConfiguration;
}
public void saveDefaultConfig() {
if (!config.exists()) {
this.plugin.saveResource(fileName, false);
}
}
}
@@ -1,281 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.events;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.hooks.EssentialsHook;
import de.myzelyam.supervanish.utils.OneDotEightUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockCanBuildEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import java.util.Collection;
public class GeneralEventListener implements Listener {
private final SuperVanish plugin;
public GeneralEventListener(SuperVanish plugin) {
this.plugin = plugin;
}
private FileConfiguration getSettings() {
return plugin.settings;
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onTeleport(PlayerTeleportEvent e) {
// remove night vision (re-added in WorldChange event)
if (!plugin.packetNightVision) {
Player p = e.getPlayer();
Collection<Player> invisiblePlayers = plugin.getOnlineInvisiblePlayers();
if (!invisiblePlayers.contains(p)) return;
if (e.getFrom().getWorld().getName()
.equals(e.getTo().getWorld().getName()))
return;
if (getSettings().getBoolean("Configuration.Players.AddNightVision"))
p.removePotionEffect(PotionEffectType.NIGHT_VISION);
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onFoodLevelChangeEvent(FoodLevelChangeEvent e) {
try {
if (e.getEntity() instanceof Player && getSettings().getBoolean(
"Configuration.Players.DisableHungerForInvisiblePlayers")) {
Player p = (Player) e.getEntity();
Collection<Player> invisiblePlayers = plugin.getOnlineInvisiblePlayers();
if (invisiblePlayers.contains(p) && e.getFoodLevel() <= p.getFoodLevel())
e.setCancelled(true);
}
} catch (Exception er) {
plugin.printException(er);
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onDamage(EntityDamageEvent e) {
try {
if (!(e.getEntity() instanceof Player)) {
return;
}
Player p = (Player) e.getEntity();
Collection<Player> invisiblePlayers = plugin.getOnlineInvisiblePlayers();
if (invisiblePlayers.contains(p)) {
e.setCancelled(true);
}
} catch (Exception er) {
plugin.printException(er);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onEntityTarget(EntityTargetEvent e) {
try {
if (!(e.getTarget() instanceof Player) || e.getTarget() == null) {
return;
}
Player p = (Player) e.getTarget();
Collection<Player> invisiblePlayers = plugin.getOnlineInvisiblePlayers();
if (invisiblePlayers.contains(p)) {
e.setCancelled(true);
}
} catch (Exception er) {
plugin.printException(er);
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerInteract(PlayerInteractEvent e) {
try {
if (!getSettings().getBoolean(
"Configuration.Players.DisablePressurePlatesForInvisiblePlayers")) {
return;
}
if (e.getAction().equals(Action.PHYSICAL)) {
if (e.getClickedBlock().getType() == Material.STONE_PLATE
|| e.getClickedBlock().getType() == Material.WOOD_PLATE
|| e.getClickedBlock().getType() == Material.TRIPWIRE ||
(!plugin.isOneDotX(7) &&
OneDotEightUtils.isPressurePlate(e.getClickedBlock().getType()))) {
if (plugin.getAllInvisiblePlayers().contains(e.getPlayer().getUniqueId().toString()))
e.setCancelled(true);
}
}
} catch (Exception er) {
plugin.printException(er);
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onPickupItem(PlayerPickupItemEvent e) {
try {
Player p = e.getPlayer();
Collection<Player> invisiblePlayers = plugin.getOnlineInvisiblePlayers();
if (invisiblePlayers.contains(p)) {
if (plugin.playerData.get("PlayerData." + p.getUniqueId().toString()
+ ".itemPickUps") == null)
if (getSettings().getBoolean("Configuration.Players.DisableItemPickUpsByDefault"))
e.setCancelled(true);
else
return;
if (!plugin.playerData.getBoolean("PlayerData." + p.getUniqueId().toString()
+ ".itemPickUps"))
e.setCancelled(true);
}
} catch (Exception er) {
plugin.printException(er);
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onBlockPlace(BlockPlaceEvent e) {
try {
Player p = e.getPlayer();
Collection<Player> invisiblePlayers = plugin.getOnlineInvisiblePlayers();
if (invisiblePlayers.contains(p)) {
if (getSettings().getBoolean("Configuration.Players.PreventBlockPlacing")) {
e.setCancelled(true);
}
}
} catch (Exception er) {
plugin.printException(er);
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onBlockBreak(BlockBreakEvent e) {
try {
Player p = e.getPlayer();
Collection<Player> invisiblePlayers = plugin.getOnlineInvisiblePlayers();
if (invisiblePlayers.contains(p)) {
if (getSettings().getBoolean("Configuration.Players.PreventBlockBreaking")) {
e.setCancelled(true);
}
}
} catch (Exception er) {
plugin.printException(er);
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerHit(EntityDamageByEntityEvent e) {
try {
if (!(e.getDamager() instanceof Player))
return;
if (e.getEntity() == null)
return;
Player p = (Player) e.getDamager();
Collection<Player> invisiblePlayers = plugin.getOnlineInvisiblePlayers();
if (invisiblePlayers == null)
return;
if (invisiblePlayers.contains(p)) {
if (getSettings().getBoolean("Configuration.Players.PreventHittingEntities")) {
e.setCancelled(true);
}
}
} catch (Exception er) {
plugin.printException(er);
}
}
@EventHandler
public void onBlockCanBuild(BlockCanBuildEvent e) {
try {
Collection<Player> invisiblePlayers = plugin.getOnlineInvisiblePlayers();
Block block = e.getBlock();
Location bLocation = block.getLocation();
for (Player p : block.getWorld().getPlayers()) {
if (!invisiblePlayers.contains(p))
continue;
if (p.getLocation().distanceSquared(bLocation) <= 2.0)
e.setBuildable(true);
}
} catch (Exception er) {
plugin.printException(er);
}
}
@EventHandler
public void onPlayerArrowBlock(EntityDamageByEntityEvent e) {
try {
Entity entityDamager = e.getDamager();
Entity entityDamaged = e.getEntity();
if (entityDamager instanceof Arrow) {
Arrow arrow = (Arrow) entityDamager;
if (entityDamaged instanceof Player
&& arrow.getShooter() instanceof Player) {
Player damaged = (Player) entityDamaged;
Collection<Player> invisiblePlayers = plugin.getOnlineInvisiblePlayers();
if (invisiblePlayers.contains(damaged)) {
Vector velocity = arrow.getVelocity();
damaged.teleport(damaged.getLocation().add(0, 2, 0));
Arrow nextArrow = arrow.getShooter().launchProjectile(Arrow.class);
nextArrow.setVelocity(velocity);
nextArrow.setBounce(false);
nextArrow.setShooter(arrow.getShooter());
nextArrow.setFireTicks(arrow.getFireTicks());
nextArrow.setCritical(arrow.isCritical());
nextArrow.setKnockbackStrength(arrow
.getKnockbackStrength());
e.setCancelled(true);
arrow.remove();
}
}
}
} catch (Exception er) {
plugin.printException(er);
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onEssentialsEnable(PluginEnableEvent e) {
try {
final Collection<Player> invisiblePlayers = plugin.getOnlineInvisiblePlayers();
if (e.getPlugin().getName().equalsIgnoreCase("Essentials")
&& getSettings().getBoolean("Configuration.Hooks.EnableEssentialsHook")) {
Bukkit.getServer().getScheduler()
.scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
for (Player player : Bukkit.getOnlinePlayers()) {
if (invisiblePlayers.contains(player)) {
EssentialsHook.hidePlayer(player);
}
}
}
}, 5);
}
} catch (Exception er) {
plugin.printException(er);
}
}
}
@@ -1,85 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.events;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.hooks.EssentialsHook;
import de.myzelyam.supervanish.utils.PlayerCache;
import de.myzelyam.supervanish.utils.ProtocolLibPacketUtils;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.plugin.EventExecutor;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.util.List;
public class JoinEvent implements EventExecutor, Listener {
private final SuperVanish plugin;
public JoinEvent(SuperVanish plugin) {
this.plugin = plugin;
}
private FileConfiguration getSettings() {
return plugin.settings;
}
@SuppressWarnings("deprecation")
@Override
public void execute(Listener listener, Event event) {
try {
if (event instanceof PlayerJoinEvent) {
PlayerJoinEvent e = (PlayerJoinEvent) event;
final Player p = e.getPlayer();
PlayerCache.fromPlayer(p);
final List<String> invisiblePlayers = plugin.getAllInvisiblePlayers();
if (getSettings().getBoolean(
"Configuration.Messages.HideNormalJoinAndLeaveMessagesWhileInvisible", true)
&& invisiblePlayers.contains(p.getUniqueId().toString())) {
e.setJoinMessage(null);
}
// vanished:
if (invisiblePlayers.contains(p.getUniqueId().toString())) {
if (plugin.getServer().getPluginManager()
.getPlugin("Essentials") != null
&& getSettings().getBoolean("Configuration.Hooks.EnableEssentialsHook")) {
EssentialsHook.hidePlayer(p);
}
if (getSettings().getBoolean("Configuration.Messages.RemindInvisiblePlayersOnJoin")) {
p.sendMessage(plugin.convertString(
plugin.getMsg("RemindingMessage"), p));
}
plugin.getVisibilityAdjuster().getHider().hideToAll(p);
p.setMetadata("vanished", new FixedMetadataValue(plugin, true));
if (plugin.getActionBarMgr() != null
&& getSettings().getBoolean(
"Configuration.Messages.DisplayActionBarsToInvisiblePlayers")) {
plugin.getActionBarMgr().addActionBar(p);
}
if (plugin.packetNightVision && getSettings().getBoolean(
"Configuration.Players.AddNightVision"))
plugin.getProtocolLibPacketUtils().sendAddPotionEffect(p, new PotionEffect(
PotionEffectType.NIGHT_VISION,
ProtocolLibPacketUtils.INFINITE_POTION_DURATION, 0));
if (plugin.getTeamMgr() != null)
plugin.getTeamMgr().setCantPush(p);
}
// not necessarily vanished:
plugin.getVisibilityAdjuster().getHider().hideAllInvisibleTo(p);
}
} catch (Exception er) {
plugin.printException(er);
}
}
}
@@ -1,68 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.events;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.utils.PlayerCache;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.EventException;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.EventExecutor;
import java.util.Collection;
public class QuitEvent implements EventExecutor, Listener {
private final SuperVanish plugin;
public QuitEvent(SuperVanish plugin) {
this.plugin = plugin;
}
private FileConfiguration getSettings() {
return plugin.settings;
}
@Override
public void execute(Listener listener, Event event) throws EventException {
try {
if (event instanceof PlayerQuitEvent) {
PlayerQuitEvent e = (PlayerQuitEvent) event;
FileConfiguration config = plugin.getConfig();
Collection<Player> onlineInvisiblePlayers = plugin.getOnlineInvisiblePlayers();
Player p = e.getPlayer();
if (onlineInvisiblePlayers.contains(p)) plugin.getTeamMgr().setCanPush(p);
if (getSettings().getBoolean("Configuration.Players.ReappearOnQuit")
&& onlineInvisiblePlayers.contains(p)) {
plugin.getVisibilityAdjuster().showPlayer(p, true);
if (getSettings().getBoolean("Configuration.Players.ReappearOnQuitHandleLeaveMsg")
&& config.getBoolean(
"Configuration.Messages.HideNormalJoinAndLeaveMessagesWhileInvisible")) {
e.setQuitMessage(null);
}
return;
}
if (config
.getBoolean("Configuration.Messages.HideNormalJoinAndLeaveMessagesWhileInvisible")
&& onlineInvisiblePlayers.contains(p)) {
e.setQuitMessage(null);
}
if (plugin.getActionBarMgr() != null && getSettings().getBoolean(
"Configuration.Messages.DisplayActionBarsToInvisiblePlayers")) {
plugin.getActionBarMgr().removeActionBar(p);
}
PlayerCache.getPlayerCacheMap().remove(p);
}
} catch (Exception er) {
plugin.printException(er);
}
}
}
@@ -1,69 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.events;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.utils.ProtocolLibPacketUtils;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable;
public class WorldChangeEvent implements Listener {
private final SuperVanish plugin;
public WorldChangeEvent(SuperVanish plugin) {
this.plugin = plugin;
}
private FileConfiguration getSettings() {
return plugin.settings;
}
@EventHandler(priority = EventPriority.MONITOR)
public void onWorldChange(PlayerChangedWorldEvent e) {
try {
final Player p = e.getPlayer();
if (!plugin.getOnlineInvisiblePlayers().contains(p))
return;
// check auto-reappear-option
if (getSettings().getBoolean("Configuration.Players.ReappearOnWorldChange")) {
plugin.getVisibilityAdjuster().showPlayer(p);
return;
}
// re-hide
plugin.getVisibilityAdjuster().getHider().hideToAll(p);
// re-add night vision (removed in teleport event)
if (getSettings().getBoolean("Configuration.Players.AddNightVision"))
if (plugin.packetNightVision) {
plugin.getProtocolLibPacketUtils().sendAddPotionEffect(p, new PotionEffect(
PotionEffectType.NIGHT_VISION,
ProtocolLibPacketUtils.INFINITE_POTION_DURATION, 0));
new BukkitRunnable() {
@Override
public void run() {
plugin.getProtocolLibPacketUtils().sendAddPotionEffect(p, new PotionEffect(
PotionEffectType.NIGHT_VISION,
ProtocolLibPacketUtils
.INFINITE_POTION_DURATION, 0));
}
}.runTaskLater(plugin, 1);
} else
p.addPotionEffect(new PotionEffect(
PotionEffectType.NIGHT_VISION, Integer.MAX_VALUE, 1));
} catch (Exception er) {
plugin.printException(er);
}
}
}
@@ -0,0 +1,44 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.features;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.event.Listener;
/**
* Represents a toggleable feature of SuperVanish
*/
public abstract class Feature implements Listener {
protected final SuperVanish plugin;
public Feature(SuperVanish plugin) {
this.plugin = plugin;
}
public void onEnable() {
}
public void onDisable() {
}
public abstract boolean isActive();
protected void delay(Runnable runnable) {
plugin.getServer().getScheduler().runTaskLater(plugin, runnable, 1);
}
}
@@ -0,0 +1,165 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.features;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.event.HandlerList;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.utils.Requirement;
public class FeatureMgr {
private static final Requirement<FeatureInfo> protocolLibInstalled = featureInfo -> Bukkit.getPluginManager()
.isPluginEnabled("ProtocolLib");
private static final Requirement<FeatureInfo> oneDotEightOrHigher = featureInfo -> featureInfo.getPlugin()
.getVersionUtil().isOneDotXOrHigher(8);
private static final Requirement<FeatureInfo> oneDotSeventeenOrHigher = featureInfo -> featureInfo.getPlugin()
.getVersionUtil().isOneDotXOrHigher(17);
private static final Requirement<FeatureInfo> supportedServer = featureInfo -> "Paper"
.equals(Bukkit.getServer().getName()) || "Purpur".equals(Bukkit.getServer().getName());
private final Map<String, FeatureInfo> registeredFeatures = new HashMap<>();
private final Set<Feature> activeFeatures = new HashSet<>();
private final SuperVanish plugin;
public FeatureMgr(SuperVanish plugin) {
this.plugin = plugin;
registeredFeatures.put("SilentOpenChest", new FeatureInfo(SilentOpenChest.class, plugin,
Arrays.asList(protocolLibInstalled, oneDotEightOrHigher)));
registeredFeatures.put("NightVision",
new FeatureInfo(NightVision.class, plugin, Arrays.asList(protocolLibInstalled, oneDotEightOrHigher)));
registeredFeatures.put("VanishIndication", new FeatureInfo(VanishIndication.class, plugin,
Arrays.asList(protocolLibInstalled, oneDotEightOrHigher)));
registeredFeatures.put("NoSculkSensorDetection", new FeatureInfo(NoSculkSensorDetection.class, plugin,
Collections.singletonList(oneDotSeventeenOrHigher)));
registeredFeatures.put("NoTurtleEggBreaking",
new FeatureInfo(NoTurtleEggBreaking.class, plugin, Collections.singletonList(oneDotSeventeenOrHigher)));
registeredFeatures.put("NoDripLeafTilt",
new FeatureInfo(NoDripLeafTilt.class, plugin, Collections.singletonList(oneDotSeventeenOrHigher)));
registeredFeatures.put("NoRaidTrigger",
new FeatureInfo(NoRaidTrigger.class, plugin, Collections.singletonList(oneDotSeventeenOrHigher)));
registeredFeatures.put("NoMobSpawn",
new FeatureInfo(NoMobSpawn.class, plugin, Collections.singletonList(supportedServer)));
}
public void enableFeatures() {
featureLoop: for (String id : registeredFeatures.keySet()) {
final FeatureInfo featureInfo = registeredFeatures.get(id);
for (Requirement<FeatureInfo> requirement : featureInfo.getRequirements()) {
if (!requirement.fulfilledBy(featureInfo)) {
continue featureLoop;
}
}
final Feature feature;
try {
feature = featureInfo.getFeatureClass().getConstructor(SuperVanish.class).newInstance(plugin);
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException
| IllegalAccessException e)
{
plugin.logException(e);
continue;
}
if (!feature.isActive()) {
continue;
}
activeFeatures.add(feature);
Bukkit.getPluginManager().registerEvents(feature, plugin);
feature.onEnable();
}
}
public void disableFeatures() {
activeFeatures.forEach(feature -> {
feature.onDisable();
HandlerList.unregisterAll(feature);
});
activeFeatures.clear();
}
@SuppressWarnings("unchecked")
public <T extends Feature> T getFeature(Class<T> featureClass) {
// noinspection unchecked on purpose
return activeFeatures.stream().filter(feature -> feature.getClass().equals(featureClass)).findFirst()
.map(feature -> (T) feature).orElse(null);
}
public Set<Feature> getActiveFeatures() {
return activeFeatures;
}
private record FeatureInfo(Class<? extends Feature> featureClass, SuperVanish plugin,
Collection<Requirement<FeatureInfo>> requirements)
{
FeatureInfo(Class<? extends Feature> featureClass, SuperVanish plugin) {
this(featureClass, plugin, Collections.emptySet());
}
public Class<? extends Feature> getFeatureClass() {
return featureClass;
}
public Collection<Requirement<FeatureInfo>> getRequirements() {
return requirements;
}
public SuperVanish getPlugin() {
return plugin;
}
}
}
@@ -0,0 +1,169 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.features;
import de.myzelyam.api.vanish.PlayerHideEvent;
import de.myzelyam.api.vanish.PlayerShowEvent;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class NightVision extends Feature implements Runnable {
public static final int INFINITE_POTION_EFFECT_LENGTH = 32767;
private final Map<UUID, PotionEffect> playerPreviousPotionEffectMap = new HashMap<>();
public NightVision(SuperVanish plugin) {
super(plugin);
}
@Override
public void onEnable() {
plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, this, 20 * 60 * 2, 20 * 60 * 2);
}
@Override
public boolean isActive() {
return plugin.getSettings().getBoolean("InvisibilityFeatures.NightVisionEffect");
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onVanish(PlayerHideEvent e) {
Player p = e.getPlayer();
// getPotionEffect(..) is 1.10+ API
if (plugin.getVersionUtil().isOneDotXOrHigher(10)) {
if (p.getPotionEffect(PotionEffectType.NIGHT_VISION) != null) {
playerPreviousPotionEffectMap.put(p.getUniqueId(), p.getPotionEffect(PotionEffectType.NIGHT_VISION));
}
}
sendAddPotionEffect(p);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onReappear(PlayerShowEvent e) {
Player p = e.getPlayer();
sendRemovePotionEffect(p);
if (playerPreviousPotionEffectMap.containsKey(p.getUniqueId())) {
p.addPotionEffect(playerPreviousPotionEffectMap.remove(p.getUniqueId()));
}
}
@EventHandler
public void onJoin(PlayerJoinEvent e) {
Player p = e.getPlayer();
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId())) {
if (playerPreviousPotionEffectMap.containsKey(p.getUniqueId())) {
p.addPotionEffect(playerPreviousPotionEffectMap.remove(p.getUniqueId()));
}
} else {
sendAddPotionEffect(p);
}
}
@EventHandler
public void onQuit(PlayerQuitEvent e) {
Player p = e.getPlayer();
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
return;
sendRemovePotionEffect(p);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onTeleport(PlayerTeleportEvent e) {
Player p = e.getPlayer();
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
return;
if (e.getFrom().getWorld() == null || e.getTo() == null || e.getTo().getWorld() == null
|| e.getFrom().getWorld().getName().equals(e.getTo().getWorld().getName()))
return;
sendRemovePotionEffect(p);
}
@EventHandler
public void onWorldChange(PlayerChangedWorldEvent e) {
Player p = e.getPlayer();
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
return;
sendAddPotionEffect(p);
}
@Override
public void run() {
// renew every now and then to prevent blinking bug
for (UUID uuid : plugin.getVanishStateMgr().getOnlineVanishedPlayers()) {
Player p = Bukkit.getPlayer(uuid);
if (p == null)
continue;
sendRemovePotionEffect(p);
sendAddPotionEffect(p);
}
}
private void sendAddPotionEffect(Player p) {
p.addPotionEffect(
new PotionEffect(PotionEffectType.NIGHT_VISION, INFINITE_POTION_EFFECT_LENGTH, 0, true, false));
}
private void sendRemovePotionEffect(Player p) {
p.removePotionEffect(PotionEffectType.NIGHT_VISION);
}
}
@@ -0,0 +1,38 @@
package de.myzelyam.supervanish.features;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
public class NoDripLeafTilt extends Feature {
public NoDripLeafTilt(SuperVanish plugin) {
super(plugin);
}
@EventHandler(priority = EventPriority.HIGH)
public void onInteract(PlayerInteractEvent e) {
Player p = e.getPlayer();
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
return;
if (!e.getAction().equals(Action.PHYSICAL) || e.getClickedBlock() == null
|| !e.getClickedBlock().getType().toString().equals("BIG_DRIPLEAF"))
return;
e.setCancelled(true);
}
@Override
public boolean isActive() {
return plugin.getSettings().getBoolean("InvisibilityFeatures.DisableDripLeaf", true);
}
}
@@ -0,0 +1,140 @@
package de.myzelyam.supervanish.features;
import com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent;
import com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent;
import com.destroystokyo.paper.event.entity.SkeletonHorseTrapEvent;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import java.util.List;
import java.util.UUID;
public class NoMobSpawn extends Feature {
private boolean suppressErrors = false;
public NoMobSpawn(SuperVanish plugin) {
super(plugin);
}
@EventHandler
public void onSkeletonHorseTrap(SkeletonHorseTrapEvent e) {
try {
List<HumanEntity> humans = e.getEligibleHumans();
int humansCount = humans.size();
for (HumanEntity human : humans) {
if (human instanceof Player) {
Player p = (Player) human;
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId())) {
humansCount--;
}
}
}
if (humansCount == 0)
e.setCancelled(true);
} catch (Exception er) {
if (!suppressErrors) {
plugin.logException(er);
suppressErrors = true;
}
}
}
@EventHandler
public void onEntitySpawn(PlayerNaturallySpawnCreaturesEvent e) {
try {
if (plugin.getVanishStateMgr().isVanished(e.getPlayer().getUniqueId()))
e.setCancelled(true);
} catch (Exception er) {
if (!suppressErrors) {
plugin.logException(er);
suppressErrors = true;
}
}
}
@EventHandler
public void onEntitySpawnerSpawn(PreSpawnerSpawnEvent e) {
try {
// First check if a non-spectator vanished player is in range
boolean vanishedPlayerInRange = false;
for (UUID vanishedUUID : plugin.getVanishStateMgr().getOnlineVanishedPlayers()) {
Player p = Bukkit.getPlayer(vanishedUUID);
if (p == null)
continue;
if (p.getWorld().equals(e.getSpawnerLocation().getWorld())
&& p.getLocation().distanceSquared(e.getSpawnerLocation()) <= 256
&& p.getGameMode() != GameMode.SPECTATOR)
vanishedPlayerInRange = true;
}
if (!vanishedPlayerInRange)
return;
// If so, only cancel if no non-vanished player is in range
for (Player p : Bukkit.getOnlinePlayers()) {
if (p.getWorld().equals(e.getSpawnerLocation().getWorld())
&& p.getLocation().distanceSquared(e.getSpawnerLocation()) <= 256
&& p.getGameMode() != GameMode.SPECTATOR
&& !plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
return;
}
e.setCancelled(true);
} catch (Exception er) {
if (!suppressErrors) {
plugin.logException(er);
suppressErrors = true;
}
}
}
@Override
public boolean isActive() {
return plugin.getSettings().getBoolean("InvisibilityFeatures.PreventMobSpawning", true);
}
}
@@ -0,0 +1,104 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.features;
import de.myzelyam.api.vanish.PlayerHideEvent;
import de.myzelyam.api.vanish.PlayerShowEvent;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scoreboard.Team;
public class NoPush extends Feature {
public NoPush(SuperVanish plugin) {
super(plugin);
}
@Override
public boolean isActive() {
return plugin.getSettings().getBoolean("InvisibilityFeatures.DisablePush");
}
public void setCantPush(Player p) {
Team team = p.getScoreboard().getTeam("Vanished");
if (team == null) {
team = p.getScoreboard().registerNewTeam("Vanished");
}
try {
team.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER);
team.addEntry(p.getName());
} catch (NoSuchMethodError | NoClassDefFoundError ignored) {
}
}
public void setCanPush(Player p) {
Team team = p.getScoreboard().getTeam("Vanished");
if (team != null)
team.removeEntry(p.getName());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onVanish(PlayerHideEvent e) {
setCantPush(e.getPlayer());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onReappear(PlayerShowEvent e) {
setCanPush(e.getPlayer());
}
@EventHandler
public void onJoin(final PlayerJoinEvent e) {
if (plugin.getVanishStateMgr().isVanished(e.getPlayer().getUniqueId()))
new BukkitRunnable() {
@Override
public void run() {
setCantPush(e.getPlayer());
}
}.runTaskLater(plugin, 5);
}
@EventHandler
public void onQuit(PlayerQuitEvent e) {
setCanPush(e.getPlayer());
}
}
@@ -0,0 +1,34 @@
package de.myzelyam.supervanish.features;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.raid.RaidTriggerEvent;
public class NoRaidTrigger extends Feature {
public NoRaidTrigger(SuperVanish plugin) {
super(plugin);
}
@EventHandler(priority = EventPriority.HIGH)
public void onInteract(RaidTriggerEvent e) {
Player p = e.getPlayer();
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
return;
e.setCancelled(true);
}
@Override
public boolean isActive() {
return plugin.getSettings().getBoolean("InvisibilityFeatures.PreventRaidTriggering", true);
}
}
@@ -0,0 +1,52 @@
package de.myzelyam.supervanish.features;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockReceiveGameEvent;
import org.bukkit.event.player.PlayerInteractEvent;
public class NoSculkSensorDetection extends Feature {
public NoSculkSensorDetection(SuperVanish plugin) {
super(plugin);
}
@EventHandler(priority = EventPriority.HIGH)
public void onSculkSensorTrigger(BlockReceiveGameEvent e) {
if (!(e.getEntity() instanceof Player))
return;
Player p = (Player) e.getEntity();
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
return;
e.setCancelled(true);
}
@EventHandler(priority = EventPriority.HIGH)
public void onInteract(PlayerInteractEvent e) {
Player p = e.getPlayer();
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
return;
if (!e.getAction().equals(Action.PHYSICAL) || e.getClickedBlock() == null)
return;
if (!e.getClickedBlock().getType().toString().matches("SCULK_SENSOR|CALIBRATED_SCULK_SENSOR|SCULK_SHRIEKER"))
return;
e.setCancelled(true);
}
@Override
public boolean isActive() {
return plugin.getSettings().getBoolean("InvisibilityFeatures.PreventSculkSensorActivation", true);
}
}
@@ -0,0 +1,38 @@
package de.myzelyam.supervanish.features;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
public class NoTurtleEggBreaking extends Feature {
public NoTurtleEggBreaking(SuperVanish plugin) {
super(plugin);
}
@EventHandler(priority = EventPriority.HIGH)
public void onInteract(PlayerInteractEvent e) {
Player p = e.getPlayer();
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
return;
if (!e.getAction().equals(Action.PHYSICAL) || e.getClickedBlock() == null
|| !e.getClickedBlock().getType().toString().equals("TURTLE_EGG"))
return;
e.setCancelled(true);
}
@Override
public boolean isActive() {
return plugin.getSettings().getBoolean("InvisibilityFeatures.PreventTurtleEggBreaking", true);
}
}
@@ -0,0 +1,456 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.features;
import static org.bukkit.Material.BLACK_SHULKER_BOX;
import static org.bukkit.Material.BLUE_SHULKER_BOX;
import static org.bukkit.Material.BROWN_SHULKER_BOX;
import static org.bukkit.Material.CHEST;
import static org.bukkit.Material.CYAN_SHULKER_BOX;
import static org.bukkit.Material.ENDER_CHEST;
import static org.bukkit.Material.GRAY_SHULKER_BOX;
import static org.bukkit.Material.GREEN_SHULKER_BOX;
import static org.bukkit.Material.ITEM_FRAME;
import static org.bukkit.Material.LIGHT_BLUE_SHULKER_BOX;
import static org.bukkit.Material.LIGHT_GRAY_SHULKER_BOX;
import static org.bukkit.Material.LIME_SHULKER_BOX;
import static org.bukkit.Material.MAGENTA_SHULKER_BOX;
import static org.bukkit.Material.ORANGE_SHULKER_BOX;
import static org.bukkit.Material.PINK_SHULKER_BOX;
import static org.bukkit.Material.PURPLE_SHULKER_BOX;
import static org.bukkit.Material.RED_SHULKER_BOX;
import static org.bukkit.Material.SHULKER_BOX;
import static org.bukkit.Material.TRAPPED_CHEST;
import static org.bukkit.Material.WHITE_SHULKER_BOX;
import static org.bukkit.Material.YELLOW_SHULKER_BOX;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerGameModeChangeEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import com.comphenix.protocol.ProtocolLibrary;
import de.myzelyam.api.vanish.PlayerShowEvent;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.hooks.OpenInvHook;
public class SilentOpenChest extends Feature {
private final Map<Player, StateInfo> playerStateInfoMap = new HashMap<>();
private final Collection<Material> additionalChestMaterials;
public SilentOpenChest(SuperVanish plugin) {
super(plugin);
additionalChestMaterials = new ArrayList<>();
if (plugin.getVersionUtil().isOneDotXOrHigher(11)) {
try {
additionalChestMaterials.addAll(Arrays.asList(BLACK_SHULKER_BOX, BLUE_SHULKER_BOX, BROWN_SHULKER_BOX,
CYAN_SHULKER_BOX, GRAY_SHULKER_BOX, GREEN_SHULKER_BOX, LIGHT_BLUE_SHULKER_BOX, LIME_SHULKER_BOX,
MAGENTA_SHULKER_BOX, ORANGE_SHULKER_BOX, PINK_SHULKER_BOX, PURPLE_SHULKER_BOX, RED_SHULKER_BOX,
WHITE_SHULKER_BOX, YELLOW_SHULKER_BOX));
try {
additionalChestMaterials.add(LIGHT_GRAY_SHULKER_BOX);
} catch (NoSuchFieldError e) {
// Old name.
additionalChestMaterials.add(Material.valueOf("SILVER_SHULKER_BOX"));
}
try {
additionalChestMaterials.add(SHULKER_BOX);
} catch (NoSuchFieldError ignored) {
// no standard shulker box in old versions
}
if (plugin.getVersionUtil().isOneDotXOrHigher(14)) {
additionalChestMaterials.add(Material.valueOf("BARREL"));
}
} catch (NoSuchFieldError | IllegalArgumentException ignored) {
// no shulker box support in very old versions
}
}
}
@Override
public void onDisable() {
for (Player p : playerStateInfoMap.keySet()) {
final StateInfo stateInfo = playerStateInfoMap.remove(p);
if (stateInfo == null) {
continue;
}
restoreState(stateInfo, p);
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void onSpectatorClick(InventoryClickEvent e) {
if (!(e.getWhoClicked() instanceof Player)) {
return;
}
final Player p = (Player) e.getWhoClicked();
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId())) {
return;
}
if (!playerStateInfoMap.containsKey(p)) {
return;
}
if (p.getGameMode() == GameMode.SPECTATOR) {
e.setCancelled(false);
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onQuit(PlayerQuitEvent e) {
final Player p = e.getPlayer();
final StateInfo stateInfo = playerStateInfoMap.remove(p);
if (stateInfo == null) {
return;
}
restoreState(stateInfo, p);
playerStateInfoMap.remove(p);
}
@EventHandler(priority = EventPriority.HIGH)
public void onTeleport(PlayerTeleportEvent e) {
final Player p = e.getPlayer();
if (playerStateInfoMap.containsKey(p) && e.getCause() == PlayerTeleportEvent.TeleportCause.SPECTATE) {
e.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onReappear(PlayerShowEvent e) {
final Player p = e.getPlayer();
final StateInfo stateInfo = playerStateInfoMap.remove(p);
if (stateInfo == null) {
return;
}
p.closeInventory();
restoreState(stateInfo, p);
playerStateInfoMap.remove(p);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onMove(PlayerMoveEvent e) {
final Player p = e.getPlayer();
if (!playerStateInfoMap.containsKey(p)) {
return;
}
final Location loc = e.getTo() != null ? e.getTo() : e.getFrom();
if (playerStateInfoMap.get(p).openLoc.distance(loc) <= .5) {
return;
}
p.closeInventory();
restoreState(playerStateInfoMap.get(p), p);
playerStateInfoMap.remove(p);
}
@EventHandler(priority = EventPriority.NORMAL)
public void onGameModeChange(PlayerGameModeChangeEvent e) {
final Player p = e.getPlayer();
final boolean condition = playerStateInfoMap.containsKey(p) && e.getNewGameMode() != GameMode.SPECTATOR
&& e.isCancelled();
// Don't let low-priority event listeners cancel the gamemode change.
if (condition) {
e.setCancelled(false);
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onChestInteract(PlayerInteractEvent e) {
final Player p = e.getPlayer();
if (!plugin.getVanishStateMgr().isVanished(p.getUniqueId()) || !p.hasPermission("sv.silentchest")) {
return;
}
if (e.getAction() != Action.RIGHT_CLICK_BLOCK) {
return;
}
if (p.getGameMode() == GameMode.SPECTATOR) {
return;
}
final ItemStack heldItem = p.getInventory().getItemInMainHand();
if (p.isSneaking() && heldItem != null && (heldItem.getType().isBlock() || heldItem.getType() == ITEM_FRAME)
&& heldItem.getType() != Material.AIR)
{
return;
}
final Block block = e.getClickedBlock();
if (block == null) {
return;
}
if (block.getType() == ENDER_CHEST) {
e.setCancelled(true);
p.openInventory(p.getEnderChest());
return;
}
if (!(block.getType() == CHEST || block.getType() == TRAPPED_CHEST
|| plugin.getVersionUtil().isOneDotXOrHigher(11) && additionalChestMaterials.contains(block.getType())))
{
return;
}
final StateInfo stateInfo = StateInfo.extract(p);
p.setVelocity(new Vector(0, 0, 0));
playerStateInfoMap.put(p, stateInfo);
p.setGameMode(GameMode.SPECTATOR);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onChestClose(InventoryCloseEvent e) {
if (!(e.getPlayer() instanceof Player)) {
return;
}
final Player p = (Player) e.getPlayer();
if (!playerStateInfoMap.containsKey(p)) {
return;
}
if (!isSilentOpenInventory(e.getView())) {
return;
}
new BukkitRunnable() {
@Override
public void run() {
final StateInfo stateInfo = playerStateInfoMap.get(p);
if (stateInfo == null) {
return;
}
restoreState(stateInfo, p);
playerStateInfoMap.remove(p);
}
}.runTaskLater(plugin, 1);
}
private void restoreState(StateInfo stateInfo, Player p) {
p.setGameMode(stateInfo.gameMode);
p.teleport(p.getLocation().add(0, 0.2, 0));
new BukkitRunnable() {
@Override
public void run() {
p.setAllowFlight(stateInfo.canFly);
p.setFlying(stateInfo.isFlying);
}
}.runTaskLater(plugin, 1);
}
@Override
public boolean isActive() {
return plugin.getSettings().getBoolean("InvisibilityFeatures.OpenChestsSilently")
&& !(plugin.getPluginHookMgr() != null && plugin.getPluginHookMgr().isHookActive(OpenInvHook.class));
}
private boolean isShulkerBox(Inventory inv) {
try {
return inv.getType() == InventoryType.SHULKER_BOX;
} catch (NoSuchFieldError e) {
return false;
}
}
private boolean isShulkerBox(InventoryView inv) {
return isShulkerBox(inv.getTopInventory());
}
private boolean isBarrel(InventoryView inv) {
try {
return inv.getType() == InventoryType.BARREL;
} catch (NoSuchFieldError e) {
return false;
}
}
private boolean isSilentOpenInventory(InventoryView inv) {
return inv.getType() == InventoryType.CHEST || inv.getType() == InventoryType.ENDER_CHEST || isShulkerBox(inv)
|| isBarrel(inv);
}
public boolean hasSilentlyOpenedChest(Player p) {
return playerStateInfoMap.containsKey(p);
}
@Override
public void onEnable() {
// ProtocolLib 5.0 maps PLAYER_INFO to ClientboundPlayerInfoUpdatePacket
final SilentOpenChestPacketAdapter packetAdapter = new SilentOpenChestPacketAdapter(this);
ProtocolLibrary.getProtocolManager().addPacketListener(packetAdapter);
}
private record StateInfo(boolean canFly, boolean isFlying, GameMode gameMode, Location openLoc) {
static StateInfo extract(Player p) {
return new StateInfo(p.getAllowFlight(), p.isFlying(), p.getGameMode(), p.getLocation());
}
}
}
@@ -0,0 +1,205 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* license, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.features;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.reflect.FieldAccessException;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.PlayerInfoData;
import com.google.common.collect.ImmutableList;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import static com.comphenix.protocol.PacketType.Play.Server.*;
/**
* Adapter that masks a vanished player's silent-chest spectator state from
* other clients. On Purpur 1.19.4 ProtocolLib's PLAYER_INFO type maps to
* ClientboundPlayerInfoUpdatePacket which carries a Set<Action> instead of the
* legacy single action; ViaSuite handles client-side re-encoding for connected
* versions 1.8-1.21.x.
*/
public class SilentOpenChestPacketAdapter extends PacketAdapter {
private final SilentOpenChest silentOpenChest;
private boolean suppressErrors = false;
public SilentOpenChestPacketAdapter(SilentOpenChest silentOpenChest) {
super(silentOpenChest.plugin, ListenerPriority.LOW, PLAYER_INFO, ABILITIES, ENTITY_METADATA);
this.silentOpenChest = silentOpenChest;
}
@Override
public void onPacketSending(PacketEvent event) {
try {
Player receiver = event.getPlayer();
if (receiver == null)
return;
if (event.getPacketType() == PLAYER_INFO) {
// multiple events share same packet object
event.setPacket(event.getPacket().shallowClone());
if (!isGameModeUpdate(event))
return;
List<PlayerInfoData> infoDataList = new ArrayList<>(event.getPacket().getPlayerInfoDataLists().read(0));
boolean modified = false;
for (PlayerInfoData infoData : ImmutableList.copyOf(infoDataList)) {
UUID uuid = extractUUID(infoData);
if (uuid == null)
continue;
if (silentOpenChest.plugin.getVisibilityChanger().getHider().isHidden(uuid, receiver))
continue;
if (!silentOpenChest.plugin.getVanishStateMgr().isVanished(uuid))
continue;
if (infoData.getGameMode() != EnumWrappers.NativeGameMode.SPECTATOR)
continue;
Player vanishedTabPlayer = Bukkit.getPlayer(uuid);
if (vanishedTabPlayer == null || !silentOpenChest.hasSilentlyOpenedChest(vanishedTabPlayer))
continue;
PlayerInfoData newData = new PlayerInfoData(uuid, infoData.getLatency(), infoData.isListed(),
EnumWrappers.NativeGameMode.SURVIVAL, infoData.getProfile(), infoData.getDisplayName(),
infoData.getRemoteChatSessionData());
int index = infoDataList.indexOf(infoData);
infoDataList.set(index, newData);
modified = true;
}
if (modified)
event.getPacket().getPlayerInfoDataLists().write(0, infoDataList);
} else if (event.getPacketType() == GAME_STATE_CHANGE) {
// Currently unused due to ProtocolLib class loading bug
if (silentOpenChest.plugin.getVanishStateMgr().isVanished(receiver.getUniqueId())) {
try {
if (event.getPacket().getIntegers().read(0) != 3)
return;
} catch (FieldAccessException e) {
// TODO
}
if (!silentOpenChest.hasSilentlyOpenedChest(receiver))
return;
event.setCancelled(true);
}
} else if (event.getPacketType() == ABILITIES) {
if (silentOpenChest.plugin.getVanishStateMgr().isVanished(receiver.getUniqueId())) {
if (!silentOpenChest.hasSilentlyOpenedChest(receiver))
return;
event.setCancelled(true);
}
} else if (event.getPacketType() == ENTITY_METADATA) {
int entityID = event.getPacket().getIntegers().read(0);
if (entityID == receiver.getEntityId()) {
if (silentOpenChest.plugin.getVanishStateMgr().isVanished(receiver.getUniqueId())) {
if (!silentOpenChest.hasSilentlyOpenedChest(receiver))
return;
event.setCancelled(true);
}
}
}
} catch (Exception | NoClassDefFoundError e) {
if (!suppressErrors) {
if (e.getMessage() == null || !e.getMessage().endsWith("is not supported for temporary players.")) {
silentOpenChest.plugin.logException(e);
silentOpenChest.plugin.getLogger()
.warning("IMPORTANT: Please make sure that you are using the latest "
+ "dev-build of ProtocolLib and that your server is up-to-date! This error likely "
+ "happened inside of ProtocolLib code which is out of Vanish-OG's control. It's part "
+ "of an optional feature module and can be removed safely by disabling "
+ "OpenChestsSilently in the config file. Please report this "
+ "error if you can reproduce it on an up-to-date server with only latest "
+ "ProtocolLib and latest Vanish-OG installed.");
suppressErrors = true;
}
}
}
}
private boolean isGameModeUpdate(PacketEvent event) {
// 1.19.3+: ClientboundPlayerInfoUpdatePacket exposes Set<Action>
try {
Set<EnumWrappers.PlayerInfoAction> actions = event.getPacket().getPlayerInfoActions().read(0);
if (actions != null)
return actions.contains(EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE);
} catch (FieldAccessException | IllegalArgumentException ignored) {
// legacy single-action packet on pre-1.19.3
}
try {
EnumWrappers.PlayerInfoAction action = event.getPacket().getPlayerInfoAction().read(0);
return action == EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE;
} catch (FieldAccessException | IllegalArgumentException ignored) {
return false;
}
}
private UUID extractUUID(PlayerInfoData infoData) {
UUID uuid = infoData.getProfileId();
if (uuid != null)
return uuid;
if (infoData.getProfile() != null)
return infoData.getProfile().getUUID();
return null;
}
}
@@ -0,0 +1,316 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.features;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.reflect.FieldAccessException;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.PlayerInfoData;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.comphenix.protocol.wrappers.WrappedRemoteChatSessionData;
import de.myzelyam.api.vanish.PlayerShowEvent;
import de.myzelyam.api.vanish.PostPlayerHideEvent;
import de.myzelyam.supervanish.SuperVanish;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerJoinEvent;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import static com.comphenix.protocol.PacketType.Play.Server.PLAYER_INFO;
/**
* Marks visible vanished players as spectators in player info updates. On
* Purpur 1.19.4 this operates on the server-native
* ClientboundPlayerInfoUpdatePacket format and ViaSuite handles translation for
* connected 1.8-1.21.x clients.
*/
public class VanishIndication extends Feature {
private boolean suppressErrors = false;
public VanishIndication(SuperVanish plugin) {
super(plugin);
}
@Override
public boolean isActive() {
return plugin.getSettings().getBoolean("IndicationFeatures.MarkVanishedPlayersAsSpectators");
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onVanish(PostPlayerHideEvent e) {
Player p = e.getPlayer();
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
if (!plugin.getVisibilityChanger().getHider().isHidden(p, onlinePlayer) && p != onlinePlayer) {
sendPlayerInfoChangeGameModePacket(onlinePlayer, p, true);
}
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onReappear(PlayerShowEvent e) {
final Player p = e.getPlayer();
for (final Player onlinePlayer : Bukkit.getOnlinePlayers()) {
if (!plugin.getVisibilityChanger().getHider().isHidden(p, onlinePlayer) && p != onlinePlayer) {
delay(() -> sendPlayerInfoChangeGameModePacket(onlinePlayer, p, false));
}
}
}
@EventHandler
public void onJoin(PlayerJoinEvent e) {
final Player p = e.getPlayer();
delay(() -> {
// tell others that p is a spectator
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId()))
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
if (!plugin.getVisibilityChanger().getHider().isHidden(p, onlinePlayer) && p != onlinePlayer) {
sendPlayerInfoChangeGameModePacket(onlinePlayer, p, true);
}
}
// tell p that others are spectators
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
if (!plugin.getVanishStateMgr().isVanished(onlinePlayer.getUniqueId()))
continue;
if (!plugin.getVisibilityChanger().getHider().isHidden(onlinePlayer, p) && p != onlinePlayer) {
sendPlayerInfoChangeGameModePacket(p, onlinePlayer, true);
}
}
});
}
@Override
public void onEnable() {
ProtocolLibrary.getProtocolManager().addPacketListener(
new PacketAdapter(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.PLAYER_INFO)
{
@Override
public void onPacketSending(PacketEvent event) {
try {
if (VanishIndication.this.plugin.getVanishStateMgr().getOnlineVanishedPlayers().isEmpty())
return;
// multiple events share same packet object
event.setPacket(event.getPacket().shallowClone());
List<PlayerInfoData> infoDataList = new ArrayList<>(
event.getPacket().getPlayerInfoDataLists().read(0));
Player receiver = event.getPlayer();
boolean modified = false;
// Iterate a snapshot (ArrayList tolerates nulls; ImmutableList does not)
// so we can safely set() on infoDataList during the loop. ProtocolLib
// can hand back null entries during login packet flow on 1.19.4.
for (PlayerInfoData infoData : new ArrayList<>(infoDataList)) {
try {
if (!isGameModeUpdate(event))
break;
if (infoData == null)
continue;
if (extractUUID(infoData) == null)
continue;
if (!VanishIndication.this.plugin.getVisibilityChanger().getHider()
.isHidden(extractUUID(infoData), receiver)
&& VanishIndication.this.plugin.getVanishStateMgr()
.isVanished(extractUUID(infoData)))
{
if (!receiver.getUniqueId().equals(extractUUID(infoData)))
if (infoData.getGameMode() != EnumWrappers.NativeGameMode.SPECTATOR) {
PlayerInfoData newData = createGameModeUpdate(infoData,
EnumWrappers.NativeGameMode.SPECTATOR);
int index = infoDataList.indexOf(infoData);
infoDataList.set(index, newData);
modified = true;
}
}
} catch (UnsupportedOperationException ignored) {
}
}
// Untouched packets must not be rewritten: writing back into
// ClientboundPlayerInfoUpdatePacket on 1.19.3+ also rewrites its
// final EnumSet<Action> field, which ProtocolLib cannot mutate.
if (modified)
event.getPacket().getPlayerInfoDataLists().write(0, infoDataList);
} catch (Exception | NoClassDefFoundError e) {
if (!suppressErrors) {
VanishIndication.this.plugin.logException(e);
plugin.getLogger().warning("IMPORTANT: Please make sure that you are using the latest "
+ "dev-build of ProtocolLib and that your server is up-to-date! This error likely "
+ "happened inside of ProtocolLib code which is out of Vanish-OG's control. It's part "
+ "of an optional feature module and can be removed safely by disabling "
+ "MarkVanishedPlayersAsSpectators in the config file. Please report this "
+ "error if you can reproduce it on an up-to-date server with only latest "
+ "ProtocolLib and latest Vanish-OG installed.");
suppressErrors = true;
}
}
}
});
}
private void sendPlayerInfoChangeGameModePacket(Player p, Player change, boolean spectator) {
PacketContainer packet = new PacketContainer(PLAYER_INFO);
if (plugin.getVersionUtil().isOneDotXOrHigher(19)) {
packet.getPlayerInfoActions().write(0, EnumSet.of(EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE));
} else {
packet.getPlayerInfoAction().write(0, EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE);
}
List<PlayerInfoData> data = new ArrayList<>();
int ping = ThreadLocalRandom.current().nextInt(20) + 15;
EnumWrappers.NativeGameMode gameMode = spectator ? EnumWrappers.NativeGameMode.SPECTATOR
: EnumWrappers.NativeGameMode.fromBukkit(change.getGameMode());
WrappedChatComponent displayName = WrappedChatComponent
.fromText(LegacyComponentSerializer.legacySection().serialize(change.playerListName()));
WrappedGameProfile profile = WrappedGameProfile.fromPlayer(change);
if (plugin.getVersionUtil().isOneDotXOrHigher(19)) {
data.add(new PlayerInfoData(change.getUniqueId(), ping, true, gameMode, profile, displayName,
(WrappedRemoteChatSessionData) null));
} else {
data.add(new PlayerInfoData(profile, ping, gameMode, displayName));
}
packet.getPlayerInfoDataLists().write(0, data);
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(p, packet);
} catch (Exception e) {
throw new RuntimeException("Cannot send packet", e);
}
}
private boolean isGameModeUpdate(PacketEvent event) {
try {
Set<EnumWrappers.PlayerInfoAction> actions = event.getPacket().getPlayerInfoActions().read(0);
if (actions != null)
return actions.contains(EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE);
} catch (FieldAccessException | IllegalArgumentException ignored) {
// legacy single-action packet on pre-1.19.3
}
try {
EnumWrappers.PlayerInfoAction action = event.getPacket().getPlayerInfoAction().read(0);
return action == EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE;
} catch (FieldAccessException | IllegalArgumentException ignored) {
return false;
}
}
private UUID extractUUID(PlayerInfoData infoData) {
UUID uuid = infoData.getProfileId();
if (uuid != null)
return uuid;
if (infoData.getProfile() != null)
return infoData.getProfile().getUUID();
return null;
}
private PlayerInfoData createGameModeUpdate(PlayerInfoData infoData, EnumWrappers.NativeGameMode gameMode) {
UUID uuid = extractUUID(infoData);
if (plugin.getVersionUtil().isOneDotXOrHigher(19)) {
return new PlayerInfoData(uuid, infoData.getLatency(), infoData.isListed(), gameMode, infoData.getProfile(),
infoData.getDisplayName(), infoData.getRemoteChatSessionData());
}
return new PlayerInfoData(infoData.getProfile(), infoData.getLatency(), gameMode, infoData.getDisplayName());
}
}
@@ -1,68 +1,87 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.hooks;
import de.myzelyam.api.vanish.VanishAPI;
import de.myzelyam.supervanish.SuperVanish;
import net.citizensnpcs.api.ai.speech.SpeechContext;
import net.citizensnpcs.api.ai.speech.Talkable;
import net.citizensnpcs.api.ai.speech.event.NPCSpeechEvent;
import net.citizensnpcs.api.ai.speech.event.SpeechEvent;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import java.util.Iterator;
import java.util.UUID;
public class CitizensHook implements Listener {
public class CitizensHook extends PluginHook {
private final SuperVanish plugin;
public CitizensHook(SuperVanish superVanish) {
super(superVanish);
public CitizensHook(SuperVanish plugin) {
this.plugin = plugin;
Bukkit.getPluginManager().registerEvents(this, plugin);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onNPCTarget(NPCSpeechEvent e) {
e.setCancelled(!checkContext(e.getContext()));
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onSpeechTargeted(SpeechEvent e) {
e.setCancelled(!checkContext(e.getContext()));
}
/**
* @return FALSE if the event should be cancelled, TRUE otherwise
*/
private boolean checkContext(SpeechContext context) {
// don't let it talk about hidden players
for (Player p : plugin.getOnlineInvisiblePlayers()) {
if (context.getMessage().contains(p.getName())) {
for (UUID uuid : superVanish.getVanishStateMgr().getOnlineVanishedPlayers()) {
if (context.getMessage().contains(Bukkit.getPlayer(uuid).getName())) {
return false;
}
}
// don't let hidden players receive it
Iterator<Talkable> iterator = context.iterator();
while (iterator.hasNext()) {
Talkable recipient = iterator.next();
Entity entity = recipient.getEntity();
if (!(entity instanceof Player))
continue;
Player player = (Player) entity;
if (VanishAPI.isInvisible(player)) {
if (superVanish.getVanishStateMgr().isVanished(player.getUniqueId())) {
iterator.remove();
}
}
// cancel contexts with only hidden recipients
return context.hasRecipients();
}
}
@@ -1,36 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.hooks;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import pgDev.bukkit.DisguiseCraft.api.PlayerDisguiseEvent;
public class DisguiseCraftHook implements Listener {
public SuperVanish plugin = (SuperVanish) Bukkit.getPluginManager()
.getPlugin("SuperVanish");
@EventHandler
public void onDisguise(PlayerDisguiseEvent e) {
try {
Player p = e.getPlayer();
if (plugin.playerData.getStringList("InvisiblePlayers")
.contains(p.getUniqueId().toString())) {
p.sendMessage(ChatColor.RED
+ "[SV] You can't disguise yourself at the moment!");
e.setCancelled(true);
}
} catch (Exception er) {
plugin.printException(er);
}
}
}
@@ -1,36 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.hooks;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.dynmap.bukkit.DynmapPlugin;
public abstract class DynmapHook {
public static SuperVanish plugin = (SuperVanish) Bukkit.getPluginManager()
.getPlugin("SuperVanish");
public static void adjustVisibility(Player p, boolean hide) {
try {
DynmapPlugin dynmap = (DynmapPlugin) Bukkit.getPluginManager()
.getPlugin("dynmap");
if (hide) {
dynmap.setPlayerVisiblity(p.getName(), false);
dynmap.sendBroadcastToWeb("",
plugin.convertString(plugin.getMsg("DynmapFakeQuit"), p));
} else {
dynmap.setPlayerVisiblity(p.getName(), true);
dynmap.sendBroadcastToWeb("",
plugin.convertString(plugin.getMsg("DynmapFakeJoin"), p));
}
} catch (Exception e) {
plugin.printException(e);
}
}
}
@@ -1,51 +1,203 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.hooks;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.User;
import de.myzelyam.api.vanish.PlayerHideEvent;
import de.myzelyam.api.vanish.PostPlayerShowEvent;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.commands.CommandAction;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
public abstract class EssentialsHook {
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.UUID;
private static SuperVanish plugin = (SuperVanish) Bukkit.getPluginManager()
.getPlugin("SuperVanish");
public class EssentialsHook extends PluginHook {
private final Set<UUID> preVanishHiddenPlayers = new HashSet<>();
private Essentials essentials;
private BukkitRunnable forcedInvisibilityRunnable = new BukkitRunnable() {
@Override
public void run() {
try {
if (!Bukkit.getPluginManager().isPluginEnabled("Essentials"))
return;
for (UUID uuid : superVanish.getVanishStateMgr().getOnlineVanishedPlayers()) {
Player p = Bukkit.getPlayer(uuid);
User user = essentials.getUser(p);
if (user == null)
continue;
if (!user.isHidden())
user.setHidden(true);
}
} catch (Exception e) {
cancel();
superVanish.logException(e);
}
public static void hidePlayer(Player p) {
try {
Essentials essentials = (Essentials) Bukkit.getPluginManager()
.getPlugin("Essentials");
if (essentials == null)
return;
User u = essentials.getUser(p);
if (u == null)
return;
if (!u.isHidden())
u.setHidden(true);
} catch (Exception e) {
plugin.printException(e);
}
};
private BukkitTask forcedInvisibilityTask;
public EssentialsHook(SuperVanish superVanish) {
super(superVanish);
}
public static void showPlayer(Player p) {
try {
Essentials essentials = (Essentials) Bukkit.getPluginManager()
.getPlugin("Essentials");
if (essentials == null)
return;
User u = essentials.getUser(p);
if (u == null)
return;
if (u.isHidden())
u.setHidden(false);
} catch (Exception e) {
plugin.printException(e);
}
@Override
public void onPluginEnable(Plugin plugin) {
essentials = (Essentials) plugin;
forcedInvisibilityTask = forcedInvisibilityRunnable.runTaskTimer(superVanish, 0, 100);
forcedInvisibilityRunnable.run();
}
@Override
public void onPluginDisable(Plugin plugin) {
essentials = null;
forcedInvisibilityTask.cancel();
}
/**
* Essentials tracks its own vanish list in {@code getVanishedPlayersNew()} and
* re-hides its members from every new joiner via the deprecated
* {@code hidePlayer(Player)} API (see EssentialsPlayerListener#onPlayerJoin).
* That deprecated call parks a {@code null} plugin ref in CraftPlayer's
* invertedVisibilityEntities map, which Vanish-OG's plugin-scoped
* {@code showPlayer(Plugin, Player)} cannot clear. So {@code /sv cleanup} must
* drive Essentials' state back to "not vanished" on every online user — that's
* the only call that removes the entry from Essentials' list *and* fires the
* deprecated {@code showPlayer(Player)} that drops the null ref.
*/
@Override
public void onCleanup() {
if (essentials == null)
return;
for (Player online : Bukkit.getOnlinePlayers()) {
try {
User user = essentials.getUser(online);
if (user == null)
continue;
if (user.isVanished())
user.setVanished(false);
if (user.isHidden())
user.setHidden(false);
} catch (Exception e) {
superVanish.logException(e);
}
}
}
@EventHandler(priority = EventPriority.LOW)
public void onJoin(PlayerJoinEvent e) {
User user = essentials.getUser(e.getPlayer());
if (user == null)
return;
if (superVanish.getVanishStateMgr().isVanished(e.getPlayer().getUniqueId()) && !user.isHidden())
user.setHidden(true);
else
user.setHidden(false);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onVanish(PlayerHideEvent e) {
User user = essentials.getUser(e.getPlayer());
if (user == null)
return;
if (user.isVanished())
user.setVanished(false);
preVanishHiddenPlayers.remove(e.getPlayer().getUniqueId());
user.setHidden(true);
}
@EventHandler
public void onReappear(PostPlayerShowEvent e) {
User user = essentials.getUser(e.getPlayer());
if (user == null)
return;
user.setHidden(false);
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onCommand(final PlayerCommandPreprocessEvent e) {
if (!CommandAction.VANISH_SELF.checkPermission(e.getPlayer(), superVanish))
return;
if (superVanish.getVanishStateMgr().isVanished(e.getPlayer().getUniqueId()))
return;
String command = e.getMessage().toLowerCase(Locale.ENGLISH).split(" ")[0].replace("/", "")
.toLowerCase(Locale.ENGLISH);
if (command.split(":").length > 1)
command = command.split(":")[1];
if (command.equals("supervanish") || command.equals("sv") || command.equals("v") || command.equals("vanish")) {
final User user = essentials.getUser(e.getPlayer());
if (user == null || !user.isAfk())
return;
user.setHidden(true);
preVanishHiddenPlayers.add(e.getPlayer().getUniqueId());
superVanish.getServer().getScheduler().runTaskLater(superVanish, new Runnable() {
@Override
public void run() {
if (preVanishHiddenPlayers.remove(e.getPlayer().getUniqueId())) {
user.setHidden(false);
}
}
}, 1);
}
}
}
@@ -0,0 +1,31 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.hooks;
public class InvalidPluginHookException extends RuntimeException {
private static final long serialVersionUID = 1L;
public InvalidPluginHookException() {
}
public InvalidPluginHookException(String message) {
super(message);
}
public InvalidPluginHookException(Throwable cause) {
super(cause);
}
}
@@ -1,38 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.hooks;
import de.myzelyam.supervanish.SuperVanish;
import me.libraryaddict.disguise.events.DisguiseEvent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class LibsDisguisesHook implements Listener {
public SuperVanish plugin = (SuperVanish) Bukkit.getPluginManager()
.getPlugin("SuperVanish");
@EventHandler
public void onDisguise(DisguiseEvent e) {
try {
if (e.getEntity() instanceof Player) {
Player p = (Player) e.getEntity();
if (plugin.playerData.getStringList("InvisiblePlayers")
.contains(p.getUniqueId().toString())) {
p.sendMessage(ChatColor.RED
+ "[SV] You can't disguise yourself at the moment!");
e.setCancelled(true);
}
}
} catch (Exception er) {
plugin.printException(er);
}
}
}
@@ -0,0 +1,152 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.hooks;
import de.myzelyam.supervanish.SuperVanish;
import io.github.miniplaceholders.api.Expansion;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.Collection;
import java.util.UUID;
public class MiniPlaceholdersHook extends PluginHook {
private static final LegacyComponentSerializer LEGACY_SERIALIZER = LegacyComponentSerializer.legacyAmpersand();
private final String yes, no, prefix, suffix;
private Expansion expansion;
public MiniPlaceholdersHook(SuperVanish superVanish) {
super(superVanish);
yes = superVanish.getMessage("PlaceholderIsVanishedYes");
no = superVanish.getMessage("PlaceholderIsVanishedNo");
prefix = superVanish.getMessage("PlaceholderVanishPrefix");
suffix = superVanish.getMessage("PlaceholderVanishSuffix");
}
@Override
public void onPluginEnable(Plugin plugin) {
expansion = Expansion.builder("supervanish")
.audiencePlaceholder("isvanished", (audience, queue, ctx) -> textTag(isVanishedText(audience)))
.audiencePlaceholder("vanishprefix",
(audience, queue, ctx) -> componentTag(isVanished(audience) ? prefix : ""))
.audiencePlaceholder("vanishsuffix",
(audience, queue, ctx) -> componentTag(isVanished(audience) ? suffix : ""))
.audiencePlaceholder("vanishedplayers", (audience, queue, ctx) -> textTag(getVanishedPlayers(audience)))
.audiencePlaceholder("playercount",
(audience, queue, ctx) -> textTag(String.valueOf(getPlayerCount(audience))))
.build();
expansion.register();
}
@Override
public void onPluginDisable(Plugin plugin) {
if (expansion != null && expansion.registered()) {
expansion.unregister();
}
expansion = null;
}
private String isVanishedText(Object audience) {
return isVanished(audience) ? yes : no;
}
private boolean isVanished(Object audience) {
if (!(audience instanceof Player))
return false;
return superVanish.getVanishStateMgr().isVanished(((Player) audience).getUniqueId());
}
private String getVanishedPlayers(Object audience) {
Player viewer = audience instanceof Player ? (Player) audience : null;
Collection<UUID> onlineVanishedPlayers = superVanish.getVanishStateMgr().getOnlineVanishedPlayers();
StringBuilder playerListMessage = new StringBuilder();
for (UUID uuid : onlineVanishedPlayers) {
Player onlineVanished = Bukkit.getPlayer(uuid);
if (onlineVanished == null)
continue;
if (viewer != null
&& superVanish.getSettings()
.getBoolean("IndicationFeatures.LayeredPermissions.HideInvisibleInCommands", false)
&& !superVanish.hasPermissionToSee(viewer, onlineVanished))
{
continue;
}
if (playerListMessage.length() > 0) {
playerListMessage.append(", ");
}
playerListMessage.append(onlineVanished.getName());
}
return playerListMessage.toString();
}
private int getPlayerCount(Object audience) {
Player viewer = audience instanceof Player ? (Player) audience : null;
int playerCount = Bukkit.getOnlinePlayers().size();
for (UUID uuid : superVanish.getVanishStateMgr().getOnlineVanishedPlayers()) {
Player onlineVanished = Bukkit.getPlayer(uuid);
if (onlineVanished == null)
continue;
if (viewer == null || !superVanish.canSee(viewer, onlineVanished)) {
playerCount--;
}
}
return playerCount;
}
private Tag textTag(String value) {
return Tag.selfClosingInserting(Component.text(value));
}
private Tag componentTag(String value) {
return Tag.selfClosingInserting(LEGACY_SERIALIZER.deserialize(value));
}
}
@@ -0,0 +1,202 @@
package de.myzelyam.supervanish.hooks;
import de.myzelyam.api.vanish.PlayerShowEvent;
import de.myzelyam.api.vanish.PostPlayerHideEvent;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
public class OpenInvHook extends PluginHook {
private boolean errorLogged = false;
private final Set<UUID> alreadyHiddenBeforeVanishing = new HashSet<>();
public OpenInvHook(SuperVanish superVanish) {
super(superVanish);
}
@EventHandler
public void onVanish(PostPlayerHideEvent e) {
try {
Player p = e.getPlayer();
if (getSilentContainerStatus(p)) {
alreadyHiddenBeforeVanishing.add(p.getUniqueId());
} else {
if (!p.hasPermission("sv.silentchest"))
return;
setSilentContainerStatus(p, true);
}
} catch (Exception | NoSuchMethodError | NoClassDefFoundError er) {
if (!errorLogged) {
superVanish.logException(er);
errorLogged = true;
}
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onReappear(PlayerShowEvent e) {
try {
Player p = e.getPlayer();
if (!alreadyHiddenBeforeVanishing.remove(p.getUniqueId())) {
setSilentContainerStatus(p, false);
}
} catch (Exception | NoSuchMethodError | NoClassDefFoundError er) {
if (!errorLogged) {
superVanish.logException(er);
errorLogged = true;
}
}
}
@EventHandler(priority = EventPriority.LOW)
public void onJoin(PlayerJoinEvent e) {
try {
Player p = e.getPlayer();
if (superVanish.getVanishStateMgr().isVanished(p.getUniqueId())) {
if (getSilentContainerStatus(p)) {
alreadyHiddenBeforeVanishing.add(p.getUniqueId());
} else {
if (!p.hasPermission("sv.silentchest"))
return;
setSilentContainerStatus(p, true);
}
}
} catch (Exception | NoSuchMethodError | NoClassDefFoundError er) {
if (!errorLogged) {
superVanish.logException(er);
errorLogged = true;
}
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onQuit(PlayerQuitEvent e) {
try {
Player p = e.getPlayer();
if (superVanish.getVanishStateMgr().isVanished(p.getUniqueId())) {
if (!alreadyHiddenBeforeVanishing.remove(p.getUniqueId())) {
setSilentContainerStatus(p, false);
}
}
} catch (Exception | NoSuchMethodError | NoClassDefFoundError er) {
if (!errorLogged) {
superVanish.logException(er);
errorLogged = true;
}
}
}
public boolean openPlayerInventory(Player vanished, Player target) {
try {
// OpenInv 4.2.0+: openInventory's second arg is ISpecialInventory,
// not org.bukkit.inventory.Inventory. The interface isn't on our
// compile classpath, so resolve it reflectively.
Class<?> iSpecialInventory = Class.forName("com.lishid.openinv.internal.ISpecialInventory");
Method getSpecialInventoryMethod = plugin.getClass().getMethod("getSpecialInventory", Player.class,
boolean.class);
Object specialInventory = getSpecialInventoryMethod.invoke(plugin, target, true);
Method openInventoryMethod = plugin.getClass().getMethod("openInventory", Player.class, iSpecialInventory);
openInventoryMethod.invoke(plugin, vanished, specialInventory);
} catch (Exception | NoSuchMethodError | NoClassDefFoundError e) {
if (!errorLogged) {
superVanish.logException(e);
errorLogged = true;
}
return false;
}
return true;
}
// OpenInv 4.2.0+ signatures take OfflinePlayer, not Player. Player extends
// OfflinePlayer so the argument is compatible; only the reflected lookup
// signature needed updating.
private boolean getSilentContainerStatus(Player player) throws ReflectiveOperationException {
Method method = plugin.getClass().getMethod("getSilentContainerStatus", OfflinePlayer.class);
return (Boolean) method.invoke(plugin, player);
}
private void setSilentContainerStatus(Player player, boolean status) throws ReflectiveOperationException {
Method method = plugin.getClass().getMethod("setSilentContainerStatus", OfflinePlayer.class, boolean.class);
method.invoke(plugin, player, status);
}
}
@@ -0,0 +1,61 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.hooks;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
/**
* Represents a hook into a plugin to support its functionality or make it
* support SuperVanish's functionality
*/
public abstract class PluginHook implements Listener {
protected final SuperVanish superVanish;
protected Plugin plugin;
public PluginHook(SuperVanish superVanish) {
this.superVanish = superVanish;
}
public void onPluginEnable(Plugin plugin) {
}
public void onPluginDisable(Plugin plugin) {
}
/**
* Called by {@code /sv cleanup} so hooks can drop any hide state they are
* responsible for. Default is a no-op — hooks that keep their own vanish
* tracking (Essentials' {@code getVanishedPlayersNew} + deprecated
* {@code hidePlayer(Player)} calls) override this to reset it.
*/
public void onCleanup() {
}
public Plugin getPlugin() {
return plugin;
}
void setPlugin(Plugin plugin) {
this.plugin = plugin;
}
}
@@ -0,0 +1,200 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.hooks;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.plugin.Plugin;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
public class PluginHookMgr implements Listener {
private static final Map<String, Class<? extends PluginHook>> REGISTERED_HOOKS = new HashMap<String, Class<? extends PluginHook>>() {
{
put("Essentials", EssentialsHook.class);
put("Citizens", CitizensHook.class);
put("Utilities-OG", MiniPlaceholdersHook.class);
put("TrailGUI", TrailGUIHook.class);
put("OpenInv", OpenInvHook.class);
put("TAB-OG", TabOGHook.class);
}
};
private final SuperVanish plugin;
private Set<PluginHook> activeHooks = new HashSet<>();
public PluginHookMgr(SuperVanish plugin) {
this.plugin = plugin;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
for (Plugin alreadyEnabledPlugin : Bukkit.getPluginManager().getPlugins())
if (alreadyEnabledPlugin.isEnabled())
onPluginEnable(new PluginEnableEvent(alreadyEnabledPlugin));
}
@EventHandler
public void onPluginEnable(PluginEnableEvent e) {
Plugin plugin = e.getPlugin();
if (REGISTERED_HOOKS.get(plugin.getName()) == null)
return;
if (isHookDisabled(plugin.getName()))
return;
PluginHook hook = null;
try {
hook = REGISTERED_HOOKS.get(plugin.getName()).getConstructor(SuperVanish.class)
.newInstance(PluginHookMgr.this.plugin);
hook.setPlugin(plugin);
hook.onPluginEnable(plugin);
Bukkit.getPluginManager().registerEvents(hook, plugin);
activeHooks.add(hook);
PluginHookMgr.this.plugin.log(Level.INFO, "Hooked into " + plugin.getName());
} catch (NoClassDefFoundError er) {
Bukkit.getLogger()
.warning("NoClassDefFoundError for SV-Hook(v" + this.plugin.getPluginMeta().getVersion() + ") "
+ (hook != null ? hook.getClass().getSimpleName() : "?") + " of plugin " + plugin.getName()
+ " v" + plugin.getPluginMeta().getVersion()
+ ", please report this if you are using the latest version of that" + " plugin!");
} catch (Exception er) {
if (er.getMessage() != null && er.getMessage().contains("Unable to find handler list for event")) {
this.plugin.log(Level.WARNING, "" + er.getMessage() + "; This is not an issue with Vanish-OG");
return;
} else if (er.getCause() != null && er.getCause().getMessage() != null
&& er.getCause().getMessage().contains("Unable to find handler list for event "))
{
this.plugin.log(Level.WARNING,
"" + er.getCause().getMessage() + "; This is not an issue with Vanish-OG");
return;
}
this.plugin.logException(new InvalidPluginHookException(er));
this.plugin.log(Level.WARNING, "Affected by this error is only the " + plugin.getName()
+ "-Hook, all other hooks and features aren't affected.");
}
}
private boolean isHookDisabled(String pluginName) {
if (pluginName.equalsIgnoreCase("dynmap"))
return !plugin.getSettings().getBoolean("HookOptions.EnableDynmapHook");
if (pluginName.equalsIgnoreCase("Utilities-OG"))
return !plugin.getSettings().getBoolean("HookOptions.EnableUtilitiesOGHook", true);
if (pluginName.equalsIgnoreCase("TAB-OG"))
return !plugin.getSettings().getBoolean("HookOptions.EnableTabOGHook", true);
return !plugin.getSettings().getBoolean("HookOptions.Enable" + pluginName + "Hook", true);
}
@EventHandler
public void onPluginDisable(PluginDisableEvent e) {
Plugin plugin = e.getPlugin();
PluginHook hook = getActiveHook(plugin);
if (hook == null)
return;
try {
hook.onPluginDisable(plugin);
} catch (Exception e1) {
this.plugin.logException(new InvalidPluginHookException(e1));
}
hook.setPlugin(null);
activeHooks.remove(hook);
}
private PluginHook getActiveHook(Plugin plugin) {
for (PluginHook hook : activeHooks)
if (hook.getPlugin() == plugin)
return hook;
return null;
}
public boolean isHookActive(Class<? extends PluginHook> hookClass) {
for (PluginHook hook : activeHooks) {
if (hook.getClass().equals(hookClass)) {
return true;
}
}
return false;
}
// Must run before the rest of the plugin tears down so TAB-OG's static
// HANDLERS list doesn't keep a reference to a disabled SuperVanish.
public void onSuperVanishDisable() {
for (PluginHook hook : activeHooks) {
if (hook instanceof TabOGHook) {
((TabOGHook) hook).onSuperVanishDisable();
}
}
}
public void onCleanup() {
for (PluginHook hook : activeHooks) {
try {
hook.onCleanup();
} catch (Exception e) {
plugin.logException(e);
}
}
}
}
@@ -1,56 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.hooks;
import de.myzelyam.api.vanish.PlayerHideEvent;
import de.myzelyam.api.vanish.PlayerShowEvent;
import de.myzelyam.api.vanish.VanishAPI;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;
import me.kvq.plugin.trails.API.SuperTrailsAPI;
public class SuperTrailsHook implements Listener {
public SuperTrailsHook(Plugin plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
for (Player p : Bukkit.getOnlinePlayers()) {
if (VanishAPI.isInvisible(p)) {
SuperTrailsAPI.HideTrailFor(p, true);
}
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onVanish(PlayerHideEvent e) {
SuperTrailsAPI.HideTrailFor(e.getPlayer(), true);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onReappear(PlayerShowEvent e) {
SuperTrailsAPI.HideTrailFor(e.getPlayer(), false);
}
@EventHandler(priority = EventPriority.MONITOR)
public void onJoin(PlayerJoinEvent e) {
SuperTrailsAPI.HideTrailFor(e.getPlayer(),
VanishAPI.isInvisible(e.getPlayer()));
}
@EventHandler(priority = EventPriority.MONITOR)
public void onQuit(PlayerQuitEvent e) {
SuperTrailsAPI.HideTrailFor(e.getPlayer(),
VanishAPI.isInvisible(e.getPlayer()));
}
}
@@ -0,0 +1,214 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.hooks;
import de.myzelyam.api.vanish.PostPlayerHideEvent;
import de.myzelyam.api.vanish.PostPlayerShowEvent;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.visibility.VanishStateMgr;
import me.neznamy.tab.api.TabPlayer;
import me.neznamy.tab.api.integration.VanishIntegration;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Method;
import java.util.UUID;
public class TabOGHook extends PluginHook {
private VanishOGIntegration integration;
public TabOGHook(SuperVanish superVanish) {
super(superVanish);
}
@Override
public void onPluginEnable(Plugin plugin) {
// Do not double-register if an earlier lifecycle already registered one.
unregisterIfPresent();
integration = new VanishOGIntegration(superVanish);
integration.register();
}
@Override
public void onPluginDisable(Plugin plugin) {
unregisterIfPresent();
}
// Called from SuperVanish.onDisable() so the integration is removed from
// TAB-OG's static HANDLERS list before the plugin's state is torn down.
// Without this, TAB-OG keeps a stale handler whose plugin reference no
// longer has valid state during subsequent logins.
public void onSuperVanishDisable() {
unregisterIfPresent();
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onVanish(PostPlayerHideEvent event) {
notifyTabFeatures(event.getPlayer().getUniqueId());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onReappear(PostPlayerShowEvent event) {
notifyTabFeatures(event.getPlayer().getUniqueId());
}
private void unregisterIfPresent() {
if (integration != null) {
try {
integration.unregister();
} catch (Throwable ignored) {
// TAB-OG may already be unloaded; removing a missing handler is harmless.
}
integration = null;
}
}
private void notifyTabFeatures(UUID playerUuid) {
// Fire once immediately for metadata-based TAB-OG features and once after
// BackendTabPlayer's vanish cache window so cache-backed features refresh too.
Bukkit.getScheduler().runTask(superVanish, () -> notifyTabFeaturesNow(playerUuid));
Bukkit.getScheduler().runTaskLater(superVanish, () -> notifyTabFeaturesNow(playerUuid), 20L);
}
private void notifyTabFeaturesNow(UUID playerUuid) {
if (integration == null) {
return;
}
try {
Class<?> tabClass = Class.forName("me.neznamy.tab.shared.TAB");
Object tab = tabClass.getMethod("getInstance").invoke(null);
if (tab == null) {
return;
}
Object tabPlayer = tabClass.getMethod("getPlayer", UUID.class).invoke(tab, playerUuid);
if (tabPlayer == null) {
return;
}
Object featureManager = tabClass.getMethod("getFeatureManager").invoke(tab);
Class<?> tabPlayerClass = Class.forName("me.neznamy.tab.shared.platform.TabPlayer");
Method vanishChangeMethod = featureManager.getClass().getMethod("onVanishStatusChange", tabPlayerClass);
vanishChangeMethod.invoke(featureManager, tabPlayer);
} catch (ReflectiveOperationException ignored) {
// TAB-OG implementation internals are optional and may differ across versions.
} catch (Throwable t) {
superVanish.logException(t);
}
}
private static final class VanishOGIntegration extends VanishIntegration {
private final SuperVanish plugin;
private VanishOGIntegration(SuperVanish plugin) {
super("Vanish-OG");
this.plugin = plugin;
}
// TAB-OG invokes this on its async CPU-manager thread during join
// processing, so every field access must tolerate partial-enable and
// partial-disable states. Any exception thrown here propagates through
// TAB-OG's feature pipeline and breaks player login packet flow.
@Override
public boolean canSee(@NotNull TabPlayer viewer, @NotNull TabPlayer target) {
try {
final VanishStateMgr stateMgr = plugin.getVanishStateMgr();
if (stateMgr == null)
return true;
if (!stateMgr.isVanished(target.getUniqueId()))
return true;
final Player bukkitViewer = Bukkit.getPlayer(viewer.getUniqueId());
if (bukkitViewer == null)
return true;
// Direct permission check only: plugin.hasPermissionToSee() reaches
// LayeredPermissionChecker, which iterates the non-thread-safe
// vanishPlayers HashSet on SuperVanish. That's safe on the Bukkit
// main thread but not here, so we stick to Player.hasPermission.
return bukkitViewer.hasPermission("sv.see");
} catch (Throwable t) {
plugin.logException(t);
return true;
}
}
@Override
public boolean isVanished(@NotNull TabPlayer player) {
try {
final VanishStateMgr stateMgr = plugin.getVanishStateMgr();
if (stateMgr == null)
return false;
return stateMgr.isVanished(player.getUniqueId());
} catch (Throwable t) {
plugin.logException(t);
return false;
}
}
}
}
@@ -1,15 +1,15 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.hooks;
import ca.jamiesinn.trailgui.Listeners;
import ca.jamiesinn.trailgui.TrailGUI;
import de.myzelyam.api.vanish.VanishAPI;
import org.bukkit.Bukkit;
import de.myzelyam.supervanish.SuperVanish;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
@@ -17,27 +17,43 @@ import org.bukkit.plugin.Plugin;
import java.util.logging.Level;
public abstract class TrailGUIHook {
import ca.jamiesinn.trailgui.Listeners;
import ca.jamiesinn.trailgui.TrailGUI;
public static void replaceMoveListener() {
final Plugin trailGUI = Bukkit.getPluginManager().getPlugin("TrailGUI");
if (trailGUI == null || !(trailGUI instanceof TrailGUI)) {
Bukkit.getLogger().log(Level.WARNING,
"[SuperVanish] Failed to hook into TrailGUI. (PluginNotFound)");
public class TrailGUIHook extends PluginHook {
public TrailGUIHook(SuperVanish superVanish) {
super(superVanish);
}
@Override
public void onPluginEnable(Plugin plugin) {
if (!(plugin instanceof TrailGUI)) {
superVanish.log(Level.WARNING, "Failed to hook into TrailGUI. (PluginNotFound)");
return;
}
PlayerMoveEvent.getHandlerList().unregister(trailGUI);
final Listeners trailGUIListeners = new Listeners((TrailGUI) trailGUI);
trailGUI.getServer().getPluginManager().registerEvents(new Listener() {
PlayerMoveEvent.getHandlerList().unregister(plugin);
final Listeners trailGUIListeners = new Listeners((TrailGUI) plugin);
plugin.getServer().getPluginManager().registerEvents(new Listener() {
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
if (Bukkit.getPluginManager().isPluginEnabled("SuperVanish")
&& VanishAPI.getInvisiblePlayers().contains(
event.getPlayer().getUniqueId().toString()))
if (superVanish.getVanishStateMgr().getOnlineVanishedPlayers()
.contains(event.getPlayer().getUniqueId()))
return;
trailGUIListeners.onPlayerMove(event);
}
}, trailGUI);
}, plugin);
}
}
@@ -0,0 +1,183 @@
/*
* Copyright © 2015, Leon Mangler and the SuperVanish contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package de.myzelyam.supervanish.listeners;
import de.myzelyam.supervanish.SuperVanish;
import de.myzelyam.supervanish.VanishPlayer;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.*;
import org.bukkit.event.player.PlayerInteractEvent;
public class GeneralListener implements Listener {
private final SuperVanish plugin;
private final FileConfiguration config;
public GeneralListener(SuperVanish plugin) {
this.plugin = plugin;
config = plugin.getSettings();
}
@EventHandler(priority = EventPriority.HIGH)
public void onDamage(EntityDamageByEntityEvent e) {
try {
if (!(e.getDamager() instanceof Player))
return;
if (e.getEntity() == null)
return;
Player p = (Player) e.getDamager();
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId())) {
if (config.getBoolean("RestrictiveOptions.PreventHittingEntities")
&& !p.hasPermission("sv.damageentities") && !p.hasPermission("sv.damage"))
{
plugin.sendMessage(p, "EntityHitDenied", p);
e.setCancelled(true);
}
}
} catch (Exception er) {
plugin.logException(er);
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onFoodLevelChange(FoodLevelChangeEvent e) {
try {
if (e.getEntity() instanceof Player && config.getBoolean("InvisibilityFeatures.DisableHunger")) {
Player p = (Player) e.getEntity();
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId()) && e.getFoodLevel() <= p.getFoodLevel())
e.setCancelled(true);
}
} catch (Exception er) {
plugin.logException(er);
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onDamage(EntityDamageEvent e) {
try {
if (!(e.getEntity() instanceof Player))
return;
Player p = (Player) e.getEntity();
if (!config.getBoolean("InvisibilityFeatures.DisableDamage"))
return;
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId())) {
e.setCancelled(true);
}
} catch (Exception er) {
plugin.logException(er);
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onTarget(EntityTargetEvent e) {
try {
if (!(e.getTarget() instanceof Player))
return;
if (!config.getBoolean("InvisibilityFeatures.DisableMobTarget"))
return;
Player p = (Player) e.getTarget();
if (plugin.getVanishStateMgr().isVanished(p.getUniqueId())) {
e.setCancelled(true);
}
} catch (Exception er) {
plugin.logException(er);
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onItemPickUp(EntityPickupItemEvent e) {
try {
if (!(e.getEntity() instanceof Player player))
return;
VanishPlayer vanishPlayer = plugin.getVanishPlayer(player);
if (vanishPlayer == null || !vanishPlayer.isOnlineVanished())
return;
if (!vanishPlayer.hasItemPickUpsEnabled())
e.setCancelled(true);
if (plugin.getSettings().getBoolean("RestrictiveOptions.PreventModifyingOwnInventory")
&& !player.hasPermission("sv.modifyowninv"))
{
e.setCancelled(true);
}
} catch (Exception er) {
plugin.logException(er);
}
}
@EventHandler
public void onPlayerCropTrample(PlayerInteractEvent e) {
try {
if (!plugin.getVanishStateMgr().isVanished(e.getPlayer().getUniqueId()))
return;
if (e.getAction() != Action.PHYSICAL)
return;
if (e.getClickedBlock() != null && e.getClickedBlock().getType().toString().matches("SOIL|FARMLAND"))
e.setCancelled(true);
} catch (Exception er) {
plugin.logException(er);
}
}
}
Loaded 100 of 140 files, more files were not shown because too many files have changed in this diff. Show more