9
0
mirror of https://github.com/HibiscusMC/HMCCosmetics.git synced 2025-12-24 17:39:18 +00:00

Compare commits

...

245 Commits

Author SHA1 Message Date
LoJoSho
61ee228990 version bump (2.4.6) 2023-06-19 14:00:05 -05:00
LoJoSho
14e061e487 fix: exiting emote does not refresh armor 2023-06-19 13:26:33 -05:00
LoJoSho
9dc2c23d04 feat: create HMCCosmeticsAPI class 2023-06-19 13:19:24 -05:00
LoJoSho
684f8a4790 clean: move events to their own api package 2023-06-19 13:16:43 -05:00
LoJoSho
5d782bb6a3 fix: send empty equipment packet on emote for player 2023-06-19 13:03:19 -05:00
LoJoSho
988ec04a2e feat: remove 1.17 support 2023-06-19 12:37:34 -05:00
LoJoSho
ebf87f01b8 version bump (2.4.5) 2023-06-16 22:41:34 -05:00
LoJoSho
6032eb0782 fix: improve handling of invalid backpacks 2023-06-16 22:34:57 -05:00
LoJoSho
6d8c46783f feat: add PAPI support for display names 2023-06-16 22:33:59 -05:00
LoJoSho
407061d125 clean: remove previous todo 2023-06-16 22:15:47 -05:00
LoJoSho
f8192d734b feat: Cosmetics now support PAPI in lore and skull owners/textures 2023-06-16 22:15:25 -05:00
LoJoSho
190f8f776d feat: WorldGuard listens to PlayerTeleportEvent 2023-06-16 17:37:49 -05:00
LoJoSho
cd80bc746e fix: wrong index for 1.18.2 player info packet 2023-06-15 13:13:16 -05:00
LoJoSho
d96a8e5622 version bump (2.4.4) 2023-06-14 21:17:29 -05:00
LoJoSho
53091f102e feat: Readded Translations 2023-06-14 21:11:06 -05:00
LoJoSho
1d24881df1 version bump (2.4.4-DEV) 2023-06-14 20:30:06 -05:00
LoJoSho
ae0dc7bd14 fix: Geary Hook 2023-06-14 20:29:36 -05:00
LoJoSho
b9a57fc48f version bump (2.4.3) 2023-06-13 11:59:54 -05:00
LoJoSho
1e2db05e45 feat: equipping emote stops emote 2023-06-13 11:59:16 -05:00
LoJoSho
4e2291d16f clean: menu class cleaning 2023-06-13 11:51:38 -05:00
LoJoSho
2e95a9bf58 version bump (2.4.3-DEV) 2023-06-13 11:12:07 -05:00
LoJoSho
0de6c1416c fix: balloons causing NPC disappearance 2023-06-13 11:11:15 -05:00
LoJoSho
f8c2e0e605 feat: add PlayerCosmeticPostEquipEvent to api 2023-06-13 11:10:24 -05:00
LoJoSho
23ad3eaf65 version bump (2.4.2) 2023-06-12 15:07:51 -05:00
LoJoSho
97887961db fix: playeranimator bump to 1.2.7 2023-06-12 14:55:50 -05:00
LoJoSho
e48dcf9150 version bump (2.4.1) 2023-06-10 16:02:27 -05:00
LoJoSho
0f65c20095 fix: include 1.20 files into jar 2023-06-10 15:49:40 -05:00
LoJoSho
68b0955a1f feat: add 1.20 NMS support 2023-06-10 15:40:13 -05:00
LoJoSho
1193bc43d7 Merge remote-tracking branch 'origin/remapped' into remapped 2023-06-10 15:18:18 -05:00
LoJoSho
f5105200de fix: unchecked wardrobes not unapplying 2023-06-10 15:17:11 -05:00
Boy
1b7fdd3dcf fix geary-hook 2023-06-10 20:23:13 +02:00
LoJoSho
2e4130012f temp remove Geary Hook 2023-06-09 09:28:37 -05:00
LoJoSho
bf7517ab20 feat: text can now be applied above player while emote playing 2023-06-08 21:30:05 -05:00
LoJoSho
813642ee92 version bump (2.4.1-DEV) 2023-05-25 16:23:03 -05:00
LoJoSho
f266721781 fix: backpacks disappearing on teleporting 2023-05-25 16:19:04 -05:00
LoJoSho
9793114ea0 fix: Geary logic not being under load 2023-05-25 13:33:50 -05:00
LoJoSho
b00c79f67b Merge pull request #111 from HibiscusMC/multi_wardrobe
Wardrobe Improvements (2.4.0)
2023-05-25 10:10:21 -05:00
LoJoSho
0528ebfa84 feat: rename setlocation to setwardrobesetting to allow modification of permission and distance ingame 2023-05-24 16:56:06 -05:00
LoJoSho
1e0ffdc08b clean: summer cleaning of CosmeticUser.java 2023-05-24 16:41:54 -05:00
LoJoSho
cc08cc6537 feat: message.yml to sync as well 2023-05-24 16:36:47 -05:00
LoJoSho
455b8cd1a1 version bump (2.4.0) 2023-05-24 16:29:07 -05:00
LoJoSho
5c6bb93e6c feat: add removeWardrobe method 2023-05-24 15:08:43 -05:00
LoJoSho
e9c7946319 feat: create new wardrobes in-game 2023-05-24 15:05:13 -05:00
LoJoSho
fcde8e7f25 feat: send message if locations are not all setup 2023-05-24 15:03:41 -05:00
LoJoSho
7fcbbd6b5a feat: add wardrobes to internal map 2023-05-24 15:03:23 -05:00
LoJoSho
a92b4c15f5 feat: check if wardrobe locations are not null 2023-05-24 15:03:13 -05:00
LoJoSho
7439aabfd1 clean: random space in wardrobe debug message 2023-05-24 14:53:59 -05:00
LoJoSho
50bda8343c fix: wardrobe region not entering wardrobe 2023-05-24 14:53:16 -05:00
LoJoSho
c189424aa8 fix: setlocation command now shows no-wardrobes message when there is no wardrobe with inputted name 2023-05-24 14:44:38 -05:00
LoJoSho
70b97667c3 feat: only show wardrobes player has access to 2023-05-24 14:38:01 -05:00
LoJoSho
128a33a21f fix: Menus being janky 2023-05-24 12:41:58 -05:00
LoJoSho
538edb67dd fix: placeholders out of bounds slight rework 2023-05-24 12:41:43 -05:00
LoJoSho
9b607a099e fix: unlocked placeholder producing out of bounds expection 2023-05-24 12:20:39 -05:00
LoJoSho
f084d9e782 feat: add values method to Menus class 2023-05-24 11:03:54 -05:00
LoJoSho
8ee1400f85 feat: menu permissions added to registered permissions 2023-05-24 11:03:40 -05:00
LoJoSho
8e33b2022b fix: going to another wg region while cosmetic hidden from wg causes cosmetics to stay hidden 2023-05-24 10:58:34 -05:00
LoJoSho
a661ea09e1 feat: better file generating logic 2023-05-24 10:11:02 -05:00
LoJoSho
9c2120d13d version bump (2.4.0-DEV) 2023-05-24 09:57:03 -05:00
LoJoSho
7ea4ccccef feat: config updater 2023-05-24 09:56:46 -05:00
LoJoSho
0b1ed0fbeb clean: create path variables to be more in line with existing code 2023-05-23 14:33:36 -05:00
LoJoSho
0aac0a2377 clean: deprecate inDistanceOfWardrobe and inDistanceOfStatic 2023-05-23 14:30:58 -05:00
LoJoSho
04810b91ef feat: add ability to select any cosmetic in wardrobe, resolves #55 2023-05-23 11:11:24 -05:00
LoJoSho
f072f0e044 clean: old variable 2023-05-23 11:06:05 -05:00
LoJoSho
6e2278f4f0 clean: loose message 2023-05-23 10:58:42 -05:00
LoJoSho
7c95d9614d clean: remove players list, just use permissions if you wish to limit it to a certain group. 2023-05-23 10:53:37 -05:00
LoJoSho
54e8e5102a feat: Multiple Wardrobes 2023-05-23 10:50:09 -05:00
LoJoSho
b270d022d4 feat: Check if there is air below emote usage 2023-05-23 09:10:00 -05:00
LoJoSho
f087933d48 Merge pull request #110 from HibiscusMC/update_geary_hook
Update Geary Hook
2023-05-22 14:31:33 -05:00
Boy
ed1d1515bc fix invalid material error before pipeline finishes 2023-05-21 23:39:09 +02:00
Boy
aa364f5e77 properly inject setup into loadPhase 2023-05-21 19:19:51 +02:00
Boy
5ae6d17ef3 update geary hook 2023-05-21 18:25:55 +02:00
LoJoSho
4590bdcde1 feat: PlayerWardrobeEnterEvent now passes wardrobe location that is modifiable 2023-05-16 15:24:26 -05:00
LoJoSho
f9465e8206 clean: finish wardrobe location overhaul 2023-05-16 15:21:20 -05:00
LoJoSho
cd3a9f1af4 clean: move wardrobe location to its own class, rename wardrobe location to NPCLocation 2023-05-16 15:09:05 -05:00
LoJoSho
853668ff1b clean: better invalid backpack debug messages 2023-05-16 14:44:48 -05:00
LoJoSho
e2ee55bab4 fix: cosmetic armor updating when a player is emoting 2023-05-16 14:17:41 -05:00
LoJoSho
7a13715897 fix: protocollib moved to correct version 2023-05-16 14:09:59 -05:00
LoJoSho
d92e3e4616 clean: include user when shown invalid backpack error 2023-05-11 19:27:12 -05:00
LoJoSho
49023ff701 fix: equipped emotes not going through emote manager 2023-05-10 16:43:08 -05:00
LoJoSho
1bd405d13e version bump (2.3.2-DEV) 2023-05-10 16:32:55 -05:00
LoJoSho
69de2fa178 version bump (2.3.1) 2023-05-09 14:20:23 -05:00
LoJoSho
cdcf904ac8 fix: cosmetic tpe gui items not processing placeholders 2023-05-08 12:23:20 -05:00
LoJoSho
80f9100bf0 fix: translation file generating 2023-05-08 12:22:57 -05:00
LoJoSho
751509ece4 version bump (2.3.1-DEV) 2023-05-08 12:22:46 -05:00
LoJoSho
f36d558e13 clean: updateCosmetic use proper method 2023-05-06 10:40:15 -05:00
LoJoSho
ab8ae8ee76 version bump (2.3.0) 2023-05-06 10:28:26 -05:00
LoJoSho
aca14f8a04 clean: config referenced wrong value in comments 2023-05-06 09:47:24 -05:00
LoJoSho
6ec13051bb clean: user tick debug message 2023-05-06 09:40:13 -05:00
LoJoSho
ebc7bfa30a feat: menu now passes int slot to gui item types 2023-05-06 09:37:54 -05:00
LoJoSho
e59717d61d feat: positive emote distances show camera facing player 2023-05-06 09:34:10 -05:00
LoJoSho
7f5a90b080 Merge pull request #105 from Craftinators/remapped
feat: allow for multiple emotes in one bbmodel file
2023-05-06 09:19:45 -05:00
LoJoSho
51d26a7983 Merge pull request #104 from HibiscusMC/2.3.0
Improved GUI configuration options (2.3.0)
2023-05-06 09:16:22 -05:00
Craftinators
d1d001fcf6 refactor(EmoteManager): move emote loading logic to EmoteManager class 2023-05-06 00:02:03 -04:00
Craftinators
79f33ca0d1 feat: allow for multiple emotes in one bbmodel file 2023-05-05 18:39:14 -04:00
LoJoSho
7f37937185 clean: removed method not needed 2023-05-05 16:34:01 -05:00
LoJoSho
0e9164a506 fix: multi-slot gui items actions not running 2023-05-05 16:23:03 -05:00
LoJoSho
91361a6373 feat: equipped and locked cosmetic item in gui 2023-05-05 14:38:54 -05:00
LoJoSho
cfe5f33a63 version bump (2.3.0-DEV) 2023-05-05 14:38:38 -05:00
LoJoSho
e50566e2cb feat: add hasCosmeticInSlot for cosmetic 2023-05-05 13:53:01 -05:00
LoJoSho
f793f4e67a Merge pull request #103 from Craftinators/main
chore: add contact link
2023-04-30 15:53:07 -05:00
Craftinators
b57428e3fe style: remove emoji from name 2023-04-30 14:13:21 -04:00
Craftinators
3137c45704 chore: add contact link
Add a contact link for general questions
2023-04-30 14:09:46 -04:00
LoJoSho
38c270558c fix: update PlayerAnimator to 1.2.6 for 1.19.4 support 2023-04-30 10:37:57 -05:00
LoJoSho
39a36fa73c Merge remote-tracking branch 'origin/remapped' into remapped
# Conflicts:
#	build.gradle.kts
2023-04-29 22:58:39 -05:00
LoJoSho
ae83355860 feat: add LibsDisguise hook, resolves #85 2023-04-29 22:57:40 -05:00
LoJoSho
60d910d148 Merge pull request #100 from Craftinators/remapped
Issue template changes
2023-04-29 12:09:21 -05:00
LoJoSho
251d227ddb Merge pull request #99 from mergu/denizen_item_support
Add support for Denizen items
2023-04-29 12:07:30 -05:00
LoJoSho
45e597c665 version bump (2.2.9-DEV) 2023-04-29 12:01:20 -05:00
Craftinators
f0e60903b5 chore: more PR description options 2023-04-29 12:55:31 -04:00
Craftinators
db49946e5e chore: add discord link at top 2023-04-29 12:49:10 -04:00
Craftinators
50ebc737e6 chore: fix 02-feature-request indent error 2023-04-29 12:47:25 -04:00
Craftinators
28d1775c86 chore: fix 02-feature_request syntax error 2023-04-29 12:46:49 -04:00
Craftinators
0a1a381ebc chore: update 02-feature_request 2023-04-29 12:45:58 -04:00
Craftinators
651067fb17 style: rename feature-request.yml 2023-04-29 12:40:43 -04:00
Craftinators
1f634d668e style: rename bug-report.yml 2023-04-29 12:40:14 -04:00
Craftinators
f5bf8c70b4 chore: modify text 2023-04-29 12:39:22 -04:00
Craftinators
f50731f83e chore: fix bug-report.yml validation errors 2023-04-29 12:36:29 -04:00
Craftinators
f44d916b32 chore: fix bug-report.yml syntax error 2023-04-29 12:34:17 -04:00
Craftinators
9cfb27da28 chore: update bug-report.yml 2023-04-29 12:33:03 -04:00
Mergu
b09bd35737 Add support for Denizen items 2023-04-29 11:56:17 -04:00
LoJoSho
b998cac5c8 clean: default earth day grabber had model field that was unused 2023-04-26 15:01:30 -05:00
LoJoSho
9b34ffebb8 version bump (2.2.8) 2023-04-23 15:44:28 -05:00
LoJoSho
3eaaf75bfb clean: removed persistant data container not being used 2023-04-23 15:42:54 -05:00
LoJoSho
c1bae96ad9 fix: cosmetic data container now contains cosmetic id 2023-04-23 15:42:31 -05:00
LoJoSho
ddb6f53655 fix: cancel event for clicking in HMCColor 2023-04-23 15:23:10 -05:00
LoJoSho
c37f52bbb1 feat: destroy loose items cover gamemode switch 2023-04-23 10:47:44 -05:00
LoJoSho
dd805f1860 feat: add cosmetics containing who they were generated for 2023-04-23 10:38:43 -05:00
LoJoSho
d9551f2827 clean: better debug messages in CosmeticUser 2023-04-22 19:09:49 -05:00
LoJoSho
1750a1bf5f fix: 1.19.2 fake player info packet issue 2023-04-22 19:05:22 -05:00
LoJoSho
d42f5ef5af fix: player still in wardrobe after death 2023-04-22 18:32:28 -05:00
LoJoSho
2ca940a929 fix: papi expansion does not persist 2023-04-22 16:31:52 -05:00
LoJoSho
36f33b54af fix: cosmetic null showing error 2023-04-22 16:27:05 -05:00
LoJoSho
d0b4be6db8 fix: wardrobe not ending with transition false 2023-04-22 16:22:18 -05:00
LoJoSho
4afa0bb538 clean: new debug messages 2023-04-22 16:21:02 -05:00
LoJoSho
201bcceaab fix: 1.19.3 fake info packet not properly casting in protocol lib 2023-04-20 14:12:25 -05:00
LoJoSho
92ad314ce1 version bump (2.2.8-DEV) 2023-04-20 14:12:05 -05:00
lucian929
b8962539e8 Add earth day cosmetics 2023-04-18 16:44:50 -04:00
LoJoSho
01db728b99 version bump (2.2.7) 2023-04-17 15:22:24 -05:00
LoJoSho
8525dda6f4 feat: add gamemode-options when exiting wardrobe 2023-04-17 15:21:16 -05:00
LoJoSho
e8f7f57e0b feat: Destroy loose cosmetics to remove unwanted cosmetics 2023-04-17 14:25:48 -05:00
LoJoSho
8c62b47d5b clean: remove unused loop 2023-04-17 10:51:56 -05:00
LoJoSho
2ab0b119e7 Merge remote-tracking branch 'origin/remapped' into remapped 2023-04-17 10:50:35 -05:00
LoJoSho
20d919c65e clean: improved animation variable 2023-04-17 10:50:28 -05:00
LoJoSho
bd41c5b9ff feat: Option to make lead invisible for balloons, resolves #95 2023-04-17 10:31:27 -05:00
LoJoSho
60aaf0cff6 feat: Equipped placeholder now takes type 2023-04-09 11:37:55 -05:00
LoJoSho
71c8f8171b fix: Standing does not readd backpack 2023-04-09 11:08:40 -05:00
LoJoSho
2bc4e3dd3f Merge pull request #93 from Craftinators/remapped
Remove `build` workflow
2023-04-06 16:43:18 -05:00
Craftinators
302eaa13c9 Merge branch 'HibiscusMC:remapped' into remapped 2023-04-06 17:40:17 -04:00
Craftinators
23ff51bab8 github: remove build workflow 2023-04-06 17:39:23 -04:00
LoJoSho
96ee695521 Merge pull request #92 from Craftinators/remapped
Minor Repository Changes
2023-04-06 16:33:24 -05:00
Craftinators
a9a587495a github: build workflow only fires on pr 2023-04-06 17:20:33 -04:00
Craftinators
0b69e20adc github: remove note from CONTRIBUTING.md 2023-04-06 01:46:43 -04:00
Craftinators
a08e531226 fix: contribution guide updates 2023-04-05 23:20:42 -04:00
Craftinators
1e27933573 github: add contribution guide 2023-04-05 22:07:16 -04:00
Craftinators
0b4815842f github: remove cache from build action 2023-04-05 19:47:30 -04:00
LoJoSho
cc6aec99e0 fix: NPE on player exit if user not created 2023-04-05 17:21:02 -05:00
Craftinators
b51bace9f5 fix: Feature Request add enhancement label 2023-04-05 13:09:08 -04:00
Craftinators
c70223a800 github: remove matrix versions >=18 2023-04-05 13:07:05 -04:00
Craftinators
36353b5693 github: expand java matrix to include versions 19 & 20 2023-04-05 12:54:30 -04:00
Craftinators
d4fc903c14 fix: revert to temurin 2023-04-05 12:45:14 -04:00
Craftinators
980d2d89df fix: oracle typo 2023-04-05 12:44:12 -04:00
Craftinators
c952a8ac08 github: try versions >17.0 2023-04-05 12:42:50 -04:00
Craftinators
a651c9b8da fix: remove java version matrix 2023-04-05 12:32:29 -04:00
Craftinators
c695e8b2f9 fix: distribution from orcale to temurin 2023-04-05 12:26:27 -04:00
Craftinators
ee72bc2ef5 fix: distribution issue 2023-04-05 12:24:58 -04:00
Craftinators
ebd47e9b56 fix: actions/setup-java@v3.6 -> actions/setup-java@v3 2023-04-05 12:20:41 -04:00
Craftinators
5cf5e7c543 github: add matrix samples 2023-04-05 12:18:54 -04:00
Craftinators
7f2d62b5e5 fix: add chmod permission changes 2023-04-05 11:45:50 -04:00
Craftinators
8d07f7cf9f github: add build workflow 2023-04-05 08:14:23 -04:00
LoJoSho
789db52b57 fix: player_move_check changed to player-move-check in configuration 2023-04-04 07:55:02 -05:00
LoJoSho
5fb3458a98 fix: player emoting then teleporting glitches out 2023-04-02 13:34:47 -05:00
LoJoSho
f6935ce60b Merge remote-tracking branch 'origin/remapped' into remapped 2023-04-02 12:54:50 -05:00
lucian929
b1eb592137 chore: update transition info for oraxen/itemsadder 2023-04-02 13:54:27 -04:00
LoJoSho
913f8ccdf7 version bump (2.2.7-DEV) 2023-04-02 12:39:23 -05:00
LoJoSho
3f951263b9 version bump (2.2.6) 2023-04-02 12:39:01 -05:00
LoJoSho
744fc87491 feat: add option to disable World Guard listener #87 2023-04-02 12:30:41 -05:00
LoJoSho
ca01a94502 feat: full 1.19.4 support 2023-04-02 12:00:31 -05:00
LoJoSho
879a58d1f4 clean: update test servers to 1.19.4 2023-04-02 11:59:32 -05:00
LoJoSho
aab40b68a7 clean: add md-5 repo for future plugins 2023-04-01 22:34:38 -05:00
LoJoSho
9533e2ec46 fix: add 1.19.4 in SUPPORTED_VERSIONS constant 2023-04-01 22:28:26 -05:00
LoJoSho
7b2e767cac fix: fixes #88 throwing runtime exception on reload 2023-04-01 22:27:38 -05:00
LoJoSho
4bdd000917 Merge remote-tracking branch 'origin/remapped' into remapped 2023-03-22 19:52:01 -05:00
LoJoSho
b397ae52f9 fix: check valid balloon entity before teleport 2023-03-22 19:51:56 -05:00
LoJoSho
40620f1daa Merge pull request #83 from Craftinators/hooks
Abstraction and Documentation of `/hooks` directory
2023-03-17 15:53:13 -05:00
Craftinators
4d8d43ee2a docs(Hooks): getActive -> isActive 2023-03-17 16:03:18 -04:00
Craftinators
4f8a32c3e8 docs(HMCPlaceholderExpansion): documented class 2023-03-17 16:01:55 -04:00
LoJoSho
1d303dee71 feat: add 1.19.4 nms support 2023-03-17 11:47:41 -05:00
LoJoSho
e9659ab1e8 version bump (2.2.6-DEV) 2023-03-17 11:27:32 -05:00
LoJoSho
ee917dbf32 fix: Riptide fixes #84 2023-03-17 11:25:08 -05:00
LoJoSho
2a275fe503 Merge remote-tracking branch 'origin/remapped' into remapped 2023-03-17 11:15:51 -05:00
LoJoSho
a5631cd2e4 fix: player during riptide have their backpack hidden #84 2023-03-17 11:15:04 -05:00
Craftinators
1ed1a2c41d docs(WGListener): documented class 2023-03-17 09:08:11 -04:00
Craftinators
c2bf0322a7 docs(WGHook): documented class 2023-03-17 09:06:37 -04:00
Craftinators
3f8f84735f docs(HookPlaceholderAPI): documented class 2023-03-17 08:58:39 -04:00
Craftinators
2fb28dda32 docs(HookSuperVanish): documented class 2023-03-17 08:54:17 -04:00
Craftinators
6192515550 docs(HookPremiumVanish): documented class 2023-03-17 08:54:10 -04:00
Craftinators
6fcf893bac docs: fixed wording 2023-03-17 08:53:37 -04:00
Craftinators
d0dfa19f2d docs(HookHMCColor): documented class 2023-03-17 08:53:09 -04:00
Craftinators
c3b4abea40 docs(HookCMI): documented class 2023-03-17 08:53:00 -04:00
Craftinators
a030d1272b docs(HookOraxen): documented class 2023-03-17 08:44:10 -04:00
Craftinators
d6c4b51b98 docs(HookMythic): documented class 2023-03-17 08:42:05 -04:00
Craftinators
a306d76c19 Merge remote-tracking branch 'origin/hooks' into hooks
# Conflicts:
#	common/src/main/java/com/hibiscusmc/hmccosmetics/hooks/items/HookMythic.java
2023-03-17 08:40:08 -04:00
Craftinators
1d51ee0711 docs(HookMythic): documented class 2023-03-17 08:39:53 -04:00
Craftinators
e340874270 docs(HookMythic): documented class 2023-03-17 08:37:52 -04:00
Craftinators
093b01d7ff docs(HookLooty): documented class 2023-03-16 18:43:52 -04:00
Craftinators
5b129cc254 docs(HookItemAdder): documented class 2023-03-16 18:40:50 -04:00
Craftinators
7a32697906 docs(HookHMCCosmetics): documented class 2023-03-16 17:55:53 -04:00
Craftinators
2ea272ee4a fix(Hook): abstraction and documentation of Hook 2023-03-16 17:39:58 -04:00
LoJoSho
9ebfc9748d Merge pull request #81 from Craftinators/docs
Documentation of `/api` directory
2023-03-16 14:22:06 -05:00
Craftinators
d1a2b6a016 docs(HMCCosmeticSetupEvent): fix documentation 2023-03-15 17:11:41 -04:00
Craftinators
af78424b07 refactor(PlayerMenuCloseEvent): event no longer cancellable 2023-03-15 15:31:25 -04:00
LoJoSho
c35546e536 Merge pull request #82 from Craftinators/remapped
PR template
2023-03-15 09:16:39 -05:00
Craftinators
7db03a2f8a fix: add colon 2023-03-15 08:39:27 -04:00
Craftinators
99f3765e6e github: add PR template 2023-03-15 08:36:02 -04:00
Craftinators
fae001a48f fix: disallow empty issues 2023-03-15 08:35:41 -04:00
Craftinators
1ccb35ad62 refactor: abstraction of menu related events 2023-03-15 08:05:15 -04:00
Craftinators
2b4e570172 clean(UserEmoteManager): remove unused import 2023-03-15 08:04:53 -04:00
Craftinators
965b6cc740 fix(PlayerCosmeticEvent): rename to PlayerCosmeticEvent 2023-03-15 08:04:28 -04:00
Craftinators
ffda4ba6f5 feat: new PlayerMenuOpenEvent class 2023-03-15 04:44:18 -04:00
Craftinators
df2da4fc89 docs(PlayerMenuOpenEvent): add class documentation 2023-03-15 04:43:50 -04:00
Craftinators
cea40033f9 docs(PlayerWardrobeLeaveEvent): add class documentation 2023-03-15 04:43:36 -04:00
Craftinators
42a01a44aa docs(PlayerWardrobeEnterEvent): add class documentation 2023-03-15 04:43:23 -04:00
Craftinators
17c07d0e01 docs(PlayerWardrobeLeaveEvent): documented class 2023-03-15 04:05:50 -04:00
Craftinators
ea4d088b04 docs(PlayerWardrobeEnterEvent): documented class 2023-03-15 04:05:39 -04:00
Craftinators
591198175a docs(PlayerMenuOpenEvent): documented class 2023-03-15 04:05:17 -04:00
Craftinators
be93369a8b docs(PlayerEmoteStopEvent): add class documentation 2023-03-15 03:58:33 -04:00
Craftinators
fd6553a52a docs(PlayerEmoteStopEvent): documented class 2023-03-15 03:57:44 -04:00
Craftinators
961f460ffb docs(PlayerEmoteStartEvent): documented class 2023-03-15 03:57:28 -04:00
Craftinators
eb925d9022 docs(HMCCosmeticSetupEvent): documented class 2023-03-15 01:45:07 -04:00
Craftinators
d05072eb2c fix(PlayerCosmeticShowEvent): remove unused import 2023-03-15 01:40:06 -04:00
Craftinators
f456ddf8a4 docs(PlayerCosmeticShowEvent): documented class 2023-03-15 01:39:00 -04:00
Craftinators
c395b68d6a docs(PlayerCosmeticRemoveEvent): documented class 2023-03-15 01:38:33 -04:00
Craftinators
fddd5d0311 docs(PlayerCosmeticHideEvent): updated documentation 2023-03-15 01:37:46 -04:00
Craftinators
f08c38ff1a docs(PlayerCosmeticEquipEvent): updated documentation 2023-03-15 01:34:58 -04:00
Craftinators
a4bd9108b1 docs(PlayerCosmeticHideEvent): documented class 2023-03-14 18:26:22 -04:00
Craftinators
de1377dc8f docs(PlayerCosmeticEquipEvent): @see when referring to classes 2023-03-14 18:25:47 -04:00
Craftinators
00ce32c528 docs(PlayerCosmeticEquipEvent): documented class 2023-03-14 15:48:18 -04:00
Craftinators
0ddcb12b31 feat: abstraction of PlayerCosmetic... styled events 2023-03-14 15:47:27 -04:00
LoJoSho
adadecfa19 Merge pull request #79 from Craftinators/remapped
`CosmeticUser.getCosmetics()` changes
2023-03-14 14:36:56 -05:00
Craftinators
ac35ef8b5d feat(CosmeticUser): preferred getCosmetics method 2023-03-13 23:56:02 -04:00
LoJoSho
65f1c72b8e fix: restarting server while player is emoting causes player to be invisible 2023-03-13 21:23:19 -05:00
Craftinators
178bff37f5 feat(CosmeticUser): new getPlayerCosmetics() 2023-03-13 15:15:13 -04:00
Craftinators
48b9d4fb41 fix(CosmeticUser): add back getCosmetic() as deprecated method 2023-03-13 15:05:19 -04:00
Craftinators
81d6583430 fix(CosmeticUser): keep mutable collection 2023-03-13 09:02:17 -04:00
Craftinators
0304c9ff44 fix(CosmeticUser): getCosmetics() changes 2023-03-13 08:59:23 -04:00
109 changed files with 2834 additions and 1102 deletions

13
.github/CONTRIBUTING.md vendored Normal file
View File

@@ -0,0 +1,13 @@
# Contributing
If you wish to contribute to the HMCCosmetics codebase, feel free to fork the repository and [submit a pull request](https://github.com/HibiscusMC/HMCCosmetics/compare).
> **Note** Contributions to the HMCCosmetics codebase should remain consistent with current code style. Remember to keep your code clean, documented and understandable, and to avoid messy or confusing code.
## Setup
To get ready to work on the codebase, please do the following:
1. Fork & clone the repository, and make sure you're on the **remapped** branch. (*This is the default branch*)
2. Code your heart out!
3. Run `./gradlew build` to ensure your project successfully builds. (*This may take a while*)
4. Finally, [submit a pull request](https://github.com/HibiscusMC/HMCCosmetics/compare)!

View File

@@ -0,0 +1,61 @@
name: Bug Report
description: Report an issue with HMCCosmetics
labels: [bug]
assignees: ["LoJoSho"]
body:
- type: markdown
attributes:
value: |
Thank you for filing an bug report! If you are here to ask a question, use our [Discord server](https://discord.gg/pcm8kWrdNt) instead!
- type: input
id: release_version
attributes:
label: Plugin Version
placeholder: vx.x.x
description: |
Insert the version of HMCCosmetics you are using (e.g. `v2.2.8`). Before continuing make sure you have the latest version of HMCCosmetics as
your issue may have already been resolved.
- type: input
id: server_version
attributes:
label: Server Version
placeholder: fork-x-x.x.x
description: |
Insert the version of your minecraft server in the format `fork-build-version` (e.g. `PAPER-521-1.19.4`, `PURPUR-1838-1.19.2`)
- type: textarea
id: description
attributes:
label: Issue description
description: Describe the issue in as much detail as possible (Include any error logs in a code block below)
- type: textarea
id: reproduce
attributes:
label: Steps to reproduce
description: Explain how to reproduce this issue step-by-step, in as much detail as possible.
placeholder: |
Steps to reproduce:
1. Do thing
2. Observe behavior
3. Post any error logs below
validations:
required: true
- type: dropdown
id: priority
attributes:
label: Issue priority
description: Please be realistic. If you need to elaborate on your reasoning, please use the issue description field above.
options:
- Low (slightly annoying)
- Medium (should be fixed somewhat soon)
- High (immediate attention needed)
validations:
required: true
- type: textarea
id: versions
attributes:
label: Other Versions
placeholder: |
- ModelEngine R3.0.1 (`/version ModelEngine`)
- Any other relevant version information such as depenedencies
description: |
List any necessary or relevant versions here.

View File

@@ -0,0 +1,28 @@
name: Feature Request
description: Request a new feature for HMCCosmetics
labels: [enhancement]
assignees: ["LoJoSho"]
body:
- type: markdown
attributes:
value: |
If you are here to ask a question, use our [Discord server](https://discord.gg/pcm8kWrdNt) instead!
- type: markdown
attributes:
value: |
Please check that the feature you are requesting does not already exist *and/or* hasn't already been requested by someone else.
- type: textarea
id: description
attributes:
label: Feature Description
description: A clear and concise description of what the problem is, or what feature you want to be implemented.
placeholder: A good addition would be...
validations:
required: true
- type: textarea
id: solution
attributes:
label: Implementation Description
description: A clear and concise description of what you want to happen, and any optional **configuration changes** that need to be made.
validations:
required: false

View File

@@ -1,62 +0,0 @@
name: Bug Report
description: Create a bug report to help us keep track of all bugs that have to be fixed
title: "[BUG] <name for bug>"
labels: [bug]
body:
- type: checkboxes
id: i-have-checked
attributes:
label: I have checked...
options:
- label: "I am using the latest version of HMCCosmetics"
required: true
- label: "I am using the latest version of any dependencies"
required: true
- label: "I have checked if any similar bug reports exist"
required: true
- type: textarea
id: description
attributes:
label: Description
description: A full description of the bug
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: Steps to reproduce
description: Explain how to reproduce this issue step-by-step, in as much detail as possible.
validations:
required: true
- type: textarea
id: hmcc-version
attributes:
label: Plugin Version
description: Run `version HMCCosmetics` in your console and paste the output
validations:
required: true
- type: textarea
id: meg-version
attributes:
label: ModelEngine Version
description: "Run `version ModelEngine` in your console and paste the output. Optional if not using balloons."
validations:
required: false
- type: textarea
id: server-version
attributes:
label: Server Version
description: "Run `version` in your console and paste the output."
validations:
required: true
- type: "dropdown"
id: "type"
attributes:
label: "How breaking is the bug?"
options:
- "Breaking Bug - Plugin unusable"
- "Non-breaking Bug - Plugin still usable, but certain features unavailable"
- "Minor Bug - Plugin completely functional, but features have non-working aspects"
validations:
required: true

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: General Questions and Help
url: https://discord.gg/pcm8kWrdNt
about: This issue tracker is not for support questions. Please refer to the Hibiscus community's help and discussion discord server.

View File

@@ -1,29 +0,0 @@
name: Feature Request
description: Create a feature request to help us keep track of all features you want to be added
title: "[FEATURE] <title>"
labels: [feature]
body:
- type: "checkboxes"
id: "i-have-checked"
attributes:
label: "I have checked that..."
options:
- label: "...such a feature does not exist already"
required: true
- label: "...such a feature request has not been submitted already"
required: true
- type: "textarea"
id: "description"
attributes:
label: "Description"
description: "A full description of the feature"
validations:
required: true
- type: "textarea"
id: "config-changes"
attributes:
label: "Config Changes"
description: "The configuration changes your feature should have"
validations:
required: false

19
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,19 @@
#### Select the option(s) that best describes this PR:
- [ ] Major breaking change
- [ ] Minor change
- [ ] Feature implementation
- [ ] Bug fix
- [ ] Chore (Changes that don't fix or add new features *and don't* modify source files)
- [ ] Refactoring (Changes that dont't fix or add new features *but do* modify source files)
- [ ] Documentation (Changes to README files and/or JavaDocs)
- [ ] Style (Changes that don't affect the meaning of the code)
- [ ] Performance
- [ ] Other (Please specify below)
#### Please describe the changes this PR makes and why it should be merged:
#### Check that:
- [ ] *Any* new classes, public methods and/or properties are properly documented with `JavaDocs`
- [ ] Syntax and style are consistent with existing code
- [ ] *Any* replaced method isn't deleted, but rather labeled as deprecated
> **Note** In the case where the new method has the exact same signature as the method it's replacing, mention above that the old method *was* deleted.

View File

@@ -8,7 +8,7 @@ plugins {
}
group = "com.hibiscusmc"
version = "2.2.5"
version = "2.4.6"
allprojects {
apply(plugin = "java")
@@ -27,6 +27,7 @@ allprojects {
// ProtocolLib repo
maven("https://repo.dmulloy2.net/repository/public/") //ProtocolLib Repo, constantly down
maven("https://repo.mineinabyss.com/releases/")
maven("https://repo.mineinabyss.com/snapshots/")
// PlaceholderAPI
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
@@ -34,8 +35,8 @@ allprojects {
//Hikari
maven("https://mvnrepository.com/artifact/com.zaxxer/HikariCP")
// Citizens
maven("https://repo.citizensnpcs.co")
// Citizens & Denizen
maven("https://maven.citizensnpcs.co/repo")
// Worldguard
maven("https://maven.enginehub.org/repo/")
@@ -59,21 +60,22 @@ allprojects {
// PlayerAnimator
maven("https://mvn.lumine.io/repository/maven/")
// md-5 Repo
maven("https://repo.md-5.net/content/groups/public/")
}
dependencies {
compileOnly(fileTree("${project.rootDir}/lib") { include("*.jar") })
compileOnly("com.mojang:authlib:1.5.25")
compileOnly("org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT")
compileOnly("org.spigotmc:spigot-api:1.18.2-R0.1-SNAPSHOT")
compileOnly("org.jetbrains:annotations:23.0.0")
compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0-SNAPSHOT")
compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0")
compileOnly("me.clip:placeholderapi:2.11.1")
compileOnly("com.ticxo.modelengine:api:R3.0.1")
compileOnly("com.ticxo:modelengine:R3.0.1")
compileOnly("com.github.oraxen:oraxen:-SNAPSHOT")
compileOnly("com.github.LoneDev6:API-ItemsAdder:3.2.5")
compileOnly("com.mineinabyss:idofront:0.12.111")
compileOnly("com.mineinabyss:geary-papermc-core:0.19.113")
compileOnly("com.mineinabyss:looty:0.8.67")
compileOnly("com.mineinabyss:geary-papermc:0.24-SNAPSHOT")
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT")
compileOnly("it.unimi.dsi:fastutil:8.5.11")
compileOnly("com.github.LeonMangler:SuperVanish:6.2.6-4")
@@ -82,10 +84,11 @@ allprojects {
dependencies {
implementation(project(path = ":common"))
implementation(project(path = ":v1_17_R1", configuration = "reobf"))
implementation(project(path = ":v1_18_R2", configuration = "reobf"))
implementation(project(path = ":v1_19_R1", configuration = "reobf"))
implementation(project(path = ":v1_19_R2", configuration = "reobf"))
implementation(project(path = ":v1_19_R3", configuration = "reobf"))
implementation(project(path = ":v1_20_R1", configuration = "reobf"))
//compileOnly("com.github.Fisher2911:FisherLib:master-SNAPSHOT")
implementation("net.kyori:adventure-api:4.11.0")
@@ -96,7 +99,9 @@ dependencies {
implementation("org.bstats:bstats-bukkit:3.0.0")
implementation("com.jeff_media:SpigotUpdateChecker:3.0.0")
implementation("com.owen1212055:particlehelper:1.0.0-SNAPSHOT")
implementation("com.ticxo.playeranimator:PlayerAnimator:R1.2.5")
implementation("com.ticxo.playeranimator:PlayerAnimator:R1.2.7")
implementation("com.github.BG-Software-LLC:CommentedConfiguration:-SNAPSHOT")
//implementation("com.ticxo.playeranimator:PlayerAnimator:R1.2.5")
}
tasks {
@@ -116,14 +121,15 @@ tasks {
}
runServer {
minecraftVersion("1.19.2")
minecraftVersion("1.19.4")
}
shadowJar {
dependsOn(":v1_17_R1:reobfJar")
dependsOn(":v1_18_R2:reobfJar")
dependsOn(":v1_19_R1:reobfJar")
dependsOn(":v1_19_R2:reobfJar")
dependsOn(":v1_19_R3:reobfJar")
dependsOn(":v1_20_R1:reobfJar")
mergeServiceFiles()
relocate("dev.triumphteam.gui", "com.hisbiscusmc.hmccosmetics.gui")
@@ -136,6 +142,7 @@ tasks {
relocate("com.jeff_media.updatechecker", "com.hisbiscusmc.hmccosmetics.updatechecker")
relocate("com.owen1212055.particlehelper", "com.hisbiscusmc.hmccosmetics.particlehelper")
relocate("com.ticxo.playeranimator", "com.hisbiscusmc.hmccosmetics.playeranimator")
relocate("com.bgsoftware", "com.hisbiscusmc.hmccosmetics.configupdater")
archiveFileName.set("HMCCosmeticsRemapped-${project.version}.jar")
dependencies {
@@ -160,10 +167,10 @@ tasks {
bukkit {
load = BukkitPluginDescription.PluginLoadOrder.POSTWORLD
main = "com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin"
apiVersion = "1.17"
apiVersion = "1.18"
authors = listOf("LoJoSho")
depend = listOf("ProtocolLib")
softDepend = listOf("ModelEngine", "Oraxen", "ItemsAdder", "Looty", "HMCColor", "WorldGuard", "MythicMobs", "PlaceholderAPI", "SuperVanish", "PremiumVanish")
softDepend = listOf("ModelEngine", "Oraxen", "ItemsAdder", "Geary", "HMCColor", "WorldGuard", "MythicMobs", "PlaceholderAPI", "SuperVanish", "PremiumVanish", "LibsDisguises", "Denizen")
version = "${project.version}"
commands {
@@ -205,7 +212,7 @@ bukkit {
register("hmccosmetics.cmd.emote.other") {
default = BukkitPluginDescription.Permission.Default.OP
}
register("hmccosmetics.cmd.setlocation") {
register("hmccosmetics.cmd.setwardrobesetting") {
default = BukkitPluginDescription.Permission.Default.OP
}
register("hmccosmetics.cmd.dataclear") {
@@ -250,4 +257,4 @@ bukkit {
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(17
))
}
}

View File

@@ -5,20 +5,23 @@ plugins {
dependencies {
compileOnly("com.mojang:authlib:1.5.25")
compileOnly("org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT")
compileOnly("org.spigotmc:spigot-api:1.18.2-R0.1-SNAPSHOT")
compileOnly("org.jetbrains:annotations:23.0.0")
compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0-SNAPSHOT")
compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0")
compileOnly("me.clip:placeholderapi:2.11.1")
compileOnly("com.ticxo.modelengine:api:R3.0.1")
compileOnly("com.ticxo:modelengine:R3.0.1")
compileOnly("com.github.oraxen:oraxen:-SNAPSHOT")
compileOnly("com.github.LoneDev6:API-ItemsAdder:3.2.5")
compileOnly("com.mineinabyss:geary-papermc-core:0.19.113")
compileOnly("com.mineinabyss:looty:0.8.67")
compileOnly("com.mineinabyss:geary-papermc:0.24-SNAPSHOT")
compileOnly("com.hibiscus:hmccolor:0.3-SNAPSHOT")
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT")
compileOnly("it.unimi.dsi:fastutil:8.5.11")
compileOnly("io.lumine:Mythic-Dist:5.2.1")
compileOnly("com.denizenscript:denizen:1.2.7-SNAPSHOT")
compileOnly("com.github.LeonMangler:SuperVanish:6.2.6-4")
compileOnlyApi("LibsDisguises:LibsDisguises:10.0.21") {
exclude("org.spigotmc", "spigot")
}
//compileOnly("com.github.Fisher2911:FisherLib:master-SNAPSHOT")
implementation("net.kyori:adventure-api:4.12.0")
@@ -29,7 +32,9 @@ dependencies {
implementation("org.bstats:bstats-bukkit:3.0.0")
implementation("com.jeff_media:SpigotUpdateChecker:3.0.0")
implementation("com.owen1212055:particlehelper:1.0.0-SNAPSHOT")
implementation("com.ticxo.playeranimator:PlayerAnimator:R1.2.5")
implementation("com.ticxo.playeranimator:PlayerAnimator:R1.2.7")
implementation("com.github.BG-Software-LLC:CommentedConfiguration:-SNAPSHOT")
//implementation("com.ticxo.playeranimator:PlayerAnimator:R1.2.5")
}
java {

View File

@@ -1,6 +1,7 @@
package com.hibiscusmc.hmccosmetics;
import com.hibiscusmc.hmccosmetics.api.HMCCosmeticSetupEvent;
import com.bgsoftware.common.config.CommentedConfiguration;
import com.hibiscusmc.hmccosmetics.api.events.HMCCosmeticSetupEvent;
import com.hibiscusmc.hmccosmetics.command.CosmeticCommand;
import com.hibiscusmc.hmccosmetics.command.CosmeticCommandTabComplete;
import com.hibiscusmc.hmccosmetics.config.DatabaseSettings;
@@ -11,6 +12,8 @@ import com.hibiscusmc.hmccosmetics.config.serializer.LocationSerializer;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.database.Database;
import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.hooks.Hooks;
import com.hibiscusmc.hmccosmetics.hooks.worldguard.WGHook;
@@ -18,14 +21,13 @@ import com.hibiscusmc.hmccosmetics.hooks.worldguard.WGListener;
import com.hibiscusmc.hmccosmetics.listener.PlayerConnectionListener;
import com.hibiscusmc.hmccosmetics.listener.PlayerGameListener;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.TranslationUtil;
import com.jeff_media.updatechecker.UpdateCheckSource;
import com.jeff_media.updatechecker.UpdateChecker;
import com.ticxo.playeranimator.PlayerAnimatorImpl;
import com.ticxo.playeranimator.api.PlayerAnimator;
import com.ticxo.playeranimator.api.animation.pack.AnimationPack;
import org.apache.commons.io.FilenameUtils;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -41,7 +43,6 @@ import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
import java.io.File;
import java.nio.file.Path;
import java.util.Map;
public final class HMCCosmeticsPlugin extends JavaPlugin {
@@ -87,13 +88,12 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
.checkNow();
onLatestVersion = checker.isUsingLatestVersion();
// File setup
if (!getDataFolder().exists()) {
saveDefaultConfig();
saveResource("translations.yml", false);
saveResource("messages.yml", false);
saveResource("cosmetics/defaultcosmetics.yml", false);
saveResource("menus/defaultmenu.yml", false);
}
saveDefaultConfig();
if (!Path.of(getDataFolder().getPath(), "messages.yml").toFile().exists()) saveResource("messages.yml", false);
if (!Path.of(getDataFolder().getPath(), "translations.yml").toFile().exists()) saveResource("translations.yml", false);
if (!Path.of(getDataFolder().getPath() + "/cosmetics/").toFile().exists()) saveResource("cosmetics/defaultcosmetics.yml", false);
if (!Path.of(getDataFolder().getPath() + "/menus/").toFile().exists()) saveResource("menus/defaultmenu.yml", false);
// Emote folder setup
File emoteFile = new File(getDataFolder().getPath() + "/emotes");
if (!emoteFile.exists()) emoteFile.mkdir();
@@ -101,6 +101,20 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
// Player Animator
PlayerAnimatorImpl.initialize(this);
// Configuration Sync
final File configFile = Path.of(getInstance().getDataFolder().getPath(), "config.yml").toFile();
final File messageFile = Path.of(getInstance().getDataFolder().getPath(), "messages.yml").toFile();
final File translationFile = Path.of(getInstance().getDataFolder().getPath(), "translations.yml").toFile();
try {
CommentedConfiguration.loadConfiguration(configFile).syncWithConfig(configFile, getInstance().getResource("config.yml"),
"database-settings", "debug-mode", "wardrobe.viewer-location", "wardrobe.npc-location", "wardrobe.wardrobe-location", "wardrobe.leave-location");
CommentedConfiguration.loadConfiguration(messageFile).syncWithConfig(messageFile, getInstance().getResource("messages.yml"));
CommentedConfiguration.loadConfiguration(translationFile).syncWithConfig(translationFile, getInstance().getResource("translations.yml"));
} catch (Exception e) {
e.printStackTrace();
}
// Setup
setup();
// Commands
@@ -120,7 +134,7 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
}
// WorldGuard
if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null) {
if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null && Settings.isWorldGuardMoveCheckEnabled()) {
getServer().getPluginManager().registerEvents(new WGListener(), this);
}
}
@@ -135,11 +149,16 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
@Override
public void onDisable() {
// Plugin shutdown logic
disable = true;
for (Player player : Bukkit.getOnlinePlayers()) {
Database.save(player);
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) continue;
if (user.getUserEmoteManager().isPlayingEmote()) {
player.setInvisible(false);
}
Database.save(user);
}
// Plugin shutdown logic
}
public static HMCCosmeticsPlugin getInstance() {
@@ -166,7 +185,7 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
WardrobeSettings.load(loader.load().node("wardrobe"));
DatabaseSettings.load(loader.load().node("database-settings"));
configLoader = loader;
} catch (ConfigurateException e) {
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -232,26 +251,19 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
getInstance().getServer().getPluginManager().addPermission(new Permission(cosmetic.getPermission()));
}
}
File emoteFolder = new File(getInstance().getDataFolder().getPath() + "/emotes/");
if (emoteFolder.exists()) {
PlayerAnimator.api.getAnimationManager().clearRegistry();
File[] emotesFiles = emoteFolder.listFiles();
for (File emoteFile : emotesFiles) {
if (!emoteFile.getName().contains("bbmodel")) continue;
String animationName = emoteFile.getName().replaceAll(".bbmodel", "");
PlayerAnimator.api.getAnimationManager().importAnimations(FilenameUtils.removeExtension(emoteFile.getName()), emoteFile);
MessagesUtil.sendDebugMessages("Added '" + animationName + "' to Player Animator ");
}
for (Map.Entry<String, AnimationPack> packEntry : PlayerAnimator.api.getAnimationManager().getRegistry().entrySet()) {
//Set<String> animationNames = packEntry.getValue().getAnimations().keySet().stream().map(animation -> packEntry.getKey().replace(":", ".") + "." + animation).collect(Collectors.toSet());
for (Menu menu : Menus.values()) {
if (menu.getPermissionNode() != null) {
if (getInstance().getServer().getPluginManager().getPermission(menu.getPermissionNode()) != null) continue;
getInstance().getServer().getPluginManager().addPermission(new Permission(menu.getPermissionNode()));
}
}
EmoteManager.loadEmotes();
getInstance().getLogger().info("Successfully Enabled HMCCosmetics");
getInstance().getLogger().info(Cosmetics.values().size() + " Cosmetics Successfully Setup");
getInstance().getLogger().info(Menus.getMenuNames().size() + " Menus Successfully Setup");
getInstance().getLogger().info(WardrobeSettings.getWardrobes().size() + " Wardrobes Successfully Setup");
getInstance().getLogger().info("Data storage is set to " + DatabaseSettings.getDatabaseType());
Bukkit.getPluginManager().callEvent(new HMCCosmeticSetupEvent());

View File

@@ -0,0 +1,49 @@
package com.hibiscusmc.hmccosmetics.api;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
public class HMCCosmeticsAPI {
/**
* Attempts to get a cosmetic from HMCCosmetics
*
* @param cosmetic Cosmetic Id
* @return A {@link Cosmetic} if exists or null if it does not
*/
@Nullable
public static Cosmetic getCosmetic(String cosmetic) {
return Cosmetics.getCosmetic(cosmetic);
}
/**
* Attempts to get the CosmeticUser from an online user. If a player is offline it will return null.
* A player maybe online but not have a CosmeticUser attached to them, either from delay specified in the config
* or from a /reload. Always check if it's null!
*
* @param uuid Player Unique ID
* @return A {@link CosmeticUser} if exists or null if it does not
*/
@Nullable
public static CosmeticUser getUser(UUID uuid) {
return CosmeticUsers.getUser(uuid);
}
/**
* Attempts to get a HMCCosmetics Menu. Returns null if no menu exists under that id.
*
* @param id Menu ID
* @return A {@link Menu} if exists or null if it does not
*/
@Nullable
public static Menu getMenu(String id) {
return Menus.getMenu(id);
}
}

View File

@@ -1,55 +0,0 @@
package com.hibiscusmc.hmccosmetics.api;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerCosmeticEquipEvent extends Event implements Cancellable {
private final CosmeticUser user;
private Cosmetic cosmetic;
private boolean isCancelled;
public PlayerCosmeticEquipEvent(CosmeticUser user, Cosmetic cosmetic) {
this.user = user;
this.cosmetic = cosmetic;
this.isCancelled = false;
}
@Override
public boolean isCancelled() {
return isCancelled;
}
@Override
public void setCancelled(boolean cancel) {
isCancelled = cancel;
}
private static final HandlerList handlers = new HandlerList();
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
public CosmeticUser getUser() {
return user;
}
public Cosmetic getCosmetic() {
return cosmetic;
}
public void setCosmetic(Cosmetic cosmetic) {
this.cosmetic = cosmetic;
}
}

View File

@@ -1,49 +0,0 @@
package com.hibiscusmc.hmccosmetics.api;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerCosmeticHideEvent extends Event implements Cancellable {
private final CosmeticUser user;
private final CosmeticUser.HiddenReason reason;
private boolean isCancelled;
public PlayerCosmeticHideEvent(CosmeticUser user, CosmeticUser.HiddenReason reason) {
this.user = user;
this.reason = reason;
this.isCancelled = false;
}
@Override
public boolean isCancelled() {
return isCancelled;
}
@Override
public void setCancelled(boolean cancel) {
isCancelled = cancel;
}
private static final HandlerList handlers = new HandlerList();
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
public CosmeticUser getUser() {
return user;
}
public CosmeticUser.HiddenReason getReason() {
return reason;
}
}

View File

@@ -1,51 +0,0 @@
package com.hibiscusmc.hmccosmetics.api;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerCosmeticRemoveEvent extends Event implements Cancellable {
private final CosmeticUser user;
private final Cosmetic cosmetic;
private boolean isCancelled;
public PlayerCosmeticRemoveEvent(CosmeticUser user, Cosmetic cosmetic) {
this.user = user;
this.cosmetic = cosmetic;
this.isCancelled = false;
}
@Override
public boolean isCancelled() {
return isCancelled;
}
@Override
public void setCancelled(boolean cancel) {
isCancelled = cancel;
}
private static final HandlerList handlers = new HandlerList();
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
public CosmeticUser getUser() {
return user;
}
public Cosmetic getCosmetic() {
return cosmetic;
}
}

View File

@@ -1,44 +0,0 @@
package com.hibiscusmc.hmccosmetics.api;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerCosmeticShowEvent extends Event implements Cancellable {
private final CosmeticUser user;
private boolean isCancelled;
public PlayerCosmeticShowEvent(CosmeticUser user) {
this.user = user;
this.isCancelled = false;
}
@Override
public boolean isCancelled() {
return isCancelled;
}
@Override
public void setCancelled(boolean cancel) {
isCancelled = cancel;
}
private static final HandlerList handlers = new HandlerList();
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
public CosmeticUser getUser() {
return user;
}
}

View File

@@ -1,50 +0,0 @@
package com.hibiscusmc.hmccosmetics.api;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerEmoteStartEvent extends Event implements Cancellable {
private final CosmeticUser user;
private String animationId; // Animation id can be invalid!
private boolean isCancelled;
public PlayerEmoteStartEvent(CosmeticUser user, String animationId) {
this.user = user;
this.animationId = animationId;
this.isCancelled = false;
}
@Override
public boolean isCancelled() {
return isCancelled;
}
@Override
public void setCancelled(boolean cancel) {
isCancelled = cancel;
}
private static final HandlerList handlers = new HandlerList();
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
public CosmeticUser getUser() {
return user;
}
public String getAnimationId() {
return animationId;
}
}

View File

@@ -1,51 +0,0 @@
package com.hibiscusmc.hmccosmetics.api;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerEmoteStopEvent extends Event implements Cancellable {
private final CosmeticUser user;
private final UserEmoteManager.StopEmoteReason stopEmoteReason;
private boolean isCancelled;
public PlayerEmoteStopEvent(CosmeticUser user, UserEmoteManager.StopEmoteReason reason) {
this.user = user;
this.stopEmoteReason = reason;
this.isCancelled = false;
}
@Override
public boolean isCancelled() {
return isCancelled;
}
@Override
public void setCancelled(boolean cancel) {
isCancelled = cancel;
}
private static final HandlerList handlers = new HandlerList();
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
public CosmeticUser getUser() {
return user;
}
public UserEmoteManager.StopEmoteReason getStopEmoteReason() {
return stopEmoteReason;
}
}

View File

@@ -1,51 +0,0 @@
package com.hibiscusmc.hmccosmetics.api;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerMenuOpenEvent extends Event implements Cancellable {
private final CosmeticUser user;
private final Menu menu;
private boolean isCancelled;
public PlayerMenuOpenEvent(CosmeticUser user, Menu menu) {
this.user = user;
this.menu = menu;
this.isCancelled = false;
}
@Override
public boolean isCancelled() {
return isCancelled;
}
@Override
public void setCancelled(boolean cancel) {
isCancelled = cancel;
}
private static final HandlerList handlers = new HandlerList();
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
public CosmeticUser getUser() {
return user;
}
public Menu getMenu() {
return menu;
}
}

View File

@@ -1,44 +0,0 @@
package com.hibiscusmc.hmccosmetics.api;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerWardrobeEnterEvent extends Event implements Cancellable {
private final CosmeticUser user;
private boolean isCancelled;
public PlayerWardrobeEnterEvent(CosmeticUser user) {
this.user = user;
this.isCancelled = false;
}
@Override
public boolean isCancelled() {
return isCancelled;
}
@Override
public void setCancelled(boolean cancel) {
isCancelled = cancel;
}
private static final HandlerList handlers = new HandlerList();
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
public CosmeticUser getUser() {
return user;
}
}

View File

@@ -1,44 +0,0 @@
package com.hibiscusmc.hmccosmetics.api;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerWardrobeLeaveEvent extends Event implements Cancellable {
private final CosmeticUser user;
private boolean isCancelled;
public PlayerWardrobeLeaveEvent(CosmeticUser user) {
this.user = user;
this.isCancelled = false;
}
@Override
public boolean isCancelled() {
return isCancelled;
}
@Override
public void setCancelled(boolean cancel) {
isCancelled = cancel;
}
private static final HandlerList handlers = new HandlerList();
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
public CosmeticUser getUser() {
return user;
}
}

View File

@@ -1,15 +1,13 @@
package com.hibiscusmc.hmccosmetics.api;
package com.hibiscusmc.hmccosmetics.api.events;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* Called when the plugin is set up and/or reloaded
*/
public class HMCCosmeticSetupEvent extends Event {
public HMCCosmeticSetupEvent() {
// Empty
}
private static final HandlerList handlers = new HandlerList();
@Override
@@ -18,6 +16,7 @@ public class HMCCosmeticSetupEvent extends Event {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}

View File

@@ -0,0 +1,70 @@
package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player equips a cosmetic
*/
public class PlayerCosmeticEquipEvent extends PlayerCosmeticEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancel = false;
private Cosmetic cosmetic;
public PlayerCosmeticEquipEvent(@NotNull CosmeticUser who, @NotNull Cosmetic cosmetic) {
super(who);
this.cosmetic = cosmetic;
}
/**
* Gets the {@link Cosmetic} being equipped in this event
*
* @return The {@link Cosmetic} which is being equipped in this event
*/
@NotNull
public Cosmetic getCosmetic() {
return cosmetic;
}
/**
* Sets the {@link Cosmetic} that the player will equip
*
* @param cosmetic The {@link Cosmetic} that the player will equip
*/
public void setCosmetic(@NotNull Cosmetic cosmetic) {
this.cosmetic = cosmetic;
}
@Override
public boolean isCancelled() {
return cancel;
}
/**
* Sets the cancellation state of this event
*
* <p>
* Canceling this event will prevent the player from equipping the cosmetic
* </p>
*
* @param cancel true if you wish to cancel this event
*/
@Override
public void setCancelled(boolean cancel) {
this.cancel = cancel;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@@ -0,0 +1,26 @@
package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
/**
* Represents a cosmetic user related event
*/
public abstract class PlayerCosmeticEvent extends Event {
protected CosmeticUser user;
public PlayerCosmeticEvent(@NotNull final CosmeticUser who) {
user = who;
}
/**
* Returns the user involved in this event
*
* @return User who is involved in this event
*/
@NotNull
public final CosmeticUser getUser() {
return user;
}
}

View File

@@ -0,0 +1,60 @@
package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* Called when cosmetics are hidden from a player
*/
public class PlayerCosmeticHideEvent extends PlayerCosmeticEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancel = false;
private final CosmeticUser.HiddenReason reason;
public PlayerCosmeticHideEvent(@NotNull CosmeticUser who, @NotNull CosmeticUser.HiddenReason reason) {
super(who);
this.reason = reason;
}
/**
* Gets the {@link CosmeticUser.HiddenReason} as to why cosmetics are being hidden for the player
*
* @return The {@link CosmeticUser.HiddenReason} why cosmetics are being hidden for the player
*/
@NotNull
public CosmeticUser.HiddenReason getReason() {
return reason;
}
@Override
public boolean isCancelled() {
return cancel;
}
/**
* Sets the cancellation state of this event
*
* <p>
* Canceling this event will prevent the player from hiding cosmetics
* </p>
*
* @param cancel true if you wish to cancel this event
*/
@Override
public void setCancelled(boolean cancel) {
this.cancel = cancel;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@@ -0,0 +1,46 @@
package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerCosmeticPostEquipEvent extends PlayerCosmeticEvent {
private static final HandlerList handlers = new HandlerList();
private Cosmetic cosmetic;
public PlayerCosmeticPostEquipEvent(@NotNull CosmeticUser who, @NotNull Cosmetic cosmetic) {
super(who);
this.cosmetic = cosmetic;
}
/**
* Gets the {@link Cosmetic} being equipped in this event
*
* @return The {@link Cosmetic} which is being equipped in this event
*/
@NotNull
public Cosmetic getCosmetic() {
return cosmetic;
}
/**
* Sets the {@link Cosmetic} that the player will equip
*
* @param cosmetic The {@link Cosmetic} that the player will equip
*/
public void setCosmetic(@NotNull Cosmetic cosmetic) {
this.cosmetic = cosmetic;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@@ -0,0 +1,59 @@
package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player removes a cosmetic
*/
public class PlayerCosmeticRemoveEvent extends PlayerCosmeticEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancel = false;
private final Cosmetic cosmetic;
public PlayerCosmeticRemoveEvent(@NotNull CosmeticUser who, @NotNull Cosmetic cosmetic) {
super(who);
this.cosmetic = cosmetic;
}
/**
* Gets the {@link Cosmetic} being removed in this event
*
* @return The {@link Cosmetic} which is being removed in this event
*/
public Cosmetic getCosmetic() {
return cosmetic;
}
@Override
public boolean isCancelled() {
return cancel;
}
/**
* Sets the cancellation state of this event
*
* <p>
* Canceling this event will prevent the player from removing the cosmetic
* </p>
*
* @param cancel true if you wish to cancel this event
*/
@Override
public void setCancelled(boolean cancel) {
this.cancel = cancel;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@@ -0,0 +1,48 @@
package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* Called when cosmetics are shown from a player
*/
public class PlayerCosmeticShowEvent extends PlayerCosmeticEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancel = false;
public PlayerCosmeticShowEvent(@NotNull CosmeticUser who) {
super(who);
}
@Override
public boolean isCancelled() {
return cancel;
}
/**
* Sets the cancellation state of this event
*
* <p>
* Canceling this event will prevent the player from showing cosmetics
* </p>
*
* @param cancel true if you wish to cancel this event
*/
@Override
public void setCancelled(boolean cancel) {
this.cancel = cancel;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@@ -0,0 +1,61 @@
package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player starts playing an emote
*/
public class PlayerEmoteStartEvent extends PlayerCosmeticEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancel = false;
private final String animationId;
public PlayerEmoteStartEvent(@NotNull CosmeticUser who, @NotNull String animationId) {
super(who);
this.animationId = animationId;
}
/**
* Gets the animation id of the emote the player started playing
* @implNote The returned string of this method may be an invalid animation id. Make sure to validate it before use
*
* @return The animation id of the emote which the player started playing
*/
@NotNull
public String getAnimationId() {
return animationId;
}
@Override
public boolean isCancelled() {
return cancel;
}
/**
* Sets the cancellation state of this event
*
* <p>
* Canceling this event will prevent the player from playing the emote
* </p>
*
* @param cancel true if you wish to cancel this event
*/
@Override
public void setCancelled(boolean cancel) {
this.cancel = cancel;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@@ -0,0 +1,74 @@
package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player stops playing an emote
*/
public class PlayerEmoteStopEvent extends PlayerCosmeticEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancel = false;
private final UserEmoteManager.StopEmoteReason reason;
public PlayerEmoteStopEvent(@NotNull CosmeticUser who, @NotNull UserEmoteManager.StopEmoteReason reason) {
super(who);
this.reason = reason;
}
/**
* Gets the {@link UserEmoteManager.StopEmoteReason} as to why the emote has stopped playing
*
* @return The {@link UserEmoteManager.StopEmoteReason} why the emote has stopped playing
* @deprecated As of release 2.2.5+, replaced by {@link #getReason()}
*/
@Deprecated
@NotNull
public UserEmoteManager.StopEmoteReason getStopEmoteReason() {
return reason;
}
/**
* Gets the {@link UserEmoteManager.StopEmoteReason} as to why the emote has stopped playing
*
* @return The {@link UserEmoteManager.StopEmoteReason} why the emote has stopped playing
* @since 2.2.5
*/
@NotNull
public UserEmoteManager.StopEmoteReason getReason() {
return reason;
}
@Override
public boolean isCancelled() {
return cancel;
}
/**
* Sets the cancellation state of this event
*
* <p>
* Canceling this event will prevent the player from stopping the emote
* </p>
*
* @param cancel true if you wish to cancel this event
*/
@Override
public void setCancelled(boolean cancel) {
this.cancel = cancel;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@@ -0,0 +1,28 @@
package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* Called when a menu is closed by a player
*/
public class PlayerMenuCloseEvent extends PlayerMenuEvent {
private static final HandlerList handlers = new HandlerList();
public PlayerMenuCloseEvent(@NotNull CosmeticUser who, @NotNull Menu menu) {
super(who, menu);
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@@ -0,0 +1,27 @@
package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.jetbrains.annotations.NotNull;
/**
* Represents a menu related event
*/
public abstract class PlayerMenuEvent extends PlayerCosmeticEvent {
protected Menu menu;
public PlayerMenuEvent(@NotNull CosmeticUser who, @NotNull Menu menu) {
super(who);
this.menu = menu;
}
/**
* Gets the {@link Menu} involved with this event
*
* @return The {@link Menu} which is involved with the event
*/
@NotNull
public final Menu getMenu() {
return menu;
}
}

View File

@@ -0,0 +1,49 @@
package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* Called when a menu is opened by a player
*/
public class PlayerMenuOpenEvent extends PlayerMenuEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancel = false;
public PlayerMenuOpenEvent(@NotNull CosmeticUser who, @NotNull Menu menu) {
super(who, menu);
}
@Override
public boolean isCancelled() {
return cancel;
}
/**
* Sets the cancellation state of this event
*
* <p>
* Canceling this event will prevent the player from opening a {@link Menu}
* </p>
*
* @param cancel true if you wish to cancel this event
*/
@Override
public void setCancelled(boolean cancel) {
this.cancel = cancel;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@@ -0,0 +1,59 @@
package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player enters their wardrobe
*/
public class PlayerWardrobeEnterEvent extends PlayerCosmeticEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancel = false;
private Wardrobe wardrobe;
public PlayerWardrobeEnterEvent(@NotNull CosmeticUser who, @NotNull Wardrobe wardrobe) {
super(who);
this.wardrobe = wardrobe;
}
@Override
public boolean isCancelled() {
return cancel;
}
/**
* Sets the cancellation state of this event
*
* <p>
* Canceling this event will prevent the player from entering their wardrobe
* </p>
*
* @param cancel true if you wish to cancel this event
*/
@Override
public void setCancelled(boolean cancel) {
this.cancel = cancel;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
public void setWardrobe(Wardrobe wardrobe) {
this.wardrobe = wardrobe;
}
public Wardrobe getWardrobe() {
return wardrobe;
}
}

View File

@@ -0,0 +1,48 @@
package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player leaves their wardrobe
*/
public class PlayerWardrobeLeaveEvent extends PlayerCosmeticEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancel = false;
public PlayerWardrobeLeaveEvent(@NotNull CosmeticUser who) {
super(who);
}
@Override
public boolean isCancelled() {
return cancel;
}
/**
* Sets the cancellation state of this event
*
* <p>
* Canceling this event will prevent the player from leaving their wardrobe
* </p>
*
* @param cancel true if you wish to cancel this event
*/
@Override
public void setCancelled(boolean cancel) {
this.cancel = cancel;
}
@Override
@NotNull
public HandlerList getHandlers() {
return handlers;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@@ -2,12 +2,15 @@ package com.hibiscusmc.hmccosmetics.command;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.config.WardrobeLocation;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticEmoteType;
import com.hibiscusmc.hmccosmetics.database.Database;
import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.gui.special.DyeMenu;
@@ -15,7 +18,6 @@ import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.ServerUtils;
import com.ticxo.playeranimator.api.PlayerAnimator;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.apache.commons.lang3.EnumUtils;
@@ -28,7 +30,6 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Set;
public class CosmeticCommand implements CommandExecutor {
@@ -195,8 +196,14 @@ public class CosmeticCommand implements CommandExecutor {
}
case ("wardrobe") -> {
if (sender instanceof Player) player = ((Player) sender).getPlayer();
if (args.length == 1) {
if (!silent) MessagesUtil.sendMessage(player, "not-enough-args");
return true;
}
if (sender.hasPermission("hmccosmetics.cmd.wardrobe.other")) {
if (args.length >= 2) player = Bukkit.getPlayer(args[1]);
if (args.length >= 3) player = Bukkit.getPlayer(args[2]);
}
if (!sender.hasPermission("hmccosmetics.cmd.wardrobe")) {
@@ -209,9 +216,19 @@ public class CosmeticCommand implements CommandExecutor {
return true;
}
if (!WardrobeSettings.getWardrobeNames().contains(args[1])) {
if (!silent) MessagesUtil.sendMessage(sender, "no-wardrobes");
return true;
}
Wardrobe wardrobe = WardrobeSettings.getWardrobe(args[1]);
CosmeticUser user = CosmeticUsers.getUser(player);
user.toggleWardrobe();
if (user.isInWardrobe()) {
user.leaveWardrobe();
} else {
user.enterWardrobe(false, wardrobe);
}
return true;
}
// cosmetic menu exampleMenu playerName
@@ -290,36 +307,56 @@ public class CosmeticCommand implements CommandExecutor {
DyeMenu.openMenu(user, cosmetic);
}
}
case ("setlocation") -> {
if (!sender.hasPermission("hmccosmetics.cmd.setlocation")) {
case ("setwardrobesetting") -> {
if (!sender.hasPermission("hmccosmetics.cmd.setwardrobesetting")) {
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
if (player == null) return true;
if (args.length < 2) {
if (args.length < 3) {
if (!silent) MessagesUtil.sendMessage(player, "not-enough-args");
return true;
}
Wardrobe wardrobe = WardrobeSettings.getWardrobe(args[1]);
if (wardrobe == null) {
wardrobe = new Wardrobe(args[1], new WardrobeLocation(null, null, null), null, -1);
WardrobeSettings.addWardrobe(wardrobe);
//MessagesUtil.sendMessage(player, "no-wardrobes");
//return true;
}
if (args[1].equalsIgnoreCase("wardrobelocation")) {
WardrobeSettings.setWardrobeLocation(player.getLocation());
if (args[2].equalsIgnoreCase("npclocation")) {
WardrobeSettings.setNPCLocation(wardrobe, player.getLocation());
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-location");
return true;
}
if (args[1].equalsIgnoreCase("viewerlocation")) {
WardrobeSettings.setViewerLocation(player.getLocation());
if (args[2].equalsIgnoreCase("viewerlocation")) {
WardrobeSettings.setViewerLocation(wardrobe, player.getLocation());
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-viewing");
return true;
}
if (args[1].equalsIgnoreCase("leavelocation")) {
WardrobeSettings.setLeaveLocation(player.getLocation());
if (args[2].equalsIgnoreCase("leavelocation")) {
WardrobeSettings.setLeaveLocation(wardrobe, player.getLocation());
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-leaving");
return true;
}
if (args.length >= 4) {
if (args[2].equalsIgnoreCase("permission")) {
WardrobeSettings.setWardrobePermission(wardrobe, args[3]);
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-permission");
return true;
}
if (args[2].equalsIgnoreCase("distance")) {
WardrobeSettings.setWardrobeDistance(wardrobe, Integer.valueOf(args[3]));
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-distance");
return true;
}
}
}
case ("dump") -> {
if (player == null) return true;
@@ -333,7 +370,7 @@ public class CosmeticCommand implements CommandExecutor {
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
player.sendMessage("Backpack Location -> " + user.getUserBackpackManager().getArmorStand().getLocation());
}
player.sendMessage("Cosmetics -> " + user.getCosmetic());
player.sendMessage("Cosmetics -> " + user.getCosmetics());
player.sendMessage("EntityId -> " + player.getEntityId());
return true;
}
@@ -429,12 +466,10 @@ public class CosmeticCommand implements CommandExecutor {
return true;
}
if (args.length >= 2) {
if (!PlayerAnimator.api.getAnimationManager().getRegistry().keySet().contains(args[1])) {
MessagesUtil.sendDebugMessages("Did not contain " + args[1]);
if (!silent) MessagesUtil.sendMessage(sender, "emote-invalid");
return true;
}
if (!EmoteManager.has(args[1])) {
MessagesUtil.sendDebugMessages("Did not contain " + args[1]);
if (!silent) MessagesUtil.sendMessage(sender, "emote-invalid");
return true;
}
if (sender.hasPermission("hmccosmetics.cmd.playemote.other")) {

View File

@@ -1,13 +1,15 @@
package com.hibiscusmc.hmccosmetics.command;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.ticxo.playeranimator.api.PlayerAnimator;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -36,7 +38,7 @@ public class CosmeticCommandTabComplete implements TabCompleter {
if (hasPermission(sender, "hmccosmetics.cmd.wardrobe")) completions.add("wardrobe");
if (hasPermission(sender, "hmccosmetics.cmd.dataclear")) completions.add("dataclear");
if (hasPermission(sender, "hmccosmetics.cmd.dye")) completions.add("dye");
if (hasPermission(sender, "hmccosmetics.cmd.setlocation")) completions.add("setlocation");
if (hasPermission(sender, "hmccosmetics.cmd.setwardrobesetting")) completions.add("setwardrobesetting");
if (hasPermission(sender, "hmccosmetics.cmd.hide")) completions.add("hide");
if (hasPermission(sender, "hmccosmetics.cmd.show")) completions.add("show");
if (hasPermission(sender, "hmccosmetics.cmd.debug")) completions.add("debug");
@@ -56,7 +58,7 @@ public class CosmeticCommandTabComplete implements TabCompleter {
completions.addAll(applyCommandComplete(user, args));
}
case "unapply" -> {
for (Cosmetic cosmetic : user.getCosmetic()) {
for (Cosmetic cosmetic : user.getCosmetics()) {
completions.add(cosmetic.getSlot().toString().toUpperCase());
}
completions.add("ALL");
@@ -66,24 +68,31 @@ public class CosmeticCommandTabComplete implements TabCompleter {
if (menu.canOpen(user.getPlayer())) completions.add(menu.getId());
}
}
case "dataclear", "wardrobe", "hide", "show", "emote" -> {
case "dataclear", "hide", "show", "emote" -> {
for (Player player : Bukkit.getOnlinePlayers()) {
completions.add(player.getName());
}
}
case "wardrobe" -> {
for (Wardrobe wardrobe : WardrobeSettings.getWardrobes()) {
if (wardrobe.hasPermission()) {
if (user.getPlayer().hasPermission(wardrobe.getPermission())) completions.add(wardrobe.getId());
} else {
completions.add(wardrobe.getId());
}
}
}
case "dye" -> {
for (CosmeticSlot slot : user.getDyeableSlots()) {
completions.add(slot.name());
}
}
case "setlocation" -> {
completions.add("wardrobelocation");
completions.add("viewerlocation");
completions.add("leavelocation");
}
case "playemote" -> {
completions.addAll(PlayerAnimator.api.getAnimationManager().getRegistry().keySet());
case "setwardrobesetting" -> {
for (Wardrobe wardrobe : WardrobeSettings.getWardrobes()) {
completions.add(wardrobe.getId());
}
}
case "playemote" -> completions.addAll(EmoteManager.getAllNames());
}
StringUtil.copyPartialMatches(args[1], completions, finalCompletions);
}
@@ -93,11 +102,18 @@ public class CosmeticCommandTabComplete implements TabCompleter {
case "dye" -> {
completions.add("#FFFFFF");
}
case "menu", "apply", "unapply", "playemote" -> {
case "menu", "wardrobe", "apply", "unapply", "playemote" -> {
for (Player player : Bukkit.getOnlinePlayers()) {
completions.add(player.getName());
}
}
case "setwardrobesetting" -> {
completions.add("npclocation");
completions.add("viewerlocation");
completions.add("leavelocation");
completions.add("permission");
completions.add("distance");
}
}
StringUtil.copyPartialMatches(args[2], completions, finalCompletions);
}

View File

@@ -2,10 +2,13 @@ package com.hibiscusmc.hmccosmetics.config;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.util.Vector;
import org.spongepowered.configurate.ConfigurationNode;
import java.util.logging.Level;
public class Settings {
// General Settings
@@ -35,13 +38,18 @@ public class Settings {
private static final String HOOK_SETTING_PATH = "hook-settings";
private static final String HOOK_ITEMADDER_PATH = "itemsadder";
private static final String HOOK_RELOAD_CHANGE_PATH = "reload-on-change";
private static final String HOOK_WORLDGUARD_PATH = "worldguard";
private static final String HOOK_WG_MOVE_CHECK_PATH = "player-move-check";
private static final String HOOK_WG_MOVE_CHECK_PATH_LEGACY = "player_move_check";
private static final String COSMETIC_EMOTE_CHECK_PATH = "emote-block-check";
private static final String COSMETIC_EMOTE_AIR_CHECK_PATH = "emote-air-check";
private static final String COSMETIC_EMOTE_DAMAGE_PATH = "emote-damage-leave";
private static final String COSMETIC_EMOTE_INVINCIBLE_PATH = "emote-invincible";
private static final String COSMETIC_ADD_ENCHANTS_HELMET_PATH = "helmet-add-enchantments";
private static final String COSMETIC_ADD_ENCHANTS_CHESTPLATE_PATH = "chest-add-enchantments";
private static final String COSMETIC_ADD_ENCHANTS_LEGGINGS_PATH = "leggings-add-enchantments";
private static final String COSMETIC_ADD_ENCHANTS_BOOTS_PATH = "boots-add-enchantments";
private static final String COSMETIC_DESTROY_LOOSE_COSMETIC_PATH = "destroy-loose-cosmetics";
private static String defaultMenu;
private static String dyeMenuName;
@@ -57,13 +65,16 @@ public class Settings {
private static boolean unapplyOnDeath;
private static boolean forcePermissionJoin;
private static boolean itemsAdderChangeReload;
private static boolean worldGuardMoveCheck;
private static boolean cosmeticEmoteBlockCheck;
private static boolean addHelmetEnchants;
private static boolean addChestplateEnchants;
private static boolean addLeggingEnchants;
private static boolean addBootsEnchants;
private static boolean emoteAirCheck;
private static boolean emoteDamageLeave;
private static boolean emoteInvincible;
private static boolean destroyLooseCosmetics;
private static int lookDownPitch;
private static int viewDistance;
private static int tickPeriod;
@@ -96,8 +107,10 @@ public class Settings {
forcePermissionJoin = cosmeticSettings.node(FORCE_PERMISSION_JOIN_PATH).getBoolean(false);
emoteDistance = cosmeticSettings.node(EMOTE_DISTANCE_PATH).getDouble(-3);
cosmeticEmoteBlockCheck = cosmeticSettings.node(COSMETIC_EMOTE_CHECK_PATH).getBoolean(true);
emoteAirCheck = cosmeticSettings.node(COSMETIC_EMOTE_AIR_CHECK_PATH).getBoolean(true);
emoteDamageLeave = cosmeticSettings.node(COSMETIC_EMOTE_DAMAGE_PATH).getBoolean(false);
emoteInvincible = cosmeticSettings.node(COSMETIC_EMOTE_INVINCIBLE_PATH).getBoolean(false);
destroyLooseCosmetics = cosmeticSettings.node(COSMETIC_DESTROY_LOOSE_COSMETIC_PATH).getBoolean(false);
addHelmetEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_HELMET_PATH).getBoolean(false);
addChestplateEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_CHESTPLATE_PATH).getBoolean(false);
addLeggingEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_LEGGINGS_PATH).getBoolean(false);
@@ -120,6 +133,14 @@ public class Settings {
ConfigurationNode hookSettings = source.node(HOOK_SETTING_PATH);
ConfigurationNode itemsAdderSettings = hookSettings.node(HOOK_ITEMADDER_PATH);
itemsAdderChangeReload = itemsAdderSettings.node(HOOK_RELOAD_CHANGE_PATH).getBoolean(false);
ConfigurationNode worldGuardSettings = hookSettings.node(HOOK_WORLDGUARD_PATH);
worldGuardMoveCheck = worldGuardSettings.node(HOOK_WG_MOVE_CHECK_PATH).getBoolean(true);
// I messed up in release 2.2.6 and forgot to change player_move_check to player-move-check.
if (!worldGuardSettings.node(HOOK_WG_MOVE_CHECK_PATH_LEGACY).virtual()) {
MessagesUtil.sendDebugMessages("There is a deprecated way of using WG hook setting. Change player_move_check to player-move-check in your configuration to prevent issues in the future. ", Level.WARNING);
worldGuardMoveCheck = worldGuardSettings.node(HOOK_WG_MOVE_CHECK_PATH_LEGACY).getBoolean(true);
}
}
private static Vector loadVector(final ConfigurationNode config) {
@@ -245,6 +266,10 @@ public class Settings {
return cosmeticEmoteBlockCheck;
}
public static boolean getEmoteAirCheck() {
return emoteAirCheck;
}
public static boolean isEmoteDamageLeave() {
return emoteDamageLeave;
}
@@ -253,6 +278,14 @@ public class Settings {
return emoteInvincible;
}
public static boolean isWorldGuardMoveCheckEnabled() {
return worldGuardMoveCheck;
}
public static boolean isDestroyLooseCosmetics() {
return destroyLooseCosmetics;
}
public static boolean getShouldAddEnchants(EquipmentSlot slot) {
switch (slot) {
case HEAD -> {

View File

@@ -0,0 +1,61 @@
package com.hibiscusmc.hmccosmetics.config;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.Location;
import javax.annotation.Nullable;
public class Wardrobe {
private String id;
private int distance = WardrobeSettings.getDefaultDistance();
private String permission;
private WardrobeLocation location;
public Wardrobe(String id, WardrobeLocation location, @Nullable String permission, int distance) {
this.id = id;
this.location = location;
if (permission != null) this.permission = permission;
if (distance != -1) this.distance = distance;
}
public String getId() {
return id;
}
public WardrobeLocation getLocation() {
return location;
}
public void setDistance(int distance) {
this.distance = distance;
}
public void setPermission(String permission) {
this.permission = permission;
}
public boolean hasPermission() {
return permission != null;
}
public int getDistance() {
return distance;
}
public String getPermission() {
return permission;
}
public void setLocation(WardrobeLocation location) {
this.location = location;
}
public boolean canEnter(CosmeticUser user) {
Location wardrobeLocation = location.getNpcLocation();
Location location = user.getPlayer().getLocation();
if (wardrobeLocation == null) return false;
if (distance == -1) return true;
if (!wardrobeLocation.getWorld().equals(location.getWorld())) return false;
return wardrobeLocation.distanceSquared(location) <= distance * distance;
}
}

View File

@@ -0,0 +1,45 @@
package com.hibiscusmc.hmccosmetics.config;
import org.bukkit.Location;
public class WardrobeLocation {
private Location npcLocation;
private Location viewerLocation;
private Location leaveLocation;
public WardrobeLocation(Location npcLocation, Location viewerLocation, Location leaveLocation) {
this.npcLocation = npcLocation;
this.viewerLocation = viewerLocation;
this.leaveLocation = leaveLocation;
}
public Location getNpcLocation() {
return npcLocation.clone();
}
public Location getViewerLocation() {
return viewerLocation.clone();
}
public Location getLeaveLocation() {
return leaveLocation.clone();
}
public boolean hasAllLocations() {
if (npcLocation == null || viewerLocation == null || leaveLocation == null) return false;
return true;
}
public void setNPCLocation(Location wardrobeLocation) {
this.npcLocation = wardrobeLocation;
}
public void setViewerLocation(Location viewerLocation) {
this.viewerLocation = viewerLocation;
}
public void setLeaveLocation(Location leaveLocation) {
this.leaveLocation = leaveLocation;
}
}

View File

@@ -6,9 +6,12 @@ import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.misc.Utils;
import net.kyori.adventure.bossbar.BossBar;
import org.apache.commons.lang3.EnumUtils;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import java.util.*;
import java.util.logging.Level;
public class WardrobeSettings {
@@ -24,11 +27,18 @@ public class WardrobeSettings {
private static final String APPLY_COSMETICS_ON_CLOSE = "apply-cosmetics-on-close";
private static final String OPEN_SOUND = "open-sound";
private static final String CLOSE_SOUND = "close-sound";
private static final String STATIC_LOCATION_PATH = "wardrobe-location";
private static final String NPC_LOCATION_PATH = "npc-location";
private static final String VIEWER_LOCATION_PATH = "viewer-location";
private static final String LEAVE_LOCATION_PATH = "leave-location";
private static final String EQUIP_PUMPKIN_WARDROBE = "equip-pumpkin";
private static final String TRY_COSMETICS_WARDROBE = "unchecked-wardrobe-cosmetics";
private static final String RETURN_LAST_LOCATION = "return-last-location";
private static final String GAMEMODE_OPTIONS_PATH = "gamemode-options";
private static final String FORCE_EXIT_GAMEMODE_PATH = "exit-gamemode-enabled";
private static final String EXIT_GAMEMODE_PATH = "exit-gamemode";
private static final String WARDROBES_PATH = "wardrobes";
private static final String PERMISSION_PATH = "permission";
private static final String DISTANCE_PATH = "distance";
private static final String BOSSBAR_PATH = "bossbar";
private static final String BOSSBAR_ENABLE_PATH = "enabled";
private static final String BOSSBAR_TEXT_PATH = "text";
@@ -54,12 +64,13 @@ public class WardrobeSettings {
private static int despawnDelay;
private static float bossbarProgress;
private static boolean applyCosmeticsOnClose;
private static boolean tryCosmeticsInWardrobe;
private static boolean equipPumpkin;
private static boolean returnLastLocation;
private static boolean enabledBossbar;
private static Location wardrobeLocation;
private static Location viewerLocation;
private static Location leaveLocation;
private static boolean forceExitGamemode;
private static GameMode exitGamemode;
private static HashMap<String, Wardrobe> wardrobes;
private static String bossbarMessage;
private static BossBar.Overlay bossbarOverlay;
private static BossBar.Color bossbarColor;
@@ -84,6 +95,11 @@ public class WardrobeSettings {
applyCosmeticsOnClose = source.node(APPLY_COSMETICS_ON_CLOSE).getBoolean();
equipPumpkin = source.node(EQUIP_PUMPKIN_WARDROBE).getBoolean();
returnLastLocation = source.node(RETURN_LAST_LOCATION).getBoolean(false);
tryCosmeticsInWardrobe = source.node(TRY_COSMETICS_WARDROBE).getBoolean(false);
ConfigurationNode gamemodeNode = source.node(GAMEMODE_OPTIONS_PATH);
forceExitGamemode = gamemodeNode.node(FORCE_EXIT_GAMEMODE_PATH).getBoolean(false);
exitGamemode = GameMode.valueOf(gamemodeNode.node(EXIT_GAMEMODE_PATH).getString("SURVIVAL"));
ConfigurationNode bossBarNode = source.node(BOSSBAR_PATH);
enabledBossbar = bossBarNode.node(BOSSBAR_ENABLE_PATH).getBoolean(false);
@@ -109,15 +125,35 @@ public class WardrobeSettings {
transitionStay = transitionNode.node(TRANSITION_STAY_PATH).getInt(2000);
transitionFadeOut = transitionNode.node(TRANSITION_FADE_OUT_PATH).getInt(2000);
try {
wardrobeLocation = LocationSerializer.INSTANCE.deserialize(Location.class, source.node(STATIC_LOCATION_PATH));
MessagesUtil.sendDebugMessages("Wardrobe Location: " + wardrobeLocation);
viewerLocation = LocationSerializer.INSTANCE.deserialize(Location.class, source.node(VIEWER_LOCATION_PATH));
MessagesUtil.sendDebugMessages("Viewer Location: " + viewerLocation);
leaveLocation = Utils.replaceIfNull(LocationSerializer.INSTANCE.deserialize(Location.class, source.node(LEAVE_LOCATION_PATH)), viewerLocation);
} catch (SerializationException e) {
throw new RuntimeException(e);
wardrobes = new HashMap<>();
for (ConfigurationNode wardrobesNode : source.node(WARDROBES_PATH).childrenMap().values()) {
String id = wardrobesNode.key().toString();
try {
Location npcLocation = LocationSerializer.INSTANCE.deserialize(Location.class, wardrobesNode.node(NPC_LOCATION_PATH));
MessagesUtil.sendDebugMessages("Wardrobe Location: " + npcLocation);
Location viewerLocation = LocationSerializer.INSTANCE.deserialize(Location.class, wardrobesNode.node(VIEWER_LOCATION_PATH));
MessagesUtil.sendDebugMessages("Viewer Location: " + viewerLocation);
Location leaveLocation = Utils.replaceIfNull(LocationSerializer.INSTANCE.deserialize(Location.class, wardrobesNode.node(LEAVE_LOCATION_PATH)), viewerLocation);
MessagesUtil.sendDebugMessages("Leave Location: " + leaveLocation);
WardrobeLocation wardrobeLocation = new WardrobeLocation(npcLocation, viewerLocation, leaveLocation);
String permission = null;
int distance = -1;
if (!wardrobesNode.node(PERMISSION_PATH).virtual()) permission = wardrobesNode.node(PERMISSION_PATH).getString();
if (!wardrobesNode.node(DISTANCE_PATH).virtual()) distance = wardrobesNode.node(DISTANCE_PATH).getInt();
Wardrobe wardrobe = new Wardrobe(id, wardrobeLocation, permission, distance);
addWardrobe(wardrobe);
} catch (Exception e) {
MessagesUtil.sendDebugMessages("Unable to create wardrobe " + id, Level.SEVERE);
}
}
//throw new RuntimeException(e);
}
public static int getDefaultDistance() {
return staticRadius;
}
public static boolean getDisableOnDamage() {
@@ -162,25 +198,36 @@ public class WardrobeSettings {
return returnLastLocation;
}
public static Location getWardrobeLocation() {
return wardrobeLocation.clone();
public static Wardrobe getWardrobe(String key) {
return wardrobes.get(key);
}
public static Location getViewerLocation() {
return viewerLocation;
public static Set<String> getWardrobeNames() {
return wardrobes.keySet();
}
public static Location getLeaveLocation() {
return leaveLocation;
public static Collection<Wardrobe> getWardrobes() {
return wardrobes.values();
}
public static void addWardrobe(Wardrobe wardrobe) {
wardrobes.put(wardrobe.getId(), wardrobe);
}
public static void removeWardrobe(String id) {
wardrobes.remove(id);
}
@Deprecated
public static boolean inDistanceOfWardrobe(final Location wardrobeLocation, final Location playerLocation) {
if (displayRadius == -1) return true;
if (!wardrobeLocation.getWorld().equals(playerLocation.getWorld())) return false;
return playerLocation.distanceSquared(wardrobeLocation) <= displayRadius * displayRadius;
}
public static boolean inDistanceOfStatic(final Location location) {
@Deprecated
public static boolean inDistanceOfStatic(Wardrobe wardrobe, final Location location) {
Location wardrobeLocation = wardrobe.getLocation().getNpcLocation();
if (wardrobeLocation == null) return false;
if (staticRadius == -1) return true;
if (!wardrobeLocation.getWorld().equals(location.getWorld())) return false;
@@ -227,57 +274,92 @@ public class WardrobeSettings {
return transitionFadeOut;
}
public static void setWardrobeLocation(Location newLocation) {
wardrobeLocation = newLocation;
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
plugin.getConfig().set("wardrobe.wardrobe-location." + "world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.wardrobe-location." + "x", newLocation.getX());
plugin.getConfig().set("wardrobe.wardrobe-location." + "y", newLocation.getY());
plugin.getConfig().set("wardrobe.wardrobe-location." + "z", newLocation.getZ());
plugin.getConfig().set("wardrobe.wardrobe-location." + "yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.wardrobe-location." + "pitch", newLocation.getPitch());
/* Configuration sets suck
source.node(WORLD).set(loc.getWorld().getName());
source.node(X).set(loc.getX());
source.node(Y).set(loc.getY());
source.node(Z).set(loc.getZ());
source.node(YAW).set(loc.getYaw());
source.node(PITCH).set(loc.getPitch());
*/
HMCCosmeticsPlugin.getInstance().saveConfig();
public static boolean isForceExitGamemode() {
return forceExitGamemode;
}
public static void setViewerLocation(Location newLocation) {
viewerLocation = newLocation;
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
plugin.getConfig().set("wardrobe.viewer-location." + "world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.viewer-location." + "x", newLocation.getX());
plugin.getConfig().set("wardrobe.viewer-location." + "y", newLocation.getY());
plugin.getConfig().set("wardrobe.viewer-location." + "z", newLocation.getZ());
plugin.getConfig().set("wardrobe.viewer-location." + "yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.viewer-location." + "pitch", newLocation.getPitch());
HMCCosmeticsPlugin.getInstance().saveConfig();
public static GameMode getExitGamemode() {
return exitGamemode;
}
public static void setLeaveLocation(Location newLocation) {
leaveLocation = newLocation;
public static boolean isTryCosmeticsInWardrobe() {
return tryCosmeticsInWardrobe;
}
/**
* Sets where the NPC/Mannequin will spawn in the wardrobe
* @param newLocation
*/
public static void setNPCLocation(Wardrobe wardrobe, Location newLocation) {
wardrobe.getLocation().setNPCLocation(newLocation);
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
plugin.getConfig().set("wardrobe.leave-location." + "world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.leave-location." + "x", newLocation.getX());
plugin.getConfig().set("wardrobe.leave-location." + "y", newLocation.getY());
plugin.getConfig().set("wardrobe.leave-location." + "z", newLocation.getZ());
plugin.getConfig().set("wardrobe.leave-location." + "yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.leave-location." + "pitch", newLocation.getPitch());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "x", newLocation.getX());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "y", newLocation.getY());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "z", newLocation.getZ());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "pitch", newLocation.getPitch());
HMCCosmeticsPlugin.getInstance().saveConfig();
plugin.saveConfig();
}
/**
* Sets where the player will view the wardrobe
* @param newLocation
*/
public static void setViewerLocation(Wardrobe wardrobe, Location newLocation) {
wardrobe.getLocation().setViewerLocation(newLocation);
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.x", newLocation.getX());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.y", newLocation.getY());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.z", newLocation.getZ());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.pitch", newLocation.getPitch());
plugin.saveConfig();
}
/**
* Sets where a player will leave the wardrobe from
* @param newLocation
*/
public static void setLeaveLocation(Wardrobe wardrobe, Location newLocation) {
wardrobe.getLocation().setLeaveLocation(newLocation);
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.x", newLocation.getX());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.y", newLocation.getY());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.z", newLocation.getZ());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.pitch", newLocation.getPitch());
plugin.saveConfig();
}
public static void setWardrobePermission(Wardrobe wardrobe, String permission) {
wardrobe.setPermission(permission);
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".permission", permission);
plugin.saveConfig();
}
public static void setWardrobeDistance(Wardrobe wardrobe, int distance) {
wardrobe.setDistance(distance);
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".distance", distance);
plugin.saveConfig();
}
}

View File

@@ -2,16 +2,14 @@ package com.hibiscusmc.hmccosmetics.config.serializer;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.hooks.Hooks;
import com.hibiscusmc.hmccosmetics.util.InventoryUtils;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.ServerUtils;
import com.hibiscusmc.hmccosmetics.util.builder.ColorBuilder;
import com.hibiscusmc.hmccosmetics.util.misc.StringUtils;
import com.hibiscusmc.hmccosmetics.util.misc.Utils;
import org.apache.commons.lang3.EnumUtils;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.*;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
@@ -123,12 +121,25 @@ public class ItemSerializer implements TypeSerializer<ItemStack> {
if (item.getType() == Material.PLAYER_HEAD) {
SkullMeta skullMeta = (SkullMeta) itemMeta;
if (!ownerNode.virtual()) {
skullMeta.setOwningPlayer(Bukkit.getOfflinePlayer(ownerNode.getString()));
String ownerString = ownerNode.getString();
if (ownerString.contains("%")) {
// This means it has PAPI placeholders in it
skullMeta.getPersistentDataContainer().set(InventoryUtils.getSkullOwner(), PersistentDataType.STRING, ownerString);
}
OfflinePlayer player = Bukkit.getOfflinePlayer(ownerString);
skullMeta.setOwningPlayer(player);
}
if (!textureNode.virtual()) {
String textureString = textureNode.getString();
if (textureString.contains("%")) {
// This means it has PAPI placeholders in it
skullMeta.getPersistentDataContainer().set(InventoryUtils.getSkullTexture(), PersistentDataType.STRING, textureString);
}
Bukkit.getUnsafe().modifyItemStack(item, "{SkullOwner:{Id:[I;0,0,0,0],Properties:{textures:[{Value:\""
+ textureNode.getString() + "\"}]}}}");
+ textureString + "\"}]}}}");
itemMeta = skullMeta;
}
}
@@ -143,9 +154,6 @@ public class ItemSerializer implements TypeSerializer<ItemStack> {
}
}
NamespacedKey key = new NamespacedKey(HMCCosmeticsPlugin.getInstance(), source.key().toString());
itemMeta.getPersistentDataContainer().set(key, PersistentDataType.STRING, source.key().toString());
item.setItemMeta(itemMeta);
return item;
}

View File

@@ -17,6 +17,7 @@ public abstract class Cosmetic {
private String id;
private String permission;
private ItemStack item;
private String material;
private CosmeticSlot slot;
private boolean dyable;
@@ -29,7 +30,10 @@ public abstract class Cosmetic {
this.permission = null;
}
if (!config.node("item").virtual()) this.item = generateItemStack(config.node("item"));
if (!config.node("item").virtual()) {
this.material = config.node("item", "material").getString();
this.item = generateItemStack(config.node("item"));
}
MessagesUtil.sendDebugMessages("Slot: " + config.node("slot").getString());
@@ -76,6 +80,10 @@ public abstract class Cosmetic {
return this.dyable;
}
public String getMaterial() {
return material;
}
public abstract void update(CosmeticUser user);
@Nullable

View File

@@ -8,6 +8,7 @@ import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import org.apache.commons.lang3.EnumUtils;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.ConfigurationNode;
@@ -33,6 +34,7 @@ public class Cosmetics {
COSMETICS.remove(cosmetic);
}
@Nullable
public static Cosmetic getCosmetic(String id) {
return COSMETICS.get(id);
}

View File

@@ -28,6 +28,7 @@ public class CosmeticArmorType extends Cosmetic {
public void update(@NotNull CosmeticUser user) {
Player player = Bukkit.getPlayer(user.getUniqueId());
if (player == null) return;
if (user.getUserEmoteManager().isPlayingEmote()) return; // There has to be a better way of doing this...
ItemStack cosmeticItem = user.getUserCosmeticItem(this);
if (equipSlot.equals(EquipmentSlot.OFF_HAND)) {
if (!player.getInventory().getItemInOffHand().getType().isAir()) return;

View File

@@ -33,8 +33,8 @@ public class CosmeticBackpackType extends Cosmetic {
Location loc = player.getLocation().clone().add(0, 2, 0);
if (user.isInWardrobe() || !user.isBackpackSpawned()) return;
if (!user.getUserBackpackManager().getArmorStand().isValid()) {
MessagesUtil.sendDebugMessages("Invalid Backpack detected! Respawning backpack, report this on the discord if this happens often!", Level.WARNING);
if (!user.getUserBackpackManager().IsValidBackpackEntity()) {
MessagesUtil.sendDebugMessages("Invalid Backpack Entity[owner=" + user.getUniqueId() + ",player_location=" + loc + "]!", Level.WARNING);
user.respawnBackpack();
return;
}

View File

@@ -19,12 +19,15 @@ public class CosmeticBalloonType extends Cosmetic {
private final String modelName;
private List<String> dyableParts;
private boolean showLead;
public CosmeticBalloonType(String id, ConfigurationNode config) {
super(id, config);
String modelId = config.node("model").getString();
showLead = config.node("show-lead").getBoolean(true);
try {
if (!config.node("dyable-parts").virtual()) {
dyableParts = config.node("dyable-parts").getList(String.class);
@@ -45,6 +48,11 @@ public class CosmeticBalloonType extends Cosmetic {
if (player == null || userBalloonManager == null) return;
if (user.isInWardrobe()) return;
if (!userBalloonManager.getModelEntity().isValid()) {
user.respawnBalloon();
return;
}
Location newLocation = player.getLocation();
Location currentLocation = user.getBalloonManager().getLocation();
newLocation = newLocation.clone().add(Settings.getBalloonOffset());
@@ -63,7 +71,7 @@ public class CosmeticBalloonType extends Cosmetic {
userBalloonManager.setLocation(newLocation);
PacketManager.sendTeleportPacket(userBalloonManager.getPufferfishBalloonId(), newLocation, false, viewer);
if (!user.getHidden()) PacketManager.sendLeashPacket(userBalloonManager.getPufferfishBalloonId(), player.getEntityId(), viewer);
if (!user.getHidden() && showLead) PacketManager.sendLeashPacket(userBalloonManager.getPufferfishBalloonId(), player.getEntityId(), viewer);
}
public String getModelName() {
@@ -80,4 +88,8 @@ public class CosmeticBalloonType extends Cosmetic {
if (dyableParts.isEmpty()) return true;
return dyableParts.contains(name);
}
public boolean isShowLead() {
return showLead;
}
}

View File

@@ -9,11 +9,13 @@ import org.spongepowered.configurate.ConfigurationNode;
public class CosmeticEmoteType extends Cosmetic {
private final String animationId;
private final String text;
public CosmeticEmoteType(String id, ConfigurationNode config) {
super(id, config);
animationId = config.node("animation").getString();
text = config.node("text").getString();
MessagesUtil.sendDebugMessages("CosmeticEmoteType Animation id " + animationId);
}
@@ -29,4 +31,8 @@ public class CosmeticEmoteType extends Cosmetic {
public String getAnimationId() {
return animationId;
}
public String getText() {
return text;
}
}

View File

@@ -37,7 +37,7 @@ public abstract class Data {
data = "HIDDEN=" + user.getHiddenReason();
}
}
for (Cosmetic cosmetic : user.getCosmetic()) {
for (Cosmetic cosmetic : user.getCosmetics()) {
Color color = user.getCosmeticColor(cosmetic.getSlot());
String input = cosmetic.getSlot() + "=" + cosmetic.getId();
if (color != null) input = input + "&" + color.asRGB();

View File

@@ -0,0 +1,85 @@
package com.hibiscusmc.hmccosmetics.emotes;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.ticxo.playeranimator.api.PlayerAnimator;
import com.ticxo.playeranimator.api.animation.pack.AnimationPack;
import org.apache.commons.io.FilenameUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Manages Emotes
*/
@SuppressWarnings("SpellCheckingInspection")
public class EmoteManager {
private static final @NotNull Map<@NotNull String, @NotNull String> emotes = new HashMap<>();
/**
* Loads all BlockBench animations from the emotes folder and puts it into the animation manager registry and local registry
*/
public static void loadEmotes() {
// Clear the PlayerAnimator and local registries
PlayerAnimator.api.getAnimationManager().clearRegistry();
emotes.clear();
// Get the emote directory and check if it exists
File emoteDir = new File(HMCCosmeticsPlugin.getInstance().getDataFolder().getPath() + "/emotes/");
if (!emoteDir.exists()) return;
// Get all the files inside the directory and check if it isn't 0
File[] emoteFiles = emoteDir.listFiles();
if (emoteFiles == null || emoteFiles.length == 0) return;
// Remove any files that don't have the file extension ".bbmodel" and check if there are still resulting files
emoteFiles = Arrays.stream(emoteFiles).filter(file -> file.getPath().endsWith(".bbmodel")).distinct().toArray(File[]::new);
if (emoteFiles.length == 0) return;
// Loop through all files, importing all block bench animations into the registry
for (File animationFile : emoteFiles) {
String animationKey = FilenameUtils.removeExtension(animationFile.getName());
PlayerAnimator.api.getAnimationManager().importAnimations(animationKey, animationFile);
}
// Loops through all the entries in the registries and unpacks any animation packs to ensure if there were multiple animations
// inside a singular file, that they are added to the local registry individually for tab completion
for (Map.Entry<String, AnimationPack> packEntry : PlayerAnimator.api.getAnimationManager().getRegistry().entrySet()) {
packEntry.getValue().getAnimations().keySet().forEach(animationName -> {
// API key is the format "animationKey.animationFileName.animationName"
String apiKey = packEntry.getKey().replace(":", ".") + "." + animationName;
emotes.put(animationName, apiKey);
});
}
}
/**
* Returns true if there is an animation with the specified name
* @param animationName Name whose presence is to be tested
* @return True if this registry contains a mapping for the specified name
*/
public static boolean has(@NotNull String animationName) {
return emotes.containsKey(animationName);
}
/**
* Returns the {@code API key} to which the specified name is mapped, or {@code null} if this map contains no mapping for the name.
* @param animationName Name whose {@code API key} is to be fetched
* @return The {@code API key} of the specified name or {@code null} if there was no animation name found
*/
public static @Nullable String get(@NotNull String animationName) {
return emotes.get(animationName);
}
/**
* Gets a set of all the laoded animation names
* @return A set of all loaded animation names
*/
public static @NotNull Set<String> getAllNames() {
return emotes.keySet();
}
}

View File

@@ -1,7 +1,7 @@
package com.hibiscusmc.hmccosmetics.gui;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.api.PlayerMenuOpenEvent;
import com.hibiscusmc.hmccosmetics.api.events.PlayerMenuOpenEvent;
import com.hibiscusmc.hmccosmetics.config.serializer.ItemSerializer;
import com.hibiscusmc.hmccosmetics.gui.type.Type;
import com.hibiscusmc.hmccosmetics.gui.type.Types;
@@ -77,26 +77,21 @@ public class Menu {
gui.setDefaultClickAction(event -> event.setCancelled(true));
// TODO: Redo this whole gui creation process to allow for all items, possibly implement caching
gui = getItems(user, gui);
final Gui finalGui = gui; // Need to make it final for the runtask
Gui finalGui = gui;
// API
PlayerMenuOpenEvent event = new PlayerMenuOpenEvent(user, this);
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
Bukkit.getPluginManager().callEvent(event);
});
if (event.isCancelled()) {
return;
}
if (event.isCancelled()) return;
// Internal
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
finalGui.open(player);
});
//gui.open(player);
}
@Contract("_, _ -> param2")
@@ -105,7 +100,7 @@ public class Menu {
for (ConfigurationNode config : config.node("items").childrenMap().values()) {
List<String> slotString = null;
List<String> slotString;
try {
slotString = config.node("slots").getList(String.class);
} catch (SerializationException e) {
@@ -118,17 +113,14 @@ public class Menu {
List<Integer> slots = getSlots(slotString);
if (slots == null) {
MessagesUtil.sendDebugMessages("Slot is null for " + config.key().toString());
continue;
}
ItemStack item;
try {
item = ItemSerializer.INSTANCE.deserialize(ItemStack.class, config.node("item"));
//item = config.node("item").get(ItemStack.class);
} catch (SerializationException e) {
throw new RuntimeException(e);
}
@@ -145,24 +137,25 @@ public class Menu {
if (Types.isType(typeId)) type = Types.getType(typeId);
}
ItemStack originalItem = item.clone();
item = updateLore(user, item, type, config);
for (int slot : slots) {
ItemStack modifiedItem = getMenuItem(user, type, config, item.clone(), slot).clone();
GuiItem guiItem = ItemBuilder.from(modifiedItem).asGuiItem();
GuiItem guiItem = ItemBuilder.from(item).asGuiItem();
Type finalType = type;
guiItem.setAction(event -> {
MessagesUtil.sendDebugMessages("Selected slot " + slot);
final ClickType clickType = event.getClick();
if (finalType != null) finalType.run(user, config, clickType);
// Need to delay the update by a tick so it will actually update with new values
for (int guiSlot : slots) {
gui.updateItem(guiSlot, getMenuItem(user, finalType, config, item.clone(), guiSlot));
}
MessagesUtil.sendDebugMessages("Updated slot " + slot);
});
Type finalType = type;
guiItem.setAction(event -> {
final ClickType clickType = event.getClick();
if (finalType != null) finalType.run(user, config, clickType);
for (int i : slots) {
gui.updateItem(i, updateLore(user, originalItem.clone(), finalType, config));
MessagesUtil.sendDebugMessages("Updated slot " + i);
}
});
MessagesUtil.sendDebugMessages("Added " + slots + " as " + guiItem + " in the menu");
gui.setItem(slots, guiItem);
MessagesUtil.sendDebugMessages("Added " + slots + " as " + guiItem + " in the menu");
gui.setItem(slot, guiItem);
}
}
return gui;
}
@@ -195,11 +188,9 @@ public class Menu {
@Contract("_, _, _, _ -> param2")
@NotNull
private ItemStack updateLore(CosmeticUser user, @NotNull ItemStack itemStack, Type type, ConfigurationNode config) {
if (itemStack.hasItemMeta()) {
itemStack.setItemMeta(type.setLore(user, config, itemStack.getItemMeta()));
}
return itemStack;
private ItemStack getMenuItem(CosmeticUser user, Type type, ConfigurationNode config, ItemStack itemStack, int slot) {
if (!itemStack.hasItemMeta()) return itemStack;
return type.setItem(user, config, itemStack, slot);
}
public String getPermissionNode() {

View File

@@ -56,6 +56,10 @@ public class Menus {
return names;
}
public static Collection<Menu> values() {
return MENUS.values();
}
public static void setup() {
MENUS.clear();

View File

@@ -48,6 +48,7 @@ public class DyeMenu {
if (color == null) return;
addCosmetic(user, cosmetic, color);
event.setCancelled(true);
} else event.setCancelled(true);
});

View File

@@ -2,6 +2,7 @@ package com.hibiscusmc.hmccosmetics.gui.type;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.spongepowered.configurate.ConfigurationNode;
@@ -24,5 +25,5 @@ public abstract class Type {
public abstract void run(CosmeticUser user, ConfigurationNode config, ClickType clickType);
public abstract ItemMeta setLore(CosmeticUser user, ConfigurationNode config, ItemMeta itemMeta);
public abstract ItemStack setItem(CosmeticUser user, ConfigurationNode config, ItemStack itemStack, int slot);
}

View File

@@ -1,6 +1,7 @@
package com.hibiscusmc.hmccosmetics.gui.type.types;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.serializer.ItemSerializer;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType;
@@ -17,12 +18,14 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import java.lang.invoke.TypeDescriptor;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@@ -72,7 +75,7 @@ public class TypeCosmetic extends Type {
if (!actionConfig.node("on-equip").virtual()) actionStrings.addAll(actionConfig.node("on-equip").getList(String.class));
MessagesUtil.sendDebugMessages("on-equip");
// TODO: Redo this
if (cosmetic.isDyable()) {
if (cosmetic.isDyable() && Hooks.isActiveHook("HMCColor")) {
DyeMenu.openMenu(user, cosmetic);
} else {
user.addPlayerCosmetic(cosmetic);
@@ -89,62 +92,58 @@ public class TypeCosmetic extends Type {
if (cosmetic instanceof CosmeticArmorType) {
if (((CosmeticArmorType) cosmetic).getEquipSlot().equals(EquipmentSlot.OFF_HAND)) {
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), run, 1);
return;
}
}
run.run();
}
@Override
public ItemMeta setLore(CosmeticUser user, @NotNull ConfigurationNode config, ItemMeta itemMeta) {
List<String> processedLore = new ArrayList<>();
public ItemStack setItem(CosmeticUser user, @NotNull ConfigurationNode config, ItemStack itemStack, int slot) {
itemStack.setItemMeta(processLoreLines(user, itemStack.getItemMeta()));
if (config.node("cosmetic").virtual()) return processLoreLines(user, itemMeta);;
if (config.node("cosmetic").virtual()) {
return itemStack;
}
String cosmeticName = config.node("cosmetic").getString();
Cosmetic cosmetic = Cosmetics.getCosmetic(cosmeticName);
if (cosmetic == null) {
return processLoreLines(user, itemMeta);
return itemStack;
}
if (user.canEquipCosmetic(cosmetic)) {
return processLoreLines(user, itemMeta);
} else {
ConfigurationNode itemConfig = config.node("item");
if (itemConfig.virtual()) return itemMeta;
if (itemConfig.node("locked-name").virtual() && itemConfig.node("locked-lore").virtual()) {
return processLoreLines(user, itemMeta);
if (user.hasCosmeticInSlot(cosmetic) && !config.node("equipped-item").virtual()) {
MessagesUtil.sendDebugMessages("GUI Equipped Item");
ConfigurationNode equippedItem = config.node("equipped-item");
try {
if (equippedItem.node("material").virtual()) equippedItem.node("material").set(config.node("item", "material").getString());
} catch (SerializationException e) {
// Nothing >:)
}
try {
List<String> lockedLore = itemMeta.getLore();
String lockedName = itemMeta.getDisplayName();
if (!itemConfig.node("locked-lore").virtual()) {
lockedLore = Utils.replaceIfNull(itemConfig.node("locked-lore").getList(String.class),
new ArrayList<String>()).
stream().map(StringUtils::parseStringToString).collect(Collectors.toList());
}
if (!itemConfig.node("locked-name").virtual()) {
lockedName = StringUtils.parseStringToString(Utils.replaceIfNull(itemConfig.node("locked-name").getString(), ""));
}
if (Hooks.isActiveHook("PlaceHolderAPI")) {
lockedName = PlaceholderAPI.setPlaceholders(user.getPlayer(), lockedName);
}
itemMeta.setDisplayName(lockedName);
if (itemMeta.hasLore()) {
itemMeta.getLore().clear();
for (String loreLine : lockedLore) {
if (Hooks.isActiveHook("PlaceHolderAPI")) loreLine = PlaceholderAPI.setPlaceholders(user.getPlayer(), loreLine);
processedLore.add(loreLine);
}
}
} catch (Exception e) {
e.printStackTrace();
itemStack = ItemSerializer.INSTANCE.deserialize(ItemStack.class, equippedItem);
} catch (SerializationException e) {
throw new RuntimeException(e);
}
itemStack.setItemMeta(processLoreLines(user, itemStack.getItemMeta()));
return itemStack;
}
itemMeta.setLore(processedLore);
return itemMeta;
if (!user.canEquipCosmetic(cosmetic) && !config.node("locked-item").virtual()) {
MessagesUtil.sendDebugMessages("GUI Locked Item");
ConfigurationNode lockedItem = config.node("locked-item");
try {
if (lockedItem.node("material").virtual()) lockedItem.node("material").set(config.node("item", "material").getString());
} catch (SerializationException e) {
// Nothing >:)
}
try {
itemStack = ItemSerializer.INSTANCE.deserialize(ItemStack.class, lockedItem);
} catch (SerializationException e) {
throw new RuntimeException(e);
}
itemStack.setItemMeta(processLoreLines(user, itemStack.getItemMeta()));
return itemStack;
}
return itemStack;
}
@Contract("_, _ -> param2")
@@ -155,12 +154,10 @@ public class TypeCosmetic extends Type {
if (itemMeta.hasLore()) {
for (String loreLine : itemMeta.getLore()) {
if (Hooks.isActiveHook("PlaceholderAPI"))
loreLine = PlaceholderAPI.setPlaceholders(user.getPlayer(), loreLine);
if (Hooks.isActiveHook("PlaceholderAPI")) loreLine = PlaceholderAPI.setPlaceholders(user.getPlayer(), loreLine);
processedLore.add(loreLine);
}
}
itemMeta.setLore(processedLore);
return itemMeta;
}

View File

@@ -6,6 +6,7 @@ import com.hibiscusmc.hmccosmetics.hooks.Hooks;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.configurate.ConfigurationNode;
@@ -53,8 +54,9 @@ public class TypeEmpty extends Type {
@Override
@SuppressWarnings("Duplicates")
public ItemMeta setLore(CosmeticUser user, ConfigurationNode config, @NotNull ItemMeta itemMeta) {
public ItemStack setItem(CosmeticUser user, ConfigurationNode config, @NotNull ItemStack itemStack, int slot) {
List<String> processedLore = new ArrayList<>();
ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta.hasLore()) {
for (String loreLine : itemMeta.getLore()) {
@@ -63,8 +65,8 @@ public class TypeEmpty extends Type {
processedLore.add(loreLine);
}
}
return itemMeta;
itemStack.setItemMeta(itemMeta);
return itemStack;
}
// That's it! Now, add it as a static in another one of your classes (such as your main class) and you are good to go.

View File

@@ -2,45 +2,92 @@ package com.hibiscusmc.hmccosmetics.hooks;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class Hook implements Listener {
/**
* Represents a hook into other minecraft plugins
*/
public abstract class Hook implements Listener {
private final String id;
private boolean active;
private boolean itemHook;
private boolean active = false;
private boolean itemHook = false;
public Hook(String id) {
public Hook(@NotNull String id) {
this.id = id;
active = false;
Hooks.addHook(this);
}
public void load() {
// Override
}
/**
* Loads this hook
*
* @implNote By default, this method does nothing. It should be overridden by child classes to implement any necessary loading logic
*/
public void load() { }
public ItemStack getItem(String itemId) {
/**
* Gets an {@link ItemStack} that is associated with the provided id from the hooked plugin
* @param itemId The id of the {@link ItemStack}
* @return The {@link ItemStack} with the id provided. If an invalid id was provided or if the hook doesn't have any related {@link ItemStack}s then this will return null
* @implNote By default, this method returns null. It should be overridden by child classes if you will to have your hook return a related {@link ItemStack}
*/
@Nullable
public ItemStack getItem(@NotNull String itemId) {
return null;
// Override
}
public String getId() {
/**
* Gets the id of this hook
*
* @return The unique id for this hook
*/
@NotNull
public final String getId() {
return id;
}
public void setActive(boolean active) {
this.active = active;
}
/**
* Gets whether this hook has been activated
* @return true if this hook is active, false otherwise
* @deprecated As of release 2.2.5+, replaced by {@link #isActive()}
*/
@Deprecated
public boolean getActive() {
return this.active;
}
public void setEnabledItemHook(boolean enabled) {
itemHook = enabled;
/**
* Gets whether this hook has been activated
* @return true if this hook is active, false otherwise
* @since 2.2.5
*/
public final boolean isActive() {
return this.active;
}
public boolean hasEnabledItemHook() {
/**
* Sets whether this hook is active
* @param active true to activate the hook, false otherwise
*/
public final void setActive(boolean active) {
this.active = active;
}
/**
* Whether the method {@link #getItem(String)} should return a non-null value
* @return true if {@link #getItem(String)} should return a non-null value, false otherwise
*
* @apiNote Even though this method returns true does not mean that {@link #getItem(String)} won't return null, rather if this returns false then {@link #getItem(String)} should return false everytime
*/
public final boolean hasEnabledItemHook() {
return itemHook;
}
/**
* Sets whether the method {@link #getItem(String)} should return a non-null value
* @param enabled true if {@link #getItem(String)} should return a non-null value, false otherwise
*/
public final void setEnabledItemHook(boolean enabled) {
itemHook = enabled;
}
}

View File

@@ -2,10 +2,7 @@ package com.hibiscusmc.hmccosmetics.hooks;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.hooks.items.*;
import com.hibiscusmc.hmccosmetics.hooks.misc.HookCMI;
import com.hibiscusmc.hmccosmetics.hooks.misc.HookHMCColor;
import com.hibiscusmc.hmccosmetics.hooks.misc.HookPremiumVanish;
import com.hibiscusmc.hmccosmetics.hooks.misc.HookSuperVanish;
import com.hibiscusmc.hmccosmetics.hooks.misc.*;
import com.hibiscusmc.hmccosmetics.hooks.placeholders.HookPlaceholderAPI;
import org.bukkit.Bukkit;
import org.bukkit.Material;
@@ -20,14 +17,16 @@ public class Hooks {
private static final HashMap<String, Hook> hooks = new HashMap<>();
private static HookOraxen ORAXEN_HOOK = new HookOraxen();
private static HookItemAdder ITEMADDER_HOOK = new HookItemAdder();
private static HookLooty LOOTY_HOOK = new HookLooty();
private static HookGeary GEARY_HOOK = new HookGeary();
private static HookMythic MYTHIC_HOOK = new HookMythic();
private static HookDenizen DENIZEN_HOOK = new HookDenizen();
private static HookHMCCosmetics HMCCOSMETIC_HOOK = new HookHMCCosmetics();
private static HookPlaceholderAPI PAPI_HOOK = new HookPlaceholderAPI();
private static HookPremiumVanish PREMIUM_VANISH_HOOK = new HookPremiumVanish();
private static HookSuperVanish SUPER_VANISH_HOOK = new HookSuperVanish();
private static HookHMCColor HMC_COLOR_HOOK = new HookHMCColor();
private static HookCMI CMI_HOOK = new HookCMI();
private static HookLibsDisguises LIBS_DISGUISES_HOOK = new HookLibsDisguises();
public static Hook getHook(@NotNull String id) {
return hooks.get(id.toLowerCase());
@@ -67,13 +66,13 @@ public class Hooks {
if (!isItemHook(split[0])) return null;
Hook hook = getHook(split[0]);
if (!hook.hasEnabledItemHook()) return null;
if (!hook.getActive()) return null;
if (!hook.isActive()) return null;
return hook.getItem(split[1]);
}
public static boolean isActiveHook(String id) {
Hook hook = getHook(id);
if (hook == null) return false;
return hook.getActive();
return hook.isActive();
}
}

View File

@@ -0,0 +1,27 @@
package com.hibiscusmc.hmccosmetics.hooks.items;
import com.denizenscript.denizen.objects.ItemTag;
import com.denizenscript.denizencore.utilities.CoreUtilities;
import com.hibiscusmc.hmccosmetics.hooks.Hook;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* A hook that integrates the plugin {@link com.denizenscript.denizen.Denizen Denizen} to provide custom items
*/
@SuppressWarnings("SpellCheckingInspection")
public class HookDenizen extends Hook {
public HookDenizen() {
super("denizen");
setEnabledItemHook(true);
}
/**
* Gets a cosmetic {@link ItemStack} that is associated with the provided id from the plugin {@link com.denizenscript.denizen.Denizen Denizen}
*/
@Override
public ItemStack getItem(@NotNull String itemId) {
ItemTag item = ItemTag.valueOf(itemId, CoreUtilities.noDebugContext);
return item == null ? null : item.getItemStack();
}
}

View File

@@ -0,0 +1,45 @@
package com.hibiscusmc.hmccosmetics.hooks.items;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.hooks.Hook;
import com.mineinabyss.geary.addons.GearyPhase;
import com.mineinabyss.geary.modules.GearyModuleKt;
import com.mineinabyss.geary.papermc.tracking.items.ItemTrackingKt;
import com.mineinabyss.geary.prefabs.PrefabKey;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* A hook that integrates the plugin {@link com.mineinabyss.geary.papermc.GearyPlugin Geary} to provide custom items
*/
@SuppressWarnings("SpellCheckingInspection")
public class HookGeary extends Hook {
private boolean enabled = false;
public HookGeary() {
super("geary");
setEnabledItemHook(true);
}
@Override
public void load() {
GearyModuleKt.getGeary().getPipeline().intercept(GearyPhase.ENABLE, () -> {
enabled = true;
HMCCosmeticsPlugin.setup();
return null;
});
}
/**
* Gets a cosmetic {@link ItemStack} that is associated with the provided id from the plugin {@link com.mineinabyss.geary.papermc.GearyPlugin Geary}
*/
@Override
public ItemStack getItem(@NotNull String itemId) {
if (enabled) {
PrefabKey prefabKey = PrefabKey.Companion.ofOrNull(itemId);
if (prefabKey == null) return null;
return ItemTrackingKt.getGearyItems().createItem(prefabKey, null);
} else return new ItemStack(Material.AIR);
}
}

View File

@@ -3,18 +3,23 @@ package com.hibiscusmc.hmccosmetics.hooks.items;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.hooks.Hook;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
public class HookHMCCosmetics extends Hook implements Listener {
/**
* A hook that integrates the plugin {@link com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin HMCCosmetics} to provide cosmetic items
*/
public class HookHMCCosmetics extends Hook {
public HookHMCCosmetics() {
super("HMCCosmetics");
setEnabledItemHook(true);
}
/**
* Gets a cosmetic {@link ItemStack} that is associated with the provided id from the plugin {@link com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin HMCCosmetics}
*/
@Override
public ItemStack getItem(String itemId) {
public ItemStack getItem(@NotNull String itemId) {
Cosmetic cosmetic = Cosmetics.getCosmetic(itemId);
if (cosmetic == null) return null;
return cosmetic.getItem();

View File

@@ -7,11 +7,14 @@ import dev.lone.itemsadder.api.CustomStack;
import dev.lone.itemsadder.api.Events.ItemsAdderLoadDataEvent;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
public class HookItemAdder extends Hook implements Listener {
/**
* A hook that integrates the plugin {@link dev.lone.itemsadder.api.ItemsAdder ItemsAdder} to provide custom items
*/
@SuppressWarnings("SpellCheckingInspection")
public class HookItemAdder extends Hook {
private boolean enabled = false;
public HookItemAdder() {
@@ -19,8 +22,11 @@ public class HookItemAdder extends Hook implements Listener {
setEnabledItemHook(true);
}
/**
* Gets a cosmetic {@link ItemStack} that is associated with the provided id from the plugin {@link dev.lone.itemsadder.api.ItemsAdder ItemsAdder}
*/
@Override
public ItemStack getItem(String itemId) {
public ItemStack getItem(@NotNull String itemId) {
if (enabled) {
CustomStack stack = CustomStack.getInstance(itemId);
if (stack == null) return null;
@@ -32,7 +38,8 @@ public class HookItemAdder extends Hook implements Listener {
@EventHandler
public void onItemAdderDataLoad(ItemsAdderLoadDataEvent event) {
if (enabled && !Settings.getItemsAdderReloadChange()) return; // Defaultly it will only run once at startup. If hook setting is enable
// By default, it will only run once at startup, if hook setting is enabled
if (enabled && !Settings.getItemsAdderReloadChange()) return;
this.enabled = true;
HMCCosmeticsPlugin.setup();
}

View File

@@ -1,22 +0,0 @@
package com.hibiscusmc.hmccosmetics.hooks.items;
import com.hibiscusmc.hmccosmetics.hooks.Hook;
import com.mineinabyss.geary.prefabs.PrefabKey;
import com.mineinabyss.looty.LootyFactory;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
public class HookLooty extends Hook implements Listener {
public HookLooty() {
super("looty");
setEnabledItemHook(true);
}
@Override
public ItemStack getItem(String itemId) {
PrefabKey prefabKey = PrefabKey.Companion.ofOrNull(itemId);
if (prefabKey == null) return null;
return LootyFactory.INSTANCE.createFromPrefab(prefabKey);
}
}

View File

@@ -2,17 +2,24 @@ package com.hibiscusmc.hmccosmetics.hooks.items;
import com.hibiscusmc.hmccosmetics.hooks.Hook;
import io.lumine.mythic.bukkit.MythicBukkit;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
public class HookMythic extends Hook implements Listener {
/**
* A hook that integrates the plugin {@link io.lumine.mythic.bukkit.MythicBukkit MythicBukkit} to provide custom items
*/
@SuppressWarnings("SpellCheckingInspection")
public class HookMythic extends Hook {
public HookMythic() {
super("mythicmobs");
setEnabledItemHook(true);
}
/**
* Gets a cosmetic {@link ItemStack} that is associated with the provided id from the plugin {@link io.lumine.mythic.bukkit.MythicBukkit MythicBukkit}
*/
@Override
public ItemStack getItem(String itemId) {
public ItemStack getItem(@NotNull String itemId) {
return MythicBukkit.inst().getItemManager().getItemStack(itemId);
}
}

View File

@@ -3,18 +3,24 @@ package com.hibiscusmc.hmccosmetics.hooks.items;
import com.hibiscusmc.hmccosmetics.hooks.Hook;
import io.th0rgal.oraxen.api.OraxenItems;
import io.th0rgal.oraxen.items.ItemBuilder;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
public class HookOraxen extends Hook implements Listener {
/**
* A hook that integrates the plugin {@link io.th0rgal.oraxen.OraxenPlugin OraxenPlugin} to provide custom items
*/
@SuppressWarnings("SpellCheckingInspection")
public class HookOraxen extends Hook {
public HookOraxen() {
super("oraxen");
setEnabledItemHook(true);
}
/**
* Gets a cosmetic {@link ItemStack} that is associated with the provided id from the plugin {@link io.th0rgal.oraxen.OraxenPlugin OraxenPlugin}
*/
@Override
public ItemStack getItem(String itemId) {
public ItemStack getItem(@NotNull String itemId) {
ItemBuilder builder = OraxenItems.getItemById(itemId);
if (builder == null) return null;
return builder.build();

View File

@@ -7,11 +7,12 @@ import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
public class HookCMI extends Hook implements Listener {
/**
* A hook that integrates the plugin {@link com.Zrips.CMI.CMI CMI}
*/
public class HookCMI extends Hook {
public HookCMI() {
super("CMI");
}

View File

@@ -1,10 +1,11 @@
package com.hibiscusmc.hmccosmetics.hooks.misc;
import com.hibiscusmc.hmccosmetics.hooks.Hook;
import org.bukkit.event.Listener;
public class HookHMCColor extends Hook implements Listener {
/**
* A hook that integrates the plugin {@link com.hibiscusmc.hmccolor.HMCColor HMCColor}
*/
public class HookHMCColor extends Hook {
public HookHMCColor() {
super("HMCColor");
}

View File

@@ -0,0 +1,32 @@
package com.hibiscusmc.hmccosmetics.hooks.misc;
import com.hibiscusmc.hmccosmetics.hooks.Hook;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import me.libraryaddict.disguise.events.DisguiseEvent;
import me.libraryaddict.disguise.events.UndisguiseEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.jetbrains.annotations.NotNull;
public class HookLibsDisguises extends Hook {
public HookLibsDisguises() {
super("LibsDisguises");
}
@EventHandler
public void onPlayerVanish(@NotNull DisguiseEvent event) {
if (!(event.getEntity() instanceof Player player)) return;
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
user.hideCosmetics(CosmeticUser.HiddenReason.PLUGIN);
}
@EventHandler
public void onPlayerShow(@NotNull UndisguiseEvent event) {
if (!(event.getEntity() instanceof Player player)) return;
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
user.showCosmetics();
}
}

View File

@@ -7,13 +7,14 @@ import de.myzelyam.api.vanish.PlayerHideEvent;
import de.myzelyam.api.vanish.PlayerShowEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
public class HookPremiumVanish extends Hook implements Listener {
// NOTE: Supervanish and Premium Vanish both use the same api
/**
* A hook that integrates the plugin {@link de.myzelyam.api.vanish.VanishAPI Supervanish}
*
* @implSpec Supervanish and Premium Vanish both use the same api
*/
public class HookPremiumVanish extends Hook {
public HookPremiumVanish() {
super("PremiumVanish");
}
@@ -33,5 +34,4 @@ public class HookPremiumVanish extends Hook implements Listener {
if (user == null) return;
user.showCosmetics();
}
}

View File

@@ -7,13 +7,14 @@ import de.myzelyam.api.vanish.PlayerHideEvent;
import de.myzelyam.api.vanish.PlayerShowEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
public class HookSuperVanish extends Hook implements Listener {
// NOTE: Supervanish and Premium Vanish both use the same api
/**
* A hook that integrates the plugin {@link de.myzelyam.api.vanish.VanishAPI Supervanish}
*
* @implSpec Supervanish and Premium Vanish both use the same api
*/
public class HookSuperVanish extends Hook {
public HookSuperVanish() {
super("SuperVanish");
}

View File

@@ -6,18 +6,23 @@ import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.TranslationUtil;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.apache.commons.lang3.EnumUtils;
import org.bukkit.OfflinePlayer;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
/**
* A hook that integrates the plugin {@link me.clip.placeholderapi.PlaceholderAPIPlugin PlaceholderAPIPlugin}
*/
public class HMCPlaceholderExpansion extends PlaceholderExpansion {
private static boolean papiEnabled = false;
public HMCPlaceholderExpansion() {
@@ -42,6 +47,11 @@ public class HMCPlaceholderExpansion extends PlaceholderExpansion {
return HMCCosmeticsPlugin.getInstance().getDescription().getVersion();
}
@Override
public boolean persist() {
return true;
}
@Override
public String onRequest(@NotNull OfflinePlayer player, @NotNull String params) {
if (!player.isOnline()) return null;
@@ -57,10 +67,11 @@ public class HMCPlaceholderExpansion extends PlaceholderExpansion {
}
if (placeholderArgs.get(1) != null) {
Cosmetic cosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1));
if (cosmetic == null) return "INVALID_COSMETIC";
Cosmetic currentCosmetic = user.getCosmetic(cosmetic.getSlot());
if (cosmetic == null || currentCosmetic == null) return "false";
if (currentCosmetic.getId() == cosmetic.getId()) return "true";
return "false";
if (currentCosmetic == null) return TranslationUtil.getTranslation("using-cosmetic", String.valueOf(false)); // I hate this way of handling translations
if (currentCosmetic.getId() == cosmetic.getId()) return TranslationUtil.getTranslation("using-cosmetic", String.valueOf(true));
return TranslationUtil.getTranslation("using-cosmetic", String.valueOf(false));
}
case "current":
if (placeholderArgs == null) {
@@ -71,26 +82,29 @@ public class HMCPlaceholderExpansion extends PlaceholderExpansion {
if (slot == null) return null;
if (user.getCosmetic(slot) == null) return null;
if (placeholderArgs.size() == 2) return user.getCosmetic(slot).getId();
String output;
switch (placeholderArgs.get(2).toLowerCase()) {
case "material" -> {
return getMaterial(user.getCosmetic(slot));
output = getMaterialName(user.getCosmetic(slot));
}
case "custommodeldata" -> {
return getModelData(user.getCosmetic(slot));
output = getModelData(user.getCosmetic(slot));
}
case "name" -> {
return getItemName(user.getCosmetic(slot));
output = getItemName(user.getCosmetic(slot));
}
case "lore" -> {
return getItemLore(user.getCosmetic(slot));
output = getItemLore(user.getCosmetic(slot));
}
case "permission" -> {
return user.getCosmetic(slot).getPermission();
output = user.getCosmetic(slot).getPermission();
}
default -> {
return user.getCosmetic(slot).getId();
output = user.getCosmetic(slot).getId();
}
}
return TranslationUtil.getTranslation("current-cosmetic", String.valueOf(output));
}
case "unlocked":
if (placeholderArgs == null) {
@@ -99,69 +113,124 @@ public class HMCPlaceholderExpansion extends PlaceholderExpansion {
if (placeholderArgs.get(1) != null) {
Cosmetic cosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1));
if (cosmetic == null) {
Cosmetic secondAttemptCosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1) + "_" + placeholderArgs.get(2));
if (secondAttemptCosmetic == null) {
return "INVALID_COSMETIC";
if (placeholderArgs.size() >= 3) {
Cosmetic secondAttemptCosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1) + "_" + placeholderArgs.get(2));
if (secondAttemptCosmetic == null) {
return "INVALID_COSMETIC";
} else {
cosmetic = secondAttemptCosmetic;
}
} else {
cosmetic = secondAttemptCosmetic;
return "INVALID_COSMETIC";
}
}
return TranslationUtil.getTranslation("unlockedCosmetic", String.valueOf(user.canEquipCosmetic(cosmetic)));
return TranslationUtil.getTranslation("unlocked-cosmetic", String.valueOf(user.canEquipCosmetic(cosmetic)));
}
case "equipped":
if (placeholderArgs == null) {
return null;
}
if (placeholderArgs.get(1) != null) {
Cosmetic cosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1));
String args1 = placeholderArgs.get(1);
if (EnumUtils.isValidEnum(CosmeticSlot.class, args1.toUpperCase())) {
return TranslationUtil.getTranslation("equipped-cosmetic", String.valueOf(user.getCosmetic(CosmeticSlot.valueOf(args1.toUpperCase())) != null));
}
MessagesUtil.sendDebugMessages(args1);
Cosmetic cosmetic = Cosmetics.getCosmetic(args1);
if (cosmetic == null) {
Cosmetic secondAttemptCosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1) + "_" + placeholderArgs.get(2));
if (secondAttemptCosmetic == null) {
return "INVALID_COSMETIC";
if (placeholderArgs.size() == 3) {
Cosmetic secondAttemptCosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1) + "_" + placeholderArgs.get(2));
if (secondAttemptCosmetic == null) {
return "INVALID_COSMETIC";
} else {
cosmetic = secondAttemptCosmetic;
}
} else {
cosmetic = secondAttemptCosmetic;
return "INVALID_COSMETIC";
}
}
if (user.getCosmetic(cosmetic.getSlot()) == null) return "false";
if (cosmetic.getId() == user.getCosmetic(cosmetic.getSlot()).getId()) {
return "true";
} else {
return "false";
}
return TranslationUtil.getTranslation("equipped-cosmetic", String.valueOf(cosmetic.getId() == user.getCosmetic(cosmetic.getSlot()).getId()));
}
case "wardrobe-enabled":
return String.valueOf(user.isInWardrobe());
return TranslationUtil.getTranslation("in-wardrobe", String.valueOf(user.isInWardrobe()));
}
return null;
}
/**
* Gets the name of the cosmetic item {@link org.bukkit.Material Material}
* @param cosmetic The cosmetic to get its {@link org.bukkit.Material Material}s name
* @return The name of the cosmetic item {@link org.bukkit.Material Material}
* @deprecated As of release 2.2.5+, use {@link #getMaterialName(Cosmetic)} instead
*/
@Deprecated
@Nullable
public String getMaterial(@NotNull Cosmetic cosmetic) {
ItemStack item = cosmetic.getItem();
if (item == null) return null;
return cosmetic.getItem().getType().toString();
return item.getType().toString();
}
/**
* Gets the name of the cosmetic item {@link org.bukkit.Material Material}
* @param cosmetic The cosmetic to get its {@link org.bukkit.Material Material}s name
* @return The name of the cosmetic item {@link org.bukkit.Material Material}
* @since 2.2.5
*/
@Nullable
public String getMaterialName(@NotNull Cosmetic cosmetic) {
ItemStack item = cosmetic.getItem();
if (item == null) return null;
return item.getType().toString();
}
/**
* Gets the cosmetic items custom model data
* @param cosmetic The cosmetic to get its custom model data
* @return The cosmetic items custom model data
*/
@Nullable
public String getModelData(@NotNull Cosmetic cosmetic) {
ItemStack item = cosmetic.getItem();
if (item == null) return null;
if (!item.hasItemMeta()) return null;
ItemMeta itemMeta = item.getItemMeta();
if (itemMeta == null) return null;
return String.valueOf(itemMeta.getCustomModelData());
}
/**
* Gets the cosmetic items display name
* @param cosmetic The cosmetic to get its items display name
* @return The cosmetic items display name
*/
@Nullable
public String getItemName(@NotNull Cosmetic cosmetic) {
ItemStack item = cosmetic.getItem();
if (item == null) return null;
if (!item.hasItemMeta()) return null;
ItemMeta itemMeta = item.getItemMeta();
if (itemMeta == null) return null;
return itemMeta.getDisplayName();
}
/**
* Gets the cosmetic items lore
* @param cosmetic The cosmetic to get its items lore
* @return The cosmetic items lore
*/
@Nullable
public String getItemLore(@NotNull Cosmetic cosmetic) {
ItemStack item = cosmetic.getItem();
if (item == null) return null;
if (item.hasItemMeta()) {
return String.valueOf(item.getItemMeta().getLore());
ItemMeta itemMeta = item.getItemMeta();
if (itemMeta == null) return null;
return String.valueOf(itemMeta.getLore());
}
return null;
}

View File

@@ -2,12 +2,17 @@ package com.hibiscusmc.hmccosmetics.hooks.placeholders;
import com.hibiscusmc.hmccosmetics.hooks.Hook;
/**
* A hook that integrates the plugin {@link me.clip.placeholderapi.PlaceholderAPI PlaceholderAPI}
*/
public class HookPlaceholderAPI extends Hook {
public HookPlaceholderAPI() {
super("PlaceholderAPI");
}
/**
* Registers HMCCosmetics Placeholder Expansion
*/
@Override
public void load() {
new HMCPlaceholderExpansion().register();

View File

@@ -4,21 +4,31 @@ import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.flags.StringFlag;
import com.sk89q.worldguard.protection.flags.registry.FlagConflictException;
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
import java.util.logging.Level;
/**
* A hook that integrates the plugin {@link com.sk89q.worldguard.WorldGuard WorldGuard}
*/
public class WGHook {
/**
* @implNote Please use {@link #getCosmeticEnableFlag()} instead
*/
public static StateFlag COSMETIC_ENABLE_FLAG;
public static StateFlag COSMETIC_WARDROBE_FLAG;
/**
* @implNote Please use {@link #getCosmeticWardrobeFlag()} instead
*/
public static StringFlag COSMETIC_WARDROBE_FLAG;
public WGHook() {
FlagRegistry registry = WorldGuard.getInstance().getFlagRegistry();
try {
StateFlag cosmeticFlag = new StateFlag("cosmetic-enable", false);
StateFlag wardrobeFlag = new StateFlag("cosmetic-wardrobe", false);
StringFlag wardrobeFlag = new StringFlag("cosmetic-wardrobe");
registry.register(cosmeticFlag);
registry.register(wardrobeFlag);
COSMETIC_ENABLE_FLAG = cosmeticFlag;
@@ -35,11 +45,19 @@ public class WGHook {
}
}
/**
* Gets the cosmetic enable {@link StateFlag}
* @return The cosmetic enable {@link StateFlag}
*/
public static StateFlag getCosmeticEnableFlag() {
return COSMETIC_ENABLE_FLAG;
}
public static StateFlag getCosmeticWardrobeFlag() {
/**
* Gets the cosmetic wardrobe {@link StateFlag}
* @return The cosmetic wardrobe {@link StateFlag}
*/
public static StringFlag getCosmeticWardrobeFlag() {
return COSMETIC_WARDROBE_FLAG;
}

View File

@@ -1,7 +1,10 @@
package com.hibiscusmc.hmccosmetics.hooks.worldguard;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
@@ -12,10 +15,13 @@ import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.jetbrains.annotations.NotNull;
/**
* Contains {@link com.sk89q.worldguard.WorldGuard WorldGuard} related event listeners
*/
public class WGListener implements Listener {
@EventHandler
public void onPlayerMove(@NotNull PlayerMoveEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
@@ -32,13 +38,48 @@ public class WGListener implements Listener {
}
for (ProtectedRegion protectedRegion : set.getRegions()) {
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticEnableFlag())) {
if (protectedRegion.getFlags().get(WGHook.getCosmeticEnableFlag()).toString().equalsIgnoreCase("ALLOW")) return;
if (protectedRegion.getFlags().get(WGHook.getCosmeticEnableFlag()).toString().equalsIgnoreCase("ALLOW")) {
if (user.getHiddenReason() == CosmeticUser.HiddenReason.WORLDGUARD) user.showCosmetics();
return;
}
user.hideCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
return;
}
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticWardrobeFlag())) {
if (!protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString().equalsIgnoreCase("ALLOW")) return;
user.enterWardrobe();
if (!WardrobeSettings.getWardrobeNames().contains(protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString())) return;
Wardrobe wardrobe = WardrobeSettings.getWardrobe(protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString());
user.enterWardrobe(true, wardrobe);
}
}
}
@EventHandler
public void onPlayerTeleport(PlayerTeleportEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
if (user == null) return;
Location location = event.getTo();
com.sk89q.worldedit.util.Location loc = BukkitAdapter.adapt(location);
RegionContainer region = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = region.createQuery();
ApplicableRegionSet set = query.getApplicableRegions(loc);
if (user.getHidden()) {
if (user.getHiddenReason() == CosmeticUser.HiddenReason.WORLDGUARD && set.getRegions().size() == 0) {
user.showCosmetics();
}
}
for (ProtectedRegion protectedRegion : set.getRegions()) {
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticEnableFlag())) {
if (protectedRegion.getFlags().get(WGHook.getCosmeticEnableFlag()).toString().equalsIgnoreCase("ALLOW")) {
if (user.getHiddenReason() == CosmeticUser.HiddenReason.WORLDGUARD) user.showCosmetics();
return;
}
user.hideCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
return;
}
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticWardrobeFlag())) {
if (!WardrobeSettings.getWardrobeNames().contains(protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString())) return;
Wardrobe wardrobe = WardrobeSettings.getWardrobe(protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString());
user.enterWardrobe(true, wardrobe);
}
}
}

View File

@@ -58,6 +58,7 @@ public class PlayerConnectionListener implements Listener {
}
}
}
return;
}
if (user.isInWardrobe()) user.leaveWardrobe();
if (user.getUserEmoteManager().isPlayingEmote()) {

View File

@@ -9,6 +9,7 @@ import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.Pair;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.api.events.PlayerCosmeticPostEquipEvent;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
@@ -23,9 +24,12 @@ import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;
import com.hibiscusmc.hmccosmetics.util.InventoryUtils;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
@@ -33,7 +37,6 @@ import org.bukkit.entity.Pose;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.*;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.*;
import org.bukkit.inventory.EquipmentSlot;
@@ -61,12 +64,20 @@ public class PlayerGameListener implements Listener {
@EventHandler
public void onPlayerClick(@NotNull InventoryClickEvent event) {
if (event.getClick() != ClickType.SHIFT_LEFT && event.getClick() != ClickType.SHIFT_RIGHT) return;
// || !event.getClickedInventory().getType().equals(InventoryType.PLAYER)
if (event.getClick().isShiftClick()) return;
MessagesUtil.sendDebugMessages("inventoryclickevent");
//if (event.getSlotType() != InventoryType.SlotType.ARMOR) return;
CosmeticUser user = CosmeticUsers.getUser(event.getWhoClicked().getUniqueId());
if (user == null) return;
ItemStack item = event.getCurrentItem();
if (item == null) return;
if (Settings.isDestroyLooseCosmetics() && InventoryUtils.isCosmeticItem(event.getCurrentItem())) {
MessagesUtil.sendDebugMessages("remvoe item");
event.getWhoClicked().getInventory().removeItem(event.getCurrentItem());
}
EquipmentSlot slot = getArmorSlot(item.getType());
if (slot == null) return;
CosmeticSlot cosmeticSlot = InventoryUtils.BukkitCosmeticSlot(slot);
@@ -104,13 +115,10 @@ public class PlayerGameListener implements Listener {
}
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK) && user.getUserBackpackManager() != null) {
user.getUserBackpackManager().hideBackpack();
user.getUserBackpackManager().getArmorStand().teleport(event.getTo());
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
user.respawnBackpack();
user.updateCosmetic();
}, 2);
}, 1);
}
if (event.getCause().equals(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL) || event.getCause().equals(PlayerTeleportEvent.TeleportCause.END_PORTAL)) return;
@@ -122,6 +130,9 @@ public class PlayerGameListener implements Listener {
user.spawnBalloon(cosmeticBalloonType);
}, 2);
}
if (user.getUserEmoteManager().isPlayingEmote()) {
user.getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.TELEPORT);
}
}
@EventHandler
@@ -195,12 +206,22 @@ public class PlayerGameListener implements Listener {
if (!user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) return;
Pose pose = event.getPose();
if (pose.equals(Pose.STANDING)) {
// #84, Riptides mess with backpacks
ItemStack currentItem = player.getInventory().getItemInMainHand();
if (currentItem != null) {
if (currentItem.hasItemMeta()) {
if (currentItem.containsEnchantment(Enchantment.RIPTIDE)) {
return;
}
}
}
if (!user.isBackpackSpawned()) {
user.spawnBackpack((CosmeticBackpackType) user.getCosmetic(CosmeticSlot.BACKPACK));
}
return;
}
if (pose.equals(Pose.SLEEPING) || pose.equals(Pose.SWIMMING) || pose.equals(Pose.FALL_FLYING)) {
if (pose.equals(Pose.SLEEPING) || pose.equals(Pose.SWIMMING) || pose.equals(Pose.FALL_FLYING) || pose.equals(Pose.SPIN_ATTACK)) {
user.despawnBackpack();
}
}
@@ -292,6 +313,14 @@ public class PlayerGameListener implements Listener {
user.updateCosmetic(CosmeticSlot.MAINHAND);
user.updateCosmetic(CosmeticSlot.OFFHAND);
}, 2);
// #84, Riptides mess with backpacks
ItemStack currentItem = event.getPlayer().getInventory().getItem(event.getNewSlot());
if (currentItem == null) return;
if (!currentItem.hasItemMeta()) return;
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK) && currentItem.containsEnchantment(Enchantment.RIPTIDE)) {
user.despawnBackpack();
}
}
@EventHandler
@@ -299,11 +328,37 @@ public class PlayerGameListener implements Listener {
CosmeticUser user = CosmeticUsers.getUser(event.getEntity());
if (user == null) return;
if (user.isInWardrobe()) user.leaveWardrobe();
if (Settings.getUnapplyOnDeath() && !event.getEntity().hasPermission("hmccosmetics.unapplydeath.bypass")) {
user.removeCosmetics();
}
}
@EventHandler
public void onPlayerGamemodeSwitch(PlayerGameModeChangeEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
if (user == null) return;
if (Settings.isDestroyLooseCosmetics()) {
ItemStack[] equippedArmor = event.getPlayer().getInventory().getArmorContents();
if (equippedArmor.length == 0) return;
for (ItemStack armor : equippedArmor) {
if (InventoryUtils.isCosmeticItem(armor)) armor.setAmount(0);
}
}
}
@EventHandler
public void onPlayerCosemticEquip(PlayerCosmeticPostEquipEvent event) {
CosmeticUser user = event.getUser();
if (user.isInWardrobe() && event.getCosmetic().getSlot().equals(CosmeticSlot.BALLOON)) {
Location NPCLocation = user.getWardrobeManager().getNpcLocation();
PacketManager.sendTeleportPacket(user.getBalloonManager().getPufferfishBalloonId(), NPCLocation.add(Settings.getBalloonOffset()), false, List.of(event.getUser().getPlayer()));
user.getBalloonManager().getModelEntity().teleport(NPCLocation.add(Settings.getBalloonOffset()));
}
}
private void registerInventoryClickListener() {
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.WINDOW_CLICK) {
@Override
@@ -347,7 +402,7 @@ public class PlayerGameListener implements Listener {
HashMap<Integer, ItemStack> items = new HashMap<>();
for (Cosmetic cosmetic : user.getCosmetic()) {
for (Cosmetic cosmetic : user.getCosmetics()) {
if ((cosmetic instanceof CosmeticArmorType cosmeticArmorType)) {
items.put(InventoryUtils.getPacketArmorSlot(cosmeticArmorType.getEquipSlot()), user.getUserCosmeticItem(cosmeticArmorType));
}

View File

@@ -5,6 +5,7 @@ import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType;
import com.hibiscusmc.hmccosmetics.user.manager.UserBalloonManager;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import net.kyori.adventure.text.Component;
import org.bukkit.Location;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
@@ -27,6 +28,8 @@ public interface NMSHandler {
Entity spawnHMCParticleCloud(Location location);
Entity spawnDisplayEntity(Location location, String text);
UserBalloonManager spawnBalloon(CosmeticUser user, CosmeticBalloonType cosmeticBalloonType);
void equipmentSlotUpdate(

View File

@@ -8,7 +8,7 @@ import java.util.logging.Level;
public class NMSHandlers {
private static final String[] SUPPORTED_VERSION = new String[]{"v1_17_R1", "v1_18_R2", "v1_19_R1", "v1_19_R2"};
private static final String[] SUPPORTED_VERSION = new String[]{"v1_18_R2", "v1_19_R1", "v1_19_R2", "v1_19_R3", "v1_20_R1"};
private static NMSHandler handler;
private static String version;

View File

@@ -1,12 +1,16 @@
package com.hibiscusmc.hmccosmetics.user;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.api.*;
import com.hibiscusmc.hmccosmetics.api.events.*;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.cosmetic.types.*;
import com.hibiscusmc.hmccosmetics.hooks.Hooks;
import com.hibiscusmc.hmccosmetics.user.manager.UserBackpackManager;
import com.hibiscusmc.hmccosmetics.user.manager.UserBalloonManager;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
@@ -16,13 +20,12 @@ import com.hibiscusmc.hmccosmetics.util.InventoryUtils;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.PlayerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Material;
import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.*;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.*;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.scheduler.BukkitTask;
import java.util.*;
@@ -30,7 +33,7 @@ import java.util.logging.Level;
public class CosmeticUser {
private UUID uniqueId;
private final UUID uniqueId;
private int taskId;
private HashMap<CosmeticSlot, Cosmetic> playerCosmetics = new HashMap<>();
private UserWardrobeManager userWardrobeManager;
@@ -52,7 +55,7 @@ public class CosmeticUser {
private void tick() {
// Occasionally updates the entity cosmetics
Runnable run = () -> {
MessagesUtil.sendDebugMessages("tick " + uniqueId, Level.INFO);
MessagesUtil.sendDebugMessages("Tick[uuid=" + uniqueId + "]", Level.INFO);
updateCosmetic();
};
@@ -77,10 +80,15 @@ public class CosmeticUser {
return playerCosmetics.get(slot);
}
@Deprecated
public Collection<Cosmetic> getCosmetic() {
return playerCosmetics.values();
}
public ImmutableCollection<Cosmetic> getCosmetics() {
return ImmutableList.copyOf(playerCosmetics.values());
}
public void addPlayerCosmetic(Cosmetic cosmetic) {
addPlayerCosmetic(cosmetic, null);
}
@@ -100,16 +108,19 @@ public class CosmeticUser {
playerCosmetics.put(cosmetic.getSlot(), cosmetic);
if (color != null) colors.put(cosmetic.getSlot(), color);
MessagesUtil.sendDebugMessages("addPlayerCosmetic " + cosmetic.getId());
MessagesUtil.sendDebugMessages("addPlayerCosmetic[id=" + cosmetic.getId() + "]");
if (cosmetic.getSlot() == CosmeticSlot.BACKPACK) {
CosmeticBackpackType backpackType = (CosmeticBackpackType) cosmetic;
spawnBackpack(backpackType);
MessagesUtil.sendDebugMessages("addPlayerCosmetic spawnBackpack " + cosmetic.getId());
MessagesUtil.sendDebugMessages("addPlayerCosmetic[spawnBackpack,id=" + cosmetic.getId() + "]");
}
if (cosmetic.getSlot() == CosmeticSlot.BALLOON) {
CosmeticBalloonType balloonType = (CosmeticBalloonType) cosmetic;
spawnBalloon(balloonType);
}
// API
PlayerCosmeticPostEquipEvent postEquipEvent = new PlayerCosmeticPostEquipEvent(this, cosmetic);
Bukkit.getPluginManager().callEvent(postEquipEvent);
}
public void removeCosmetics() {
@@ -135,7 +146,7 @@ public class CosmeticUser {
despawnBalloon();
}
if (slot == CosmeticSlot.EMOTE) {
if (getUserEmoteManager().isPlayingEmote()) getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.UNEQUIP);
}
colors.remove(slot);
playerCosmetics.remove(slot);
@@ -151,6 +162,11 @@ public class CosmeticUser {
return playerCosmetics.containsKey(slot);
}
public boolean hasCosmeticInSlot(Cosmetic cosmetic) {
if (getCosmetic(cosmetic.getSlot()) == null) return false;
return Objects.equals(cosmetic.getId(), getCosmetic(cosmetic.getSlot()).getId());
}
public Set<CosmeticSlot> getSlotsWithCosmetics() {
return Set.copyOf(playerCosmetics.keySet());
}
@@ -168,7 +184,7 @@ public class CosmeticUser {
}
public void updateCosmetic() {
for (Cosmetic cosmetic : playerCosmetics.values()) {
for (Cosmetic cosmetic : getCosmetics()) {
updateCosmetic(cosmetic.getSlot());
}
}
@@ -195,6 +211,45 @@ public class CosmeticUser {
}
if (item.hasItemMeta()) {
ItemMeta itemMeta = item.getItemMeta();
if (item.getType() == Material.PLAYER_HEAD) {
SkullMeta skullMeta = (SkullMeta) itemMeta;
if (skullMeta.getPersistentDataContainer().has(InventoryUtils.getSkullOwner(), PersistentDataType.STRING)) {
String owner = skullMeta.getPersistentDataContainer().get(InventoryUtils.getSkullOwner(), PersistentDataType.STRING);
if (Hooks.isActiveHook("PlaceholderAPI")) owner = PlaceholderAPI.setPlaceholders(getPlayer(), owner);
skullMeta.setOwningPlayer(Bukkit.getOfflinePlayer(owner));
//skullMeta.getPersistentDataContainer().remove(InventoryUtils.getSkullOwner()); // Don't really need this?
}
if (skullMeta.getPersistentDataContainer().has(InventoryUtils.getSkullTexture(), PersistentDataType.STRING)) {
String texture = skullMeta.getPersistentDataContainer().get(InventoryUtils.getSkullTexture(), PersistentDataType.STRING);
if (Hooks.isActiveHook("PlaceholderAPI")) texture = PlaceholderAPI.setPlaceholders(getPlayer(), texture);
Bukkit.getUnsafe().modifyItemStack(item, "{SkullOwner:{Id:[I;0,0,0,0],Properties:{textures:[{Value:\""
+ texture + "\"}]}}}");
//skullMeta.getPersistentDataContainer().remove(InventoryUtils.getSkullTexture()); // Don't really need this?
}
itemMeta = skullMeta;
}
List<String> processedLore = new ArrayList<>();
if (itemMeta.hasLore()) {
for (String loreLine : itemMeta.getLore()) {
if (Hooks.isActiveHook("PlaceholderAPI")) loreLine = PlaceholderAPI.setPlaceholders(getPlayer(), loreLine);
processedLore.add(loreLine);
}
}
if (itemMeta.hasDisplayName()) {
String displayName = itemMeta.getDisplayName();
if (Hooks.isActiveHook("PlaceholderAPI")) displayName = PlaceholderAPI.setPlaceholders(getPlayer(), displayName);
itemMeta.setDisplayName(displayName);
}
itemMeta.setLore(processedLore);
if (colors.containsKey(cosmetic.getSlot())) {
Color color = colors.get(cosmetic.getSlot());
if (itemMeta instanceof LeatherArmorMeta leatherMeta) {
@@ -205,6 +260,9 @@ public class CosmeticUser {
mapMeta.setColor(color);
}
}
itemMeta.getPersistentDataContainer().set(InventoryUtils.getCosmeticKey(), PersistentDataType.STRING, cosmetic.getId());
itemMeta.getPersistentDataContainer().set(InventoryUtils.getOwnerKey(), PersistentDataType.STRING, getPlayer().getUniqueId().toString());
item.setItemMeta(itemMeta);
}
return item;
@@ -226,27 +284,28 @@ public class CosmeticUser {
return userEmoteManager;
}
public void enterWardrobe() {
enterWardrobe(false);
}
public void enterWardrobe(boolean ignoreDistance) {
enterWardrobe(ignoreDistance, WardrobeSettings.getLeaveLocation(), WardrobeSettings.getViewerLocation(), WardrobeSettings.getWardrobeLocation());
}
public void enterWardrobe(boolean ignoreDistance, Location exitLocation, Location viewingLocation, Location npcLocation) {
if (!WardrobeSettings.inDistanceOfStatic(getPlayer().getLocation()) && !ignoreDistance) {
public void enterWardrobe(boolean ignoreDistance, Wardrobe wardrobe) {
if (wardrobe.hasPermission() && !getPlayer().hasPermission(wardrobe.getPermission())) {
MessagesUtil.sendMessage(getPlayer(), "no-permission");
return;
}
if (!wardrobe.canEnter(this) && !ignoreDistance) {
MessagesUtil.sendMessage(getPlayer(), "not-near-wardrobe");
return;
}
PlayerWardrobeEnterEvent event = new PlayerWardrobeEnterEvent(this);
if (!wardrobe.getLocation().hasAllLocations()) {
MessagesUtil.sendMessage(getPlayer(), "wardrobe-not-setup");
return;
}
PlayerWardrobeEnterEvent event = new PlayerWardrobeEnterEvent(this, wardrobe);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
wardrobe = event.getWardrobe();
if (userWardrobeManager == null) {
userWardrobeManager = new UserWardrobeManager(this, exitLocation, viewingLocation, npcLocation);
userWardrobeManager = new UserWardrobeManager(this, wardrobe);
userWardrobeManager.start();
}
}
@@ -257,6 +316,7 @@ public class CosmeticUser {
if (event.isCancelled()) {
return;
}
MessagesUtil.sendDebugMessages("Leaving Wardrobe");
if (!getWardrobeManager().getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return;
getWardrobeManager().setWardrobeStatus(UserWardrobeManager.WardrobeStatus.STOPPING);
@@ -273,20 +333,14 @@ public class CosmeticUser {
userWardrobeManager.end();
userWardrobeManager = null;
}, WardrobeSettings.getTransitionDelay());
} else {
userWardrobeManager.end();
userWardrobeManager = null;
}
}
public boolean isInWardrobe() {
if (userWardrobeManager == null) return false;
return true;
}
public void toggleWardrobe() {
if (isInWardrobe()) {
leaveWardrobe();
} else {
enterWardrobe();
}
return userWardrobeManager != null;
}
public void spawnBackpack(CosmeticBackpackType cosmeticBackpackType) {
@@ -302,8 +356,7 @@ public class CosmeticUser {
}
public boolean isBackpackSpawned() {
if (this.userBackpackManager == null) return false;
return true;
return this.userBackpackManager != null;
}
public void spawnBalloon(CosmeticBalloonType cosmeticBalloonType) {
@@ -315,8 +368,6 @@ public class CosmeticUser {
List<Player> viewer = PlayerUtils.getNearbyPlayers(player);
viewer.add(player);
PacketManager.sendLeashPacket(getBalloonManager().getPufferfishBalloonId(), player.getEntityId(), viewer);
}
public void despawnBalloon() {
@@ -356,9 +407,9 @@ public class CosmeticUser {
}
public List<CosmeticSlot> getDyeableSlots() {
ArrayList<CosmeticSlot> dyableSlots = new ArrayList();
ArrayList<CosmeticSlot> dyableSlots = new ArrayList<>();
for (Cosmetic cosmetic : getCosmetic()) {
for (Cosmetic cosmetic : getCosmetics()) {
if (cosmetic.isDyable()) dyableSlots.add(cosmetic.getSlot());
}
@@ -367,8 +418,10 @@ public class CosmeticUser {
public boolean canEquipCosmetic(Cosmetic cosmetic) {
if (!cosmetic.requiresPermission()) return true;
if (getPlayer().hasPermission(cosmetic.getPermission())) return true;
return false;
if (isInWardrobe()) {
if (WardrobeSettings.isTryCosmeticsInWardrobe() && userWardrobeManager.getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return true;
}
return getPlayer().hasPermission(cosmetic.getPermission());
}
public void hidePlayer() {
@@ -390,7 +443,7 @@ public class CosmeticUser {
}
public void hideCosmetics(HiddenReason reason) {
if (hideCosmetics == true) return;
if (hideCosmetics) return;
PlayerCosmeticHideEvent event = new PlayerCosmeticHideEvent(this, reason);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
@@ -401,8 +454,7 @@ public class CosmeticUser {
hiddenReason = reason;
if (hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
getBalloonManager().removePlayerFromModel(getPlayer());
List<Player> viewer = PlayerUtils.getNearbyPlayers(getPlayer());
PacketManager.sendLeashPacket(getBalloonManager().getPufferfishBalloonId(), -1, viewer);
getBalloonManager().sendRemoveLeashPacket();
}
if (hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
userBackpackManager.clearItems();

View File

@@ -39,6 +39,14 @@ public class UserBackpackManager {
return invisibleArmorStand;
}
public boolean IsValidBackpackEntity() {
if (invisibleArmorStand == null) {
MessagesUtil.sendDebugMessages("InvisibleArmorStand is Null!");
return false;
}
return getArmorStand().isValid();
}
public void spawnBackpack(CosmeticBackpackType cosmeticBackpackType) {
MessagesUtil.sendDebugMessages("spawnBackpack Bukkit - Start");

View File

@@ -6,6 +6,8 @@ import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.PlayerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager;
import com.ticxo.modelengine.api.ModelEngineAPI;
import com.ticxo.modelengine.api.model.ActiveModel;
import com.ticxo.modelengine.api.model.ModeledEntity;
@@ -17,12 +19,14 @@ import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
public class UserBalloonManager {
private BalloonType balloonType;
private CosmeticBalloonType cosmeticBalloonType;
private final int balloonID;
private final UUID uniqueID;
private final ArmorStand modelEntity;
@@ -44,6 +48,7 @@ public class UserBalloonManager {
balloonType = BalloonType.NONE;
}
}
this.cosmeticBalloonType = cosmeticBalloonType;
MessagesUtil.sendDebugMessages("balloontype is " + balloonType);
if (balloonType == BalloonType.MODELENGINE) {
@@ -85,6 +90,7 @@ public class UserBalloonManager {
}
modelEntity.remove();
cosmeticBalloonType = null;
}
public void addPlayerToModel(final CosmeticUser user, final CosmeticBalloonType cosmeticBalloonType) {
@@ -156,6 +162,19 @@ public class UserBalloonManager {
this.getModelEntity().setVelocity(vector);
}
public void sendRemoveLeashPacket(List<Player> viewer) {
PacketManager.sendLeashPacket(getPufferfishBalloonId(), -1, viewer);
}
public void sendRemoveLeashPacket() {
PacketManager.sendLeashPacket(getPufferfishBalloonId(), -1, getLocation());
}
public void sendLeashPacket(int entityId) {
if (cosmeticBalloonType == null) return;
if (cosmeticBalloonType.isShowLead()) PacketManager.sendLeashPacket(getPufferfishBalloonId(), entityId, getLocation());
}
public enum BalloonType {
MODELENGINE,
ITEM,

View File

@@ -1,33 +1,41 @@
package com.hibiscusmc.hmccosmetics.user.manager;
import com.hibiscusmc.hmccosmetics.api.PlayerCosmeticRemoveEvent;
import com.hibiscusmc.hmccosmetics.api.PlayerEmoteStartEvent;
import com.hibiscusmc.hmccosmetics.api.PlayerEmoteStopEvent;
import com.hibiscusmc.hmccosmetics.api.events.PlayerEmoteStartEvent;
import com.hibiscusmc.hmccosmetics.api.events.PlayerEmoteStopEvent;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticEmoteType;
import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.jetbrains.annotations.NotNull;
public class UserEmoteManager {
CosmeticUser user;
private CosmeticUser user;
private UserEmoteModel model;
private Entity textEntity;
public UserEmoteManager(CosmeticUser user) {
this.user = user;
}
public void playEmote(@NotNull CosmeticEmoteType cosmeticEmoteType) {
MessagesUtil.sendDebugMessages("playEmote " + cosmeticEmoteType.getAnimationId());
playEmote(cosmeticEmoteType.getAnimationId());
public void playEmote(String animationId) {
MessagesUtil.sendDebugMessages("playEmote " + animationId);
playEmote(EmoteManager.get(animationId), null);
}
public void playEmote(String animationId) {
public void playEmote(@NotNull CosmeticEmoteType cosmeticEmoteType) {
MessagesUtil.sendDebugMessages("playEmote " + cosmeticEmoteType.getAnimationId());
playEmote(EmoteManager.get(cosmeticEmoteType.getAnimationId()), cosmeticEmoteType.getText());
}
public void playEmote(String emoteAnimation, String text) {
if (isPlayingEmote()) return;
if (user.isInWardrobe()) return;
// API
PlayerEmoteStartEvent event = new PlayerEmoteStartEvent(user, animationId);
PlayerEmoteStartEvent event = new PlayerEmoteStartEvent(user, emoteAnimation);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
@@ -35,7 +43,14 @@ public class UserEmoteManager {
// Internal
try {
model = new UserEmoteModel(user);
model.playAnimation(animationId);
// Play animation id
if (emoteAnimation != null) {
model.playAnimation(emoteAnimation);
}
// Show the text
if (text != null && textEntity == null) {
textEntity = NMSHandlers.getHandler().spawnDisplayEntity(user.getPlayer().getLocation().add(0, 3, 0), text);
}
} catch (Exception e) {
e.printStackTrace();
}
@@ -56,11 +71,24 @@ public class UserEmoteManager {
}
// Internal
model.stopAnimation();
if (textEntity != null) {
textEntity.remove();
textEntity = null;
}
}
public void despawnTextEntity() {
if (textEntity != null) {
textEntity.remove();
textEntity = null;
}
}
public enum StopEmoteReason {
SNEAK,
DAMAGE,
CONNECTION
CONNECTION,
TELEPORT,
UNEQUIP
}
}

View File

@@ -36,9 +36,6 @@ public class UserEmoteModel extends PlayerModel {
@Override
public void playAnimation(@NotNull String id) {
if (id.contains(":")) id = id.split(":", 2)[1]; // A:B -> B -> B.B.B
if (!id.contains(".")) id = id + "." + id + "." + id; // Make into a format that playerAnimator works with. Requires 3 splits.
super.playAnimation(id);
emotePlaying = id;
@@ -47,9 +44,9 @@ public class UserEmoteModel extends PlayerModel {
Player player = user.getPlayer();
List<Player> viewer = Collections.singletonList(user.getPlayer());
List<Player> outsideViewers = PacketManager.getViewers(player.getLocation());
outsideViewers.remove(player);
// Send equipment packet to the player as well (Fixes Optifine still rendering armor when emoting)
PacketManager.equipmentSlotUpdate(player, true, outsideViewers);
outsideViewers.remove(player);
Location newLocation = player.getLocation().clone();
newLocation.setPitch(0);
@@ -57,11 +54,21 @@ public class UserEmoteModel extends PlayerModel {
double DISTANCE = Settings.getEmoteDistance();
Location thirdPersonLocation = newLocation.add(newLocation.getDirection().normalize().multiply(DISTANCE));
if (DISTANCE > 0) {
MessagesUtil.sendDebugMessages("Yaw " + (int) thirdPersonLocation.getYaw());
MessagesUtil.sendDebugMessages("New Yaw " + ServerUtils.getNextYaw((int) thirdPersonLocation.getYaw(), 180));
thirdPersonLocation.setYaw(ServerUtils.getNextYaw((int) thirdPersonLocation.getYaw(), 180));
}
if (Settings.getCosmeticEmoteBlockCheck() && thirdPersonLocation.getBlock().getType().isOccluding()) {
stopAnimation();
MessagesUtil.sendMessage(player, "emote-blocked");
return;
}
// Check if block below player is an air block
if (Settings.getEmoteAirCheck() && newLocation.clone().subtract(0, 1, 0).getBlock().getType().isAir()) {
stopAnimation();
MessagesUtil.sendMessage(player, "emote-blocked");
}
user.getPlayer().setInvisible(true);
user.hideCosmetics(CosmeticUser.HiddenReason.EMOTE);
@@ -70,7 +77,7 @@ public class UserEmoteModel extends PlayerModel {
PacketManager.sendEntitySpawnPacket(thirdPersonLocation, armorStandId, EntityType.ARMOR_STAND, UUID.randomUUID(), viewer);
PacketManager.sendInvisibilityPacket(armorStandId, viewer);
PacketManager.sendLookPacket(armorStandId, player.getLocation(), viewer);
PacketManager.sendLookPacket(armorStandId, thirdPersonLocation, viewer);
PacketManager.gamemodeChangePacket(player, 3);
PacketManager.sendCameraPacket(armorStandId, viewer);
@@ -100,6 +107,8 @@ public class UserEmoteModel extends PlayerModel {
List<Player> viewer = Collections.singletonList(player);
List<Player> outsideViewers = PacketManager.getViewers(player.getLocation());
// Send Equipment packet to all (Fixes Optifine Issue)
PacketManager.equipmentSlotUpdate(player, false, outsideViewers);
outsideViewers.remove(player);
int entityId = player.getEntityId();
@@ -111,7 +120,7 @@ public class UserEmoteModel extends PlayerModel {
}
if (user.getPlayer() != null) player.setInvisible(false);
PacketManager.equipmentSlotUpdate(player, false, outsideViewers);
user.getUserEmoteManager().despawnTextEntity();
user.showPlayer();
user.showCosmetics();
});

View File

@@ -2,6 +2,8 @@ package com.hibiscusmc.hmccosmetics.user.manager;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.config.WardrobeLocation;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
@@ -38,6 +40,8 @@ public class UserWardrobeManager {
private String npcName;
private GameMode originalGamemode;
private final CosmeticUser user;
private final Wardrobe wardrobe;
private final WardrobeLocation wardrobeLocation;
private final Location viewingLocation;
private final Location npcLocation;
private Location exitLocation;
@@ -45,15 +49,18 @@ public class UserWardrobeManager {
private boolean active;
private WardrobeStatus wardrobeStatus;
public UserWardrobeManager(CosmeticUser user, Location exitLocation, Location viewingLocation, Location npcLocation) {
public UserWardrobeManager(CosmeticUser user, Wardrobe wardrobe) {
NPC_ID = NMSHandlers.getHandler().getNextEntityId();
ARMORSTAND_ID = NMSHandlers.getHandler().getNextEntityId();
WARDROBE_UUID = UUID.randomUUID();
this.user = user;
this.exitLocation = exitLocation;
this.viewingLocation = viewingLocation;
this.npcLocation = npcLocation;
this.wardrobe = wardrobe;
this.wardrobeLocation = wardrobe.getLocation();
this.exitLocation = wardrobeLocation.getLeaveLocation();
this.viewingLocation = wardrobeLocation.getViewerLocation();
this.npcLocation = wardrobeLocation.getNpcLocation();
wardrobeStatus = WardrobeStatus.SETUP;
}
@@ -109,12 +116,13 @@ public class UserWardrobeManager {
}
if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
PacketManager.sendLeashPacket(user.getBalloonManager().getPufferfishBalloonId(), -1, viewer);
PacketManager.sendLeashPacket(user.getBalloonManager().getPufferfishBalloonId(), NPC_ID, viewer); // This needs a possible fix
user.getBalloonManager().sendRemoveLeashPacket(viewer);
user.getBalloonManager().sendLeashPacket(NPC_ID);
//PacketManager.sendLeashPacket(VIEWER.getBalloonEntity().getModelId(), NPC_ID, viewer);
PacketManager.sendTeleportPacket(user.getBalloonManager().getPufferfishBalloonId(), npcLocation.clone().add(Settings.getBalloonOffset()), false, viewer);
user.getBalloonManager().getModelEntity().teleport(npcLocation.clone().add(Settings.getBalloonOffset()));
Location balloonLocation = npcLocation.clone().add(Settings.getBalloonOffset());
PacketManager.sendTeleportPacket(user.getBalloonManager().getPufferfishBalloonId(), balloonLocation , false, viewer);
user.getBalloonManager().getModelEntity().teleport(balloonLocation);
}
if (WardrobeSettings.getEnabledBossbar()) {
@@ -156,25 +164,41 @@ public class UserWardrobeManager {
List<Player> outsideViewers = PacketManager.getViewers(viewingLocation);
outsideViewers.remove(player);
MessagesUtil.sendMessage(player, "closed-wardrobe");
if (player != null) MessagesUtil.sendMessage(player, "closed-wardrobe");
Runnable run = () -> {
this.active = false;
// For Wardrobe Temp Cosmetics
for (Cosmetic cosmetic : user.getCosmetics()) {
MessagesUtil.sendDebugMessages("Checking... " + cosmetic.getId());
if (!user.canEquipCosmetic(cosmetic)) {
MessagesUtil.sendDebugMessages("Unable to keep " + cosmetic.getId());
user.removeCosmeticSlot(cosmetic.getSlot());
}
}
// NPC
if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) PacketManager.sendLeashPacket(user.getBalloonManager().getModelId(), -1, viewer);
if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) user.getBalloonManager().sendRemoveLeashPacket();
PacketManager.sendEntityDestroyPacket(NPC_ID, viewer); // Success
PacketManager.sendRemovePlayerPacket(player, WARDROBE_UUID, viewer); // Success
// Player
PacketManager.sendCameraPacket(player.getEntityId(), viewer);
PacketManager.gamemodeChangePacket(player, ServerUtils.convertGamemode(this.originalGamemode)); // Success
// Armorstand
PacketManager.sendEntityDestroyPacket(ARMORSTAND_ID, viewer); // Sucess
//PacketManager.sendEntityDestroyPacket(player.getEntityId(), viewer); // Success
player.setGameMode(this.originalGamemode);
if (WardrobeSettings.isForceExitGamemode()) {
MessagesUtil.sendDebugMessages("Force Exit Gamemode " + WardrobeSettings.getExitGamemode());
player.setGameMode(WardrobeSettings.getExitGamemode());
PacketManager.gamemodeChangePacket(player, ServerUtils.convertGamemode(WardrobeSettings.getExitGamemode())); // Success
} else {
MessagesUtil.sendDebugMessages("Original Gamemode " + this.originalGamemode);
player.setGameMode(this.originalGamemode);
PacketManager.gamemodeChangePacket(player, ServerUtils.convertGamemode(this.originalGamemode)); // Success
}
user.showPlayer();
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
@@ -199,13 +223,6 @@ public class UserWardrobeManager {
target.hideBossBar(bossBar);
}
// For Wardrobe Temp Cosmetics
for (Cosmetic cosmetic : user.getCosmetic()) {
if (cosmetic.requiresPermission()) {
if (!player.hasPermission(cosmetic.getPermission())) user.removeCosmeticSlot(cosmetic.getSlot());
}
}
user.updateCosmetic();
};
run.run();
@@ -219,16 +236,16 @@ public class UserWardrobeManager {
public void run() {
Player player = user.getPlayer();
if (!active || player == null) {
MessagesUtil.sendDebugMessages("Active is false");
MessagesUtil.sendDebugMessages("WardrobeEnd[user=" + user.getUniqueId() + ",reason=Active is false]");
this.cancel();
return;
}
MessagesUtil.sendDebugMessages("Update ");
MessagesUtil.sendDebugMessages("WardrobeUpdate[user=" + user.getUniqueId() + ",status=" + getWardrobeStatus() + "]");
List<Player> viewer = Collections.singletonList(player);
List<Player> outsideViewers = PacketManager.getViewers(viewingLocation);
outsideViewers.remove(player);
Location location = WardrobeSettings.getWardrobeLocation().clone();
Location location = npcLocation;
int yaw = data.get();
location.setYaw(yaw);
@@ -252,11 +269,12 @@ public class UserWardrobeManager {
}
if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
PacketManager.sendTeleportPacket(user.getBalloonManager().getPufferfishBalloonId(), WardrobeSettings.getWardrobeLocation().add(Settings.getBalloonOffset()), false, viewer);
user.getBalloonManager().getModelEntity().teleport(WardrobeSettings.getWardrobeLocation().add(Settings.getBalloonOffset()));
PacketManager.sendLeashPacket(user.getBalloonManager().getPufferfishBalloonId(), -1, outsideViewers);
// The two lines below broke, solved by listening to PlayerCosmeticPostEquipEvent
//PacketManager.sendTeleportPacket(user.getBalloonManager().getPufferfishBalloonId(), npcLocation.add(Settings.getBalloonOffset()), false, viewer);
//user.getBalloonManager().getModelEntity().teleport(npcLocation.add(Settings.getBalloonOffset()));
user.getBalloonManager().sendRemoveLeashPacket(outsideViewers);
PacketManager.sendEntityDestroyPacket(user.getBalloonManager().getModelId(), outsideViewers);
PacketManager.sendLeashPacket(user.getBalloonManager().getPufferfishBalloonId(), NPC_ID, viewer); // Pufferfish goes away for some reason?
user.getBalloonManager().sendLeashPacket(NPC_ID);
}
if (WardrobeSettings.isEquipPumpkin()) {
@@ -286,4 +304,8 @@ public class UserWardrobeManager {
RUNNING,
STOPPING,
}
public Location getNpcLocation() {
return npcLocation;
}
}

View File

@@ -1,8 +1,12 @@
package com.hibiscusmc.hmccosmetics.util;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -137,4 +141,27 @@ public class InventoryUtils {
}
}
}
public static boolean isCosmeticItem(ItemStack itemStack) {
if (itemStack == null) return false;
itemStack = itemStack.clone();
if (!itemStack.hasItemMeta()) return false;
return itemStack.getItemMeta().getPersistentDataContainer().has(getCosmeticKey(), PersistentDataType.STRING);
}
public static NamespacedKey getCosmeticKey() {
return new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "cosmetic");
}
public static NamespacedKey getOwnerKey() {
return new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "owner");
}
public static NamespacedKey getSkullOwner() {
return new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "skullowner");
}
public static NamespacedKey getSkullTexture() {
return new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "skulltexture");
}
}

View File

@@ -0,0 +1,20 @@
package com.hibiscusmc.hmccosmetics.util;
public class TranslationPair {
private String key;
private String value;
public TranslationPair(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
}

View File

@@ -2,38 +2,37 @@ package com.hibiscusmc.hmccosmetics.util;
import org.spongepowered.configurate.ConfigurationNode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class TranslationUtil {
private static HashMap<String, String> keys = new HashMap<>();
// unlocked-cosmetic -> true -> True
private static HashMap<String, List<TranslationPair>> keys = new HashMap<>();
public static void setup(ConfigurationNode config) {
// TODO: Finish this
/*
for (ConfigurationNode node : config.childrenMap().values()) {
HashMap<Pair> translableMessages = new HashMap<>();
ArrayList<TranslationPair> pairs = new ArrayList<>();
for (ConfigurationNode translatableMessage : node.childrenMap().values()) {
translableMessages.put( new Pair<>(translatableMessage.key().toString(), translatableMessage.getString()))
String key = translatableMessage.key().toString();
key.replaceAll("'", ""); // Autoupdater adds ' to it? Removes it from the key
TranslationPair pair = new TranslationPair(key, translatableMessage.getString());
pairs.add(pair);
MessagesUtil.sendDebugMessages("setupTranslation key:" + node.key().toString() + " | " + node);
MessagesUtil.sendDebugMessages("Overall Key " + node.key().toString());
MessagesUtil.sendDebugMessages("Key '" + pair.getKey() + "' Value '" + pair.getValue() + "'");
}
keys.put(node.key().toString().toLowerCase(), HashMap);
keys.put(node.key().toString().toLowerCase(), pairs);
}
*/
}
public static String getTranslation(String key, String message) {
// TODO: Finish this
return message;
/*
key = key.toLowerCase();
MessagesUtil.sendDebugMessages("getTranslation key:" + key + " | " + message);
if (!keys.containsKey(key)) return message;
List<Pair> config = keys.get(key);
if (config.getFirst() == message) {
return config.getSecond().toString();
List<TranslationPair> pairs = keys.get(key);
for (TranslationPair pair : pairs) {
if (pair.getKey() == message) return pair.getValue();
}
return message;
*/
}
}

View File

@@ -7,6 +7,7 @@ import org.bukkit.entity.Player;
public class BasePacket {
public static void sendPacket(Player player, PacketContainer packet) {
if (player == null) return;
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false);
}
}

View File

@@ -135,7 +135,8 @@ public class PacketManager extends BasePacket {
packet.getModifier().writeDefaults();
packet.getIntegers().write(0, entityId);
WrappedDataWatcher wrapper = new WrappedDataWatcher();
if (!NMSHandlers.getVersion().contains("v1_19_R2")) {
if (NMSHandlers.getVersion().contains("v1_18_R2") || NMSHandlers.getVersion().contains("v1_19_R1")) {
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x20);
packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects());
} else {
@@ -305,8 +306,14 @@ public class PacketManager extends BasePacket {
WrappedGameProfile wrappedGameProfile = new WrappedGameProfile(uuid, name);
WrappedSignedProperty skinData = PlayerUtils.getSkin(skinnedPlayer);
if (skinData != null) wrappedGameProfile.getProperties().put("textures", skinData);
if (!NMSHandlers.getVersion().contains("v1_19_R2")) {
info.setData(List.of(new PlayerInfoData(wrappedGameProfile, 0, EnumWrappers.NativeGameMode.CREATIVE, WrappedChatComponent.fromText(name))));
// For sor some reason <1.19.2 handles it on the 0 field index, newer versions handles it on the 1
if (NMSHandlers.getVersion().contains("v1_18_R2") || NMSHandlers.getVersion().contains("v1_19_R1")) {
info.getHandle().getPlayerInfoDataLists().write(0, Collections.singletonList(new PlayerInfoData(
wrappedGameProfile,
0,
EnumWrappers.NativeGameMode.CREATIVE,
WrappedChatComponent.fromText(name)
)));
} else {
info.getHandle().getPlayerInfoDataLists().write(1, Collections.singletonList(new PlayerInfoData(
wrappedGameProfile,
@@ -316,8 +323,6 @@ public class PacketManager extends BasePacket {
)));
}
for (final Player p : sendTo) sendPacket(p, info.getHandle());
return;
}
/**
@@ -364,7 +369,7 @@ public class PacketManager extends BasePacket {
final UUID uuid,
final List<Player> sendTo
) {
if (!NMSHandlers.getVersion().contains("v1_19_R2")) {
if (NMSHandlers.getVersion().contains("v1_18_R2") || NMSHandlers.getVersion().contains("v1_19_R1")) {
WrapperPlayServerPlayerInfo info = new WrapperPlayServerPlayerInfo();
info.setAction(EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
@@ -377,6 +382,7 @@ public class PacketManager extends BasePacket {
for (final Player p : sendTo) sendPacket(p, info.getHandle());
return;
}
PacketContainer packet = new PacketContainer(PacketType.Play.Server.PLAYER_INFO_REMOVE);
packet.getUUIDLists().write(0, List.of(uuid));
for (final Player p : sendTo) sendPacket(p, packet);

View File

@@ -26,11 +26,12 @@ public class WrapperPlayServerPlayerInfo extends AbstractPacket {
}
public void setAction(PlayerInfoAction value) {
if (!NMSHandlers.getVersion().contains("v1_19_R2")) {
if (NMSHandlers.getVersion().contains("v1_17_R1") || NMSHandlers.getVersion().contains("v1_18_R2") || NMSHandlers.getVersion().contains("v1_19_R1")) {
handle.getPlayerInfoAction().write(0, value);
} else {
handle.getPlayerInfoActions().write(0, Set.of(value));
return;
}
// New way of handling it 1.19.3+
handle.getPlayerInfoActions().write(0, Set.of(value));
}
public List<PlayerInfoData> getData() {

View File

@@ -25,6 +25,7 @@ cosmetic-settings:
emote-distance: -3 # This shows how far away the camera should be while a player is doing an emote. Negative is behind player.
emote-block-check: true # If the server should check if the block is open where the camera is placed (prevents players viewing through blocks)
emote-air-check: true # Check if there is air under a player, if there is, don't play emote
emote-damage-leave: true # If the player should leave the emote when they take damage
emote-invincible: false # If the player should not take damage while doing an emote
@@ -33,6 +34,10 @@ cosmetic-settings:
leggings-add-enchantments: false # If the plugin should keep enchants on leggings. This is useful as some enchantments are client side only.
boots-add-enchantments: false # If the plugin should keep enchants on boots. This is useful as some enchantments are client side only.
# This attempts to destroy cosmetics that get loose in the wild, such as through a player entering creative mode.
# Most servers who don't use creative mode and have properly set up the plugin should have no need for this and can leave it disabled.
destroy-loose-cosmetics: false
# view distance in blocks that other players will see the backpack cosmetic
# setting this to lower than the server player view distance should fix the
# bug where players see random backpacks. Put -1 to ignore and send packets to everyone.
@@ -53,6 +58,10 @@ hook-settings:
# This causes the plugin to reload itself after any ItemsAdder change. This keeps the plugin fully up to date with IA, but
# could cause console spam as HMCCosmetics has to reload itself as well.
reload-on-change: false
worldguard:
# Checks worldguard regions for HMCC flags. If set to false, flags will not work properly.
# Requires restart to apply changes.
player-move-check: true
wardrobe:
# spawn static wardrobe if in this radius of wardrobe-location
static-radius: 10
@@ -62,6 +71,13 @@ wardrobe:
equip-pumpkin: false
# Rather than having a set exit location, this will send the player back to where they entered the wardrobe. Not recommended for WG regions
return-last-location: false
# If players in wardrobes should be able to equip any cosmetic, regardless of permission (Cosmetics they do not have access to will be removed when they leave the wardrobe)
unchecked-wardrobe-cosmetics: false
gamemode-options:
exit-gamemode-enabled: false # Setting this to false will set the gamemode the player came in as. True sets to exit-gamemode gamemode
exit-gamemode: "SURVIVAL" # Only activates if exit-gamemode-enabled is true, find gamemodes here: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/GameMode.html
# Bossbar that shows when a player is in a wardrobe.
bossbar:
enabled: false
@@ -71,29 +87,33 @@ wardrobe:
color: BLUE
transition:
enabled: true
# If you use ItemsAdder, set this to "<black>%img_title%
# If you use Oraxen, set this to "<black><glyph:title>"
text: "<black>"
delay: 40
title-fade-in: 1000 # milliseconds
title-stay: 500 # milliseconds
title-fade-out: 1000 # milliseconds
wardrobe-location:
world: "World"
x: 0
y: 0
z: 0
yaw: 0
pitch: 0
viewer-location:
world: "World"
x: 5
y: 0
z: 5
yaw: 0
pitch: 0
leave-location:
world: "World"
x: 5
y: 5
z: 5
yaw: 0
pitch: 0
wardrobes:
default:
npc-location:
world: "world"
x: 0
y: 0
z: 0
yaw: 0
pitch: 0
viewer-location:
world: "world"
x: 5
y: 0
z: 5
yaw: 0
pitch: 0
leave-location:
world: "world"
x: 5
y: 5
z: 5
yaw: 0
pitch: 0

View File

@@ -110,4 +110,22 @@ explorer_backpack:
material: LEATHER_HORSE_ARMOR
model-data: 3
name: "<white>Explorer's Backpack"
amount: 1
garbage_truck_balloon:
slot: BALLOON
permission: "hmccosmetics.garbage_truck_balloon"
model: garbage_truck_balloon
item:
material: PAPER
model-data: 14
name: "<green>Garbage Truck Balloon"
amount: 1
earth_day_grabber:
slot: OFFHAND
dyeable: true
permission: "hmccosmetics.earth_day_grabber"
item:
material: LEATHER_HORSE_ARMOR
model-data: 4
name: "<green>Earth Day Grabber"
amount: 1

View File

@@ -167,4 +167,26 @@ items:
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_explorer_backpack%"
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_explorer_backpack%"
type: cosmetic
cosmetic: explorer_backpack
cosmetic: explorer_backpack
garbage_truck_balloon:
slots:
- 16
item:
material: hmccosmetics:garbage_truck_balloon
lore:
- ""
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_garbage_truck_balloon%"
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_garbage_truck_balloon%"
type: cosmetic
cosmetic: garbage_truck_balloon
earth_day_grabber:
slots:
- 17
item:
material: hmccosmetics:earth_day_grabber
lore:
- ""
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_earth_day_grabber%"
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_earth_day_grabber%"
type: cosmetic
cosmetic: earth_day_grabber

View File

@@ -11,6 +11,10 @@ not-near-wardrobe: "%prefix% <red>You are not near the wardrobe!"
set-wardrobe-location: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe location!"
set-wardrobe-viewing: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe viewing location!"
set-wardrobe-leaving: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe leaving location!"
set-wardrobe-permission: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe permission!"
set-wardrobe-distance: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe distance!"
no-wardrobes: "%prefix% <red>There are no wardrobes with that name!"
wardrobe-not-setup: "%prefix% <red>This wardrobe does not have all required locations set!"
equip-cosmetic: "%prefix% <gradient:#6D9DC5:#45CDE9>You have equipped <cosmetic>!"
unequip-cosmetic: "%prefix% <gradient:#6D9DC5:#45CDE9>You have unequipped <cosmetic>!"

View File

@@ -1,3 +1,15 @@
unlockedCosmetic:
true: "True"
false: "false"
unlocked-cosmetic:
true: "true"
false: "false"
equipped-cosmetic:
true: "true"
false: "false"
in-wardrobe:
true: "true"
false: "false"
using-cosmetic:
true: "true"
false: "false"
current-cosmetic:
true: "true"
false: "false"

View File

@@ -8,8 +8,9 @@ pluginManagement {
rootProject.name = "HMCCosmetics"
include(
"common",
"v1_17_R1",
"v1_18_R2",
"v1_19_R1",
"v1_19_R2"
"v1_19_R2",
"v1_19_R3",
"v1_20_R1",
)

View File

@@ -1,31 +0,0 @@
package com.hibiscusmc.hmccosmetics.nms.v1_17_R1;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.decoration.ArmorStand;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
import org.bukkit.persistence.PersistentDataType;
public class MEGEntity extends ArmorStand {
public MEGEntity(Location loc) {
super(EntityType.ARMOR_STAND, ((CraftWorld) loc.getWorld()).getHandle());
this.setPos(loc.getX(), loc.getY(), loc.getZ());
MessagesUtil.sendDebugMessages("Spawned MEGEntity at " + loc);
setInvisible(true);
setNoGravity(true);
setSilent(true);
setInvulnerable(true);
setSmall(true);
setMarker(true);
persist = false;
getBukkitEntity().getPersistentDataContainer().set(new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "cosmeticMob"), PersistentDataType.SHORT, Short.valueOf("1"));
((CraftWorld) loc.getWorld()).getHandle().addFreshEntity(this);
}
}

View File

@@ -13,6 +13,7 @@ import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.PlayerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager;
import com.mojang.datafixers.util.Pair;
import net.kyori.adventure.text.Component;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
@@ -99,6 +100,12 @@ public class NMSHandler implements com.hibiscusmc.hmccosmetics.nms.NMSHandler {
}
@Override
public org.bukkit.entity.Entity spawnDisplayEntity(Location location, String text) {
return null;
}
@Override
@@ -115,7 +122,7 @@ public class NMSHandler implements com.hibiscusmc.hmccosmetics.nms.NMSHandler {
PacketManager.sendEntitySpawnPacket(newLoc, userBalloonManager1.getPufferfishBalloonId(), EntityType.PUFFERFISH, userBalloonManager1.getPufferfishBalloonUniqueId(), sentTo);
PacketManager.sendInvisibilityPacket(userBalloonManager1.getPufferfishBalloonId(), sentTo);
PacketManager.sendLeashPacket(userBalloonManager1.getPufferfishBalloonId(), player.getEntityId(), sentTo);
userBalloonManager1.sendLeashPacket(player.getEntityId());
return userBalloonManager1;
}

View File

@@ -13,6 +13,7 @@ import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.PlayerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager;
import com.mojang.datafixers.util.Pair;
import net.kyori.adventure.text.Component;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
@@ -99,6 +100,12 @@ public class NMSHandler implements com.hibiscusmc.hmccosmetics.nms.NMSHandler {
}
@Override
public org.bukkit.entity.Entity spawnDisplayEntity(Location location, String text) {
return null;
}
@Override
@@ -115,7 +122,7 @@ public class NMSHandler implements com.hibiscusmc.hmccosmetics.nms.NMSHandler {
PacketManager.sendEntitySpawnPacket(newLoc, userBalloonManager1.getPufferfishBalloonId(), EntityType.PUFFERFISH, userBalloonManager1.getPufferfishBalloonUniqueId(), sentTo);
PacketManager.sendInvisibilityPacket(userBalloonManager1.getPufferfishBalloonId(), sentTo);
PacketManager.sendLeashPacket(userBalloonManager1.getPufferfishBalloonId(), player.getEntityId(), sentTo);
userBalloonManager1.sendLeashPacket(player.getEntityId());
return userBalloonManager1;
}

View File

@@ -13,6 +13,7 @@ import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.PlayerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager;
import com.mojang.datafixers.util.Pair;
import net.kyori.adventure.text.Component;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
@@ -99,6 +100,11 @@ public class NMSHandler implements com.hibiscusmc.hmccosmetics.nms.NMSHandler {
}
@Override
public org.bukkit.entity.Entity spawnDisplayEntity(Location location, String text) {
return null;
}
@Override
@@ -115,7 +121,7 @@ public class NMSHandler implements com.hibiscusmc.hmccosmetics.nms.NMSHandler {
PacketManager.sendEntitySpawnPacket(newLoc, userBalloonManager1.getPufferfishBalloonId(), EntityType.PUFFERFISH, userBalloonManager1.getPufferfishBalloonUniqueId(), sentTo);
PacketManager.sendInvisibilityPacket(userBalloonManager1.getPufferfishBalloonId(), sentTo);
PacketManager.sendLeashPacket(userBalloonManager1.getPufferfishBalloonId(), player.getEntityId(), sentTo);
userBalloonManager1.sendLeashPacket(player.getEntityId());
return userBalloonManager1;
}

View File

@@ -4,7 +4,7 @@ plugins {
}
dependencies {
paperDevBundle("1.17.1-R0.1-SNAPSHOT")
paperDevBundle("1.19.4-R0.1-SNAPSHOT")
implementation(project(":common"))
}

Some files were not shown because too many files have changed in this diff Show More