9
0
mirror of https://github.com/HibiscusMC/HMCCosmetics.git synced 2025-12-22 08:29:27 +00:00

Compare commits

..

349 Commits

Author SHA1 Message Date
LoJoSho
442cddb81e version bump (2.7.0) 2024-01-12 11:45:03 -06:00
Boy
1f38d1aa46 chore: bump hmccolor 2024-01-10 01:52:27 +01:00
LoJoSho
ce7dc03350 fix: player dying causing NPE 2024-01-06 11:09:21 -06:00
LoJoSho
9a75fcb55b fix: check if player is still online after join delay 2024-01-05 13:36:12 -06:00
LoJoSho
5522eed2d1 fix: pose changes in wardrobe causes backpack being unattached 2024-01-03 12:38:17 -06:00
LoJoSho
1737330b87 feat: balloons now disappear when hidden 2024-01-02 21:10:38 -06:00
LoJoSho
eff25664f3 clean: move gamemode and world hidden checks to player join 2024-01-02 21:10:06 -06:00
LoJoSho
27d3a1df42 feat: add disabled worlds option 2024-01-02 20:45:18 -06:00
LoJoSho
63bda02869 fix: hidden backpacks still having armorstands spawned 2024-01-02 20:34:25 -06:00
LoJoSho
8c251a8c69 clean: add debug messages for respawning of cosmetics 2024-01-02 11:10:36 -06:00
LoJoSho
4b481ef3ea clean: refactor overlapping Hibiscus Commons util class names 2023-12-29 12:19:00 -06:00
LoJoSho
2d62c96d3d Merge pull request #129 from HibiscusMC/hibiscuscommons
Refactor to Hibiscus Commons Library (2.7.0)
2023-12-29 12:13:49 -06:00
LoJoSho
f8cb436c5b fix: handle IA reloading 2023-12-28 20:49:23 -06:00
LoJoSho
0de31fcd04 chore: update hibiscus commons to 0.2.1 2023-12-28 19:07:59 -06:00
LoJoSho
99edb501a5 fix: itemsadder reload 2023-12-28 19:07:46 -06:00
LoJoSho
66aaed009f fix: players being invisible if disconnect in wardrobe 2023-12-27 10:54:08 -06:00
LoJoSho
4c0b86b127 chore: updates adventure platform to 4.3.2 2023-12-27 10:22:52 -06:00
LoJoSho
155133a2a0 fix: players opening menu in setup phase of wardrobes 2023-12-27 09:50:58 -06:00
LoJoSho
93062d47a8 fix: cosmetic armor happening in wardrobe 2023-12-27 09:46:59 -06:00
LoJoSho
1f0c67a805 clean: remove cmi jars 2023-12-24 21:30:27 -06:00
LoJoSho
74feb112f6 feat: remove nms in HMCC, update to support Hibiscus Commons 0.1.8 2023-12-23 12:37:20 -06:00
LoJoSho
967349f5af version bump (2.7.0-DEV) 2023-12-23 12:01:31 -06:00
LoJoSho
d7fe2475ed Merge branch 'remapped' into hibiscuscommons 2023-12-23 11:58:46 -06:00
Boy
f87bf93641 fix: check instance instead of id for shading 2023-12-23 18:56:17 +01:00
LoJoSho
4b467b4644 fix: check instance instead of id for shading 2023-12-23 11:54:20 -06:00
LoJoSho
15234a904f clean: remove barely used text emote feature 2023-12-22 22:09:22 -06:00
LoJoSho
9ff6d3f60c feat: balloon entities entirely through bukkit 2023-12-22 22:05:09 -06:00
LoJoSho
aeba867e9e chore: update adventure classes 2023-12-22 21:57:30 -06:00
LoJoSho
d21e148f39 chore: update HibiscusCommons to 0.1.7 2023-12-22 21:50:47 -06:00
LoJoSho
51188fdeba feat: move to Hibiscus Commmons library 2023-12-22 21:25:50 -06:00
LoJoSho
dcf072f3de fix: balloons and backpacks being respawned while in wardrobe 2023-12-20 15:38:32 -06:00
LoJoSho
ebf09d8e0f fix: check if user is still in wardrobe before spawning npc 2023-12-20 15:38:02 -06:00
LoJoSho
ca5cb25331 clean: move configurate back to being shaded 2023-12-20 14:02:58 -06:00
LoJoSho
65877bff5b clean: move nms spawn balloon method to CosmeticUser 2023-12-19 19:55:57 -06:00
LoJoSho
4a75c7b333 Merge remote-tracking branch 'origin/remapped' into remapped 2023-12-19 19:48:02 -06:00
Boy
be4f1d6675 chore: add TypeCosmetic-initializer with id-argument for extending class 2023-12-20 02:47:33 +01:00
LoJoSho
55d4f9ae09 clean: move private bulkUpdate method to updateCosmetic since it was just using that method anyways 2023-12-19 19:28:06 -06:00
LoJoSho
88691956ba fix: locked-item not appearing in wardrobes with unchecked cosmetics 2023-12-19 18:39:54 -06:00
LoJoSho
a6133a2b45 clean: remove triumph gui from library loader (was used for testing in last build) 2023-12-19 18:00:15 -06:00
LoJoSho
0aa821e51a feat: move adventure and configurate to Spigots library loader 2023-12-19 15:17:41 -06:00
LoJoSho
fb37ea8af9 clean: removed unused relocations 2023-12-19 14:49:15 -06:00
LoJoSho
0f36803026 feat: add PlayerArmorChangeEvent for Paper servers 2023-12-18 19:40:28 -06:00
LoJoSho
2910540c26 fix: enchants not being passed to cosmetics 2023-12-18 19:23:53 -06:00
LoJoSho
93fb885195 fix: further wardrobe armor fixes for Optifine clients 2023-12-18 19:04:25 -06:00
LoJoSho
2438d5385f clean: add eco as soft depend 2023-12-18 14:51:14 -06:00
LoJoSho
73ce071427 feat: add HookFlags to hooks 2023-12-18 13:35:40 -06:00
LoJoSho
e3485b7733 fix: forgot to reverse order when condensing the method 2023-12-18 13:20:02 -06:00
LoJoSho
7ff4fbb3d7 feat: add support for Eco item lookup system 2023-12-18 13:19:43 -06:00
LoJoSho
de5b9be6ac fix: server-side teleporation causing players to be stuck in wardrobe area 2023-12-18 12:52:35 -06:00
LoJoSho
0c6e8eb160 fix: bad clients failing to removing player model in wardrobe 2023-12-18 12:52:07 -06:00
LoJoSho
9b85fd2d8c feat: player teleport when entering wardrobe, allows better support for long distance wardrobes 2023-12-17 22:41:12 -06:00
LoJoSho
a136b95451 clean: remove deperecated #getCosmetic 2023-12-17 11:24:31 -06:00
LoJoSho
cf5eb64029 feat: priority system for menus 2023-12-16 18:30:58 -06:00
LoJoSho
c4591b030b feat: reduced packets for armor cosmetics 2023-12-16 16:13:52 -06:00
LoJoSho
9dc6eb1dfc version bump (2.6.7-DEV) 2023-12-16 09:52:27 -06:00
LoJoSho
d7c1bf39e2 version bump (2.6.6) 2023-12-16 09:49:40 -06:00
LoJoSho
ae1527fca3 feat: add 1.20.3/4 nms support 2023-12-10 13:02:04 -06:00
LoJoSho
d14698b282 clean: get static context correctly in main plugin class 2023-11-22 17:09:08 -06:00
LoJoSho
800d3be25f clean: removed formatArmorItemType method in StringUtils 2023-11-22 17:04:45 -06:00
LoJoSho
27599030cf clean: optimize imports 2023-11-22 16:59:49 -06:00
LoJoSho
3ee959abd6 feat: add HMCColor support in commands, resolves #114 2023-11-20 17:05:23 -06:00
LoJoSho
617df48cc2 feat: add amount placeholder, resolves #127 2023-11-20 16:09:52 -06:00
LoJoSho
9e290c2dfd version bump (2.6.6-DEV) 2023-11-20 16:07:49 -06:00
LoJoSho
f98614c4ee Merge remote-tracking branch 'origin/remapped' into remapped 2023-11-15 11:41:06 -06:00
LoJoSho
d28bb23f8c version bump (2.6.5) 2023-11-15 11:40:55 -06:00
Boy
502cb533f8 fix: drop runOnOrAfter for GearyHook 2023-11-05 01:05:38 +01:00
LoJoSho
b7fdc2087a fix: removed no longer needed entity id check on damage, caused conflicts with MythicMobs 2023-11-04 08:44:36 -05:00
LoJoSho
10a42a3c96 feat: papi placeholders now work for heads in menus 2023-10-29 14:01:28 -05:00
LoJoSho
51fc52e24b feat: add config option to disable cosmetics in certain gamemodes 2023-10-27 20:34:07 -05:00
LoJoSho
be632d8e8c fix: ME4 balloons not hiding for player 2023-10-27 19:50:34 -05:00
LoJoSho
a732a2b0a0 clean: remove hikari repo, set CommentedConfiguration to specific commit to fix Jitpack jank 2023-10-27 19:44:59 -05:00
Boy
b14a0b5d16 update geary-hook 2023-10-27 16:44:31 +02:00
LoJoSho
50393c62b0 fix: offhand cosmetics not checking if item is air 2023-10-26 13:38:48 -05:00
LoJoSho
dbc4a07895 fix: empty menu type not adding papi placeholders 2023-10-16 11:16:57 -05:00
LoJoSho
ab329e4fbf feat: define what offline and invalid player return in translations 2023-10-15 11:05:29 -05:00
LoJoSho
90ad700d0a feat: define no-cosmetic and none differently in translations 2023-10-15 10:41:45 -05:00
LoJoSho
56529d6111 Merge remote-tracking branch 'origin/remapped' into remapped 2023-10-15 10:32:29 -05:00
LoJoSho
b6a06007e8 Merge remote-tracking branch 'origin/remapped' into remapped 2023-10-15 10:31:54 -05:00
LoJoSho
edccc9ce4e fix: (last commit) forgot to reverse check 2023-10-15 10:28:54 -05:00
LoJoSho
e0b2f0f6b1 fix: improve nms version checker 2023-10-14 14:47:05 -05:00
LoJoSho
57f4d3703c fix: current placeholder returning null when no cosmetics are equipped 2023-10-13 11:47:14 -05:00
LoJoSho
8ef6692198 fix: emotes on lower versions not initializing 2023-10-13 10:41:39 -05:00
LoJoSho
c48830f3ac fix: move to configurate for full yml loading 2023-10-13 10:38:58 -05:00
LoJoSho
734c04c1f4 feat: me4 balloons working? 2023-10-11 21:46:17 -05:00
LoJoSho
b08b4019a9 clean: latest changes to try to get me4 working 2023-10-10 12:32:43 -05:00
LoJoSho
cfb7876b6e fix: player packet merged into entity packet in 1.20.2 2023-10-06 16:13:41 -05:00
LoJoSho
6047d0e3c3 clean: update me to 4.0.2 2023-10-06 15:20:59 -05:00
LoJoSho
880c333df9 Merge branch 'remapped' into me4 2023-10-06 14:56:16 -05:00
LoJoSho
c4d7b657dd feat: add option to disable emotes entirely 2023-10-06 12:44:59 -05:00
LoJoSho
5be3ce8d21 Merge remote-tracking branch 'origin/remapped' into remapped 2023-10-06 12:33:55 -05:00
LoJoSho
33bba631fc feat: model engine 4 2023-10-02 15:55:21 -05:00
LoJoSho
775b9c299d feat: basic 1.20.2 support 2023-09-24 10:59:24 -05:00
LoJoSho
6e02331c13 version bump (2.6.5-DEV) 2023-09-24 10:40:45 -05:00
LoJoSho
b7457cec9c Merge remote-tracking branch 'origin/remapped' into remapped 2023-09-15 16:40:21 -05:00
lucian929
e7288a1910 fixed config issues for vanilla rp config 2023-09-15 17:39:30 -04:00
LoJoSho
26b90bd8bb version bump (2.6.5-DEV) 2023-09-13 11:03:46 -05:00
LoJoSho
24a10b6838 version bump (2.6.4) 2023-09-13 10:58:04 -05:00
LoJoSho
af7bc0dc3f feat: add hmccosmetics and cosmetic aliases 2023-09-09 12:52:53 -05:00
LoJoSho
162d4a6ed6 fix: setting viewlocation now sets from eye level location 2023-09-09 12:34:53 -05:00
LoJoSho
41140f60c5 fix: distances referencing display radius when that no longer exists in config 2023-09-09 12:31:20 -05:00
LoJoSho
a6145a607c clean: move to integer parse 2023-09-09 11:38:52 -05:00
LoJoSho
89c6951a93 fix: getOfflinePlayer always returns a notnull object 2023-09-09 11:38:02 -05:00
LoJoSho
28c466e342 clean: remove old inheritance that no longer matters 2023-09-09 11:35:37 -05:00
LoJoSho
90caa23cd7 clean: remove unneeded if statements 2023-09-09 11:27:49 -05:00
LoJoSho
910f223151 Merge remote-tracking branch 'origin/remapped' into remapped 2023-09-01 18:11:51 -05:00
LoJoSho
ac1b50a957 clean: remove old removal passenger logic from PlayerQuitEvent 2023-08-31 18:29:59 -05:00
LoJoSho
9cb9bad3c8 fix: rework of equipment packet modification to be more vanilla-like 2023-08-30 22:10:25 -05:00
LoJoSho
f68e2633a2 version bump (2.6.4-DEV) 2023-08-30 11:50:54 -05:00
LoJoSho
c8ad5c0881 version bump (2.6.3) 2023-08-30 11:17:24 -05:00
LoJoSho
c93a718799 fix: check if item is null 2023-08-30 09:55:40 -05:00
LoJoSho
b5f781e00f fix: add wardrobe section to ignorable config updater 2023-08-29 21:48:46 -05:00
LoJoSho
f6cd73f436 clean: remove now unused NMS methods relating to backpacks 2023-08-29 21:37:43 -05:00
LoJoSho
8b0fcc5da9 fix: balloon pufferfish not properly being destroyed out of range 2023-08-29 17:41:35 -05:00
LoJoSho
b5787f22bf fix: add distance and permission to default config 2023-08-29 14:50:10 -05:00
LoJoSho
c1c431d914 fix: process PAPI placeholders on player command action 2023-08-28 21:36:06 -05:00
LoJoSho
b41dc66508 fix: hotbar visually messing up if player spun scrolled fast enough 2023-08-28 10:58:44 -05:00
LoJoSho
cfbf74257b feat: add offhand-always-show option 2023-08-27 20:59:56 -05:00
LoJoSho
9b2083b90a version bump (2.6.3-DEV) 2023-08-27 20:59:37 -05:00
LoJoSho
33437cd387 version bump (2.6.2) 2023-08-27 13:52:50 -05:00
LoJoSho
9f4e4616d4 fix: entity metadata being set incorrectly on 1.19.3+ 2023-08-27 13:44:48 -05:00
LoJoSho
01c62bc94e feat: add MMOItems hook 2023-08-27 13:31:59 -05:00
LoJoSho
3be4bdeb6f clean: optimize imports 2023-08-27 13:09:05 -05:00
LoJoSho
145aec9b7f feat: entity cooldown teleportation packet option 2023-08-27 12:44:53 -05:00
LoJoSho
4a2266bbfa clean: a bit of work on packet listeners 2023-08-27 11:51:25 -05:00
LoJoSho
7fa3cd6cb7 clean: removed unused NMS methods 2023-08-27 10:11:59 -05:00
LoJoSho
9c5fe9c426 fix: offhand cosmetic visually going into mainhand for other players when swapping 2023-08-26 14:31:02 -05:00
LoJoSho
0a9d750d3e clean: wardrobe javadocs and Lombok 2023-08-26 10:37:21 -05:00
LoJoSho
da996fb146 version bump (2.6.2-DEV) 2023-08-26 10:17:41 -05:00
LoJoSho
c051b267cf version bump (2.6.1) 2023-08-25 21:51:48 -05:00
LoJoSho
d1fc84b5bc fix: non-thirdperson backpacks interactable 2023-08-25 15:27:42 -05:00
LoJoSho
b47b9d8235 clean: remove deprecated methods relating to static radius distance 2023-08-24 18:48:31 -05:00
LoJoSho
edccc844c9 fix: remove static radius from default config, it's deprecated 2023-08-24 18:42:21 -05:00
LoJoSho
5788b2cce0 version bump (2.6.1-DEV) 2023-08-24 18:39:39 -05:00
LoJoSho
627ebafb79 chore: remove description saying it supports Vanilla and ItemsAdder 2023-08-24 12:16:47 -05:00
lucian929
ef3bf3fc19 remove itemsadder info for menu shading till it works 2023-08-24 13:07:59 -04:00
LoJoSho
97c02883b8 fix: check for empty hand for offhand listener 2023-08-23 12:42:36 -05:00
LoJoSho
ad516e80d1 feat: improve handling of removing armor cosmetic 2023-08-23 11:15:01 -05:00
LoJoSho
317ee261db feat: force backpack riding packets 2023-08-23 11:04:07 -05:00
LoJoSho
5f8fb642a4 fix: deprecated and removal of usage of equipmentSlotUpdate in NMSHandler 2023-08-22 23:29:12 -05:00
LoJoSho
7f4a1bc3f2 clean: supress deprecated in getUserCosmeticItem 2023-08-22 23:28:21 -05:00
LoJoSho
e2a727864e fix: unchecked cosmetics in wardrobe showing unlocked in PAPI, resolves #123 2023-08-22 09:50:23 -05:00
LoJoSho
c0014476fd fix: wardrobe not properly spawning in backpacks 2023-08-22 09:49:19 -05:00
LoJoSho
8ec6a87b94 version bump (2.6.0) 2023-08-21 18:59:34 -05:00
LoJoSho
97cf079b63 fix: invisibility wearing off while swimming with backpack equipped causing NPE 2023-08-21 18:59:21 -05:00
LoJoSho
82f13c349f feat: packet backpacks 2023-08-19 14:30:29 -05:00
LoJoSho
f91c174b20 fix: console command not sending from console 2023-08-19 12:27:20 -05:00
LoJoSho
3ae6a11626 feat: console command now processes placeholders 2023-08-19 12:25:58 -05:00
LoJoSho
f2fab91916 feat: add option to move in emote when out of camera mode 2023-08-18 10:01:19 -05:00
LoJoSho
55890fa4ac feat: add getNMSVersion and getHMCCVersion to the API 2023-08-17 12:38:23 -05:00
LoJoSho
fa2aa2c6dc fix: spawned invalid entity trying to respawn itself after spawning itself 2023-08-17 12:28:33 -05:00
LoJoSho
0b5f986cfc fix: offhand cosmetics flickering 2023-08-17 12:27:59 -05:00
LoJoSho
26361b833f fix: shades not working between empty columns 2023-08-16 13:39:03 -05:00
LoJoSho
28a37848c8 feat: added option to disable emoting third person camera 2023-08-16 12:22:41 -05:00
LoJoSho
7131a45d9c feat: per-balloon cosmetic offsets 2023-08-16 10:30:46 -05:00
LoJoSho
6d9325ed18 feat: add ability to define height of first person backpacks 2023-08-14 12:03:31 -05:00
LoJoSho
0640b33d50 fix: update HMCColor to .8 2023-08-14 11:46:08 -05:00
Boy
8b944b8e29 fix geary 2023-08-14 15:26:03 +02:00
LoJoSho
4481fa1c12 fix: not returning causing NPE in equipped cosmetic placeholder 2023-08-11 09:36:55 -05:00
LoJoSho
de133fa288 clean: bump oraxen to 1.160.0 2023-08-11 09:15:31 -05:00
LoJoSho
20da7797c9 fix: equipped cosmetic placeholder returning untranslated string when no cosmetics is in slot 2023-08-08 20:31:33 -05:00
LoJoSho
2aed727832 fix: first person backpacks not passing color 2023-08-07 10:40:03 -05:00
LoJoSho
b6731ba21a clean: minor stuff in data 2023-08-06 10:49:14 -05:00
LoJoSho
d333527664 clean: move data strings to StringBuilder 2023-08-06 10:41:05 -05:00
LoJoSho
a82bb8183b clean: data to lombok in Database 2023-08-06 10:32:55 -05:00
LoJoSho
1eaeb8ecea clean: renames, missing priority, and ignoredCancelled in PlayerGameListener 2023-08-06 10:31:46 -05:00
LoJoSho
7a9d2f0041 clean spelled onPlayerCosmeticEquip correctly 2023-08-06 10:25:31 -05:00
LoJoSho
6d11deb9aa clean PlayerGameListener moved respawnBackpack method to lamdas 2023-08-06 10:24:53 -05:00
LoJoSho
f5f33f5fe7 clean: item null not showing the location where it occured 2023-08-06 10:21:12 -05:00
LoJoSho
62a1d04040 clean: prevent accidentally passing a null to a notnull method in menu types 2023-08-06 10:10:47 -05:00
LoJoSho
17db498e18 clean: lamdas <3 2023-08-06 10:09:26 -05:00
LoJoSho
0c11e1b1e5 clean: move title updater to StringBuilder 2023-08-06 10:08:54 -05:00
LoJoSho
d20eb11f45 clean: parameter was missing in contract getMenuItem 2023-08-06 10:06:18 -05:00
LoJoSho
51e19d3c36 clean: menu slots are never null, check if empty instead 2023-08-06 10:05:05 -05:00
LoJoSho
8e8d86b94c clean: worldguard listener moved to isEmpty from == 0 2023-08-06 10:01:36 -05:00
LoJoSho
c0caea2447 clean: make hooks final 2023-08-06 09:58:55 -05:00
LoJoSho
33356ea81d clean: move to Lombok for getters (wip) 2023-08-05 22:01:11 -05:00
LoJoSho
a486b13e7e clean: convert MenuItem to record 2023-08-05 21:57:31 -05:00
LoJoSho
938a561d25 feat: add shift left and right click events to action system, resolves #122 2023-08-05 20:04:42 -05:00
LoJoSho
1c61b72624 feat: Lombok + background item cosmetic shading 2023-08-05 19:06:33 -05:00
LoJoSho
46d82b01f0 version bump (2.5.3-DEV) 2023-08-05 10:10:59 -05:00
LoJoSho
c98f132871 version bump (2.5.2) 2023-08-03 11:01:25 -05:00
LoJoSho
554bdf91bd fix: ModelEngine not accepting uppercase 2023-08-02 16:06:03 -05:00
LoJoSho
fced771953 Merge pull request #121 from MomoPewpew/DvZ
Fixed interaction between backpack cosmetics and other passengers
2023-08-02 15:58:53 -05:00
MomoPewpew
6ec47c3f08 Fixed documentation typo 2023-08-02 22:06:45 +02:00
MomoPewpew
2df2646622 Backpack bug fixes
Putting on a backpack will no longer throw off all current riders
Acquiring a new rider will now reattach your backpack
2023-08-02 21:49:19 +02:00
MomoPewpew
e8d1dd1798 Revert "Reattach backpacks after a player is mounted or dismounted"
This reverts commit 2ab59dd2b2.
2023-08-01 20:36:57 +02:00
LoJoSho
59479fc474 clean: translation class more clear 2023-08-01 13:10:25 -05:00
LoJoSho
14b27abe92 clean: change TranslationPair to a record 2023-08-01 13:06:27 -05:00
LoJoSho
8c2c6db81b clean: better for loop 2023-08-01 13:03:14 -05:00
LoJoSho
5696039799 fix: entering wardrobe with riptide on a trident breaking wardrobe 2023-08-01 12:59:15 -05:00
LoJoSho
3068ce5a03 clean: IntelliJ complaining about missing <> 2023-08-01 12:51:28 -05:00
LoJoSho
548d0c3e9a clean: suppress deprecated warning 2023-08-01 12:47:31 -05:00
LoJoSho
a37d6d984b clean: latest version is never null 2023-08-01 12:44:51 -05:00
LoJoSho
d41b385b2a clean: handle IntelliJ warnings in PlayerGameListener 2023-08-01 12:42:58 -05:00
MomoPewpew
2ab59dd2b2 Reattach backpacks after a player is mounted or dismounted 2023-08-01 19:35:09 +02:00
LoJoSho
450083baf0 clean: replace instance check with null check 2023-08-01 12:29:14 -05:00
LoJoSho
0d3129bc3f clean: add proper event priorities 2023-08-01 12:26:08 -05:00
LoJoSho
fe68c43c1f clean: move invalid backpack message to normal debug from warning 2023-08-01 12:12:04 -05:00
LoJoSho
4aa1f412fe feat: add getAllCosmetics and getAllCosmeticUsers as API methods 2023-07-31 15:36:13 -05:00
LoJoSho
e53e0110f9 feat: require specific click type for cosmetic interactions 2023-07-31 15:29:24 -05:00
LoJoSho
f645907ed5 clean: remove unused settings 2023-07-31 15:04:41 -05:00
LoJoSho
af465180c0 version bump (2.5.2-DEV) 2023-07-31 15:04:19 -05:00
LoJoSho
210e6f61d6 version bump (2.5.1) 2023-07-30 22:06:39 -05:00
LoJoSho
14288479f4 fix: looping logic if entity is invalid 2023-07-30 22:05:51 -05:00
LoJoSho
8453a8b20d version bump (2.5.0) 2023-07-30 10:55:25 -05:00
lucian929
e59ee03ac7 feat: add hibiscus flower cosmetic 2023-07-29 19:04:41 -04:00
lucian929
01155f40dd fix: i forgot jetpack 2023-07-29 18:48:39 -04:00
lucian929
fa9f81e5e2 feat: add firstperson-items for cosmetics 2023-07-29 18:34:47 -04:00
LoJoSho
54bcef1a45 Merge pull request #120 from AverageGithub/fixes
Fixes
2023-07-28 10:55:04 -05:00
AverageGithub
8e14899397 Fix to 1.18 & 1.19.1/2 2023-07-28 14:21:30 +02:00
AverageGithub
061718a3b6 Fix title times not being used correctly 2023-07-28 13:05:24 +02:00
AverageGithub
2eea426460 Fix skin layers 2023-07-28 13:00:40 +02:00
LoJoSho
b0136d6076 Merge pull request #119 from AverageGithub/exploit-fix
fix players in wardrobe after teleporting
2023-07-27 09:01:35 -05:00
AverageGithub
d0b45b951c Fix import messup 2023-07-27 10:53:15 +02:00
AverageGithub
e42f5c8c7d Fix exploit 2023-07-27 10:48:08 +02:00
LoJoSho
5d4fb85fec fix: first-person backpack not in correct position in first seconds on join 2023-07-26 15:23:24 -05:00
LoJoSho
04b11a0830 feat: backend recode of the menu system, add refresh rate to auto-update gui 2023-07-26 15:09:25 -05:00
LoJoSho
353086b9c1 fix: not formatting minimessage in translations 2023-07-26 12:46:50 -05:00
LoJoSho
4e40a7cc96 clean: remove unused backpack type 2023-07-25 19:21:25 -05:00
LoJoSho
e2715fe631 fix: remove entities from players 2023-07-25 19:20:41 -05:00
LoJoSho
c7deb756db fix: first-person backpacks in hidden areas 2023-07-25 19:20:20 -05:00
LoJoSho
11f26f8f0a fix: first-person backpacks not showing properly in wardrobes 2023-07-25 19:12:46 -05:00
LoJoSho
6d814d86b3 feat: second iteration of first-person backpacks (focused on other player viewing the backpack) 2023-07-25 15:06:57 -05:00
LoJoSho
12f8b05469 feat: first iteration of first-person backpacks 2023-07-25 14:09:09 -05:00
LoJoSho
b5322bc10b clean: push runserver to 1.20.1 2023-07-25 10:21:37 -05:00
LoJoSho
7a4fd9a98b clean: remove unused utils 2023-07-19 13:39:27 -05:00
LoJoSho
239e13fab2 clean: annotations turned bad 2023-07-19 13:37:58 -05:00
LoJoSho
94b5a1bb3b Merge remote-tracking branch 'origin/remapped' into remapped
# Conflicts:
#	common/src/main/java/com/hibiscusmc/hmccosmetics/api/HMCCosmeticsAPI.java
2023-07-19 13:19:21 -05:00
LoJoSho
71ed820917 feat: slightly expanded api to equip and uneqip cosmetics in main API class 2023-07-19 13:19:04 -05:00
LoJoSho
20532fbaf2 feat: slightly expanded api to equip and remove cosmetics in main API class 2023-07-19 13:18:06 -05:00
LoJoSho
4068af98d2 fix: supervanish dependency 2023-07-19 12:26:50 -05:00
LoJoSho
95e83992de feat: update to gradle 8 2023-07-19 12:25:07 -05:00
LoJoSho
96817d7279 clean: update plugin-yml gradle plugin 2023-07-19 11:09:25 -05:00
LoJoSho
ba7a99247a fix: showing hidden cosmetics actionbar while playing emotes 2023-07-19 10:08:43 -05:00
LoJoSho
f1da6105c0 feat: disable playing emotes in WG region 2023-07-19 10:07:08 -05:00
LoJoSho
c06a4fcede feat: move ModelEngine integration to hook system 2023-07-19 09:54:10 -05:00
LoJoSho
afb20ea0bb clean: update PAPI dependency 2023-07-09 21:44:15 -05:00
LoJoSho
774caf8d91 version bump (2.4.11-DEV) 2023-07-09 21:25:41 -05:00
LoJoSho
a0c2c8a9aa clean: removed unused packet 2023-07-09 21:05:04 -05:00
LoJoSho
5b7f75f7a0 version bump (2.4.10) 2023-07-09 17:53:13 -05:00
LoJoSho
3f7d010dfa clean: optimize imports 2023-07-08 22:48:28 -05:00
LoJoSho
4d84bd681d clean: optimize imports 2023-07-08 22:48:17 -05:00
LoJoSho
0daff3044d feat: move placeholder processing to one method 2023-07-08 22:47:42 -05:00
LoJoSho
ee87338cd4 fix: Cosmin taking up our command >:( 2023-07-08 22:27:06 -05:00
LoJoSho
2b467e63ce feat: remove internal data (deprecated) 2023-07-08 22:11:37 -05:00
LoJoSho
6000cf9c1b clean: clean 2 am coding 2023-07-08 12:04:42 -05:00
LoJoSho
f2b0fb29d3 fix: Leads not properly disappearing teleporting into WG region with hidden cosmetics 2023-07-08 11:40:08 -05:00
LoJoSho
d2962ba5ed version bump (2.4.10-DEV) 2023-07-08 11:39:41 -05:00
LoJoSho
b37083a298 version bump (2.4.9) 2023-06-29 10:00:24 -05:00
LoJoSho
e35a29a13b feat: empty cosmetic type item name go through PAPI 2023-06-29 09:57:08 -05:00
LoJoSho
344aaf32e0 fix: PAPI placeholders not being applied in displaynames in guis 2023-06-28 18:06:58 -05:00
LoJoSho
6498cb43ea version bump (2.4.9-DEV) 2023-06-28 18:06:41 -05:00
LoJoSho
0120720cc3 version bump (2.4.8) 2023-06-27 10:27:43 -05:00
LoJoSho
d1bfa5abbc feat: add force-show-join to show regardless of hidden in database 2023-06-27 10:16:30 -05:00
LoJoSho
71a080a3d5 feat: Option to open menu on wardrobe enter 2023-06-27 09:54:35 -05:00
LoJoSho
78f48703db fix: prevent kicking when message is null/empty 2023-06-27 09:44:11 -05:00
LoJoSho
b9e5096d33 feat: actionbar when player has hidden cosmetics 2023-06-27 09:43:56 -05:00
LoJoSho
d7603b5108 version bump (2.4.8-DEV) 2023-06-27 09:28:03 -05:00
LoJoSho
756e3390a1 clean: remove old code commented out 2023-06-24 20:45:59 -05:00
LoJoSho
8054a35f43 feat: add recursive file lookup 2023-06-23 14:45:27 -05:00
LoJoSho
3b863e6dde version bump (2.4.7) 2023-06-22 13:38:54 -05:00
LoJoSho
b682dd7c42 feat: optimize new packet pufferfish system 2023-06-22 13:15:44 -05:00
LoJoSho
f34f5f01aa version bump (2.4.7-DEV) 2023-06-22 12:56:04 -05:00
LoJoSho
cb9248db7a feat: Refactored CosmeticUser to accept other entities, not just players 2023-06-22 12:55:56 -05:00
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
006319a757 Merge remote-tracking branch 'origin/remapped' into remapped 2023-05-27 10:05:33 -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
a8ff8e6a7a Merge remote-tracking branch 'origin/remapped' into remapped 2023-05-08 09:50:55 -05:00
LoJoSho
8b20207442 Merge remote-tracking branch 'origin/remapped' into remapped 2023-04-24 10:32:56 -05:00
LoJoSho
8bbe12ed84 Merge remote-tracking branch 'origin/remapped' into remapped
# Conflicts:
#	build.gradle.kts
2023-01-30 10:40:00 -06:00
LoJoSho
d23f3e19d2 Moved ProtocolLib Repo 2022-11-16 13:38:02 -06:00
134 changed files with 2827 additions and 4751 deletions

View File

@@ -2,13 +2,13 @@ import net.minecrell.pluginyml.bukkit.BukkitPluginDescription
plugins { plugins {
id("java") id("java")
id("com.github.johnrengelman.shadow") version "7.1.2" id("com.github.johnrengelman.shadow") version "8.1.1"
id("xyz.jpenilla.run-paper") version "2.0.0" id("xyz.jpenilla.run-paper") version "2.0.0"
id("net.minecrell.plugin-yml.bukkit") version "0.5.2" id("net.minecrell.plugin-yml.bukkit") version "0.6.0"
} }
group = "com.hibiscusmc" group = "com.hibiscusmc"
version = "2.3.1" version = "2.7.0"
allprojects { allprojects {
apply(plugin = "java") apply(plugin = "java")
@@ -27,13 +27,11 @@ allprojects {
// ProtocolLib repo // ProtocolLib repo
maven("https://repo.dmulloy2.net/repository/public/") //ProtocolLib Repo, constantly down maven("https://repo.dmulloy2.net/repository/public/") //ProtocolLib Repo, constantly down
maven("https://repo.mineinabyss.com/releases/") maven("https://repo.mineinabyss.com/releases/")
maven("https://repo.mineinabyss.com/snapshots/")
// PlaceholderAPI // PlaceholderAPI
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
//Hikari
maven("https://mvnrepository.com/artifact/com.zaxxer/HikariCP")
// Citizens & Denizen // Citizens & Denizen
maven("https://maven.citizensnpcs.co/repo") maven("https://maven.citizensnpcs.co/repo")
@@ -62,46 +60,50 @@ allprojects {
// md-5 Repo // md-5 Repo
maven("https://repo.md-5.net/content/groups/public/") maven("https://repo.md-5.net/content/groups/public/")
// MMOItems
maven("https://nexus.phoenixdevt.fr/repository/maven-public/")
// Eco-Suite/Auxilor Repo
maven("https://repo.auxilor.io/repository/maven-public/")
// Hibiscus Commons
maven("https://repo.hibiscusmc.com/releases")
} }
dependencies { dependencies {
compileOnly(fileTree("${project.rootDir}/lib") { include("*.jar") }) compileOnly(fileTree("${project.rootDir}/lib") { include("*.jar") })
compileOnly("com.mojang:authlib:1.5.25") 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("io.papermc.paper:paper-api:1.18.2-R0.1-SNAPSHOT")
compileOnly("org.jetbrains:annotations:23.0.0") compileOnly("org.jetbrains:annotations:23.0.0")
compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0-SNAPSHOT") compileOnly("com.comphenix.protocol:ProtocolLib:5.1.0")
compileOnly("me.clip:placeholderapi:2.11.1") compileOnly("me.clip:placeholderapi:2.11.3")
compileOnly("com.ticxo.modelengine:api:R3.0.1") compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.2")
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.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT") compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT")
compileOnly("it.unimi.dsi:fastutil:8.5.11") compileOnly("it.unimi.dsi:fastutil:8.5.11")
compileOnly("com.github.LeonMangler:SuperVanish:6.2.6-4") compileOnly("org.projectlombok:lombok:1.18.2")
compileOnly("me.lojosho:HibiscusCommons:0.2.2")
// Handled by Spigot Library Loader
compileOnly("net.kyori:adventure-api:4.15.0")
compileOnly("net.kyori:adventure-text-minimessage:4.15.0")
compileOnly("net.kyori:adventure-platform-bukkit:4.3.2")
annotationProcessor("org.projectlombok:lombok:1.18.28")
testCompileOnly("org.projectlombok:lombok:1.18.28")
testAnnotationProcessor("org.projectlombok:lombok:1.18.28")
implementation("dev.triumphteam:triumph-gui:3.1.7") {
exclude("net.kyori") // Already have adventure API
}
implementation("com.owen1212055:particlehelper:1.0.0-SNAPSHOT")
implementation("com.ticxo.playeranimator:PlayerAnimator:R1.2.7")
} }
} }
dependencies { dependencies {
implementation(project(path = ":common")) 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"))
//compileOnly("com.github.Fisher2911:FisherLib:master-SNAPSHOT")
implementation("net.kyori:adventure-api:4.11.0")
implementation("net.kyori:adventure-text-minimessage:4.11.0")
implementation("net.kyori:adventure-platform-bukkit:4.1.2")
implementation("dev.triumphteam:triumph-gui:3.1.3")
implementation("org.spongepowered:configurate-yaml:4.1.2")
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:R1.2.6")
//implementation("com.ticxo.playeranimator:PlayerAnimator:R1.2.5")
} }
tasks { tasks {
@@ -121,25 +123,13 @@ tasks {
} }
runServer { runServer {
minecraftVersion("1.19.4") minecraftVersion("1.20.4")
} }
shadowJar { 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")
mergeServiceFiles() mergeServiceFiles()
relocate("dev.triumphteam.gui", "com.hisbiscusmc.hmccosmetics.gui") relocate("dev.triumphteam.gui", "com.hisbiscusmc.hmccosmetics.gui")
relocate("me.mattstudios.mf", "com.hisbiscusmc.hmccosmetics.mf")
relocate("net.kyori.adventure", "com.hisbiscusmc.hmccosmetics.adventure")
relocate("org.spongepowered.configurate", "com.hisbiscusmc.hmccosmetics.configurate")
relocate("org.bstats", "com.hisbiscusmc.hmccosmetics.bstats")
relocate("com.zaxxer.hikaricp", "com.hisbiscusmc.hmccosmetics.hikaricp")
relocate("com.j256.ormlite", "com.hisbiscusmc.hmccosmetics.ormlite")
relocate("com.jeff_media.updatechecker", "com.hisbiscusmc.hmccosmetics.updatechecker")
relocate("com.owen1212055.particlehelper", "com.hisbiscusmc.hmccosmetics.particlehelper") relocate("com.owen1212055.particlehelper", "com.hisbiscusmc.hmccosmetics.particlehelper")
relocate("com.ticxo.playeranimator", "com.hisbiscusmc.hmccosmetics.playeranimator") relocate("com.ticxo.playeranimator", "com.hisbiscusmc.hmccosmetics.playeranimator")
archiveFileName.set("HMCCosmeticsRemapped-${project.version}.jar") archiveFileName.set("HMCCosmeticsRemapped-${project.version}.jar")
@@ -166,15 +156,19 @@ tasks {
bukkit { bukkit {
load = BukkitPluginDescription.PluginLoadOrder.POSTWORLD load = BukkitPluginDescription.PluginLoadOrder.POSTWORLD
main = "com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin" main = "com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin"
apiVersion = "1.17" apiVersion = "1.18"
authors = listOf("LoJoSho") authors = listOf("LoJoSho")
depend = listOf("ProtocolLib") depend = listOf("HibiscusCommons", "ProtocolLib")
softDepend = listOf("ModelEngine", "Oraxen", "ItemsAdder", "Looty", "HMCColor", "WorldGuard", "MythicMobs", "PlaceholderAPI", "SuperVanish", "PremiumVanish", "LibsDisguises", "Denizen") softDepend = listOf("ModelEngine", "Oraxen", "ItemsAdder", "Geary", "HMCColor", "WorldGuard", "MythicMobs", "PlaceholderAPI", "SuperVanish", "PremiumVanish", "LibsDisguises", "Denizen", "MMOItems", "Eco")
version = "${project.version}" version = "${project.version}"
loadBefore = listOf(
"Cosmin" // Fixes an issue with Cosmin loading before and taking /cosmetic, when messing with what we do.
)
commands { commands {
register("cosmetic") { register("cosmetic") {
description = "Base Cosmetic Command" description = "Base Cosmetic Command"
aliases = listOf("hmccosmetics", "cosmetics")
} }
} }
permissions { permissions {
@@ -211,7 +205,7 @@ bukkit {
register("hmccosmetics.cmd.emote.other") { register("hmccosmetics.cmd.emote.other") {
default = BukkitPluginDescription.Permission.Default.OP default = BukkitPluginDescription.Permission.Default.OP
} }
register("hmccosmetics.cmd.setlocation") { register("hmccosmetics.cmd.setwardrobesetting") {
default = BukkitPluginDescription.Permission.Default.OP default = BukkitPluginDescription.Permission.Default.OP
} }
register("hmccosmetics.cmd.dataclear") { register("hmccosmetics.cmd.dataclear") {
@@ -256,4 +250,4 @@ bukkit {
java { java {
toolchain.languageVersion.set(JavaLanguageVersion.of(17 toolchain.languageVersion.set(JavaLanguageVersion.of(17
)) ))
} }

View File

@@ -3,40 +3,6 @@ plugins {
id("maven-publish") id("maven-publish")
} }
dependencies {
compileOnly("com.mojang:authlib:1.5.25")
compileOnly("org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT")
compileOnly("org.jetbrains:annotations:23.0.0")
compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0-SNAPSHOT")
compileOnly("me.clip:placeholderapi:2.11.1")
compileOnly("com.ticxo.modelengine:api: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.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")
implementation("net.kyori:adventure-text-minimessage:4.12.0")
implementation("net.kyori:adventure-platform-bukkit:4.2.0")
implementation("dev.triumphteam:triumph-gui:3.1.3")
implementation("org.spongepowered:configurate-yaml:4.1.2")
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:R1.2.6")
//implementation("com.ticxo.playeranimator:PlayerAnimator:R1.2.5")
}
java { java {
toolchain.languageVersion.set(JavaLanguageVersion.of(17 toolchain.languageVersion.set(JavaLanguageVersion.of(17
)) ))

View File

@@ -1,8 +0,0 @@
pluginManagement {
repositories {
gradlePluginPortal()
maven("https://repo.papermc.io/repository/maven-public/")
}
}
rootProject.name = "HMCCosmetics"

View File

@@ -1,105 +1,94 @@
package com.hibiscusmc.hmccosmetics; package com.hibiscusmc.hmccosmetics;
import com.hibiscusmc.hmccosmetics.api.HMCCosmeticSetupEvent; import com.hibiscusmc.hmccosmetics.api.HMCCosmeticsAPI;
import com.hibiscusmc.hmccosmetics.api.events.HMCCosmeticSetupEvent;
import com.hibiscusmc.hmccosmetics.command.CosmeticCommand; import com.hibiscusmc.hmccosmetics.command.CosmeticCommand;
import com.hibiscusmc.hmccosmetics.command.CosmeticCommandTabComplete; import com.hibiscusmc.hmccosmetics.command.CosmeticCommandTabComplete;
import com.hibiscusmc.hmccosmetics.config.DatabaseSettings; import com.hibiscusmc.hmccosmetics.config.DatabaseSettings;
import com.hibiscusmc.hmccosmetics.config.Settings; import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings; import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.config.serializer.ItemSerializer;
import com.hibiscusmc.hmccosmetics.config.serializer.LocationSerializer;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.database.Database; import com.hibiscusmc.hmccosmetics.database.Database;
import com.hibiscusmc.hmccosmetics.emotes.EmoteManager; import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus; import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.hooks.Hooks; import com.hibiscusmc.hmccosmetics.hooks.items.HookHMCCosmetics;
import com.hibiscusmc.hmccosmetics.hooks.placeholders.HMCPlaceholderExpansion;
import com.hibiscusmc.hmccosmetics.hooks.worldguard.WGHook; import com.hibiscusmc.hmccosmetics.hooks.worldguard.WGHook;
import com.hibiscusmc.hmccosmetics.hooks.worldguard.WGListener; import com.hibiscusmc.hmccosmetics.hooks.worldguard.WGListener;
import com.hibiscusmc.hmccosmetics.listener.PaperPlayerGameListener;
import com.hibiscusmc.hmccosmetics.listener.PlayerConnectionListener; import com.hibiscusmc.hmccosmetics.listener.PlayerConnectionListener;
import com.hibiscusmc.hmccosmetics.listener.PlayerGameListener; import com.hibiscusmc.hmccosmetics.listener.PlayerGameListener;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers; import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.TranslationUtil; 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.PlayerAnimatorImpl;
import org.bstats.bukkit.Metrics; import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
import me.lojosho.hibiscuscommons.HibiscusPlugin;
import me.lojosho.hibiscuscommons.config.serializer.ItemSerializer;
import me.lojosho.hibiscuscommons.config.serializer.LocationSerializer;
import me.lojosho.shaded.configupdater.common.config.CommentedConfiguration;
import me.lojosho.shaded.configurate.ConfigurateException;
import me.lojosho.shaded.configurate.ConfigurationOptions;
import me.lojosho.shaded.configurate.yaml.NodeStyle;
import me.lojosho.shaded.configurate.yaml.YamlConfigurationLoader;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.permissions.Permission; import org.bukkit.permissions.Permission;
import org.bukkit.plugin.java.JavaPlugin;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.ConfigurationOptions;
import org.spongepowered.configurate.yaml.NodeStyle;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
import java.io.File; import java.io.File;
import java.nio.file.Path; import java.nio.file.Path;
public final class HMCCosmeticsPlugin extends JavaPlugin { public final class HMCCosmeticsPlugin extends HibiscusPlugin {
private static HMCCosmeticsPlugin instance; private static HMCCosmeticsPlugin instance;
private static boolean disable = false;
private static YamlConfigurationLoader configLoader; private static YamlConfigurationLoader configLoader;
private static final int pluginId = 13873;
private static boolean hasModelEngine = false; public HMCCosmeticsPlugin() {
private static boolean onLatestVersion = true; super(13873, 1879);
private static String latestVersion = ""; new HookHMCCosmetics();
}
@Override @Override
public void onEnable() { public void onStart() {
// Plugin startup logic // Plugin startup logic
instance = this; instance = this;
// bstats https://bstats.org/plugin/bukkit/HMCCosmetics/13873
Metrics metrics = new Metrics(this, pluginId);
// NMS version check
if (!NMSHandlers.getHandler().getSupported()) {
getLogger().severe("This version is not supported! Consider switching versions?");
getServer().getPluginManager().disablePlugin(this);
return;
}
// Update Checker
UpdateChecker checker = new UpdateChecker(this, UpdateCheckSource.POLYMART, "1879")
.onSuccess((commandSenders, latestVersion) -> {
this.latestVersion = (String) latestVersion;
if (!this.latestVersion.equalsIgnoreCase(getDescription().getVersion())) {
getLogger().info("+++++++++++++++++++++++++++++++++++");
getLogger().info("There is a new update for HMCCosmetics!");
getLogger().info("Please download it as soon as possible for possible fixes and new features.");
getLogger().info("Current Version " + getDescription().getVersion() + " | Latest Version " + latestVersion);
getLogger().info("Spigot: https://www.spigotmc.org/resources/100107/");
getLogger().info("Polymart: https://polymart.org/resource/1879");
getLogger().info("+++++++++++++++++++++++++++++++++++");
}
})
.setNotifyRequesters(false)
.setNotifyOpsOnJoin(false)
.checkEveryXHours(24)
.checkNow();
onLatestVersion = checker.isUsingLatestVersion();
// File setup // File setup
if (!getDataFolder().exists()) { saveDefaultConfig();
saveDefaultConfig(); if (!Path.of(getDataFolder().getPath(), "messages.yml").toFile().exists()) saveResource("messages.yml", false);
//saveResource("translations.yml", false); if (!Path.of(getDataFolder().getPath(), "translations.yml").toFile().exists()) saveResource("translations.yml", false);
saveResource("messages.yml", false); if (!Path.of(getDataFolder().getPath() + "/cosmetics/").toFile().exists()) saveResource("cosmetics/defaultcosmetics.yml", false);
saveResource("cosmetics/defaultcosmetics.yml", false); if (!Path.of(getDataFolder().getPath() + "/menus/").toFile().exists()) saveResource("menus/defaultmenu.yml", false);
saveResource("menus/defaultmenu.yml", false);
}
// Emote folder setup // Emote folder setup
File emoteFile = new File(getDataFolder().getPath() + "/emotes"); File emoteFile = new File(getDataFolder().getPath() + "/emotes");
if (!emoteFile.exists()) emoteFile.mkdir(); if (!emoteFile.exists()) emoteFile.mkdir();
// Player Animator // Player Animator
PlayerAnimatorImpl.initialize(this); if (!HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R2") && !HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R3")) PlayerAnimatorImpl.initialize(this); // PlayerAnimator does not support 1.20.2 yet
// 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", "wardrobe.wardrobes", "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();
}
// Move this over to Hibiscus Commons later
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) new HMCPlaceholderExpansion().register();
// Setup
setup(); setup();
// Commands // Commands
@@ -109,17 +98,15 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
// Listener // Listener
getServer().getPluginManager().registerEvents(new PlayerConnectionListener(), this); getServer().getPluginManager().registerEvents(new PlayerConnectionListener(), this);
getServer().getPluginManager().registerEvents(new PlayerGameListener(), this); getServer().getPluginManager().registerEvents(new PlayerGameListener(), this);
// Taken from PaperLib
if (HibiscusCommonsPlugin.isOnPaper()) {
getServer().getPluginManager().registerEvents(new PaperPlayerGameListener(), this);
}
// Database // Database
new Database(); new Database();
// ModelEngine
if (Bukkit.getPluginManager().getPlugin("ModelEngine") != null) {
hasModelEngine = true;
}
// WorldGuard // WorldGuard
if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null && Settings.isWorldGuardMoveCheckEnabled()) { if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null && Settings.isWorldGuardMoveCheck()) {
getServer().getPluginManager().registerEvents(new WGListener(), this); getServer().getPluginManager().registerEvents(new WGListener(), this);
} }
} }
@@ -133,15 +120,17 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
} }
@Override @Override
public void onDisable() { public void onEnd() {
// Plugin shutdown logic // Plugin shutdown logic
disable = true;
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
CosmeticUser user = CosmeticUsers.getUser(player); CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) continue; if (user == null) continue;
if (user.getUserEmoteManager().isPlayingEmote()) { if (user.getUserEmoteManager().isPlayingEmote()) {
player.setInvisible(false); player.setInvisible(false);
} }
if (user.isInWardrobe()) {
user.leaveWardrobe(true);
}
Database.save(user); Database.save(user);
} }
} }
@@ -170,7 +159,7 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
WardrobeSettings.load(loader.load().node("wardrobe")); WardrobeSettings.load(loader.load().node("wardrobe"));
DatabaseSettings.load(loader.load().node("database-settings")); DatabaseSettings.load(loader.load().node("database-settings"));
configLoader = loader; configLoader = loader;
} catch (ConfigurateException e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@@ -205,9 +194,6 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
// Misc Hooks setup (like items)
Hooks.setup();
// Cosmetics setup // Cosmetics setup
Cosmetics.setup(); Cosmetics.setup();
@@ -236,41 +222,21 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
getInstance().getServer().getPluginManager().addPermission(new Permission(cosmetic.getPermission())); getInstance().getServer().getPluginManager().addPermission(new Permission(cosmetic.getPermission()));
} }
} }
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(); if (Settings.isEmotesEnabled() && !HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R2") && !HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R3")) EmoteManager.loadEmotes(); // PlayerAnimator does not support 1.20.2 yet
getInstance().getLogger().info("Successfully Enabled HMCCosmetics"); getInstance().getLogger().info("Successfully Enabled HMCCosmetics");
getInstance().getLogger().info(Cosmetics.values().size() + " Cosmetics Successfully Setup"); getInstance().getLogger().info(Cosmetics.values().size() + " Cosmetics Successfully Setup");
getInstance().getLogger().info(Menus.getMenuNames().size() + " Menus 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()); getInstance().getLogger().info("Data storage is set to " + DatabaseSettings.getDatabaseType());
Bukkit.getPluginManager().callEvent(new HMCCosmeticSetupEvent()); Bukkit.getPluginManager().callEvent(new HMCCosmeticSetupEvent());
} }
public static boolean isDisable() {
return disable;
}
public static YamlConfigurationLoader getConfigLoader() {
return configLoader;
}
public static void saveConfig(ConfigurationNode node) {
try {
HMCCosmeticsPlugin.getConfigLoader().save(node);
HMCCosmeticsPlugin.getInstance().getLogger().info("Set new location " + node.path());
} catch (ConfigurateException e) {
throw new RuntimeException(e);
}
}
public static boolean hasModelEngine() {
return hasModelEngine;
}
public static boolean isOnLatestVersion() {
return onLatestVersion;
}
public static String getLatestVersion() {
return latestVersion;
}
} }

View File

@@ -0,0 +1,117 @@
package com.hibiscusmc.hmccosmetics.api;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
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 me.lojosho.hibiscuscommons.nms.NMSHandlers;
import org.bukkit.Color;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
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(@NotNull 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(@NotNull 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(@NotNull String id) {
return Menus.getMenu(id);
}
/**
* Equips a cosmetic to a player. You can use getUser and getCosmetic to get the CosmeticUser and Cosmetic to equip.
* @param user CosmeticUser to equip cosmetic to
* @param cosmetic Cosmetic to equip
*/
public static void equipCosmetic(@NotNull CosmeticUser user, @NotNull Cosmetic cosmetic) {
equipCosmetic(user, cosmetic, null);
}
/**
* Equips a cosmetic to a player with a color. You can use getUser and getCosmetic to get the CosmeticUser and Cosmetic to equip.
* @param user CosmeticUser to equip cosmetic to
* @param cosmetic Cosmetic to equip
* @param color Color to apply to cosmetic
*/
public static void equipCosmetic(@NotNull CosmeticUser user, @NotNull Cosmetic cosmetic, @Nullable Color color) {
user.addPlayerCosmetic(cosmetic, color);
}
/**
* Removes a cosmetic in cosmeticslot.
* @param user The user to remove the cosmetic from
* @param slot The slot to remove the cosmetic from
*/
public static void unequipCosmetic(@NotNull CosmeticUser user, @NotNull CosmeticSlot slot) {
user.removeCosmeticSlot(slot);
}
/**
* Gets all Cosmetics that are currently registered with HMCC. This list is immutable!
* @return A list of all registered cosmetics
*/
public static List<Cosmetic> getAllCosmetics() {
return List.copyOf(Cosmetics.values());
}
/**
* Gets all CosmeticUsers that are currently registered with HMCC. This list is immutable!
* @return A list of all registered CosmeticUsers
*/
public static List<CosmeticUser> getAllCosmeticUsers() {
return List.copyOf(CosmeticUsers.values());
}
/**
* This returns the NMS version of the server as recognized by HMCCosmetics. This will be null until HMCC setup has been completed.
* @return The NMS version of the server in String format
*/
@Nullable
public static String getNMSVersion() {
return NMSHandlers.getVersion();
}
/**
* This returns the HMCCosmetics version.
* @return The HMCCosmetics version in String format
*/
@NotNull
public static String getHMCCVersion() {
return HMCCosmeticsPlugin.getInstance().getDescription().getVersion();
}
}

View File

@@ -1,4 +1,4 @@
package com.hibiscusmc.hmccosmetics.api; package com.hibiscusmc.hmccosmetics.api.events;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;

View File

@@ -1,4 +1,4 @@
package com.hibiscusmc.hmccosmetics.api; package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;

View File

@@ -1,4 +1,4 @@
package com.hibiscusmc.hmccosmetics.api; package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Event; import org.bukkit.event.Event;

View File

@@ -1,4 +1,4 @@
package com.hibiscusmc.hmccosmetics.api; package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;

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

@@ -1,4 +1,4 @@
package com.hibiscusmc.hmccosmetics.api; package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;

View File

@@ -1,4 +1,4 @@
package com.hibiscusmc.hmccosmetics.api; package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;

View File

@@ -1,4 +1,4 @@
package com.hibiscusmc.hmccosmetics.api; package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;

View File

@@ -1,4 +1,4 @@
package com.hibiscusmc.hmccosmetics.api; package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager; import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;

View File

@@ -1,4 +1,4 @@
package com.hibiscusmc.hmccosmetics.api; package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.gui.Menu; import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;

View File

@@ -1,4 +1,4 @@
package com.hibiscusmc.hmccosmetics.api; package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.gui.Menu; import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;

View File

@@ -1,4 +1,4 @@
package com.hibiscusmc.hmccosmetics.api; package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.gui.Menu; import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;

View File

@@ -1,6 +1,9 @@
package com.hibiscusmc.hmccosmetics.api; package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -11,9 +14,12 @@ import org.jetbrains.annotations.NotNull;
public class PlayerWardrobeEnterEvent extends PlayerCosmeticEvent implements Cancellable { public class PlayerWardrobeEnterEvent extends PlayerCosmeticEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList(); private static final HandlerList handlers = new HandlerList();
private boolean cancel = false; private boolean cancel = false;
@Getter @Setter
private Wardrobe wardrobe;
public PlayerWardrobeEnterEvent(@NotNull CosmeticUser who) { public PlayerWardrobeEnterEvent(@NotNull CosmeticUser who, @NotNull Wardrobe wardrobe) {
super(who); super(who);
this.wardrobe = wardrobe;
} }
@Override @Override

View File

@@ -1,4 +1,4 @@
package com.hibiscusmc.hmccosmetics.api; package com.hibiscusmc.hmccosmetics.api.events;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;

View File

@@ -1,7 +1,11 @@
package com.hibiscusmc.hmccosmetics.command; package com.hibiscusmc.hmccosmetics.command;
import com.hibiscusmc.hmccolor.HMCColorConfig;
import com.hibiscusmc.hmccolor.HMCColorContextKt;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings; 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.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot; import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
@@ -15,7 +19,8 @@ import com.hibiscusmc.hmccosmetics.gui.special.DyeMenu;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers; import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.ServerUtils; import com.hibiscusmc.hmccosmetics.util.HMCCServerUtils;
import me.lojosho.hibiscuscommons.hooks.Hooks;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.apache.commons.lang3.EnumUtils; import org.apache.commons.lang3.EnumUtils;
@@ -102,7 +107,20 @@ public class CosmeticCommand implements CommandExecutor {
} }
if (sender.hasPermission("hmccosmetics.cmd.apply.color")) { if (sender.hasPermission("hmccosmetics.cmd.apply.color")) {
if (args.length >= 4) color = ServerUtils.hex2Rgb(args[3]); if (args.length >= 4) {
// TODO: Add sub-color support somehow... (and make this neater)
String textColor = args[3];
if (!textColor.contains("#") && Hooks.isActiveHook("HMCColor")) {
HMCColorConfig.Colors colors = HMCColorContextKt.getHmcColor().getConfig().getColors().get(textColor);
if (colors != null) {
String hmccolor = colors.getBaseColor().getColor();
if (hmccolor.contains("#")) color = HMCCServerUtils.hex2Rgb(hmccolor);
else color = HMCCServerUtils.rgbToRgb(hmccolor);
}
} else {
color = HMCCServerUtils.hex2Rgb(textColor);
}
}
} }
if (args.length == 1) { if (args.length == 1) {
@@ -194,8 +212,14 @@ public class CosmeticCommand implements CommandExecutor {
} }
case ("wardrobe") -> { case ("wardrobe") -> {
if (sender instanceof Player) player = ((Player) sender).getPlayer(); 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 (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")) { if (!sender.hasPermission("hmccosmetics.cmd.wardrobe")) {
@@ -208,9 +232,19 @@ public class CosmeticCommand implements CommandExecutor {
return true; 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); CosmeticUser user = CosmeticUsers.getUser(player);
user.toggleWardrobe(); if (user.isInWardrobe()) {
user.leaveWardrobe();
} else {
user.enterWardrobe(false, wardrobe);
}
return true; return true;
} }
// cosmetic menu exampleMenu playerName // cosmetic menu exampleMenu playerName
@@ -244,7 +278,6 @@ public class CosmeticCommand implements CommandExecutor {
case ("dataclear") -> { case ("dataclear") -> {
if (args.length == 1) return true; if (args.length == 1) return true;
OfflinePlayer selectedPlayer = Bukkit.getOfflinePlayer(args[1]); OfflinePlayer selectedPlayer = Bukkit.getOfflinePlayer(args[1]);
if (selectedPlayer == null) return true;
if (!sender.hasPermission("hmccosmetics.cmd.dataclear") && !sender.isOp()) { if (!sender.hasPermission("hmccosmetics.cmd.dataclear") && !sender.isOp()) {
if (!silent) MessagesUtil.sendMessage(sender, "no-permission"); if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true; return true;
@@ -279,7 +312,7 @@ public class CosmeticCommand implements CommandExecutor {
if (!silent) MessagesUtil.sendMessage(player, "invalid-color"); if (!silent) MessagesUtil.sendMessage(player, "invalid-color");
return true; return true;
} }
Color color = ServerUtils.hex2Rgb(args[2]); Color color = HMCCServerUtils.hex2Rgb(args[2]);
if (color == null) { if (color == null) {
if (!silent) MessagesUtil.sendMessage(player, "invalid-color"); if (!silent) MessagesUtil.sendMessage(player, "invalid-color");
return true; return true;
@@ -289,36 +322,56 @@ public class CosmeticCommand implements CommandExecutor {
DyeMenu.openMenu(user, cosmetic); DyeMenu.openMenu(user, cosmetic);
} }
} }
case ("setlocation") -> { case ("setwardrobesetting") -> {
if (!sender.hasPermission("hmccosmetics.cmd.setlocation")) { if (!sender.hasPermission("hmccosmetics.cmd.setwardrobesetting")) {
if (!silent) MessagesUtil.sendMessage(sender, "no-permission"); if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true; return true;
} }
if (player == null) return true; if (player == null) return true;
if (args.length < 2) { if (args.length < 3) {
if (!silent) MessagesUtil.sendMessage(player, "not-enough-args"); if (!silent) MessagesUtil.sendMessage(player, "not-enough-args");
return true; 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")) { if (args[2].equalsIgnoreCase("npclocation")) {
WardrobeSettings.setWardrobeLocation(player.getLocation()); WardrobeSettings.setNPCLocation(wardrobe, player.getLocation());
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-location"); if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-location");
return true; return true;
} }
if (args[1].equalsIgnoreCase("viewerlocation")) { if (args[2].equalsIgnoreCase("viewerlocation")) {
WardrobeSettings.setViewerLocation(player.getLocation()); WardrobeSettings.setViewerLocation(wardrobe, player.getEyeLocation());
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-viewing"); if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-viewing");
return true; return true;
} }
if (args[1].equalsIgnoreCase("leavelocation")) { if (args[2].equalsIgnoreCase("leavelocation")) {
WardrobeSettings.setLeaveLocation(player.getLocation()); WardrobeSettings.setLeaveLocation(wardrobe, player.getLocation());
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-leaving"); if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-leaving");
return true; 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.parseInt(args[3]));
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-distance");
return true;
}
}
} }
case ("dump") -> { case ("dump") -> {
if (player == null) return true; if (player == null) return true;
@@ -330,7 +383,7 @@ public class CosmeticCommand implements CommandExecutor {
} }
player.sendMessage("Passengers -> " + player.getPassengers()); player.sendMessage("Passengers -> " + player.getPassengers());
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) { if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
player.sendMessage("Backpack Location -> " + user.getUserBackpackManager().getArmorStand().getLocation()); player.sendMessage("Backpack Location -> " + user.getUserBackpackManager().getEntityManager().getLocation());
} }
player.sendMessage("Cosmetics -> " + user.getCosmetics()); player.sendMessage("Cosmetics -> " + user.getCosmetics());
player.sendMessage("EntityId -> " + player.getEntityId()); player.sendMessage("EntityId -> " + player.getEntityId());
@@ -385,7 +438,7 @@ public class CosmeticCommand implements CommandExecutor {
return true; return true;
} }
if (Settings.getDebugMode()) { if (Settings.isDebugMode()) {
Settings.setDebugMode(false); Settings.setDebugMode(false);
if (!silent) MessagesUtil.sendMessage(sender, "debug-disabled"); if (!silent) MessagesUtil.sendMessage(sender, "debug-disabled");
} else { } else {
@@ -442,7 +495,7 @@ public class CosmeticCommand implements CommandExecutor {
return true; return true;
} }
CosmeticUser user = CosmeticUsers.getUser(player); CosmeticUser user = CosmeticUsers.getUser(player);
user.getUserEmoteManager().playEmote(EmoteManager.get(args[1])); user.getUserEmoteManager().playEmote(args[1]);
return true; return true;
} }
} }

View File

@@ -1,5 +1,8 @@
package com.hibiscusmc.hmccosmetics.command; package com.hibiscusmc.hmccosmetics.command;
import com.hibiscusmc.hmccolor.HMCColorContextKt;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot; import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
@@ -8,6 +11,7 @@ import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus; import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers; import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import me.lojosho.hibiscuscommons.hooks.Hooks;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@@ -36,7 +40,7 @@ public class CosmeticCommandTabComplete implements TabCompleter {
if (hasPermission(sender, "hmccosmetics.cmd.wardrobe")) completions.add("wardrobe"); if (hasPermission(sender, "hmccosmetics.cmd.wardrobe")) completions.add("wardrobe");
if (hasPermission(sender, "hmccosmetics.cmd.dataclear")) completions.add("dataclear"); if (hasPermission(sender, "hmccosmetics.cmd.dataclear")) completions.add("dataclear");
if (hasPermission(sender, "hmccosmetics.cmd.dye")) completions.add("dye"); 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.hide")) completions.add("hide");
if (hasPermission(sender, "hmccosmetics.cmd.show")) completions.add("show"); if (hasPermission(sender, "hmccosmetics.cmd.show")) completions.add("show");
if (hasPermission(sender, "hmccosmetics.cmd.debug")) completions.add("debug"); if (hasPermission(sender, "hmccosmetics.cmd.debug")) completions.add("debug");
@@ -66,20 +70,29 @@ public class CosmeticCommandTabComplete implements TabCompleter {
if (menu.canOpen(user.getPlayer())) completions.add(menu.getId()); 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()) { for (Player player : Bukkit.getOnlinePlayers()) {
completions.add(player.getName()); 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" -> { case "dye" -> {
for (CosmeticSlot slot : user.getDyeableSlots()) { for (CosmeticSlot slot : user.getDyeableSlots()) {
completions.add(slot.name()); completions.add(slot.name());
} }
} }
case "setlocation" -> { case "setwardrobesetting" -> {
completions.add("wardrobelocation"); for (Wardrobe wardrobe : WardrobeSettings.getWardrobes()) {
completions.add("viewerlocation"); completions.add(wardrobe.getId());
completions.add("leavelocation"); }
} }
case "playemote" -> completions.addAll(EmoteManager.getAllNames()); case "playemote" -> completions.addAll(EmoteManager.getAllNames());
} }
@@ -91,11 +104,18 @@ public class CosmeticCommandTabComplete implements TabCompleter {
case "dye" -> { case "dye" -> {
completions.add("#FFFFFF"); completions.add("#FFFFFF");
} }
case "menu", "apply", "unapply", "playemote" -> { case "menu", "wardrobe", "apply", "unapply", "playemote" -> {
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
completions.add(player.getName()); 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); StringUtil.copyPartialMatches(args[2], completions, finalCompletions);
} }
@@ -104,6 +124,7 @@ public class CosmeticCommandTabComplete implements TabCompleter {
String subcommand = args[0].toLowerCase(); String subcommand = args[0].toLowerCase();
switch (subcommand) { switch (subcommand) {
case "apply" -> { case "apply" -> {
if (Hooks.isActiveHook("HMCColor")) completions.addAll(HMCColorContextKt.getHmcColor().getConfig().getColors().keySet());
completions.add("#FFFFFF"); completions.add("#FFFFFF");
} }
} }

View File

@@ -1,10 +1,10 @@
package com.hibiscusmc.hmccosmetics.config; package com.hibiscusmc.hmccosmetics.config;
import org.spongepowered.configurate.ConfigurationNode; import lombok.Getter;
import me.lojosho.shaded.configurate.ConfigurationNode;
public class DatabaseSettings { public class DatabaseSettings {
//private static final String DATABASE_SETTINGS_PATH = "cosmetic-settings";
private static final String DATABASE_TYPE_PATH = "type"; private static final String DATABASE_TYPE_PATH = "type";
private static final String MYSQL_DATABASE_SETTINGS = "mysql"; private static final String MYSQL_DATABASE_SETTINGS = "mysql";
@@ -17,18 +17,24 @@ public class DatabaseSettings {
private static final String ENABLE_DELAY = "enabled"; private static final String ENABLE_DELAY = "enabled";
private static final String DELAY_LENGTH = "delay"; private static final String DELAY_LENGTH = "delay";
@Getter
private static String databaseType; private static String databaseType;
@Getter
private static String database; private static String database;
@Getter
private static String password; private static String password;
@Getter
private static String host; private static String host;
@Getter
private static String username; private static String username;
@Getter
private static int port; private static int port;
@Getter
private static boolean enabledDelay; private static boolean enabledDelay;
@Getter
private static int delayLength; private static int delayLength;
public static void load(ConfigurationNode source) { public static void load(ConfigurationNode source) {
//ConfigurationNode databaseSettings = source.node(DATABASE_SETTINGS_PATH);
databaseType = source.node(DATABASE_TYPE_PATH).getString(); databaseType = source.node(DATABASE_TYPE_PATH).getString();
ConfigurationNode mySql = source.node(MYSQL_DATABASE_SETTINGS); ConfigurationNode mySql = source.node(MYSQL_DATABASE_SETTINGS);
@@ -44,36 +50,4 @@ public class DatabaseSettings {
enabledDelay = delay.node(ENABLE_DELAY).getBoolean(false); enabledDelay = delay.node(ENABLE_DELAY).getBoolean(false);
delayLength = delay.node(DELAY_LENGTH).getInt(2); delayLength = delay.node(DELAY_LENGTH).getInt(2);
} }
public static String getDatabaseType() {
return databaseType;
}
public static String getDatabase() {
return database;
}
public static String getPassword() {
return password;
}
public static String getHost() {
return host;
}
public static String getUsername() {
return username;
}
public static int getPort() {
return port;
}
public static boolean isEnabledDelay() {
return enabledDelay;
}
public static int getDelayLength() {
return delayLength;
}
} }

View File

@@ -1,12 +1,14 @@
package com.hibiscusmc.hmccosmetics.config; package com.hibiscusmc.hmccosmetics.config;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import lombok.Getter;
import me.lojosho.shaded.configurate.ConfigurationNode;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import org.spongepowered.configurate.ConfigurationNode;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
public class Settings { public class Settings {
@@ -15,17 +17,8 @@ public class Settings {
private static final String DEFAULT_MENU = "default-menu"; private static final String DEFAULT_MENU = "default-menu";
private static final String CONFIG_VERSION = "config-version"; private static final String CONFIG_VERSION = "config-version";
private static final String COSMETIC_SETTINGS_PATH = "cosmetic-settings"; private static final String COSMETIC_SETTINGS_PATH = "cosmetic-settings";
private static final String REQUIRE_EMPTY_HELMET_PATH = "require-empty-helmet";
private static final String REQUIRE_EMPTY_OFF_HAND_PATH = "require-empty-off-hand";
private static final String REQUIRE_EMPTY_CHEST_PLATE_PATH = "require-empty-chest-plate";
private static final String REQUIRE_EMPTY_PANTS_PATH = "require-empty-pants";
private static final String REQUIRE_EMPTY_BOOTS_PATH = "require-empty-boots";
private static final String BALLOON_OFFSET = "balloon-offset"; private static final String BALLOON_OFFSET = "balloon-offset";
private static final String FIRST_PERSON_BACKPACK_MODE = "first-person-backpack-mode";
private static final transient String LOOK_DOWN_PITCH_PATH = "look-down-backpack-remove";
private static final String VIEW_DISTANCE_PATH = "view-distance"; private static final String VIEW_DISTANCE_PATH = "view-distance";
private static final String PARTICLE_COUNT = "particle-count";
private static final String DYE_MENU_PATH = "dye-menu"; private static final String DYE_MENU_PATH = "dye-menu";
private static final String DYE_MENU_NAME = "title"; private static final String DYE_MENU_NAME = "title";
private static final String DYE_MENU_INPUT_SLOT = "input-slot"; private static final String DYE_MENU_INPUT_SLOT = "input-slot";
@@ -34,6 +27,9 @@ public class Settings {
private static final String TICK_PERIOD_PATH = "tick-period"; private static final String TICK_PERIOD_PATH = "tick-period";
private static final String UNAPPLY_DEATH_PATH = "unapply-on-death"; private static final String UNAPPLY_DEATH_PATH = "unapply-on-death";
private static final String FORCE_PERMISSION_JOIN_PATH = "force-permission-join"; private static final String FORCE_PERMISSION_JOIN_PATH = "force-permission-join";
private static final String FORCE_SHOW_COSMETICS_PATH = "force-show-join";
private static final String DISABLED_GAMEMODE_PATH = "disabled-gamemode";
private static final String DISABLED_GAMEMODE_GAMEMODES_PATH = "gamemodes";
private static final String EMOTE_DISTANCE_PATH = "emote-distance"; private static final String EMOTE_DISTANCE_PATH = "emote-distance";
private static final String HOOK_SETTING_PATH = "hook-settings"; private static final String HOOK_SETTING_PATH = "hook-settings";
private static final String HOOK_ITEMADDER_PATH = "itemsadder"; private static final String HOOK_ITEMADDER_PATH = "itemsadder";
@@ -41,43 +37,126 @@ public class Settings {
private static final String HOOK_WORLDGUARD_PATH = "worldguard"; 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 = "player-move-check";
private static final String HOOK_WG_MOVE_CHECK_PATH_LEGACY = "player_move_check"; private static final String HOOK_WG_MOVE_CHECK_PATH_LEGACY = "player_move_check";
private static final String COSMETIC_EMOTE_ENABLE = "emote-enable";
private static final String COSMETIC_EMOTE_CHECK_PATH = "emote-block-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_DAMAGE_PATH = "emote-damage-leave";
private static final String COSMETIC_EMOTE_INVINCIBLE_PATH = "emote-invincible"; private static final String COSMETIC_EMOTE_INVINCIBLE_PATH = "emote-invincible";
private static final String COSMETIC_EMOTE_CAMERA_PATH = "emote-camera";
private static final String COSMETIC_EMOTE_MOVE_CHECK_PATH = "emote-move";
private static final String COSMETIC_DISABLED_WORLDS_PATH = "disabled-worlds";
private static final String COSMETIC_PACKET_ENTITY_TELEPORT_COOLDOWN_PATH = "entity-cooldown-teleport-packet";
private static final String COSMETIC_BACKPACK_FORCE_RIDING_PACKET_PATH = "backpack-force-riding-packet";
private static final String COSMETIC_FORCE_OFFHAND_COSMETIC_SHOW_PATH = "offhand-always-show";
private static final String COSMETIC_ADD_ENCHANTS_HELMET_PATH = "helmet-add-enchantments"; 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_CHESTPLATE_PATH = "chest-add-enchantments";
private static final String COSMETIC_ADD_ENCHANTS_LEGGINGS_PATH = "leggings-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_ADD_ENCHANTS_BOOTS_PATH = "boots-add-enchantments";
private static final String COSMETIC_DESTROY_LOOSE_COSMETIC_PATH = "destroy-loose-cosmetics"; private static final String COSMETIC_DESTROY_LOOSE_COSMETIC_PATH = "destroy-loose-cosmetics";
private static final String MENU_SETTINGS_PATH = "menu-settings";
private static final String COSMETIC_TYPE_SETTINGS_PATH = "cosmetic-type";
private static final String EQUIP_CLICK_TYPE = "equip-click";
private static final String UNEQUIP_CLICK_TYPE = "unequip-click";
private static final String SHADING_PATH = "shading";
private static final String FIRST_ROW_SHIFT_PATH = "first-row-shift";
private static final String SEQUENT_ROW_SHIFT_PATH = "sequent-row-shift";
private static final String INDIVIDUAL_COLUMN_SHIFT_PATH = "individual-column-shift";
private static final String BACKGROUND_PATH = "background";
private static final String CLEAR_BACKGROUND_PATH = "clear-background";
private static final String EQUIPPED_COSMETIC_COLOR_PATH = "equipped-cosmetic-color";
private static final String EQUIPABLE_COSMETIC_COLOR_PATH = "equipable-cosmetic-color";
private static final String LOCKED_COSMETIC_COLOR_PATH = "locked-cosmetic-color";
private static final String ENABLED_PATH = "enabled";
@Getter
private static String defaultMenu; private static String defaultMenu;
@Getter
private static String dyeMenuName; private static String dyeMenuName;
@Getter
private static int dyeMenuInputSlot; private static int dyeMenuInputSlot;
@Getter
private static int dyeMenuOutputSlot; private static int dyeMenuOutputSlot;
@Getter
private static int configVersion; private static int configVersion;
private static boolean requireEmptyHelmet; @Getter
private static boolean requireEmptyOffHand;
private static boolean requireEmptyChestPlate;
private static boolean requireEmptyPants;
private static boolean requireEmptyBoots;
private static boolean debugMode; private static boolean debugMode;
@Getter
private static boolean unapplyOnDeath; private static boolean unapplyOnDeath;
@Getter
private static boolean forcePermissionJoin; private static boolean forcePermissionJoin;
@Getter
private static boolean forceShowOnJoin;
@Getter
private static boolean itemsAdderChangeReload; private static boolean itemsAdderChangeReload;
@Getter
private static boolean worldGuardMoveCheck; private static boolean worldGuardMoveCheck;
@Getter
private static boolean cosmeticEmoteBlockCheck; private static boolean cosmeticEmoteBlockCheck;
@Getter
private static boolean addHelmetEnchants; private static boolean addHelmetEnchants;
@Getter
private static boolean addChestplateEnchants; private static boolean addChestplateEnchants;
@Getter
private static boolean addLeggingEnchants; private static boolean addLeggingEnchants;
@Getter
private static boolean addBootsEnchants; private static boolean addBootsEnchants;
@Getter
private static boolean emoteAirCheck;
@Getter
private static boolean emoteDamageLeave; private static boolean emoteDamageLeave;
@Getter
private static boolean emoteInvincible; private static boolean emoteInvincible;
@Getter
private static boolean destroyLooseCosmetics; private static boolean destroyLooseCosmetics;
private static int lookDownPitch; @Getter
private static boolean backpackForceRidingEnabled;
@Getter
private static boolean cosmeticForceOffhandCosmeticShow;
@Getter
private static boolean emotesEnabled;
@Getter
private static boolean disabledGamemodesEnabled;
@Getter
private static List<String> disabledGamemodes;
@Getter
private static List<String> disabledWorlds;
@Getter
private static int viewDistance; private static int viewDistance;
@Getter
private static int tickPeriod; private static int tickPeriod;
@Getter
private static int packetEntityTeleportCooldown;
@Getter
private static double emoteDistance; private static double emoteDistance;
@Getter
private static Vector balloonOffset; private static Vector balloonOffset;
@Getter
private static String cosmeticEquipClickType;
@Getter
private static String cosmeticUnEquipClickType;
@Getter
private static boolean defaultShading;
@Getter
private static String firstRowShift;
@Getter
private static String sequentRowShift;
@Getter
private static String individualColumnShift;
@Getter
private static String background;
@Getter
private static String clearBackground;
@Getter
private static String equippedCosmeticColor;
@Getter
private static String equipableCosmeticColor;
@Getter
private static String lockedCosmeticColor;
@Getter
private static boolean emoteCameraEnabled;
@Getter
private static boolean emoteMoveCheck;
public static void load(ConfigurationNode source) { public static void load(ConfigurationNode source) {
@@ -96,29 +175,56 @@ public class Settings {
ConfigurationNode cosmeticSettings = source.node(COSMETIC_SETTINGS_PATH); ConfigurationNode cosmeticSettings = source.node(COSMETIC_SETTINGS_PATH);
requireEmptyHelmet = cosmeticSettings.node(REQUIRE_EMPTY_HELMET_PATH).getBoolean(); ConfigurationNode disabledGamemodeSettings = cosmeticSettings.node(DISABLED_GAMEMODE_PATH);
requireEmptyOffHand = cosmeticSettings.node(REQUIRE_EMPTY_OFF_HAND_PATH).getBoolean(); disabledGamemodesEnabled = disabledGamemodeSettings.node(ENABLED_PATH).getBoolean(true);
requireEmptyChestPlate = cosmeticSettings.node(REQUIRE_EMPTY_CHEST_PLATE_PATH).getBoolean(); try {
requireEmptyPants = cosmeticSettings.node(REQUIRE_EMPTY_PANTS_PATH).getBoolean(); disabledGamemodes = disabledGamemodeSettings.node(DISABLED_GAMEMODE_GAMEMODES_PATH).getList(String.class);
requireEmptyBoots = cosmeticSettings.node(REQUIRE_EMPTY_BOOTS_PATH).getBoolean(); disabledWorlds = cosmeticSettings.node(COSMETIC_DISABLED_WORLDS_PATH).getList(String.class);
} catch (Exception e) {
disabledGamemodes = new ArrayList<>();
disabledWorlds = new ArrayList<>();
}
unapplyOnDeath = cosmeticSettings.node(UNAPPLY_DEATH_PATH).getBoolean(false); unapplyOnDeath = cosmeticSettings.node(UNAPPLY_DEATH_PATH).getBoolean(false);
forcePermissionJoin = cosmeticSettings.node(FORCE_PERMISSION_JOIN_PATH).getBoolean(false); forcePermissionJoin = cosmeticSettings.node(FORCE_PERMISSION_JOIN_PATH).getBoolean(false);
forceShowOnJoin = cosmeticSettings.node(FORCE_SHOW_COSMETICS_PATH).getBoolean(false);
emotesEnabled = cosmeticSettings.node(COSMETIC_EMOTE_ENABLE).getBoolean(true);
emoteDistance = cosmeticSettings.node(EMOTE_DISTANCE_PATH).getDouble(-3); emoteDistance = cosmeticSettings.node(EMOTE_DISTANCE_PATH).getDouble(-3);
cosmeticEmoteBlockCheck = cosmeticSettings.node(COSMETIC_EMOTE_CHECK_PATH).getBoolean(true); 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); emoteDamageLeave = cosmeticSettings.node(COSMETIC_EMOTE_DAMAGE_PATH).getBoolean(false);
emoteInvincible = cosmeticSettings.node(COSMETIC_EMOTE_INVINCIBLE_PATH).getBoolean(false); emoteInvincible = cosmeticSettings.node(COSMETIC_EMOTE_INVINCIBLE_PATH).getBoolean(false);
destroyLooseCosmetics = cosmeticSettings.node(COSMETIC_DESTROY_LOOSE_COSMETIC_PATH).getBoolean(false); destroyLooseCosmetics = cosmeticSettings.node(COSMETIC_DESTROY_LOOSE_COSMETIC_PATH).getBoolean(false);
backpackForceRidingEnabled = cosmeticSettings.node(COSMETIC_BACKPACK_FORCE_RIDING_PACKET_PATH).getBoolean(false);
addHelmetEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_HELMET_PATH).getBoolean(false); addHelmetEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_HELMET_PATH).getBoolean(false);
addChestplateEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_CHESTPLATE_PATH).getBoolean(false); addChestplateEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_CHESTPLATE_PATH).getBoolean(false);
addLeggingEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_LEGGINGS_PATH).getBoolean(false); addLeggingEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_LEGGINGS_PATH).getBoolean(false);
addBootsEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_BOOTS_PATH).getBoolean(false); addBootsEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_BOOTS_PATH).getBoolean(false);
tickPeriod = cosmeticSettings.node(TICK_PERIOD_PATH).getInt(-1); tickPeriod = cosmeticSettings.node(TICK_PERIOD_PATH).getInt(-1);
lookDownPitch = cosmeticSettings.node(LOOK_DOWN_PITCH_PATH).getInt(); viewDistance = cosmeticSettings.node(VIEW_DISTANCE_PATH).getInt(-3);
viewDistance = cosmeticSettings.node(VIEW_DISTANCE_PATH).getInt(); emoteCameraEnabled = cosmeticSettings.node(COSMETIC_EMOTE_CAMERA_PATH).getBoolean(true);
emoteMoveCheck = cosmeticSettings.node(COSMETIC_EMOTE_MOVE_CHECK_PATH).getBoolean(false);
packetEntityTeleportCooldown = cosmeticSettings.node(COSMETIC_PACKET_ENTITY_TELEPORT_COOLDOWN_PATH).getInt(-1);
cosmeticForceOffhandCosmeticShow = cosmeticSettings.node(COSMETIC_FORCE_OFFHAND_COSMETIC_SHOW_PATH).getBoolean(false);
ConfigurationNode menuSettings = source.node(MENU_SETTINGS_PATH);
ConfigurationNode shadingSettings = menuSettings.node(SHADING_PATH);
defaultShading = shadingSettings.node(ENABLED_PATH).getBoolean();
firstRowShift = shadingSettings.node(FIRST_ROW_SHIFT_PATH).getString();
sequentRowShift = shadingSettings.node(SEQUENT_ROW_SHIFT_PATH).getString();
individualColumnShift = shadingSettings.node(INDIVIDUAL_COLUMN_SHIFT_PATH).getString();
background = shadingSettings.node(BACKGROUND_PATH).getString();
clearBackground = shadingSettings.node(CLEAR_BACKGROUND_PATH).getString();
equippedCosmeticColor = shadingSettings.node(EQUIPPED_COSMETIC_COLOR_PATH).getString();
equipableCosmeticColor = shadingSettings.node(EQUIPABLE_COSMETIC_COLOR_PATH).getString();
lockedCosmeticColor = shadingSettings.node(LOCKED_COSMETIC_COLOR_PATH).getString();
ConfigurationNode cosmeticTypeSettings = menuSettings.node(COSMETIC_TYPE_SETTINGS_PATH);
cosmeticEquipClickType = cosmeticTypeSettings.node(EQUIP_CLICK_TYPE).getString("ALL");
cosmeticUnEquipClickType = cosmeticTypeSettings.node(UNEQUIP_CLICK_TYPE).getString("ALL");
final var balloonSection = cosmeticSettings.node(BALLOON_OFFSET); final var balloonSection = cosmeticSettings.node(BALLOON_OFFSET);
balloonOffset = loadVector(balloonSection); balloonOffset = loadVector(balloonSection);
ConfigurationNode dyeMenuSettings = source.node(DYE_MENU_PATH); ConfigurationNode dyeMenuSettings = source.node(DYE_MENU_PATH);
@@ -140,145 +246,10 @@ public class Settings {
} }
} }
private static Vector loadVector(final ConfigurationNode config) { public static Vector loadVector(final ConfigurationNode config) {
return new Vector(config.node("x").getDouble(), config.node("y").getDouble(), config.node("z").getDouble()); return new Vector(config.node("x").getDouble(), config.node("y").getDouble(), config.node("z").getDouble());
} }
public static boolean isRequireEmptyHelmet() {
return requireEmptyHelmet;
}
public static boolean isRequireEmptyOffHand() {
return requireEmptyOffHand;
}
public static boolean isRequireEmptyChestPlate() {
return requireEmptyChestPlate;
}
public static boolean isRequireEmptyPants() {
return requireEmptyPants;
}
public static boolean isRequireEmptyBoots() {
return requireEmptyBoots;
}
public static boolean getRequireEmpty(CosmeticSlot slot) {
switch (slot) {
case HELMET -> {
return requireEmptyHelmet;
}
case CHESTPLATE -> {
return requireEmptyChestPlate;
}
case LEGGINGS -> {
return requireEmptyPants;
}
case BOOTS -> {
return requireEmptyBoots;
}
case OFFHAND -> {
return requireEmptyOffHand;
}
}
return false;
}
public static boolean getRequireEmpty(EquipmentSlot slot) {
switch (slot) {
case HEAD -> {
return requireEmptyHelmet;
}
case CHEST -> {
return requireEmptyChestPlate;
}
case LEGS -> {
return requireEmptyPants;
}
case FEET -> {
return requireEmptyBoots;
}
case OFF_HAND -> {
return requireEmptyOffHand;
}
}
return false;
}
public static Vector getBalloonOffset() {
if (balloonOffset == null) HMCCosmeticsPlugin.getInstance().getLogger().info("Shits null");
return balloonOffset;
}
public static int getLookDownPitch() {
return lookDownPitch;
}
public static int getViewDistance() {
return viewDistance;
}
public static String getDefaultMenu() {
return defaultMenu;
}
public static int getConfigVersion() {
return configVersion;
}
public static String getDyeMenuName() {
return dyeMenuName;
}
public static int getDyeMenuInputSlot() { return dyeMenuInputSlot; }
public static int getDyeMenuOutputSlot() { return dyeMenuOutputSlot; }
public static boolean isDebugEnabled() {
return debugMode;
}
public static boolean getItemsAdderReloadChange() {
return itemsAdderChangeReload;
}
public static int getTickPeriod() {
return tickPeriod;
}
public static boolean getUnapplyOnDeath() {
return unapplyOnDeath;
}
public static boolean getForcePermissionJoin() {
return forcePermissionJoin;
}
public static boolean getDebugMode() {
return debugMode;
}
public static double getEmoteDistance() {
return emoteDistance;
}
public static boolean getCosmeticEmoteBlockCheck() {
return cosmeticEmoteBlockCheck;
}
public static boolean isEmoteDamageLeave() {
return emoteDamageLeave;
}
public static boolean isEmoteInvincible() {
return emoteInvincible;
}
public static boolean isWorldGuardMoveCheckEnabled() {
return worldGuardMoveCheck;
}
public static boolean isDestroyLooseCosmetics() {
return destroyLooseCosmetics;
}
public static boolean getShouldAddEnchants(EquipmentSlot slot) { public static boolean getShouldAddEnchants(EquipmentSlot slot) {
switch (slot) { switch (slot) {
case HEAD -> { case HEAD -> {

View File

@@ -0,0 +1,57 @@
package com.hibiscusmc.hmccosmetics.config;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
public class Wardrobe {
@Getter
private final String id;
@Getter @Setter
private int distance;
@Getter @Setter
private String permission;
@Getter @Setter
private WardrobeLocation location;
/**
* This creates a Wardrobe object with all the information that a user will need when entering.
* @param id The id of the wardrobe
* @param location The 3 locations of the Wardrobe, if any of these 3 locations are null, the wardrobe will not work
* @param permission The permission required to enter the wardrobe, if null, no permission is required
* @param distance The distance from the wardrobe that the player can be to enter, if -1, the player can enter from any distance
*/
public Wardrobe(@NotNull String id, @NotNull WardrobeLocation location, @Nullable String permission, int distance) {
this.id = id;
this.location = location;
this.distance = distance;
if (permission != null) this.permission = permission;
}
/**
* This checks if the wardrobe has a permission. If it's null, no permission is required and will return false. If it's not null, it will return true.
* @return if the wardrobe has a permission
*/
public boolean hasPermission() {
return permission != null;
}
/**
* Calculates if a player can enter a wardrobe. Will return true if the player can enter, else false.
* @param user The user that is trying to enter the wardrobe
* @return if the player can enter the wardrobe
*/
public boolean canEnter(@NotNull CosmeticUser user) {
Location wardrobeLocation = location.getNpcLocation();
Location location = user.getEntity().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,36 @@
package com.hibiscusmc.hmccosmetics.config;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.Location;
import org.jetbrains.annotations.Nullable;
public class WardrobeLocation {
@Getter @Setter
private Location npcLocation;
@Getter @Setter
private Location viewerLocation;
@Getter @Setter
private Location leaveLocation;
/**
* This creates a WardrobeLocation object with the 3 locations that are required for a wardrobe to work
* @param npcLocation The location of the NPC
* @param viewerLocation The location of the viewer
* @param leaveLocation The location that the player will be teleported to when they leave the wardrobe if return-last-location in the config is false
*/
public WardrobeLocation(@Nullable Location npcLocation, @Nullable Location viewerLocation, @Nullable Location leaveLocation) {
this.npcLocation = npcLocation;
this.viewerLocation = viewerLocation;
this.leaveLocation = leaveLocation;
}
/**
* Checks if any of the locations are null
* @return true if all locations are not null, else false
*/
public boolean hasAllLocations() {
return npcLocation != null && viewerLocation != null && leaveLocation != null;
}
}

View File

@@ -1,38 +1,48 @@
package com.hibiscusmc.hmccosmetics.config; package com.hibiscusmc.hmccosmetics.config;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.serializer.LocationSerializer;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.misc.Utils; import com.hibiscusmc.hmccosmetics.util.misc.Utils;
import lombok.Getter;
import me.lojosho.hibiscuscommons.config.serializer.LocationSerializer;
import me.lojosho.shaded.configurate.ConfigurationNode;
import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.bossbar.BossBar;
import org.apache.commons.lang3.EnumUtils; import org.apache.commons.lang3.EnumUtils;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException; import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
import java.util.logging.Level;
public class WardrobeSettings { public class WardrobeSettings {
private static final String WARDROBE_PATH = "wardrobe";
private static final String DISABLE_ON_DAMAGE_PATH = "disable-on-damage"; private static final String DISABLE_ON_DAMAGE_PATH = "disable-on-damage";
private static final String DISPLAY_RADIUS_PATH = "display-radius";
private static final String PORTABLE_PATH = "portable"; private static final String PORTABLE_PATH = "portable";
private static final String ALWAYS_DISPLAY_PATH = "always-display"; private static final String ALWAYS_DISPLAY_PATH = "always-display";
private static final String STATIC_RADIUS_PATH = "static-radius";
private static final String ROTATION_SPEED_PATH = "rotation-speed"; private static final String ROTATION_SPEED_PATH = "rotation-speed";
private static final String SPAWN_DELAY_PATH = "spawn-delay"; private static final String SPAWN_DELAY_PATH = "spawn-delay";
private static final String DESPAWN_DELAY_PATH = "despawn-delay"; private static final String DESPAWN_DELAY_PATH = "despawn-delay";
private static final String APPLY_COSMETICS_ON_CLOSE = "apply-cosmetics-on-close"; private static final String APPLY_COSMETICS_ON_CLOSE = "apply-cosmetics-on-close";
private static final String OPEN_SOUND = "open-sound"; private static final String OPEN_SOUND = "open-sound";
private static final String CLOSE_SOUND = "close-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 VIEWER_LOCATION_PATH = "viewer-location";
private static final String LEAVE_LOCATION_PATH = "leave-location"; private static final String LEAVE_LOCATION_PATH = "leave-location";
private static final String EQUIP_PUMPKIN_WARDROBE = "equip-pumpkin"; 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 RETURN_LAST_LOCATION = "return-last-location";
private static final String WARDROBE_MENU_OPTIONS = "menu-options";
private static final String WARDROBE_ENTER_OPEN_MENU_PATH = "enter-open-menu";
private static final String GAMEMODE_OPTIONS_PATH = "gamemode-options"; private static final String GAMEMODE_OPTIONS_PATH = "gamemode-options";
private static final String FORCE_EXIT_GAMEMODE_PATH = "exit-gamemode-enabled"; private static final String FORCE_EXIT_GAMEMODE_PATH = "exit-gamemode-enabled";
private static final String EXIT_GAMEMODE_PATH = "exit-gamemode"; 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_PATH = "bossbar";
private static final String BOSSBAR_ENABLE_PATH = "enabled"; private static final String BOSSBAR_ENABLE_PATH = "enabled";
private static final String BOSSBAR_TEXT_PATH = "text"; private static final String BOSSBAR_TEXT_PATH = "text";
@@ -48,41 +58,61 @@ public class WardrobeSettings {
private static final String TRANSITION_FADE_OUT_PATH = "title-fade-out"; private static final String TRANSITION_FADE_OUT_PATH = "title-fade-out";
private static ConfigurationNode configRoot; private static ConfigurationNode configRoot;
@Getter
private static boolean disableOnDamage; private static boolean disableOnDamage;
private static int displayRadius; @Getter
private static boolean portable; private static boolean portable;
@Getter
private static boolean alwaysDisplay; private static boolean alwaysDisplay;
private static int staticRadius; @Getter
private static int rotationSpeed; private static int rotationSpeed;
@Getter
private static int spawnDelay; private static int spawnDelay;
@Getter
private static int despawnDelay; private static int despawnDelay;
@Getter
private static float bossbarProgress; private static float bossbarProgress;
@Getter
private static boolean applyCosmeticsOnClose; private static boolean applyCosmeticsOnClose;
@Getter
private static boolean tryCosmeticsInWardrobe;
@Getter
private static boolean equipPumpkin; private static boolean equipPumpkin;
@Getter
private static boolean returnLastLocation; private static boolean returnLastLocation;
@Getter
private static boolean enabledBossbar; private static boolean enabledBossbar;
@Getter
private static boolean enterOpenMenu;
@Getter
private static boolean forceExitGamemode; private static boolean forceExitGamemode;
@Getter
private static GameMode exitGamemode; private static GameMode exitGamemode;
private static Location wardrobeLocation; private static HashMap<String, Wardrobe> wardrobes;
private static Location viewerLocation; @Getter
private static Location leaveLocation;
private static String bossbarMessage; private static String bossbarMessage;
@Getter
private static BossBar.Overlay bossbarOverlay; private static BossBar.Overlay bossbarOverlay;
@Getter
private static BossBar.Color bossbarColor; private static BossBar.Color bossbarColor;
@Getter
private static boolean enabledTransition; private static boolean enabledTransition;
@Getter
private static String transitionText; private static String transitionText;
@Getter
private static int transitionDelay; private static int transitionDelay;
@Getter
private static int transitionFadeIn; private static int transitionFadeIn;
@Getter
private static int transitionStay; private static int transitionStay;
@Getter
private static int transitionFadeOut; private static int transitionFadeOut;
public static void load(ConfigurationNode source) { public static void load(ConfigurationNode source) {
configRoot = source; configRoot = source;
disableOnDamage = source.node(DISABLE_ON_DAMAGE_PATH).getBoolean(); disableOnDamage = source.node(DISABLE_ON_DAMAGE_PATH).getBoolean();
displayRadius = source.node(DISPLAY_RADIUS_PATH).getInt();
portable = source.node(PORTABLE_PATH).getBoolean(); portable = source.node(PORTABLE_PATH).getBoolean();
staticRadius = source.node(STATIC_RADIUS_PATH).getInt();
alwaysDisplay = source.node(ALWAYS_DISPLAY_PATH).getBoolean(); alwaysDisplay = source.node(ALWAYS_DISPLAY_PATH).getBoolean();
rotationSpeed = source.node(ROTATION_SPEED_PATH).getInt(); rotationSpeed = source.node(ROTATION_SPEED_PATH).getInt();
spawnDelay = source.node(SPAWN_DELAY_PATH).getInt(); spawnDelay = source.node(SPAWN_DELAY_PATH).getInt();
@@ -90,6 +120,10 @@ public class WardrobeSettings {
applyCosmeticsOnClose = source.node(APPLY_COSMETICS_ON_CLOSE).getBoolean(); applyCosmeticsOnClose = source.node(APPLY_COSMETICS_ON_CLOSE).getBoolean();
equipPumpkin = source.node(EQUIP_PUMPKIN_WARDROBE).getBoolean(); equipPumpkin = source.node(EQUIP_PUMPKIN_WARDROBE).getBoolean();
returnLastLocation = source.node(RETURN_LAST_LOCATION).getBoolean(false); returnLastLocation = source.node(RETURN_LAST_LOCATION).getBoolean(false);
tryCosmeticsInWardrobe = source.node(TRY_COSMETICS_WARDROBE).getBoolean(false);
ConfigurationNode menuOptionsNode = source.node(WARDROBE_MENU_OPTIONS);
enterOpenMenu = menuOptionsNode.node(WARDROBE_ENTER_OPEN_MENU_PATH).getBoolean(false);
ConfigurationNode gamemodeNode = source.node(GAMEMODE_OPTIONS_PATH); ConfigurationNode gamemodeNode = source.node(GAMEMODE_OPTIONS_PATH);
forceExitGamemode = gamemodeNode.node(FORCE_EXIT_GAMEMODE_PATH).getBoolean(false); forceExitGamemode = gamemodeNode.node(FORCE_EXIT_GAMEMODE_PATH).getBoolean(false);
@@ -119,183 +153,123 @@ public class WardrobeSettings {
transitionStay = transitionNode.node(TRANSITION_STAY_PATH).getInt(2000); transitionStay = transitionNode.node(TRANSITION_STAY_PATH).getInt(2000);
transitionFadeOut = transitionNode.node(TRANSITION_FADE_OUT_PATH).getInt(2000); transitionFadeOut = transitionNode.node(TRANSITION_FADE_OUT_PATH).getInt(2000);
try { wardrobes = new HashMap<>();
wardrobeLocation = LocationSerializer.INSTANCE.deserialize(Location.class, source.node(STATIC_LOCATION_PATH)); for (ConfigurationNode wardrobesNode : source.node(WARDROBES_PATH).childrenMap().values()) {
MessagesUtil.sendDebugMessages("Wardrobe Location: " + wardrobeLocation); String id = wardrobesNode.key().toString();
viewerLocation = LocationSerializer.INSTANCE.deserialize(Location.class, source.node(VIEWER_LOCATION_PATH)); try {
MessagesUtil.sendDebugMessages("Viewer Location: " + viewerLocation); Location npcLocation = LocationSerializer.INSTANCE.deserialize(Location.class, wardrobesNode.node(NPC_LOCATION_PATH));
leaveLocation = Utils.replaceIfNull(LocationSerializer.INSTANCE.deserialize(Location.class, source.node(LEAVE_LOCATION_PATH)), viewerLocation); MessagesUtil.sendDebugMessages("Wardrobe Location: " + npcLocation);
} catch (SerializationException e) { Location viewerLocation = LocationSerializer.INSTANCE.deserialize(Location.class, wardrobesNode.node(VIEWER_LOCATION_PATH));
throw new RuntimeException(e); 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 = wardrobesNode.node(PERMISSION_PATH).getString();
int distance = wardrobesNode.node(DISTANCE_PATH).getInt(-1);
Wardrobe wardrobe = new Wardrobe(id, wardrobeLocation, permission, distance);
addWardrobe(wardrobe);
} catch (Exception e) {
MessagesUtil.sendDebugMessages("Unable to create wardrobe " + id, Level.SEVERE);
}
} }
} }
public static boolean getDisableOnDamage() { public static Wardrobe getWardrobe(String key) {
return disableOnDamage; return wardrobes.get(key);
} }
public static int getDisplayRadius() { public static Set<String> getWardrobeNames() {
return displayRadius; return wardrobes.keySet();
} }
public static boolean isPortable() { public static Collection<Wardrobe> getWardrobes() {
return portable; return wardrobes.values();
} }
public static boolean isAlwaysDisplay() { public static void addWardrobe(Wardrobe wardrobe) {
return alwaysDisplay; wardrobes.put(wardrobe.getId(), wardrobe);
} }
public static int getStaticRadius() { public static void removeWardrobe(String id) {
return staticRadius; wardrobes.remove(id);
} }
public static int getRotationSpeed() { /**
return rotationSpeed; * Sets where the NPC/Mannequin will spawn in the wardrobe
} * @param newLocation
*/
public static int getSpawnDelay() { public static void setNPCLocation(Wardrobe wardrobe, Location newLocation) {
return spawnDelay; wardrobe.getLocation().setNpcLocation(newLocation);
}
public static int getDespawnDelay() {
return despawnDelay;
}
public static boolean isApplyCosmeticsOnClose() {
return applyCosmeticsOnClose;
}
public static boolean isEquipPumpkin() {
return equipPumpkin;
}
public static boolean isReturnLastLocation() {
return returnLastLocation;
}
public static Location getWardrobeLocation() {
return wardrobeLocation.clone();
}
public static Location getViewerLocation() {
return viewerLocation;
}
public static Location getLeaveLocation() {
return leaveLocation;
}
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) {
if (wardrobeLocation == null) return false;
if (staticRadius == -1) return true;
if (!wardrobeLocation.getWorld().equals(location.getWorld())) return false;
return wardrobeLocation.distanceSquared(location) <= staticRadius * staticRadius;
}
public static boolean getEnabledBossbar() {
return enabledBossbar;
}
public static float getBossbarProgress() {
return bossbarProgress;
}
public static String getBossbarText() {
return bossbarMessage;
}
public static BossBar.Overlay getBossbarOverlay() {
return bossbarOverlay;
}
public static BossBar.Color getBossbarColor() {
return bossbarColor;
}
public static boolean isEnabledTransition() {
return enabledTransition;
}
public static String getTransitionText() {
return transitionText;
}
public static int getTransitionDelay() {
return transitionDelay;
}
public static int getTransitionFadeIn() {
return transitionFadeIn;
}
public static int getTransitionStay() {
return transitionStay;
}
public static int getTransitionFadeOut() {
return transitionFadeOut;
}
public static boolean isForceExitGamemode() {
return forceExitGamemode;
}
public static GameMode getExitGamemode() {
return exitGamemode;
}
public static void setWardrobeLocation(Location newLocation) {
wardrobeLocation = newLocation;
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance(); HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
plugin.getConfig().set("wardrobe.wardrobe-location." + "world", newLocation.getWorld().getName()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.wardrobe-location." + "x", newLocation.getX()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "x", newLocation.getX());
plugin.getConfig().set("wardrobe.wardrobe-location." + "y", newLocation.getY()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "y", newLocation.getY());
plugin.getConfig().set("wardrobe.wardrobe-location." + "z", newLocation.getZ()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "z", newLocation.getZ());
plugin.getConfig().set("wardrobe.wardrobe-location." + "yaw", newLocation.getYaw()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.wardrobe-location." + "pitch", newLocation.getPitch()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "pitch", newLocation.getPitch());
/* Configuration sets suck plugin.saveConfig();
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 void setViewerLocation(Location newLocation) { /**
viewerLocation = newLocation; * 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(); HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
plugin.getConfig().set("wardrobe.viewer-location." + "world", newLocation.getWorld().getName()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.viewer-location." + "x", newLocation.getX()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.x", newLocation.getX());
plugin.getConfig().set("wardrobe.viewer-location." + "y", newLocation.getY()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.y", newLocation.getY());
plugin.getConfig().set("wardrobe.viewer-location." + "z", newLocation.getZ()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.z", newLocation.getZ());
plugin.getConfig().set("wardrobe.viewer-location." + "yaw", newLocation.getYaw()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.viewer-location." + "pitch", newLocation.getPitch()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.pitch", newLocation.getPitch());
HMCCosmeticsPlugin.getInstance().saveConfig(); plugin.saveConfig();
} }
public static void setLeaveLocation(Location newLocation) { /**
leaveLocation = newLocation; * 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(); HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
plugin.getConfig().set("wardrobe.leave-location." + "world", newLocation.getWorld().getName()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.leave-location." + "x", newLocation.getX()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.x", newLocation.getX());
plugin.getConfig().set("wardrobe.leave-location." + "y", newLocation.getY()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.y", newLocation.getY());
plugin.getConfig().set("wardrobe.leave-location." + "z", newLocation.getZ()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.z", newLocation.getZ());
plugin.getConfig().set("wardrobe.leave-location." + "yaw", newLocation.getYaw()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.leave-location." + "pitch", newLocation.getPitch()); plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.pitch", newLocation.getPitch());
HMCCosmeticsPlugin.getInstance().saveConfig(); 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

@@ -1,154 +0,0 @@
package com.hibiscusmc.hmccosmetics.config.serializer;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.hooks.Hooks;
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.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.persistence.PersistentDataType;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import org.spongepowered.configurate.serialize.TypeSerializer;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.stream.Collectors;
public class ItemSerializer implements TypeSerializer<ItemStack> {
public static final ItemSerializer INSTANCE = new ItemSerializer();
private static final String MATERIAL = "material";
private static final String AMOUNT = "amount";
private static final String NAME = "name";
private static final String UNBREAKABLE = "unbreakable";
private static final String GLOWING = "glowing";
private static final String LORE = "lore";
private static final String MODEL_DATA = "model-data";
private static final String NBT_TAGS = "nbt-tag";
private static final String ENCHANTS = "enchants";
private static final String ITEM_FLAGS = "item-flags";
private static final String TEXTURE = "texture";
private static final String OWNER = "owner";
private static final String COLOR = "color";
private static final String RED = "red";
private static final String GREEN = "green";
private static final String BLUE = "blue";
private ItemSerializer() {
}
@Override
public ItemStack deserialize(final Type type, final ConfigurationNode source)
throws SerializationException {
final ConfigurationNode materialNode = source.node(MATERIAL);
final ConfigurationNode amountNode = source.node(AMOUNT);
final ConfigurationNode nameNode = source.node(NAME);
final ConfigurationNode unbreakableNode = source.node(UNBREAKABLE);
final ConfigurationNode glowingNode = source.node(GLOWING);
final ConfigurationNode loreNode = source.node(LORE);
final ConfigurationNode modelDataNode = source.node(MODEL_DATA);
final ConfigurationNode nbtNode = source.node(NBT_TAGS);
final ConfigurationNode enchantsNode = source.node(ENCHANTS);
final ConfigurationNode itemFlagsNode = source.node(ITEM_FLAGS);
final ConfigurationNode textureNode = source.node(TEXTURE);
final ConfigurationNode ownerNode = source.node(OWNER);
final ConfigurationNode colorNode = source.node(COLOR);
final ConfigurationNode redNode = colorNode.node(RED);
final ConfigurationNode greenNode = colorNode.node(GREEN);
final ConfigurationNode blueNode = colorNode.node(BLUE);
if (materialNode.virtual()) return null;
String material = materialNode.getString();
ItemStack item = Hooks.getItem(material);
if (item == null) {
HMCCosmeticsPlugin.getInstance().getLogger().severe("Invalid Material -> " + material);
return new ItemStack(Material.AIR);
}
item.setAmount(amountNode.getInt(1));
ItemMeta itemMeta = item.getItemMeta();
if (itemMeta == null) return item;
if (!nameNode.virtual())
itemMeta.setDisplayName(StringUtils.parseStringToString(Utils.replaceIfNull(nameNode.getString(), "")));
if (!unbreakableNode.virtual()) itemMeta.setUnbreakable(unbreakableNode.getBoolean());
if (!glowingNode.virtual()) {
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
itemMeta.addEnchant(Enchantment.LUCK, 1, true);
}
if (!loreNode.virtual()) itemMeta.setLore(Utils.replaceIfNull(loreNode.getList(String.class),
new ArrayList<String>()).
stream().map(StringUtils::parseStringToString).collect(Collectors.toList()));
if (!modelDataNode.virtual()) itemMeta.setCustomModelData(modelDataNode.getInt());
if (!nbtNode.virtual()) {
for (ConfigurationNode nbtNodes : nbtNode.childrenMap().values()) {
itemMeta.getPersistentDataContainer().set(NamespacedKey.minecraft(nbtNodes.key().toString()), PersistentDataType.STRING, nbtNodes.getString());
}
}
if (!enchantsNode.virtual()) {
for (ConfigurationNode enchantNode : enchantsNode.childrenMap().values()) {
if (Enchantment.getByKey(NamespacedKey.minecraft(enchantNode.key().toString())) == null) continue;
itemMeta.addEnchant(Enchantment.getByKey(NamespacedKey.minecraft(enchantNode.key().toString())), enchantNode.getInt(1), true);
}
}
try {
if (!itemFlagsNode.virtual()) {
for (String itemFlag : itemFlagsNode.getList(String.class)) {
if (!EnumUtils.isValidEnum(ItemFlag.class, itemFlag)) continue;
MessagesUtil.sendDebugMessages("Added " + itemFlag + " to the item!");
itemMeta.addItemFlags(ItemFlag.valueOf(itemFlag));
}
}
} catch (Exception e) {
e.printStackTrace();
}
if (item.getType() == Material.PLAYER_HEAD) {
SkullMeta skullMeta = (SkullMeta) itemMeta;
if (!ownerNode.virtual()) {
skullMeta.setOwningPlayer(Bukkit.getOfflinePlayer(ownerNode.getString()));
}
if (!textureNode.virtual()) {
Bukkit.getUnsafe().modifyItemStack(item, "{SkullOwner:{Id:[I;0,0,0,0],Properties:{textures:[{Value:\""
+ textureNode.getString() + "\"}]}}}");
itemMeta = skullMeta;
}
}
if (!colorNode.virtual()) {
if (ColorBuilder.canBeColored(item.getType())) {
if (!redNode.virtual()) {
itemMeta = ColorBuilder.color(itemMeta, Color.fromRGB(redNode.getInt(0), greenNode.getInt(0), blueNode.getInt(0)));
} else {
itemMeta = ColorBuilder.color(itemMeta, ServerUtils.hex2Rgb(colorNode.getString("#FFFFFF")));
}
}
}
item.setItemMeta(itemMeta);
return item;
}
@Override
public void serialize(final Type type, @Nullable final ItemStack obj, final ConfigurationNode node) throws SerializationException {
}
}

View File

@@ -1,46 +0,0 @@
package com.hibiscusmc.hmccosmetics.config.serializer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import org.spongepowered.configurate.serialize.TypeSerializer;
import java.lang.reflect.Type;
public class LocationSerializer implements TypeSerializer<Location> {
public static final LocationSerializer INSTANCE = new LocationSerializer();
private static final String WORLD = "world";
private static final String X = "x";
private static final String Y = "y";
private static final String Z = "z";
private static final String PITCH = "pitch";
private static final String YAW = "yaw";
private LocationSerializer() {}
@Override
@Nullable
public Location deserialize(final Type type, final ConfigurationNode source) throws SerializationException {
final World world = Bukkit.getWorld(source.node(WORLD).getString());
if (world == null) return null;
return new Location(
world,
source.node(X).getDouble(),
source.node(Y).getDouble(),
source.node(Z).getDouble(),
source.node(YAW).getFloat(),
source.node(PITCH).getFloat()
);
}
@Override
public void serialize(final Type type, @Nullable final Location loc, final ConfigurationNode source) throws SerializationException {
// Empty
}
}

View File

@@ -1,24 +1,31 @@
package com.hibiscusmc.hmccosmetics.cosmetic; package com.hibiscusmc.hmccosmetics.cosmetic;
import com.hibiscusmc.hmccosmetics.config.serializer.ItemSerializer;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import lombok.Getter;
import lombok.Setter;
import me.lojosho.hibiscuscommons.config.serializer.ItemSerializer;
import me.lojosho.shaded.configurate.ConfigurationNode;
import me.lojosho.shaded.configurate.serialize.SerializationException;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import java.util.logging.Level; import java.util.logging.Level;
public abstract class Cosmetic { public abstract class Cosmetic {
@Getter @Setter
private String id; private String id;
@Getter @Setter
private String permission; private String permission;
private ItemStack item; private ItemStack item;
@Getter @Setter
private String material; private String material;
@Getter @Setter
private CosmeticSlot slot; private CosmeticSlot slot;
@Getter @Setter
private boolean dyable; private boolean dyable;
protected Cosmetic(String id, @NotNull ConfigurationNode config) { protected Cosmetic(String id, @NotNull ConfigurationNode config) {
@@ -44,46 +51,10 @@ public abstract class Cosmetic {
Cosmetics.addCosmetic(this); Cosmetics.addCosmetic(this);
} }
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
public CosmeticSlot getSlot() {
return this.slot;
}
public void setSlot(CosmeticSlot slot) {
this.slot = slot;
}
public String getPermission() {
return this.permission;
}
public void setPermission(String permission) {
this.permission = permission;
}
public boolean requiresPermission() { public boolean requiresPermission() {
return permission != null; return permission != null;
} }
public void setDyable(boolean dyable) {
this.dyable = dyable;
}
public boolean isDyable() {
return this.dyable;
}
public String getMaterial() {
return material;
}
public abstract void update(CosmeticUser user); public abstract void update(CosmeticUser user);
@Nullable @Nullable

View File

@@ -5,18 +5,21 @@ import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings; import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.types.*; import com.hibiscusmc.hmccosmetics.cosmetic.types.*;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import me.lojosho.shaded.configurate.CommentedConfigurationNode;
import me.lojosho.shaded.configurate.ConfigurateException;
import me.lojosho.shaded.configurate.ConfigurationNode;
import me.lojosho.shaded.configurate.yaml.YamlConfigurationLoader;
import org.apache.commons.lang3.EnumUtils; import org.apache.commons.lang3.EnumUtils;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
import java.io.File; import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Stream;
public class Cosmetics { public class Cosmetics {
@@ -68,19 +71,23 @@ public class Cosmetics {
File[] directoryListing = cosmeticFolder.listFiles(); File[] directoryListing = cosmeticFolder.listFiles();
if (directoryListing == null) return; if (directoryListing == null) return;
for (File child : directoryListing) { try (Stream<Path> walkStream = Files.walk(cosmeticFolder.toPath())) {
if (child.toString().contains(".yml") || child.toString().contains(".yaml")) { walkStream.filter(p -> p.toFile().isFile()).forEach(child -> {
MessagesUtil.sendDebugMessages("Scanning " + child); if (child.toString().contains(".yml") || child.toString().contains(".yaml")) {
// Loads file MessagesUtil.sendDebugMessages("Scanning " + child);
YamlConfigurationLoader loader = YamlConfigurationLoader.builder().path(child.toPath()).build(); // Loads file
CommentedConfigurationNode root; YamlConfigurationLoader loader = YamlConfigurationLoader.builder().path(child).build();
try { CommentedConfigurationNode root;
root = loader.load(); try {
} catch (ConfigurateException e) { root = loader.load();
throw new RuntimeException(e); } catch (ConfigurateException e) {
throw new RuntimeException(e);
}
setupCosmetics(root);
} }
setupCosmetics(root); });
} } catch (Exception e) {
e.printStackTrace();
} }
} }
@@ -106,7 +113,7 @@ public class Cosmetics {
default -> new CosmeticArmorType(id, cosmeticConfig); default -> new CosmeticArmorType(id, cosmeticConfig);
} }
} catch (Exception e) { } catch (Exception e) {
if (Settings.isDebugEnabled()) e.printStackTrace(); if (Settings.isDebugMode()) e.printStackTrace();
} }
} }
} }

View File

@@ -2,17 +2,18 @@ package com.hibiscusmc.hmccosmetics.cosmetic.types;
import com.hibiscusmc.hmccosmetics.config.Settings; import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.InventoryUtils; import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager; import me.lojosho.hibiscuscommons.util.packets.PacketManager;
import me.lojosho.shaded.configurate.ConfigurationNode;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.spongepowered.configurate.ConfigurationNode;
public class CosmeticArmorType extends Cosmetic { public class CosmeticArmorType extends Cosmetic {
@@ -21,24 +22,34 @@ public class CosmeticArmorType extends Cosmetic {
public CosmeticArmorType(String id, ConfigurationNode config) { public CosmeticArmorType(String id, ConfigurationNode config) {
super(id, config); super(id, config);
this.equipSlot = InventoryUtils.getEquipmentSlot(getSlot()); this.equipSlot = HMCCInventoryUtils.getEquipmentSlot(getSlot());
} }
@Override @Override
public void update(@NotNull CosmeticUser user) { public void update(@NotNull CosmeticUser user) {
Player player = Bukkit.getPlayer(user.getUniqueId()); if (user.getUserEmoteManager().isPlayingEmote() || user.isInWardrobe()) return;
if (player == null) return; Entity entity = Bukkit.getEntity(user.getUniqueId());
ItemStack cosmeticItem = user.getUserCosmeticItem(this); if (entity == null) return;
if (equipSlot.equals(EquipmentSlot.OFF_HAND)) { if (!Settings.isCosmeticForceOffhandCosmeticShow()
if (!player.getInventory().getItemInOffHand().getType().isAir()) return; && equipSlot.equals(EquipmentSlot.OFF_HAND)
} && ((user.getEntity() instanceof Player) && !user.getPlayer().getInventory().getItemInOffHand().getType().isAir())) return;
ItemStack equippedItem = player.getInventory().getItem(equipSlot); ItemStack item = getItem(user);
if (item == null) return;
PacketManager.equipmentSlotUpdate(entity.getEntityId(), equipSlot, item, HMCCPacketManager.getViewers(entity.getLocation()));
}
public ItemStack getItem(@NotNull CosmeticUser user) {
return getItem(user, user.getUserCosmeticItem(this));
}
public ItemStack getItem(@NotNull CosmeticUser user, ItemStack cosmeticItem) {
if (!(user.getEntity() instanceof HumanEntity humanEntity)) return null;
if (Settings.getShouldAddEnchants(equipSlot)) { if (Settings.getShouldAddEnchants(equipSlot)) {
ItemStack equippedItem = humanEntity.getInventory().getItem(equipSlot);
cosmeticItem.addUnsafeEnchantments(equippedItem.getEnchantments()); cosmeticItem.addUnsafeEnchantments(equippedItem.getEnchantments());
} }
// Basically, if force offhand is off AND there is no item in an offhand slot, then the equipment packet to add the cosmetic
NMSHandlers.getHandler().equipmentSlotUpdate(player.getEntityId(), equipSlot, cosmeticItem, PacketManager.getViewers(player.getLocation())); return cosmeticItem;
//PacketManager.equipmentSlotUpdate(player, getSlot(), PacketManager.getViewers(player.getLocation())); Old method
} }
public EquipmentSlot getEquipSlot() { public EquipmentSlot getEquipSlot() {

View File

@@ -1,66 +1,95 @@
package com.hibiscusmc.hmccosmetics.cosmetic.types; package com.hibiscusmc.hmccosmetics.cosmetic.types;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.manager.UserBackpackManager;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager; import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import lombok.Getter;
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
import me.lojosho.shaded.configurate.ConfigurationNode;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.spongepowered.configurate.ConfigurationNode;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
public class CosmeticBackpackType extends Cosmetic { public class CosmeticBackpackType extends Cosmetic {
@Getter
private final String modelName; private final String modelName;
private UserBackpackManager.BackpackType backpackType; @Getter
private int height = -1;
private ItemStack firstPersonBackpack;
public CosmeticBackpackType(String id, ConfigurationNode config) { public CosmeticBackpackType(String id, ConfigurationNode config) {
super(id, config); super(id, config);
modelName = config.node("model").getString(); modelName = config.node("model").getString();
backpackType = UserBackpackManager.BackpackType.valueOf(config.node("type").getString("NORMAL").toUpperCase());
if (!config.node("firstperson-item").virtual()) {
this.firstPersonBackpack = generateItemStack(config.node("firstperson-item"));
this.height = config.node("height").getInt(5);
}
} }
@Override @Override
public void update(@NotNull CosmeticUser user) { public void update(@NotNull CosmeticUser user) {
Player player = Bukkit.getPlayer(user.getUniqueId()); Entity entity = Bukkit.getEntity(user.getUniqueId());
if (player == null) return; if (entity == null) return;
Location loc = player.getLocation().clone().add(0, 2, 0); Location loc = entity.getLocation().clone().add(0, 2, 0);
if (user.isInWardrobe() || !user.isBackpackSpawned()) return; if (user.isInWardrobe() || !user.isBackpackSpawned()) return;
if (!user.getUserBackpackManager().getArmorStand().isValid()) { // This needs to be moved to purely packet based, there are far to many plugin doing dumb stuff that prevents spawning armorstands ignoring our spawn reason.
MessagesUtil.sendDebugMessages("Invalid Backpack detected! Respawning backpack, report this on the discord if this happens often!", Level.WARNING); List<Player> outsideViewers = user.getUserBackpackManager().getEntityManager().refreshViewers(loc);
user.respawnBackpack();
return; user.getUserBackpackManager().getEntityManager().teleport(loc);
} user.getUserBackpackManager().getEntityManager().setRotation((int) loc.getYaw(), isFirstPersonCompadible());
if (loc.getWorld() != user.getUserBackpackManager().getArmorStand().getWorld()) {
user.getUserBackpackManager().getArmorStand().teleport(loc); HMCCPacketManager.sendEntitySpawnPacket(user.getEntity().getLocation(), user.getUserBackpackManager().getFirstArmorStandId(), EntityType.ARMOR_STAND, UUID.randomUUID(), outsideViewers);
HMCCPacketManager.sendArmorstandMetadata(user.getUserBackpackManager().getFirstArmorStandId(), outsideViewers);
PacketManager.equipmentSlotUpdate(user.getUserBackpackManager().getFirstArmorStandId(), EquipmentSlot.HEAD, user.getUserCosmeticItem(this, getItem()), outsideViewers);
// If true, it will send the riding packet to all players. If false, it will send the riding packet only to new players
if (Settings.isBackpackForceRidingEnabled()) HMCCPacketManager.sendRidingPacket(entity.getEntityId(), user.getUserBackpackManager().getFirstArmorStandId(), user.getUserBackpackManager().getEntityManager().getViewers());
else HMCCPacketManager.sendRidingPacket(entity.getEntityId(), user.getUserBackpackManager().getFirstArmorStandId(), outsideViewers);
if (!user.isInWardrobe() && isFirstPersonCompadible() && user.getPlayer() != null) {
List<Player> owner = List.of(user.getPlayer());
ArrayList<Integer> particleCloud = user.getUserBackpackManager().getAreaEffectEntityId();
for (int i = 0; i < particleCloud.size(); i++) {
if (i == 0) {
HMCCPacketManager.sendRidingPacket(entity.getEntityId(), particleCloud.get(i), owner);
} else {
HMCCPacketManager.sendRidingPacket(particleCloud.get(i - 1), particleCloud.get(i) , owner);
}
}
HMCCPacketManager.sendRidingPacket(particleCloud.get(particleCloud.size() - 1), user.getUserBackpackManager().getFirstArmorStandId(), owner);
if (!user.getHidden()) {
//if (loc.getPitch() < -70) NMSHandlers.getHandler().equipmentSlotUpdate(user.getUserBackpackManager().getFirstArmorStandId(), EquipmentSlot.HEAD, new ItemStack(Material.AIR), owner);
//else NMSHandlers.getHandler().equipmentSlotUpdate(user.getUserBackpackManager().getFirstArmorStandId(), EquipmentSlot.HEAD, firstPersonBackpack, owner);
PacketManager.equipmentSlotUpdate(user.getUserBackpackManager().getFirstArmorStandId(), EquipmentSlot.HEAD, user.getUserCosmeticItem(this, firstPersonBackpack), owner);
}
MessagesUtil.sendDebugMessages("First Person Backpack Update[owner=" + user.getUniqueId() + ",player_location=" + loc + "]!", Level.INFO);
} }
user.getUserBackpackManager().getArmorStand().teleport(loc);
if (user.getUserBackpackManager().getBackpackType().equals(UserBackpackManager.BackpackType.FIRST_PERSON)) {
user.getUserBackpackManager().teleportEffectEntity(loc);
PacketManager.sendRidingPacket(player.getEntityId(), user.getUserBackpackManager().getAreaEffectEntityId(), loc);
PacketManager.sendRidingPacket(user.getUserBackpackManager().getAreaEffectEntityId(), user.getUserBackpackManager().getFirstArmorStandId(), loc);
} else {
PacketManager.sendRidingPacket(player.getEntityId(), user.getUserBackpackManager().getFirstArmorStandId(), loc);
}
user.getUserBackpackManager().getArmorStand().setRotation(loc.getYaw(), loc.getPitch());
user.getUserBackpackManager().showBackpack(); user.getUserBackpackManager().showBackpack();
} }
public String getModelName() { public boolean isFirstPersonCompadible() {
return modelName; return firstPersonBackpack != null;
} }
public UserBackpackManager.BackpackType getBackpackType() { public ItemStack getFirstPersonBackpack() {
return backpackType; return firstPersonBackpack;
} }
} }

View File

@@ -2,32 +2,44 @@ package com.hibiscusmc.hmccosmetics.cosmetic.types;
import com.hibiscusmc.hmccosmetics.config.Settings; import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.user.manager.UserBalloonManager;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager; import com.hibiscusmc.hmccosmetics.user.manager.UserBalloonManager;
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import lombok.Getter;
import me.lojosho.shaded.configurate.ConfigurationNode;
import me.lojosho.shaded.configurate.serialize.SerializationException;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import java.util.List; import java.util.List;
public class CosmeticBalloonType extends Cosmetic { public class CosmeticBalloonType extends Cosmetic {
@Getter
private final String modelName; private final String modelName;
@Getter
private List<String> dyableParts; private List<String> dyableParts;
private boolean showLead; @Getter
private final boolean showLead;
@Getter
private Vector balloonOffset;
public CosmeticBalloonType(String id, ConfigurationNode config) { public CosmeticBalloonType(String id, ConfigurationNode config) {
super(id, config); super(id, config);
String modelId = config.node("model").getString(); String modelId = config.node("model").getString();
showLead = config.node("show-lead").getBoolean(true); showLead = config.node("show-lead").getBoolean(true);
ConfigurationNode balloonOffsetNode = config.node("balloon-offset");
if (balloonOffsetNode.virtual())
balloonOffset = Settings.getBalloonOffset();
else
balloonOffset = Settings.loadVector(balloonOffsetNode);
try { try {
if (!config.node("dyable-parts").virtual()) { if (!config.node("dyable-parts").virtual()) {
dyableParts = config.node("dyable-parts").getList(String.class); dyableParts = config.node("dyable-parts").getList(String.class);
@@ -36,16 +48,16 @@ public class CosmeticBalloonType extends Cosmetic {
// Seriously? // Seriously?
throw new RuntimeException(e); throw new RuntimeException(e);
} }
if (modelId != null) modelId = modelId.toLowerCase(); // ME only accepts lowercase
this.modelName = modelId; this.modelName = modelId;
} }
@Override @Override
public void update(@NotNull CosmeticUser user) { public void update(@NotNull CosmeticUser user) {
Player player = Bukkit.getPlayer(user.getUniqueId()); Entity entity = Bukkit.getEntity(user.getUniqueId());
UserBalloonManager userBalloonManager = user.getBalloonManager(); UserBalloonManager userBalloonManager = user.getBalloonManager();
if (player == null || userBalloonManager == null) return; if (entity == null || userBalloonManager == null) return;
if (user.isInWardrobe()) return; if (user.isInWardrobe()) return;
if (!userBalloonManager.getModelEntity().isValid()) { if (!userBalloonManager.getModelEntity().isValid()) {
@@ -53,16 +65,15 @@ public class CosmeticBalloonType extends Cosmetic {
return; return;
} }
Location newLocation = player.getLocation(); Location newLocation = entity.getLocation();
Location currentLocation = user.getBalloonManager().getLocation(); Location currentLocation = user.getBalloonManager().getLocation();
newLocation = newLocation.clone().add(Settings.getBalloonOffset()); newLocation = newLocation.clone().add(getBalloonOffset());
List<Player> viewer = PacketManager.getViewers(player.getLocation()); List<Player> viewer = HMCCPacketManager.getViewers(entity.getLocation());
viewer.add(player);
if (player.getLocation().getWorld() != userBalloonManager.getLocation().getWorld()) { if (entity.getLocation().getWorld() != userBalloonManager.getLocation().getWorld()) {
userBalloonManager.getModelEntity().teleport(newLocation); userBalloonManager.getModelEntity().teleport(newLocation);
PacketManager.sendTeleportPacket(userBalloonManager.getPufferfishBalloonId(), newLocation, false, viewer); HMCCPacketManager.sendTeleportPacket(userBalloonManager.getPufferfishBalloonId(), newLocation, false, viewer);
return; return;
} }
@@ -70,16 +81,17 @@ public class CosmeticBalloonType extends Cosmetic {
userBalloonManager.setVelocity(velocity.multiply(1.1)); userBalloonManager.setVelocity(velocity.multiply(1.1));
userBalloonManager.setLocation(newLocation); userBalloonManager.setLocation(newLocation);
PacketManager.sendTeleportPacket(userBalloonManager.getPufferfishBalloonId(), newLocation, false, viewer); HMCCPacketManager.sendTeleportPacket(userBalloonManager.getPufferfishBalloonId(), newLocation, false, viewer);
if (!user.getHidden() && showLead) PacketManager.sendLeashPacket(userBalloonManager.getPufferfishBalloonId(), player.getEntityId(), viewer); HMCCPacketManager.sendLeashPacket(userBalloonManager.getPufferfishBalloonId(), entity.getEntityId(), viewer);
} if (user.getHidden()) {
userBalloonManager.getPufferfish().hidePufferfish();
public String getModelName() { return;
return this.modelName; }
} if (!user.getHidden() && showLead) {
List<Player> sendTo = userBalloonManager.getPufferfish().refreshViewers(newLocation);
public List<String> getDyableParts() { if (sendTo.isEmpty()) return;
return dyableParts; user.getBalloonManager().getPufferfish().spawnPufferfish(newLocation, sendTo);
}
} }
public boolean isDyablePart(String name) { public boolean isDyablePart(String name) {
@@ -88,8 +100,4 @@ public class CosmeticBalloonType extends Cosmetic {
if (dyableParts.isEmpty()) return true; if (dyableParts.isEmpty()) return true;
return dyableParts.contains(name); return dyableParts.contains(name);
} }
public boolean isShowLead() {
return showLead;
}
} }

View File

@@ -3,17 +3,19 @@ package com.hibiscusmc.hmccosmetics.cosmetic.types;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import me.lojosho.shaded.configurate.ConfigurationNode;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.spongepowered.configurate.ConfigurationNode;
public class CosmeticEmoteType extends Cosmetic { public class CosmeticEmoteType extends Cosmetic {
private final String animationId; private final String animationId;
private final String text;
public CosmeticEmoteType(String id, ConfigurationNode config) { public CosmeticEmoteType(String id, ConfigurationNode config) {
super(id, config); super(id, config);
animationId = config.node("animation").getString(); animationId = config.node("animation").getString();
text = config.node("text").getString();
MessagesUtil.sendDebugMessages("CosmeticEmoteType Animation id " + animationId); MessagesUtil.sendDebugMessages("CosmeticEmoteType Animation id " + animationId);
} }
@@ -29,4 +31,8 @@ public class CosmeticEmoteType extends Cosmetic {
public String getAnimationId() { public String getAnimationId() {
return animationId; return animationId;
} }
public String getText() {
return text;
}
} }

View File

@@ -2,11 +2,11 @@ package com.hibiscusmc.hmccosmetics.cosmetic.types;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.PlayerUtils; import com.hibiscusmc.hmccosmetics.util.HMCCPlayerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager; import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import me.lojosho.shaded.configurate.ConfigurationNode;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.spongepowered.configurate.ConfigurationNode;
public class CosmeticMainhandType extends Cosmetic { public class CosmeticMainhandType extends Cosmetic {
@@ -18,6 +18,6 @@ public class CosmeticMainhandType extends Cosmetic {
public void update(@NotNull CosmeticUser user) { public void update(@NotNull CosmeticUser user) {
Player player = user.getPlayer(); Player player = user.getPlayer();
PacketManager.equipmentSlotUpdate(player.getEntityId(), user, getSlot(), PlayerUtils.getNearbyPlayers(player)); HMCCPacketManager.equipmentSlotUpdate(player.getEntityId(), user, getSlot(), HMCCPlayerUtils.getNearbyPlayers(player));
} }
} }

View File

@@ -2,23 +2,20 @@ package com.hibiscusmc.hmccosmetics.database;
import com.hibiscusmc.hmccosmetics.config.DatabaseSettings; import com.hibiscusmc.hmccosmetics.config.DatabaseSettings;
import com.hibiscusmc.hmccosmetics.database.types.Data; import com.hibiscusmc.hmccosmetics.database.types.Data;
import com.hibiscusmc.hmccosmetics.database.types.InternalData;
import com.hibiscusmc.hmccosmetics.database.types.MySQLData; import com.hibiscusmc.hmccosmetics.database.types.MySQLData;
import com.hibiscusmc.hmccosmetics.database.types.SQLiteData; import com.hibiscusmc.hmccosmetics.database.types.SQLiteData;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers; import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import lombok.Getter;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.UUID; import java.util.UUID;
public class Database { public class Database {
@Getter
private static Data data; private static Data data;
@Deprecated
private static InternalData INTERNAL_DATA = new InternalData();
private static final MySQLData MYSQL_DATA = new MySQLData(); private static final MySQLData MYSQL_DATA = new MySQLData();
private static final SQLiteData SQLITE_DATA = new SQLiteData(); private static final SQLiteData SQLITE_DATA = new SQLiteData();
@@ -54,10 +51,6 @@ public class Database {
return data.get(uniqueId); return data.get(uniqueId);
} }
public static Data getData() {
return data;
}
public static void clearData(UUID uniqueId) { public static void clearData(UUID uniqueId) {
data.clear(uniqueId); data.clear(uniqueId);
} }

View File

@@ -31,29 +31,32 @@ public abstract class Data {
// BACKPACK=colorfulbackpack&RRGGBB,HELMET=niftyhat,BALLOON=colorfulballoon,CHESTPLATE=niftychestplate // BACKPACK=colorfulbackpack&RRGGBB,HELMET=niftyhat,BALLOON=colorfulballoon,CHESTPLATE=niftychestplate
@NotNull @NotNull
public final String serializeData(@NotNull CosmeticUser user) { public final String serializeData(@NotNull CosmeticUser user) {
String data = ""; StringBuilder data = new StringBuilder();
if (user.getHidden()) { if (user.getHidden()) {
if (shouldHiddenSave(user.getHiddenReason())) { if (shouldHiddenSave(user.getHiddenReason())) {
data = "HIDDEN=" + user.getHiddenReason(); data.append("HIDDEN=").append(user.getHiddenReason());
} }
} }
for (Cosmetic cosmetic : user.getCosmetics()) { for (Cosmetic cosmetic : user.getCosmetics()) {
Color color = user.getCosmeticColor(cosmetic.getSlot()); Color color = user.getCosmeticColor(cosmetic.getSlot());
String input = cosmetic.getSlot() + "=" + cosmetic.getId(); String input = cosmetic.getSlot() + "=" + cosmetic.getId();
if (color != null) input = input + "&" + color.asRGB(); if (color != null) input = input + "&" + color.asRGB();
if (data.length() == 0) { if (data.isEmpty()) {
data = input; data.append(input);
continue; continue;
} }
data = data + "," + input; data.append(",").append(input);
} }
return data; return data.toString();
}
public final Map<CosmeticSlot, Map<Cosmetic, Color>> deserializeData(CosmeticUser user, @NotNull String raw) {
return deserializeData(user, raw, Settings.isForcePermissionJoin());
} }
@NotNull @NotNull
public final Map<CosmeticSlot, Map<Cosmetic, Color>> deserializeData(CosmeticUser user, @NotNull String raw) { public final Map<CosmeticSlot, Map<Cosmetic, Color>> deserializeData(CosmeticUser user, @NotNull String raw, boolean permissionCheck) {
Map<CosmeticSlot, Map<Cosmetic, Color>> cosmetics = new HashMap<>(); Map<CosmeticSlot, Map<Cosmetic, Color>> cosmetics = new HashMap<>();
boolean checkPermission = Settings.getForcePermissionJoin();
String[] rawData = raw.split(","); String[] rawData = raw.split(",");
for (String a : rawData) { for (String a : rawData) {
@@ -64,6 +67,7 @@ public abstract class Data {
MessagesUtil.sendDebugMessages("First split (suppose slot) " + splitData[0]); MessagesUtil.sendDebugMessages("First split (suppose slot) " + splitData[0]);
if (splitData[0].equalsIgnoreCase("HIDDEN")) { if (splitData[0].equalsIgnoreCase("HIDDEN")) {
if (EnumUtils.isValidEnum(CosmeticUser.HiddenReason.class, splitData[1])) { if (EnumUtils.isValidEnum(CosmeticUser.HiddenReason.class, splitData[1])) {
if (Settings.isForceShowOnJoin()) continue;
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> { Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
user.hideCosmetics(CosmeticUser.HiddenReason.valueOf(splitData[1])); user.hideCosmetics(CosmeticUser.HiddenReason.valueOf(splitData[1]));
}); });
@@ -75,8 +79,8 @@ public abstract class Data {
String[] colorSplitData = splitData[1].split("&"); String[] colorSplitData = splitData[1].split("&");
if (Cosmetics.hasCosmetic(colorSplitData[0])) cosmetic = Cosmetics.getCosmetic(colorSplitData[0]); if (Cosmetics.hasCosmetic(colorSplitData[0])) cosmetic = Cosmetics.getCosmetic(colorSplitData[0]);
if (slot == null || cosmetic == null) continue; if (slot == null || cosmetic == null) continue;
if (cosmetic.requiresPermission() && checkPermission) { if (permissionCheck && cosmetic.requiresPermission()) {
if (!user.getPlayer().hasPermission(cosmetic.getPermission())) { if (user.getPlayer() != null && !user.getPlayer().hasPermission(cosmetic.getPermission())) {
continue; continue;
} }
} }
@@ -84,8 +88,8 @@ public abstract class Data {
} else { } else {
if (Cosmetics.hasCosmetic(splitData[1])) cosmetic = Cosmetics.getCosmetic(splitData[1]); if (Cosmetics.hasCosmetic(splitData[1])) cosmetic = Cosmetics.getCosmetic(splitData[1]);
if (slot == null || cosmetic == null) continue; if (slot == null || cosmetic == null) continue;
if (cosmetic.requiresPermission() && checkPermission) { if (permissionCheck && cosmetic.requiresPermission()) {
if (!user.getPlayer().hasPermission(cosmetic.getPermission())) { if (user.getPlayer() != null && !user.getPlayer().hasPermission(cosmetic.getPermission())) {
continue; continue;
} }
} }
@@ -97,9 +101,9 @@ public abstract class Data {
return cosmetics; return cosmetics;
} }
private boolean shouldHiddenSave(CosmeticUser.@NotNull HiddenReason reason) { private boolean shouldHiddenSave(CosmeticUser.HiddenReason reason) {
switch (reason) { switch (reason) {
case EMOTE, NONE -> { case EMOTE, NONE, GAMEMODE, WORLD -> {
return false; return false;
} }
default -> { default -> {

View File

@@ -1,66 +0,0 @@
package com.hibiscusmc.hmccosmetics.database.types;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.NamespacedKey;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.persistence.PersistentDataType;
import java.util.Map;
import java.util.UUID;
@Deprecated
public class InternalData extends Data {
NamespacedKey key = new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "cosmetics");
@Override
public void setup() {
// Nothing
}
@Override
public void save(CosmeticUser user) {
Player player = Bukkit.getPlayer(user.getUniqueId());
player.getPersistentDataContainer().set(key, PersistentDataType.STRING, serializeData(user));
}
@Override
public CosmeticUser get(UUID uniqueId) {
Player player = Bukkit.getPlayer(uniqueId);
CosmeticUser user = new CosmeticUser(uniqueId);
if (!player.getPersistentDataContainer().has(key, PersistentDataType.STRING)) return user;
String rawData = player.getPersistentDataContainer().get(key, PersistentDataType.STRING);
Map<CosmeticSlot, Map<Cosmetic, Color>> a = deserializeData(user, rawData);
for (Map<Cosmetic, Color> cosmeticColors : a.values()) {
for (Cosmetic cosmetic : cosmeticColors.keySet()) {
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
// This can not be async.
user.addPlayerCosmetic(cosmetic, cosmeticColors.get(cosmetic));
});
}
}
return user;
}
@Override
public void clear(UUID uniqueId) {
OfflinePlayer player = Bukkit.getOfflinePlayer(uniqueId);
if (player.isOnline()) {
Player onlinePlayer = player.getPlayer();
if (onlinePlayer.getPersistentDataContainer().has(key, PersistentDataType.STRING)) {
onlinePlayer.getPersistentDataContainer().remove(key);
}
return;
}
}
}

View File

@@ -2,11 +2,15 @@ package com.hibiscusmc.hmccosmetics.database.types;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.DatabaseSettings; import com.hibiscusmc.hmccosmetics.config.DatabaseSettings;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.sql.*; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Properties; import java.util.Properties;
import java.util.UUID; import java.util.UUID;
@@ -123,9 +127,7 @@ public class MySQLData extends SQLData {
public PreparedStatement preparedStatement(String query) { public PreparedStatement preparedStatement(String query) {
PreparedStatement ps = null; PreparedStatement ps = null;
if (!isConnectionOpen()) { if (!isConnectionOpen()) MessagesUtil.sendDebugMessages("Connection is not open");
HMCCosmeticsPlugin.getInstance().getLogger().info("Connection is not open");
}
try { try {
if (connection == null) throw new NullPointerException("Connection is null"); if (connection == null) throw new NullPointerException("Connection is null");

View File

@@ -15,7 +15,7 @@ import java.util.UUID;
public abstract class SQLData extends Data { public abstract class SQLData extends Data {
@Override @Override
@SuppressWarnings({"Duplicates", "resource"}) // Duplicate is from deprecated InternalData @SuppressWarnings({"resource"}) // Duplicate is from deprecated InternalData
public CosmeticUser get(UUID uniqueId) { public CosmeticUser get(UUID uniqueId) {
CosmeticUser user = new CosmeticUser(uniqueId); CosmeticUser user = new CosmeticUser(uniqueId);
@@ -57,7 +57,7 @@ public abstract class SQLData extends Data {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
}; };
if (!HMCCosmeticsPlugin.isDisable()) { if (!HMCCosmeticsPlugin.getInstance().isDisabled()) {
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), run); Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), run);
} else { } else {
run.run(); run.run();

View File

@@ -6,7 +6,10 @@ import org.bukkit.Bukkit;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.sql.*; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
@@ -71,7 +74,7 @@ public class SQLiteData extends SQLData {
Class.forName("org.sqlite.JDBC"); Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection("jdbc:sqlite:" + dataFolder); connection = DriverManager.getConnection("jdbc:sqlite:" + dataFolder);
} catch (SQLException e) { } catch (SQLException e) {
System.out.println(e.getMessage()); e.printStackTrace();
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@@ -80,9 +83,7 @@ public class SQLiteData extends SQLData {
@Override @Override
public PreparedStatement preparedStatement(String query) { public PreparedStatement preparedStatement(String query) {
PreparedStatement ps = null; PreparedStatement ps = null;
if (!isConnectionOpen()) { if (!isConnectionOpen()) MessagesUtil.sendDebugMessages("Connection is not open");
HMCCosmeticsPlugin.getInstance().getLogger().info("Connection is not open");
}
try { try {
ps = connection.prepareStatement(query); ps = connection.prepareStatement(query);

View File

@@ -18,7 +18,7 @@ import java.util.Set;
*/ */
@SuppressWarnings("SpellCheckingInspection") @SuppressWarnings("SpellCheckingInspection")
public class EmoteManager { public class EmoteManager {
private static final @NotNull Map<@NotNull String, @NotNull String> emotes = new HashMap<>(); private static final @NotNull Map<String, String> emotes = new HashMap<>();
/** /**
* Loads all BlockBench animations from the emotes folder and puts it into the animation manager registry and local registry * Loads all BlockBench animations from the emotes folder and puts it into the animation manager registry and local registry

View File

@@ -1,17 +1,25 @@
package com.hibiscusmc.hmccosmetics.gui; package com.hibiscusmc.hmccosmetics.gui;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; 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.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.gui.type.Type; import com.hibiscusmc.hmccosmetics.gui.type.Type;
import com.hibiscusmc.hmccosmetics.gui.type.Types; import com.hibiscusmc.hmccosmetics.gui.type.Types;
import com.hibiscusmc.hmccosmetics.gui.type.types.TypeCosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.misc.Adventure;
import com.hibiscusmc.hmccosmetics.util.misc.Placeholder;
import dev.triumphteam.gui.builder.item.ItemBuilder; import dev.triumphteam.gui.builder.item.ItemBuilder;
import dev.triumphteam.gui.guis.Gui; import dev.triumphteam.gui.guis.Gui;
import dev.triumphteam.gui.guis.GuiItem; import dev.triumphteam.gui.guis.GuiItem;
import lombok.Getter;
import me.lojosho.hibiscuscommons.config.serializer.ItemSerializer;
import me.lojosho.hibiscuscommons.hooks.Hooks;
import me.lojosho.hibiscuscommons.util.AdventureUtils;
import me.lojosho.hibiscuscommons.util.StringUtils;
import me.lojosho.shaded.configurate.ConfigurationNode;
import me.lojosho.shaded.configurate.serialize.SerializationException;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -19,19 +27,27 @@ import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import java.util.ArrayList; import java.util.*;
import java.util.List; import java.util.concurrent.atomic.AtomicInteger;
public class Menu { public class Menu {
@Getter
private final String id; private final String id;
@Getter
private final String title; private final String title;
@Getter
private final int rows; private final int rows;
@Getter
private final ConfigurationNode config; private final ConfigurationNode config;
@Getter
private final String permissionNode; private final String permissionNode;
private final HashMap<Integer, List<MenuItem>> items;
@Getter
private final int refreshRate;
@Getter
private final boolean shading;
public Menu(String id, @NotNull ConfigurationNode config) { public Menu(String id, @NotNull ConfigurationNode config) {
this.id = id; this.id = id;
@@ -40,20 +56,69 @@ public class Menu {
title = config.node("title").getString("chest"); title = config.node("title").getString("chest");
rows = config.node("rows").getInt(1); rows = config.node("rows").getInt(1);
permissionNode = config.node("permission").getString(""); permissionNode = config.node("permission").getString("");
refreshRate = config.node("refresh-rate").getInt(-1);
shading = config.node("shading").getBoolean(Settings.isDefaultShading());
items = new HashMap<>();
setupItems();
Menus.addMenu(this); Menus.addMenu(this);
} }
public String getId() { private void setupItems() {
return id; for (ConfigurationNode config : config.node("items").childrenMap().values()) {
}
public String getTitle() { List<String> slotString;
return this.title; try {
} slotString = config.node("slots").getList(String.class);
} catch (SerializationException e) {
continue;
}
if (slotString == null) {
MessagesUtil.sendDebugMessages("Unable to get valid slot for " + config.key().toString());
continue;
}
public int getRows() { List<Integer> slots = getSlots(slotString);
return this.getRows();
if (slots.isEmpty()) {
MessagesUtil.sendDebugMessages("Slot is empty for " + config.key().toString());
continue;
}
ItemStack item;
try {
item = ItemSerializer.INSTANCE.deserialize(ItemStack.class, config.node("item"));
} catch (SerializationException e) {
throw new RuntimeException(e);
}
if (item == null) {
MessagesUtil.sendDebugMessages("Something went wrong with the item creation for " + config.key().toString());
continue;
}
int priority = config.node("priority").getInt(1);
Type type = null;
if (!config.node("type").virtual()) {
String typeId = config.node("type").getString("");
if (Types.isType(typeId)) type = Types.getType(typeId);
}
for (Integer slot : slots) {
MenuItem menuItem = new MenuItem(slots, item, type, priority, config);
if (items.containsKey(slot)) {
List<MenuItem> menuItems = items.get(slot);
menuItems.add(menuItem);
menuItems.sort(priorityCompare);
items.put(slot, menuItems);
} else {
items.put(slot, new ArrayList<>(Arrays.asList(menuItem)));
}
}
}
} }
public void openMenu(CosmeticUser user) { public void openMenu(CosmeticUser user) {
@@ -69,103 +134,126 @@ public class Menu {
return; return;
} }
} }
final Component component = Adventure.MINI_MESSAGE.deserialize(Placeholder.applyPapiPlaceholders(player, this.title)); final Component component = AdventureUtils.MINI_MESSAGE.deserialize(Hooks.processPlaceholders(player, this.title));
Gui gui = Gui.gui(). Gui gui = Gui.gui()
title(component). .title(component)
rows(this.rows). .rows(this.rows)
create(); .create();
gui.setDefaultClickAction(event -> event.setCancelled(true)); gui.setDefaultClickAction(event -> event.setCancelled(true));
gui = getItems(user, gui); AtomicInteger taskid = new AtomicInteger(-1);
gui.setOpenGuiAction(event -> {
Runnable run = () -> {
if (gui.getInventory().getViewers().isEmpty() && taskid.get() != -1) {
Bukkit.getScheduler().cancelTask(taskid.get());
}
Gui finalGui = gui; updateMenu(user, gui);
};
if (refreshRate != -1) {
taskid.set(Bukkit.getScheduler().scheduleSyncRepeatingTask(HMCCosmeticsPlugin.getInstance(), run, 0, refreshRate));
} else {
run.run();
}
});
gui.setCloseGuiAction(event -> {
if (taskid.get() != -1) Bukkit.getScheduler().cancelTask(taskid.get());
});
// API
PlayerMenuOpenEvent event = new PlayerMenuOpenEvent(user, this); PlayerMenuOpenEvent event = new PlayerMenuOpenEvent(user, this);
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> Bukkit.getPluginManager().callEvent(event));
if (event.isCancelled()) return;
// Internal
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> { Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
Bukkit.getPluginManager().callEvent(event); gui.open(player);
updateMenu(user, gui); // fixes shading? I know I do this twice but it's easier than writing a whole new class to deal with this shit
}); });
if (event.isCancelled()) {
return;
}
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
finalGui.open(player);
});
//gui.open(player);
} }
@Contract("_, _ -> param2") private void updateMenu(CosmeticUser user, Gui gui) {
private Gui getItems(@NotNull CosmeticUser user, Gui gui) { StringBuilder title = new StringBuilder(this.title);
Player player = user.getPlayer();
for (ConfigurationNode config : config.node("items").childrenMap().values()) { int row = 0;
if (shading) {
for (int i = 0; i < gui.getInventory().getSize(); i++) {
// Handles the title
if (i % 9 == 0) {
if (row == 0) {
title.append(Settings.getFirstRowShift()); // Goes back to the start of the gui
} else {
title.append(Settings.getSequentRowShift());
}
row += 1;
} else {
title.append(Settings.getIndividualColumnShift()); // Goes to the next slot
}
List<String> slotString = null; boolean occupied = false;
try {
slotString = config.node("slots").getList(String.class);
} catch (SerializationException e) {
continue;
}
if (slotString == null) {
MessagesUtil.sendDebugMessages("Unable to get valid slot for " + config.key().toString());
continue;
}
List<Integer> slots = getSlots(slotString); if (items.containsKey(i)) {
// Handles the items
List<MenuItem> menuItems = items.get(i);
MenuItem item = menuItems.get(0);
updateItem(user, gui, i);
if (slots == null) { if (item.type() instanceof TypeCosmetic) {
MessagesUtil.sendDebugMessages("Slot is null for " + config.key().toString()); Cosmetic cosmetic = Cosmetics.getCosmetic(item.itemConfig().node("cosmetic").getString(""));
continue; if (cosmetic == null) continue;
} if (user.hasCosmeticInSlot(cosmetic)) {
title.append(Settings.getEquippedCosmeticColor());
ItemStack item; } else {
try { if (user.canEquipCosmetic(cosmetic, true)) {
item = ItemSerializer.INSTANCE.deserialize(ItemStack.class, config.node("item")); title.append(Settings.getEquipableCosmeticColor());
//item = config.node("item").get(ItemStack.class); } else {
} catch (SerializationException e) { title.append(Settings.getLockedCosmeticColor());
throw new RuntimeException(e); }
}
if (item == null) {
MessagesUtil.sendDebugMessages("something went wrong! " + item);
continue;
}
Type type = null;
if (!config.node("type").virtual()) {
String typeId = config.node("type").getString();
if (Types.isType(typeId)) type = Types.getType(typeId);
}
for (int slot : slots) {
ItemStack originalItem = updateItem(user, item, type, config, slot).clone();
GuiItem guiItem = ItemBuilder.from(originalItem).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
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
for (int guiSlot : slots) {
gui.updateItem(guiSlot, updateItem(user, originalItem, finalType, config, guiSlot));
} }
}, 1); occupied = true;
MessagesUtil.sendDebugMessages("Updated slot " + slot); }
}); }
if (occupied) {
MessagesUtil.sendDebugMessages("Added " + slots + " as " + guiItem + " in the menu"); title.append(Settings.getBackground().replaceAll("<row>", String.valueOf(row)));
gui.setItem(slot, guiItem); } else {
title.append(Settings.getClearBackground().replaceAll("<row>", String.valueOf(row)));
}
}
MessagesUtil.sendDebugMessages("Updated menu with title " + title);
gui.updateTitle(StringUtils.parseStringToString(Hooks.processPlaceholders(user.getPlayer(), title.toString())));
} else {
for (int i = 0; i < gui.getInventory().getSize(); i++) {
if (items.containsKey(i)) {
updateItem(user, gui, i);
}
} }
} }
return gui; }
private void updateItem(CosmeticUser user, Gui gui, int slot) {
if (!items.containsKey(slot)) return;
List<MenuItem> menuItems = items.get(slot);
if (menuItems.isEmpty()) return;
for (MenuItem item : menuItems) {
Type type = item.type();
ItemStack modifiedItem = getMenuItem(user, type, item.itemConfig(), item.item().clone(), slot);
if (modifiedItem.getType().isAir()) continue;
GuiItem guiItem = ItemBuilder.from(modifiedItem).asGuiItem();
guiItem.setAction(event -> {
MessagesUtil.sendDebugMessages("Selected slot " + slot);
final ClickType clickType = event.getClick();
if (type != null) type.run(user, item.itemConfig(), clickType);
updateMenu(user, gui);
});
MessagesUtil.sendDebugMessages("Added " + slot + " as " + guiItem + " in the menu");
gui.updateItem(slot, guiItem);
break;
}
} }
@NotNull @NotNull
@@ -175,8 +263,8 @@ public class Menu {
for (String a : slotString) { for (String a : slotString) {
if (a.contains("-")) { if (a.contains("-")) {
String[] split = a.split("-"); String[] split = a.split("-");
int min = Integer.valueOf(split[0]); int min = Integer.parseInt(split[0]);
int max = Integer.valueOf(split[1]); int max = Integer.parseInt(split[1]);
slots.addAll(getSlots(min, max)); slots.addAll(getSlots(min, max));
} else { } else {
slots.add(Integer.valueOf(a)); slots.add(Integer.valueOf(a));
@@ -194,21 +282,17 @@ public class Menu {
return slots; return slots;
} }
@Contract("_, _, _, _ -> param2") @Contract("_, _, _, _, _ -> param2")
@NotNull @NotNull
private ItemStack updateItem(CosmeticUser user, @NotNull ItemStack itemStack, Type type, ConfigurationNode config, int slot) { private ItemStack getMenuItem(CosmeticUser user, Type type, ConfigurationNode config, ItemStack itemStack, int slot) {
if (itemStack.hasItemMeta()) { if (!itemStack.hasItemMeta()) return itemStack;
itemStack = type.setItem(user, config, itemStack, slot); return type.setItem(user, config, itemStack, slot);
}
return itemStack;
}
public String getPermissionNode() {
return permissionNode;
} }
public boolean canOpen(Player player) { public boolean canOpen(Player player) {
if (permissionNode.isEmpty()) return true; if (permissionNode.isEmpty()) return true;
return player.isOp() || player.hasPermission(permissionNode); return player.isOp() || player.hasPermission(permissionNode);
} }
public static Comparator<MenuItem> priorityCompare = Comparator.comparing(MenuItem::priority).reversed();
} }

View File

@@ -0,0 +1,11 @@
package com.hibiscusmc.hmccosmetics.gui;
import com.hibiscusmc.hmccosmetics.gui.type.Type;
import me.lojosho.shaded.configurate.ConfigurationNode;
import org.bukkit.inventory.ItemStack;
import java.util.List;
public record MenuItem(List<Integer> slots, ItemStack item, Type type, int priority, ConfigurationNode itemConfig) {
}

View File

@@ -3,19 +3,22 @@ package com.hibiscusmc.hmccosmetics.gui;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings; import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import me.lojosho.shaded.configurate.CommentedConfigurationNode;
import me.lojosho.shaded.configurate.ConfigurateException;
import me.lojosho.shaded.configurate.yaml.YamlConfigurationLoader;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
import java.io.File; import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Stream;
public class Menus { public class Menus {
@@ -56,33 +59,39 @@ public class Menus {
return names; return names;
} }
public static Collection<Menu> values() {
return MENUS.values();
}
public static void setup() { public static void setup() {
MENUS.clear(); MENUS.clear();
File cosmeticFolder = new File(HMCCosmeticsPlugin.getInstance().getDataFolder() + "/menus"); File cosmeticFolder = new File(HMCCosmeticsPlugin.getInstance().getDataFolder() + "/menus");
if (!cosmeticFolder.exists()) cosmeticFolder.mkdir(); if (!cosmeticFolder.exists()) cosmeticFolder.mkdir();
File[] directoryListing = cosmeticFolder.listFiles(); // Recursive file lookup
if (directoryListing == null) return; try (Stream<Path> walkStream = Files.walk(cosmeticFolder.toPath())) {
walkStream.filter(p -> p.toFile().isFile()).forEach(child -> {
for (File child : directoryListing) { if (child.toString().endsWith("yml") || child.toString().endsWith("yaml")) {
if (child.toString().contains(".yml") || child.toString().contains(".yaml")) { MessagesUtil.sendDebugMessages("Scanning " + child);
MessagesUtil.sendDebugMessages("Scanning " + child); // Loads file
// Loads file YamlConfigurationLoader loader = YamlConfigurationLoader.builder().path(child).build();
YamlConfigurationLoader loader = YamlConfigurationLoader.builder().path(child.toPath()).build(); CommentedConfigurationNode root;
CommentedConfigurationNode root; try {
try { root = loader.load();
root = loader.load(); } catch (ConfigurateException e) {
} catch (ConfigurateException e) { throw new RuntimeException(e);
throw new RuntimeException(e); }
try {
new Menu(FilenameUtils.removeExtension(child.getFileName().toString()), root);
} catch (Exception e) {
MessagesUtil.sendDebugMessages("Unable to create menu in " + child.getFileName().toString(), Level.WARNING);
if (Settings.isDebugMode()) e.printStackTrace();
}
} }
try { });
new Menu(FilenameUtils.removeExtension(child.getName()), root); } catch (Exception e) {
} catch (Exception e) { e.printStackTrace();
MessagesUtil.sendDebugMessages("Unable to create menu in " + child, Level.WARNING);
if (Settings.isDebugEnabled()) e.printStackTrace();
}
}
} }
} }
} }

View File

@@ -3,6 +3,8 @@ package com.hibiscusmc.hmccosmetics.gui.action.actions;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.gui.action.Action; import com.hibiscusmc.hmccosmetics.gui.action.Action;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import me.lojosho.hibiscuscommons.hooks.Hooks;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class ActionConsoleCommand extends Action { public class ActionConsoleCommand extends Action {
@@ -13,6 +15,6 @@ public class ActionConsoleCommand extends Action {
@Override @Override
public void run(@NotNull CosmeticUser user, String raw) { public void run(@NotNull CosmeticUser user, String raw) {
HMCCosmeticsPlugin.getInstance().getServer().dispatchCommand(user.getPlayer(), raw); HMCCosmeticsPlugin.getInstance().getServer().dispatchCommand(Bukkit.getConsoleSender(), Hooks.processPlaceholders(user.getPlayer(), raw));
} }
} }

View File

@@ -1,6 +1,5 @@
package com.hibiscusmc.hmccosmetics.gui.action.actions; package com.hibiscusmc.hmccosmetics.gui.action.actions;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.gui.Menu; import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus; import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.gui.action.Action; import com.hibiscusmc.hmccosmetics.gui.action.Action;

View File

@@ -3,8 +3,8 @@ package com.hibiscusmc.hmccosmetics.gui.action.actions;
import com.hibiscusmc.hmccosmetics.gui.action.Action; import com.hibiscusmc.hmccosmetics.gui.action.Action;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.ServerUtils; import com.hibiscusmc.hmccosmetics.util.HMCCServerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager; import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import com.owen1212055.particlehelper.api.particle.types.BlockDataParticle; import com.owen1212055.particlehelper.api.particle.types.BlockDataParticle;
import com.owen1212055.particlehelper.api.particle.types.DestinationParticle; import com.owen1212055.particlehelper.api.particle.types.DestinationParticle;
import com.owen1212055.particlehelper.api.particle.types.velocity.VelocityParticle; import com.owen1212055.particlehelper.api.particle.types.velocity.VelocityParticle;
@@ -42,9 +42,9 @@ public class ActionParticle extends Action {
return; return;
} }
particle = ServerUtils.addParticleValues(particle, rawString); particle = HMCCServerUtils.addParticleValues(particle, rawString);
Location location = user.getPlayer().getLocation(); Location location = user.getPlayer().getLocation();
for (Player player : PacketManager.getViewers(location)) { for (Player player : HMCCPacketManager.getViewers(location)) {
particle.compile().send(player, location); particle.compile().send(player, location);
} }
} }

View File

@@ -3,6 +3,7 @@ package com.hibiscusmc.hmccosmetics.gui.action.actions;
import com.hibiscusmc.hmccosmetics.gui.action.Action; import com.hibiscusmc.hmccosmetics.gui.action.Action;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import me.lojosho.hibiscuscommons.hooks.Hooks;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class ActionPlayerCommand extends Action { public class ActionPlayerCommand extends Action {
@@ -13,6 +14,6 @@ public class ActionPlayerCommand extends Action {
@Override @Override
public void run(@NotNull CosmeticUser user, String raw) { public void run(@NotNull CosmeticUser user, String raw) {
user.getPlayer().performCommand(MessagesUtil.processStringNoKeyString(user.getPlayer(), raw)); user.getPlayer().performCommand(MessagesUtil.processStringNoKeyString(user.getPlayer(), Hooks.processPlaceholders(user.getPlayer(), raw)));
} }
} }

View File

@@ -1,14 +1,13 @@
package com.hibiscusmc.hmccosmetics.gui.special; package com.hibiscusmc.hmccosmetics.gui.special;
import com.hibiscusmc.hmccolor.HMCColorApi; import com.hibiscusmc.hmccolor.HMCColorApi;
import com.hibiscusmc.hmccolor.gui.guis.Gui; import com.hibiscusmc.hmccolor.shaded.gui.guis.Gui;
import com.hibiscusmc.hmccolor.gui.guis.GuiItem; import com.hibiscusmc.hmccolor.shaded.gui.guis.GuiItem;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings; import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.hooks.Hooks;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.misc.Placeholder; import me.lojosho.hibiscuscommons.hooks.Hooks;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.Material; import org.bukkit.Material;
@@ -32,8 +31,8 @@ public class DyeMenu {
ItemStack originalItem = user.getUserCosmeticItem(cosmetic); ItemStack originalItem = user.getUserCosmeticItem(cosmetic);
if (originalItem == null || !cosmetic.isDyable()) return; if (originalItem == null || !cosmetic.isDyable()) return;
Gui gui = HMCColorApi.INSTANCE.colorMenu(); Gui gui = HMCColorApi.INSTANCE.colorMenu(player);
gui.updateTitle(Placeholder.applyPapiPlaceholders(player, Settings.getDyeMenuName())); gui.updateTitle(Hooks.processPlaceholders(player, Settings.getDyeMenuName()));
gui.setItem(Settings.getDyeMenuInputSlot(), new GuiItem(originalItem)); gui.setItem(Settings.getDyeMenuInputSlot(), new GuiItem(originalItem));
gui.setDefaultTopClickAction(event -> { gui.setDefaultTopClickAction(event -> {
if (event.getSlot() == Settings.getDyeMenuOutputSlot()) { if (event.getSlot() == Settings.getDyeMenuOutputSlot()) {

View File

@@ -1,10 +1,9 @@
package com.hibiscusmc.hmccosmetics.gui.type; package com.hibiscusmc.hmccosmetics.gui.type;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import me.lojosho.shaded.configurate.ConfigurationNode;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.spongepowered.configurate.ConfigurationNode;
public abstract class Type { public abstract class Type {

View File

@@ -1,60 +1,83 @@
package com.hibiscusmc.hmccosmetics.gui.type.types; package com.hibiscusmc.hmccosmetics.gui.type.types;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.serializer.ItemSerializer; import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType; import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType;
import com.hibiscusmc.hmccosmetics.gui.action.Actions; import com.hibiscusmc.hmccosmetics.gui.action.Actions;
import com.hibiscusmc.hmccosmetics.gui.special.DyeMenu; import com.hibiscusmc.hmccosmetics.gui.special.DyeMenu;
import com.hibiscusmc.hmccosmetics.gui.type.Type; import com.hibiscusmc.hmccosmetics.gui.type.Type;
import com.hibiscusmc.hmccosmetics.hooks.Hooks;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.misc.StringUtils; import me.lojosho.hibiscuscommons.config.serializer.ItemSerializer;
import com.hibiscusmc.hmccosmetics.util.misc.Utils; import me.lojosho.hibiscuscommons.hooks.Hooks;
import me.clip.placeholderapi.PlaceholderAPI; import me.lojosho.shaded.configurate.ConfigurationNode;
import me.lojosho.shaded.configurate.serialize.SerializationException;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; 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.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
public class TypeCosmetic extends Type { public class TypeCosmetic extends Type {
public TypeCosmetic(String id) {
super(id);
}
public TypeCosmetic() { public TypeCosmetic() {
super("cosmetic"); super("cosmetic");
} }
@Override @Override
public void run(CosmeticUser user, @NotNull ConfigurationNode config, ClickType clickType) { public void run(CosmeticUser user, @NotNull ConfigurationNode config, ClickType clickType) {
if (config.node("cosmetic").virtual()) return; MessagesUtil.sendDebugMessages("Running Cosmetic Click Type");
if (config.node("cosmetic").virtual()) {
MessagesUtil.sendDebugMessages("Cosmetic Config Field Virtual");
return;
}
String cosmeticName = config.node("cosmetic").getString(); String cosmeticName = config.node("cosmetic").getString();
Cosmetic cosmetic = Cosmetics.getCosmetic(cosmeticName); Cosmetic cosmetic = Cosmetics.getCosmetic(cosmeticName);
Player player = user.getPlayer(); Player player = user.getPlayer();
if (cosmetic == null) { if (cosmetic == null) {
MessagesUtil.sendDebugMessages("No Cosmetic Found");
MessagesUtil.sendMessage(player, "invalid-cosmetic"); MessagesUtil.sendMessage(player, "invalid-cosmetic");
return; return;
} }
if (!user.canEquipCosmetic(cosmetic)) { if (!user.canEquipCosmetic(cosmetic)) {
MessagesUtil.sendDebugMessages("No Cosmetic Permission");
MessagesUtil.sendMessage(player, "no-cosmetic-permission"); MessagesUtil.sendMessage(player, "no-cosmetic-permission");
return; return;
} }
boolean isUnEquippingCosmetic = false;
if (user.getCosmetic(cosmetic.getSlot()) == cosmetic) isUnEquippingCosmetic = true;
String requiredClick;
if (isUnEquippingCosmetic) requiredClick = Settings.getCosmeticUnEquipClickType();
else requiredClick = Settings.getCosmeticEquipClickType();
MessagesUtil.sendDebugMessages("Required click type: " + requiredClick);
MessagesUtil.sendDebugMessages("Click type: " + clickType.name());
if (!requiredClick.equalsIgnoreCase("ANY") && !requiredClick.equalsIgnoreCase(clickType.name())) {
MessagesUtil.sendMessage(user.getPlayer(), "invalid-click-type");
return;
}
List<String> actionStrings = new ArrayList<>(); List<String> actionStrings = new ArrayList<>();
ConfigurationNode actionConfig = config.node("actions"); ConfigurationNode actionConfig = config.node("actions");
MessagesUtil.sendDebugMessages("Running Actions");
try { try {
if (!actionConfig.node("any").virtual()) actionStrings.addAll(actionConfig.node("any").getList(String.class)); if (!actionConfig.node("any").virtual()) actionStrings.addAll(actionConfig.node("any").getList(String.class));
@@ -65,9 +88,15 @@ public class TypeCosmetic extends Type {
if (clickType.isRightClick()) { if (clickType.isRightClick()) {
if (!actionConfig.node("right-click").virtual()) actionStrings.addAll(actionConfig.node("right-click").getList(String.class)); if (!actionConfig.node("right-click").virtual()) actionStrings.addAll(actionConfig.node("right-click").getList(String.class));
} }
if (clickType.equals(ClickType.SHIFT_LEFT)) {
if (!actionConfig.node("shift-left-click").virtual()) actionStrings.addAll(actionConfig.node("shift-left-click").getList(String.class));
}
if (clickType.equals(ClickType.SHIFT_RIGHT)) {
if (!actionConfig.node("shift-right-click").virtual()) actionStrings.addAll(actionConfig.node("shift-right-click").getList(String.class));
}
} }
if (user.getCosmetic(cosmetic.getSlot()) == cosmetic) { if (isUnEquippingCosmetic) {
if (!actionConfig.node("on-unequip").virtual()) actionStrings.addAll(actionConfig.node("on-unequip").getList(String.class)); if (!actionConfig.node("on-unequip").virtual()) actionStrings.addAll(actionConfig.node("on-unequip").getList(String.class));
MessagesUtil.sendDebugMessages("on-unequip"); MessagesUtil.sendDebugMessages("on-unequip");
user.removeCosmeticSlot(cosmetic); user.removeCosmeticSlot(cosmetic);
@@ -75,7 +104,7 @@ public class TypeCosmetic extends Type {
if (!actionConfig.node("on-equip").virtual()) actionStrings.addAll(actionConfig.node("on-equip").getList(String.class)); if (!actionConfig.node("on-equip").virtual()) actionStrings.addAll(actionConfig.node("on-equip").getList(String.class));
MessagesUtil.sendDebugMessages("on-equip"); MessagesUtil.sendDebugMessages("on-equip");
// TODO: Redo this // TODO: Redo this
if (cosmetic.isDyable()) { if (cosmetic.isDyable() && Hooks.isActiveHook("HMCColor")) {
DyeMenu.openMenu(user, cosmetic); DyeMenu.openMenu(user, cosmetic);
} else { } else {
user.addPlayerCosmetic(cosmetic); user.addPlayerCosmetic(cosmetic);
@@ -85,7 +114,7 @@ public class TypeCosmetic extends Type {
Actions.runActions(user, actionStrings); Actions.runActions(user, actionStrings);
} catch (SerializationException e) { } catch (SerializationException e) {
throw new RuntimeException(e); e.printStackTrace();
} }
// Fixes issue with offhand cosmetics not appearing. Yes, I know this is dumb // Fixes issue with offhand cosmetics not appearing. Yes, I know this is dumb
Runnable run = () -> user.updateCosmetic(cosmetic.getSlot()); Runnable run = () -> user.updateCosmetic(cosmetic.getSlot());
@@ -95,16 +124,16 @@ public class TypeCosmetic extends Type {
} }
} }
run.run(); run.run();
MessagesUtil.sendDebugMessages("Finished Type Click Run");
} }
@Override @Override
public ItemStack setItem(CosmeticUser user, @NotNull ConfigurationNode config, ItemStack itemStack, int slot) { public ItemStack setItem(CosmeticUser user, @NotNull ConfigurationNode config, ItemStack itemStack, int slot) {
ItemMeta itemMeta = itemStack.getItemMeta(); itemStack.setItemMeta(processLoreLines(user, itemStack.getItemMeta()));
itemStack.setItemMeta(processLoreLines(user, itemMeta));
if (config.node("cosmetic").virtual()) { if (config.node("cosmetic").virtual()) {
return itemStack; return itemStack;
}; }
String cosmeticName = config.node("cosmetic").getString(); String cosmeticName = config.node("cosmetic").getString();
Cosmetic cosmetic = Cosmetics.getCosmetic(cosmeticName); Cosmetic cosmetic = Cosmetics.getCosmetic(cosmeticName);
if (cosmetic == null) { if (cosmetic == null) {
@@ -128,7 +157,7 @@ public class TypeCosmetic extends Type {
return itemStack; return itemStack;
} }
if (!user.canEquipCosmetic(cosmetic) && !config.node("locked-item").virtual()) { if (!user.canEquipCosmetic(cosmetic, true) && !config.node("locked-item").virtual()) {
MessagesUtil.sendDebugMessages("GUI Locked Item"); MessagesUtil.sendDebugMessages("GUI Locked Item");
ConfigurationNode lockedItem = config.node("locked-item"); ConfigurationNode lockedItem = config.node("locked-item");
try { try {
@@ -153,14 +182,21 @@ public class TypeCosmetic extends Type {
private ItemMeta processLoreLines(CosmeticUser user, @NotNull ItemMeta itemMeta) { private ItemMeta processLoreLines(CosmeticUser user, @NotNull ItemMeta itemMeta) {
List<String> processedLore = new ArrayList<>(); List<String> processedLore = new ArrayList<>();
if (itemMeta.hasDisplayName()) {
itemMeta.setDisplayName(Hooks.processPlaceholders(user.getPlayer(), itemMeta.getDisplayName()));
}
if (itemMeta.hasLore()) { if (itemMeta.hasLore()) {
for (String loreLine : itemMeta.getLore()) { for (String loreLine : itemMeta.getLore()) {
if (Hooks.isActiveHook("PlaceholderAPI")) processedLore.add(Hooks.processPlaceholders(user.getPlayer(), loreLine));
loreLine = PlaceholderAPI.setPlaceholders(user.getPlayer(), loreLine);
processedLore.add(loreLine);
} }
} }
if (itemMeta instanceof SkullMeta skullMeta) {
if (skullMeta.hasOwner()) {
skullMeta.setOwner(Hooks.processPlaceholders(user.getPlayer(), skullMeta.getOwner()));
}
}
itemMeta.setLore(processedLore); itemMeta.setLore(processedLore);
return itemMeta; return itemMeta;
} }

View File

@@ -2,15 +2,15 @@ package com.hibiscusmc.hmccosmetics.gui.type.types;
import com.hibiscusmc.hmccosmetics.gui.action.Actions; import com.hibiscusmc.hmccosmetics.gui.action.Actions;
import com.hibiscusmc.hmccosmetics.gui.type.Type; import com.hibiscusmc.hmccosmetics.gui.type.Type;
import com.hibiscusmc.hmccosmetics.hooks.Hooks;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import me.clip.placeholderapi.PlaceholderAPI; import me.lojosho.hibiscuscommons.hooks.Hooks;
import me.lojosho.shaded.configurate.ConfigurationNode;
import me.lojosho.shaded.configurate.serialize.SerializationException;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -43,6 +43,12 @@ public class TypeEmpty extends Type {
if (clickType.isRightClick()) { if (clickType.isRightClick()) {
if (!actionConfig.node("right-click").virtual()) actionStrings.addAll(actionConfig.node("right-click").getList(String.class)); if (!actionConfig.node("right-click").virtual()) actionStrings.addAll(actionConfig.node("right-click").getList(String.class));
} }
if (clickType.equals(ClickType.SHIFT_LEFT)) {
if (!actionConfig.node("shift-left-click").virtual()) actionStrings.addAll(actionConfig.node("shift-left-click").getList(String.class));
}
if (clickType.equals(ClickType.SHIFT_RIGHT)) {
if (!actionConfig.node("shift-right-click").virtual()) actionStrings.addAll(actionConfig.node("shift-right-click").getList(String.class));
}
} }
// We run the actions once we got the raw strings from the config. // We run the actions once we got the raw strings from the config.
@@ -58,13 +64,23 @@ public class TypeEmpty extends Type {
List<String> processedLore = new ArrayList<>(); List<String> processedLore = new ArrayList<>();
ItemMeta itemMeta = itemStack.getItemMeta(); ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta.hasDisplayName()) {
itemMeta.setDisplayName(Hooks.processPlaceholders(user.getPlayer(), itemMeta.getDisplayName()));
}
if (itemMeta.hasLore()) { if (itemMeta.hasLore()) {
for (String loreLine : itemMeta.getLore()) { for (String loreLine : itemMeta.getLore()) {
if (Hooks.isActiveHook("PlaceholderAPI")) processedLore.add(Hooks.processPlaceholders(user.getPlayer(), loreLine));
loreLine = PlaceholderAPI.setPlaceholders(user.getPlayer(), loreLine);
processedLore.add(loreLine);
} }
} }
if (itemMeta instanceof SkullMeta skullMeta) {
if (skullMeta.hasOwner()) {
skullMeta.setOwner(Hooks.processPlaceholders(user.getPlayer(), skullMeta.getOwner()));
}
}
itemMeta.setLore(processedLore);
itemStack.setItemMeta(itemMeta); itemStack.setItemMeta(itemMeta);
return itemStack; return itemStack;
} }

View File

@@ -1,93 +0,0 @@
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;
/**
* Represents a hook into other minecraft plugins
*/
public abstract class Hook implements Listener {
private final String id;
private boolean active = false;
private boolean itemHook = false;
public Hook(@NotNull String id) {
this.id = id;
Hooks.addHook(this);
}
/**
* 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() { }
/**
* 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;
}
/**
* Gets the id of this hook
*
* @return The unique id for this hook
*/
@NotNull
public final String getId() {
return id;
}
/**
* 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;
}
/**
* 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;
}
/**
* 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

@@ -1,78 +0,0 @@
package com.hibiscusmc.hmccosmetics.hooks;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.hooks.items.*;
import com.hibiscusmc.hmccosmetics.hooks.misc.*;
import com.hibiscusmc.hmccosmetics.hooks.placeholders.HookPlaceholderAPI;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
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 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());
}
public static boolean isItemHook(@NotNull String id) {
return hooks.containsKey(id.toLowerCase());
}
public static void addHook(Hook hook) {
hooks.put(hook.getId().toLowerCase(), hook);
}
public static void setup() {
for (Hook hook : hooks.values()) {
if (Bukkit.getPluginManager().getPlugin(hook.getId()) != null) {
HMCCosmeticsPlugin.getInstance().getServer().getPluginManager().registerEvents(hook, HMCCosmeticsPlugin.getInstance());
hook.setActive(true);
hook.load();
HMCCosmeticsPlugin.getInstance().getLogger().info("Successfully hooked into " + hook.getId());
}
}
}
@Nullable
public static ItemStack getItem(@NotNull String raw) {
if (!raw.contains(":")) {
Material mat = Material.getMaterial(raw.toUpperCase());
if (mat == null) return null;
return new ItemStack(mat);
}
// Ex. Oraxen:BigSword
// split[0] is the plugin name
// split[1] is the item name
String[] split = raw.split(":", 2);
if (!isItemHook(split[0])) return null;
Hook hook = getHook(split[0]);
if (!hook.hasEnabledItemHook()) 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.isActive();
}
}

View File

@@ -1,27 +0,0 @@
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

@@ -2,7 +2,8 @@ package com.hibiscusmc.hmccosmetics.hooks.items;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.hooks.Hook; import me.lojosho.hibiscuscommons.hooks.Hook;
import me.lojosho.hibiscuscommons.hooks.HookFlag;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -11,8 +12,7 @@ import org.jetbrains.annotations.NotNull;
*/ */
public class HookHMCCosmetics extends Hook { public class HookHMCCosmetics extends Hook {
public HookHMCCosmetics() { public HookHMCCosmetics() {
super("HMCCosmetics"); super("HMCCosmetics", HookFlag.ITEM_SUPPORT);
setEnabledItemHook(true);
} }
/** /**

View File

@@ -1,46 +0,0 @@
package com.hibiscusmc.hmccosmetics.hooks.items;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.hooks.Hook;
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.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* 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() {
super("itemsadder");
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(@NotNull String itemId) {
if (enabled) {
CustomStack stack = CustomStack.getInstance(itemId);
if (stack == null) return null;
return stack.getItemStack();
} else {
return new ItemStack(Material.AIR);
}
}
@EventHandler
public void onItemAdderDataLoad(ItemsAdderLoadDataEvent event) {
// 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,28 +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.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* A hook that integrates the plugin {@link com.mineinabyss.looty.LootyPlugin Looty} to provide custom items
*/
@SuppressWarnings("SpellCheckingInspection")
public class HookLooty extends Hook {
public HookLooty() {
super("looty");
setEnabledItemHook(true);
}
/**
* Gets a cosmetic {@link ItemStack} that is associated with the provided id from the plugin {@link com.mineinabyss.looty.LootyPlugin Looty}
*/
@Override
public ItemStack getItem(@NotNull String itemId) {
PrefabKey prefabKey = PrefabKey.Companion.ofOrNull(itemId);
if (prefabKey == null) return null;
return LootyFactory.INSTANCE.createFromPrefab(prefabKey);
}
}

View File

@@ -1,25 +0,0 @@
package com.hibiscusmc.hmccosmetics.hooks.items;
import com.hibiscusmc.hmccosmetics.hooks.Hook;
import io.lumine.mythic.bukkit.MythicBukkit;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* 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(@NotNull String itemId) {
return MythicBukkit.inst().getItemManager().getItemStack(itemId);
}
}

View File

@@ -1,28 +0,0 @@
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.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* 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(@NotNull String itemId) {
ItemBuilder builder = OraxenItems.getItemById(itemId);
if (builder == null) return null;
return builder.build();
}
}

View File

@@ -1,35 +0,0 @@
package com.hibiscusmc.hmccosmetics.hooks.misc;
import com.Zrips.CMI.events.CMIPlayerUnVanishEvent;
import com.Zrips.CMI.events.CMIPlayerVanishEvent;
import com.hibiscusmc.hmccosmetics.hooks.Hook;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.jetbrains.annotations.NotNull;
/**
* A hook that integrates the plugin {@link com.Zrips.CMI.CMI CMI}
*/
public class HookCMI extends Hook {
public HookCMI() {
super("CMI");
}
@EventHandler
public void onPlayerVanish(@NotNull CMIPlayerVanishEvent event) {
Player player = event.getPlayer();
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
user.hideCosmetics(CosmeticUser.HiddenReason.PLUGIN);
}
@EventHandler
public void onPlayerShow(@NotNull CMIPlayerUnVanishEvent event) {
Player player = event.getPlayer();
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
user.showCosmetics();
}
}

View File

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

View File

@@ -1,32 +0,0 @@
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

@@ -1,37 +0,0 @@
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 de.myzelyam.api.vanish.PlayerHideEvent;
import de.myzelyam.api.vanish.PlayerShowEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.jetbrains.annotations.NotNull;
/**
* 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");
}
@EventHandler
public void onPlayerVanish(@NotNull PlayerHideEvent event) {
Player player = event.getPlayer();
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
user.hideCosmetics(CosmeticUser.HiddenReason.PLUGIN);
}
@EventHandler
public void onPlayerShow(@NotNull PlayerShowEvent event) {
Player player = event.getPlayer();
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
user.showCosmetics();
}
}

View File

@@ -1,37 +0,0 @@
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 de.myzelyam.api.vanish.PlayerHideEvent;
import de.myzelyam.api.vanish.PlayerShowEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.jetbrains.annotations.NotNull;
/**
* 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");
}
@EventHandler
public void onPlayerVanish(@NotNull PlayerHideEvent event) {
Player player = event.getPlayer();
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
user.hideCosmetics(CosmeticUser.HiddenReason.PLUGIN);
}
@EventHandler
public void onPlayerShow(@NotNull PlayerShowEvent event) {
Player player = event.getPlayer();
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
user.showCosmetics();
}
}

View File

@@ -54,84 +54,76 @@ public class HMCPlaceholderExpansion extends PlaceholderExpansion {
@Override @Override
public String onRequest(@NotNull OfflinePlayer player, @NotNull String params) { public String onRequest(@NotNull OfflinePlayer player, @NotNull String params) {
if (!player.isOnline()) return null; if (!player.isOnline()) return TranslationUtil.getTranslation("user-cosmetic", "offline");
CosmeticUser user = CosmeticUsers.getUser(player.getPlayer()); CosmeticUser user = CosmeticUsers.getUser(player.getPlayer());
if (user == null) return null; if (user == null) return TranslationUtil.getTranslation("user-cosmetic", "invalid-user");
List<String> placeholderArgs = Arrays.asList(params.split("_", 3)); List<String> placeholderArgs = Arrays.asList(params.split("_", 3));
switch (placeholderArgs.get(0).toLowerCase()) { switch (placeholderArgs.get(0).toLowerCase()) {
case "using": case "using":
if (placeholderArgs == null) { if (placeholderArgs.size() >= 2) {
return null;
}
if (placeholderArgs.get(1) != null) {
Cosmetic cosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1)); Cosmetic cosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1));
if (cosmetic == null) return "INVALID_COSMETIC"; if (cosmetic == null) return "INVALID_COSMETIC";
Cosmetic currentCosmetic = user.getCosmetic(cosmetic.getSlot()); Cosmetic currentCosmetic = user.getCosmetic(cosmetic.getSlot());
if (currentCosmetic == null) 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 "true"; if (currentCosmetic.getId() == cosmetic.getId()) return TranslationUtil.getTranslation("using-cosmetic", String.valueOf(true));
return "false"; return TranslationUtil.getTranslation("using-cosmetic", String.valueOf(false));
} }
case "current": case "current":
if (placeholderArgs == null) { if (placeholderArgs.size() >= 2) {
return null;
}
if (placeholderArgs.get(1) != null) {
CosmeticSlot slot = CosmeticSlot.valueOf(placeholderArgs.get(1).toUpperCase()); CosmeticSlot slot = CosmeticSlot.valueOf(placeholderArgs.get(1).toUpperCase());
if (slot == null) return null; if (slot == null) return null;
if (user.getCosmetic(slot) == null) return null; if (user.getCosmetic(slot) == null) return TranslationUtil.getTranslation("current-cosmetic", "no-cosmetic");
if (placeholderArgs.size() == 2) return user.getCosmetic(slot).getId(); if (placeholderArgs.size() == 2) return user.getCosmetic(slot).getId();
String output;
switch (placeholderArgs.get(2).toLowerCase()) { switch (placeholderArgs.get(2).toLowerCase()) {
case "material" -> { case "material" -> {
return getMaterialName(user.getCosmetic(slot)); output = getMaterialName(user.getCosmetic(slot));
} }
case "custommodeldata" -> { case "custommodeldata" -> {
return getModelData(user.getCosmetic(slot)); output = getModelData(user.getCosmetic(slot));
} }
case "name" -> { case "name" -> {
return getItemName(user.getCosmetic(slot)); output = getItemName(user.getCosmetic(slot));
} }
case "lore" -> { case "lore" -> {
return getItemLore(user.getCosmetic(slot)); output = getItemLore(user.getCosmetic(slot));
} }
case "permission" -> { case "permission" -> {
return user.getCosmetic(slot).getPermission(); output = user.getCosmetic(slot).getPermission();
} }
default -> { default -> {
return user.getCosmetic(slot).getId(); output = user.getCosmetic(slot).getId();
} }
} }
if (output == null) output = "none";
return TranslationUtil.getTranslation("current-cosmetic", output);
} }
case "unlocked": case "unlocked":
if (placeholderArgs == null) { if (placeholderArgs.size() >= 2) {
return null;
}
if (placeholderArgs.get(1) != null) {
Cosmetic cosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1)); Cosmetic cosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1));
if (cosmetic == null) { if (cosmetic == null) {
Cosmetic secondAttemptCosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1) + "_" + placeholderArgs.get(2)); if (placeholderArgs.size() >= 3) {
if (secondAttemptCosmetic == null) { Cosmetic secondAttemptCosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1) + "_" + placeholderArgs.get(2));
return "INVALID_COSMETIC"; if (secondAttemptCosmetic == null) {
return "INVALID_COSMETIC";
} else {
cosmetic = secondAttemptCosmetic;
}
} else { } 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, true)));
} }
case "equipped": case "equipped":
if (placeholderArgs == null) { if (placeholderArgs.size() >= 2) {
return null;
}
if (placeholderArgs.get(1) != null) {
String args1 = placeholderArgs.get(1); String args1 = placeholderArgs.get(1);
if (EnumUtils.isValidEnum(CosmeticSlot.class, args1.toUpperCase())) { if (EnumUtils.isValidEnum(CosmeticSlot.class, args1.toUpperCase())) {
if (user.getCosmetic(CosmeticSlot.valueOf(args1.toUpperCase())) != null) { return TranslationUtil.getTranslation("equipped-cosmetic", String.valueOf(user.getCosmetic(CosmeticSlot.valueOf(args1.toUpperCase())) != null));
return "true";
} else {
return "false";
}
} }
MessagesUtil.sendDebugMessages(args1); MessagesUtil.sendDebugMessages(args1);
@@ -149,15 +141,34 @@ public class HMCPlaceholderExpansion extends PlaceholderExpansion {
return "INVALID_COSMETIC"; return "INVALID_COSMETIC";
} }
} }
if (user.getCosmetic(cosmetic.getSlot()) == null) return "false"; Cosmetic equippedCosmetic = user.getCosmetic(cosmetic.getSlot());
if (cosmetic.getId() == user.getCosmetic(cosmetic.getSlot()).getId()) { if (equippedCosmetic == null) return TranslationUtil.getTranslation("equipped-cosmetic", "false");
return "true"; return TranslationUtil.getTranslation("equipped-cosmetic", String.valueOf(cosmetic.getId().equals(equippedCosmetic.getId())));
} else { }
return "false"; // %hmccosmetics_amount_balloon_unlocked%
case "amount":
if (placeholderArgs.size() >= 2) {
String args1 = placeholderArgs.get(1).toUpperCase(); // changes offhand to OFFHAND
if (!EnumUtils.isValidEnum(CosmeticSlot.class, args1)) return null;
CosmeticSlot slot = CosmeticSlot.valueOf(args1);
int amount = 0;
boolean checkUnlocked = false;
if (placeholderArgs.size() >= 3) if (placeholderArgs.get(2).equalsIgnoreCase("unlocked")) checkUnlocked = true;
for (Cosmetic cosmetic : Cosmetics.values()) {
if (cosmetic.getSlot() != slot) continue;
if (checkUnlocked && !user.canEquipCosmetic(cosmetic)) continue;
amount += 1;
} }
return TranslationUtil.getTranslation("amount-cosmetic", String.valueOf(amount));
} else {
return TranslationUtil.getTranslation("amount-cosmetic", String.valueOf(Cosmetics.values().size()));
} }
case "wardrobe-enabled": case "wardrobe-enabled":
return String.valueOf(user.isInWardrobe()); return TranslationUtil.getTranslation("in-wardrobe", String.valueOf(user.isInWardrobe()));
} }
return null; return null;
} }
@@ -216,6 +227,7 @@ public class HMCPlaceholderExpansion extends PlaceholderExpansion {
if (!item.hasItemMeta()) return null; if (!item.hasItemMeta()) return null;
ItemMeta itemMeta = item.getItemMeta(); ItemMeta itemMeta = item.getItemMeta();
if (itemMeta == null) return null; if (itemMeta == null) return null;
if (!itemMeta.hasDisplayName()) return null;
return itemMeta.getDisplayName(); return itemMeta.getDisplayName();
} }

View File

@@ -1,20 +0,0 @@
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,6 +4,7 @@ import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.sk89q.worldguard.WorldGuard; import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.flags.Flag; import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.StateFlag; 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.FlagConflictException;
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry; import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
@@ -16,21 +17,26 @@ public class WGHook {
/** /**
* @implNote Please use {@link #getCosmeticEnableFlag()} instead * @implNote Please use {@link #getCosmeticEnableFlag()} instead
*/ */
public static StateFlag COSMETIC_ENABLE_FLAG; private static StateFlag COSMETIC_ENABLE_FLAG;
private static StateFlag EMOTES_ENABLE_FLAG;
/** /**
* @implNote Please use {@link #getCosmeticWardrobeFlag()} instead * @implNote Please use {@link #getCosmeticWardrobeFlag()} instead
*/ */
public static StateFlag COSMETIC_WARDROBE_FLAG; private static StringFlag COSMETIC_WARDROBE_FLAG;
public WGHook() { public WGHook() {
FlagRegistry registry = WorldGuard.getInstance().getFlagRegistry(); FlagRegistry registry = WorldGuard.getInstance().getFlagRegistry();
try { try {
StateFlag cosmeticFlag = new StateFlag("cosmetic-enable", false); StateFlag cosmeticFlag = new StateFlag("cosmetic-enable", false);
StateFlag wardrobeFlag = new StateFlag("cosmetic-wardrobe", false); StateFlag emoteFlag = new StateFlag("emotes-enable", false);
StringFlag wardrobeFlag = new StringFlag("cosmetic-wardrobe");
registry.register(cosmeticFlag); registry.register(cosmeticFlag);
registry.register(emoteFlag);
registry.register(wardrobeFlag); registry.register(wardrobeFlag);
COSMETIC_ENABLE_FLAG = cosmeticFlag; COSMETIC_ENABLE_FLAG = cosmeticFlag;
EMOTES_ENABLE_FLAG = emoteFlag;
COSMETIC_WARDROBE_FLAG = wardrobeFlag; COSMETIC_WARDROBE_FLAG = wardrobeFlag;
} catch (FlagConflictException e) { } catch (FlagConflictException e) {
Flag<?> existing = registry.get("cosmetic-enable"); Flag<?> existing = registry.get("cosmetic-enable");
@@ -52,11 +58,19 @@ public class WGHook {
return COSMETIC_ENABLE_FLAG; return COSMETIC_ENABLE_FLAG;
} }
/**
* Gets the emotes enable {@link StateFlag}
* @return The emotes enable {@link StateFlag}
*/
public static StateFlag getEmotesEnableFlag() {
return EMOTES_ENABLE_FLAG;
}
/** /**
* Gets the cosmetic wardrobe {@link StateFlag} * Gets the cosmetic wardrobe {@link StateFlag}
* @return The cosmetic wardrobe {@link StateFlag} * @return The cosmetic wardrobe {@link StateFlag}
*/ */
public static StateFlag getCosmeticWardrobeFlag() { public static StringFlag getCosmeticWardrobeFlag() {
return COSMETIC_WARDROBE_FLAG; return COSMETIC_WARDROBE_FLAG;
} }

View File

@@ -1,5 +1,8 @@
package com.hibiscusmc.hmccosmetics.hooks.worldguard; package com.hibiscusmc.hmccosmetics.hooks.worldguard;
import com.hibiscusmc.hmccosmetics.api.events.PlayerEmoteStartEvent;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers; import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
@@ -9,39 +12,95 @@ import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.RegionContainer; import com.sk89q.worldguard.protection.regions.RegionContainer;
import com.sk89q.worldguard.protection.regions.RegionQuery; import com.sk89q.worldguard.protection.regions.RegionQuery;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
* Contains {@link com.sk89q.worldguard.WorldGuard WorldGuard} related event listeners * Contains {@link com.sk89q.worldguard.WorldGuard WorldGuard} related event listeners
*/ */
public class WGListener implements Listener { public class WGListener implements Listener {
@EventHandler @EventHandler(priority = EventPriority.MONITOR)
public void onPlayerMove(@NotNull PlayerMoveEvent event) { public void onPlayerMove(@NotNull PlayerMoveEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer()); CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
if (user == null) return; if (user == null) return;
Location location = event.getPlayer().getLocation(); Location location = event.getPlayer().getLocation();
com.sk89q.worldedit.util.Location loc = BukkitAdapter.adapt(location); ApplicableRegionSet set = getRegions(location);
RegionContainer region = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = region.createQuery();
ApplicableRegionSet set = query.getApplicableRegions(loc);
if (user.getHidden()) { if (user.getHidden()) {
if (user.getHiddenReason() == CosmeticUser.HiddenReason.WORLDGUARD && set.getRegions().size() == 0) { if (user.getHiddenReason() == CosmeticUser.HiddenReason.WORLDGUARD && set.getRegions().isEmpty()) {
user.showCosmetics(); user.showCosmetics();
} }
} }
for (ProtectedRegion protectedRegion : set.getRegions()) { for (ProtectedRegion protectedRegion : set.getRegions()) {
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticEnableFlag())) { 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); user.hideCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
return; return;
} }
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticWardrobeFlag())) { if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticWardrobeFlag())) {
if (!protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString().equalsIgnoreCase("ALLOW")) return; if (!WardrobeSettings.getWardrobeNames().contains(protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString())) return;
user.enterWardrobe(); Wardrobe wardrobe = WardrobeSettings.getWardrobe(protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString());
user.enterWardrobe(true, wardrobe);
} }
} }
} }
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerTeleport(PlayerTeleportEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
if (user == null) return;
Location location = event.getTo();
ApplicableRegionSet set = getRegions(location);
if (user.getHidden()) {
if (user.getHiddenReason() == CosmeticUser.HiddenReason.WORLDGUARD && set.getRegions().isEmpty()) {
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);
}
}
}
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerEmote(PlayerEmoteStartEvent event) {
Player player = event.getUser().getPlayer();
if (player == null) return;
Location location = player.getLocation();
ApplicableRegionSet set = getRegions(location);
for (ProtectedRegion protectedRegion : set.getRegions()) {
if (protectedRegion.getFlags().containsKey(WGHook.getEmotesEnableFlag())) {
if (protectedRegion.getFlags().get(WGHook.getEmotesEnableFlag()).toString().equalsIgnoreCase("DENY")) {
event.setCancelled(true);
return;
}
return;
}
}
}
private ApplicableRegionSet getRegions(Location location) {
com.sk89q.worldedit.util.Location loc = BukkitAdapter.adapt(location);
RegionContainer region = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = region.createQuery();
return query.getApplicableRegions(loc);
}
} }

View File

@@ -0,0 +1,30 @@
package com.hibiscusmc.hmccosmetics.listener;
import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class PaperPlayerGameListener implements Listener {
@EventHandler
public void onPlayerArmorEquip(PlayerArmorChangeEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
if (user == null) return;
if (user.isInWardrobe()) return;
user.updateCosmetic(slotTypeToCosmeticType(event.getSlotType()));
}
private CosmeticSlot slotTypeToCosmeticType(PlayerArmorChangeEvent.SlotType slotType) {
return switch (slotType) {
case HEAD -> CosmeticSlot.HELMET;
case FEET -> CosmeticSlot.BOOTS;
case LEGS -> CosmeticSlot.LEGGINGS;
case CHEST -> CosmeticSlot.CHESTPLATE;
default -> null;
};
}
}

View File

@@ -2,15 +2,15 @@ package com.hibiscusmc.hmccosmetics.listener;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.DatabaseSettings; import com.hibiscusmc.hmccosmetics.config.DatabaseSettings;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.database.Database; import com.hibiscusmc.hmccosmetics.database.Database;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers; import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager; import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
@@ -18,25 +18,47 @@ import org.jetbrains.annotations.NotNull;
public class PlayerConnectionListener implements Listener { public class PlayerConnectionListener implements Listener {
@EventHandler @EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoin(@NotNull PlayerJoinEvent event) { public void onPlayerJoin(@NotNull PlayerJoinEvent event) {
if (event.getPlayer().isOp() || event.getPlayer().hasPermission("hmccosmetics.notifyupdate")) { if (event.getPlayer().isOp() || event.getPlayer().hasPermission("hmccosmetics.notifyupdate")) {
if (!HMCCosmeticsPlugin.getLatestVersion().equalsIgnoreCase(HMCCosmeticsPlugin.getInstance().getDescription().getVersion()) && HMCCosmeticsPlugin.getLatestVersion() != null) if (!HMCCosmeticsPlugin.getInstance().getLatestVersion().equalsIgnoreCase(HMCCosmeticsPlugin.getInstance().getDescription().getVersion()) && HMCCosmeticsPlugin.getInstance().getLatestVersion().isEmpty())
MessagesUtil.sendMessageNoKey( MessagesUtil.sendMessageNoKey(
event.getPlayer(), event.getPlayer(),
"<br>" + "<br>" +
"<GRAY>There is a new version of <light_purple><Bold>HMCCosmetics<reset><gray> available!<br>" + "<GRAY>There is a new version of <light_purple><Bold>HMCCosmetics<reset><gray> available!<br>" +
"<GRAY>Current version: <red>" + HMCCosmeticsPlugin.getInstance().getDescription().getVersion() + " <GRAY>| Latest version: <light_purple>" + HMCCosmeticsPlugin.getLatestVersion() + "<br>" + "<GRAY>Current version: <red>" + HMCCosmeticsPlugin.getInstance().getDescription().getVersion() + " <GRAY>| Latest version: <light_purple>" + HMCCosmeticsPlugin.getInstance().getLatestVersion() + "<br>" +
"<GRAY>Download it on <gold><click:OPEN_URL:'https://www.spigotmc.org/resources/100107/'>Spigot<reset> <gray>or <gold><click:OPEN_URL:'https://polymart.org/resource/1879'>Polymart<reset><gray>!" + "<GRAY>Download it on <gold><click:OPEN_URL:'https://www.spigotmc.org/resources/100107/'>Spigot<reset> <gray>or <gold><click:OPEN_URL:'https://polymart.org/resource/1879'>Polymart<reset><gray>!" +
"<br>" "<br>"
); );
} }
Runnable run = () -> { Runnable run = () -> {
if (!event.getPlayer().isOnline()) return; // If a player is no longer online, don't run this.
CosmeticUser user = Database.get(event.getPlayer().getUniqueId()); CosmeticUser user = Database.get(event.getPlayer().getUniqueId());
CosmeticUsers.addUser(user); CosmeticUsers.addUser(user);
MessagesUtil.sendDebugMessages("Run User Join"); MessagesUtil.sendDebugMessages("Run User Join");
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> user.updateCosmetic(), 4);
// Handle gamemode check
if (Settings.getDisabledGamemodes().contains(user.getPlayer().getGameMode().toString())) {
user.hideCosmetics(CosmeticUser.HiddenReason.GAMEMODE);
} else {
if (user.getHiddenReason() != null && user.getHiddenReason().equals(CosmeticUser.HiddenReason.GAMEMODE)) {
user.showCosmetics();
}
}
// Handle world check
if (Settings.getDisabledWorlds().contains(user.getPlayer().getWorld().getName())) {
user.hideCosmetics(CosmeticUser.HiddenReason.WORLD);
} else {
if (user.getHiddenReason() != null && user.getHiddenReason().equals(CosmeticUser.HiddenReason.WORLD)) {
user.showCosmetics();
}
}
// And finally, launch an update for the cosmetics they have.
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
if (user.getPlayer() == null) return;
user.updateCosmetic();
}, 4);
}; };
if (DatabaseSettings.isEnabledDelay()) { if (DatabaseSettings.isEnabledDelay()) {
@@ -47,20 +69,14 @@ public class PlayerConnectionListener implements Listener {
} }
} }
@EventHandler @EventHandler(priority = EventPriority.MONITOR)
public void onPlayerQuit(@NotNull PlayerQuitEvent event) { public void onPlayerQuit(@NotNull PlayerQuitEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer()); CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
if (user == null) { // Remove any passengers if a user failed to initialize. Bugs can cause this to happen if (user == null) return; // Player never initialized, don't do anything
if (!event.getPlayer().getPassengers().isEmpty()) { if (user.isInWardrobe()) {
for (Entity entity : event.getPlayer().getPassengers()) { user.leaveWardrobe(true);
if (entity.getType() == EntityType.ARMOR_STAND) { user.getPlayer().setInvisible(false);
entity.remove();
}
}
}
return;
} }
if (user.isInWardrobe()) user.leaveWardrobe();
if (user.getUserEmoteManager().isPlayingEmote()) { if (user.getUserEmoteManager().isPlayingEmote()) {
user.getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.CONNECTION); user.getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.CONNECTION);
event.getPlayer().setInvisible(false); event.getPlayer().setInvisible(false);

View File

@@ -9,6 +9,7 @@ import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.EnumWrappers; import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.Pair; import com.comphenix.protocol.wrappers.Pair;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.api.events.PlayerCosmeticPostEquipEvent;
import com.hibiscusmc.hmccosmetics.config.Settings; import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot; import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
@@ -21,9 +22,17 @@ import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers; import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager; import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;
import com.hibiscusmc.hmccosmetics.util.InventoryUtils; import com.hibiscusmc.hmccosmetics.user.manager.UserWardrobeManager;
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import me.lojosho.hibiscuscommons.api.events.HibiscusHookReload;
import me.lojosho.hibiscuscommons.api.events.HibiscusPlayerUnVanishEvent;
import me.lojosho.hibiscuscommons.api.events.HibiscusPlayerVanishEvent;
import me.lojosho.hibiscuscommons.hooks.items.HookItemAdder;
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
@@ -32,6 +41,7 @@ import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Pose; import org.bukkit.entity.Pose;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.*; import org.bukkit.event.entity.*;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
@@ -42,6 +52,8 @@ import org.bukkit.persistence.PersistentDataType;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.spigotmc.event.entity.EntityDismountEvent;
import org.spigotmc.event.entity.EntityMountEvent;
import java.util.*; import java.util.*;
@@ -50,16 +62,18 @@ public class PlayerGameListener implements Listener {
public PlayerGameListener() { public PlayerGameListener() {
registerInventoryClickListener(); registerInventoryClickListener();
registerMenuChangeListener(); registerMenuChangeListener();
registerEntityStatusListener();
registerPlayerEquipmentListener(); registerPlayerEquipmentListener();
registerPlayerArmListener(); registerPlayerArmListener();
registerEntityUseListener(); registerEntityUseListener();
registerSlotChangeListener();
//registerLookMovement(); //registerLookMovement();
//registerMoveListener(); //registerMoveListener();
//registerTeleportMovement(); //registerTeleportMovement();
} }
@EventHandler @EventHandler(priority = EventPriority.LOW)
public void onPlayerClick(@NotNull InventoryClickEvent event) { public void onPlayerClick(@NotNull InventoryClickEvent event) {
// || !event.getClickedInventory().getType().equals(InventoryType.PLAYER) // || !event.getClickedInventory().getType().equals(InventoryType.PLAYER)
if (event.getClick().isShiftClick()) return; if (event.getClick().isShiftClick()) return;
@@ -70,14 +84,14 @@ public class PlayerGameListener implements Listener {
ItemStack item = event.getCurrentItem(); ItemStack item = event.getCurrentItem();
if (item == null) return; if (item == null) return;
if (Settings.isDestroyLooseCosmetics() && InventoryUtils.isCosmeticItem(event.getCurrentItem())) { if (Settings.isDestroyLooseCosmetics() && HMCCInventoryUtils.isCosmeticItem(event.getCurrentItem())) {
MessagesUtil.sendDebugMessages("remvoe item"); MessagesUtil.sendDebugMessages("remvoe item");
event.getWhoClicked().getInventory().removeItem(event.getCurrentItem()); event.getWhoClicked().getInventory().removeItem(event.getCurrentItem());
} }
EquipmentSlot slot = getArmorSlot(item.getType()); EquipmentSlot slot = getArmorSlot(item.getType());
if (slot == null) return; if (slot == null) return;
CosmeticSlot cosmeticSlot = InventoryUtils.BukkitCosmeticSlot(slot); CosmeticSlot cosmeticSlot = HMCCInventoryUtils.BukkitCosmeticSlot(slot);
if (cosmeticSlot == null) return; if (cosmeticSlot == null) return;
if (!user.hasCosmeticInSlot(cosmeticSlot)) return; if (!user.hasCosmeticInSlot(cosmeticSlot)) return;
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> { Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
@@ -86,7 +100,7 @@ public class PlayerGameListener implements Listener {
MessagesUtil.sendDebugMessages("Event fired, updated cosmetic " + cosmeticSlot); MessagesUtil.sendDebugMessages("Event fired, updated cosmetic " + cosmeticSlot);
} }
@EventHandler @EventHandler(priority = EventPriority.LOW)
public void onPlayerShift(PlayerToggleSneakEvent event) { public void onPlayerShift(PlayerToggleSneakEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId()); CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId());
@@ -101,7 +115,7 @@ public class PlayerGameListener implements Listener {
user.leaveWardrobe(); user.leaveWardrobe();
} }
@EventHandler @EventHandler(priority = EventPriority.LOW)
public void onPlayerTeleport(PlayerTeleportEvent event) { public void onPlayerTeleport(PlayerTeleportEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId()); CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId());
@@ -111,32 +125,36 @@ public class PlayerGameListener implements Listener {
return; return;
} }
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK) && user.getUserBackpackManager() != null) { if (user.isInWardrobe()) {
user.getUserBackpackManager().hideBackpack(); user.leaveWardrobe();
user.getUserBackpackManager().getArmorStand().teleport(event.getTo());
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
user.updateCosmetic();
}, 2);
} }
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
if (user.getEntity() == null || user.isInWardrobe()) return; // fixes disconnecting when in wardrobe (the entity stuff)
if (Settings.getDisabledWorlds().contains(user.getEntity().getLocation().getWorld().getName())) {
user.hideCosmetics(CosmeticUser.HiddenReason.WORLD);
} else {
if (user.getHiddenReason() != null && user.getHiddenReason().equals(CosmeticUser.HiddenReason.WORLD)) {
user.showCosmetics();
}
}
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK) && user.getUserBackpackManager() != null) {
user.respawnBackpack();
}
if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
user.respawnBalloon();
}
user.updateCosmetic();
}, 1);
if (event.getCause().equals(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL) || event.getCause().equals(PlayerTeleportEvent.TeleportCause.END_PORTAL)) return; if (event.getCause().equals(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL) || event.getCause().equals(PlayerTeleportEvent.TeleportCause.END_PORTAL)) return;
if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
final CosmeticBalloonType cosmeticBalloonType = (CosmeticBalloonType) user.getCosmetic(CosmeticSlot.BALLOON);
user.despawnBalloon();
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
user.spawnBalloon(cosmeticBalloonType);
}, 2);
}
if (user.getUserEmoteManager().isPlayingEmote()) { if (user.getUserEmoteManager().isPlayingEmote()) {
user.getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.TELEPORT); user.getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.TELEPORT);
} }
} }
@EventHandler @EventHandler(priority = EventPriority.LOW)
public void portalTeleport(PlayerPortalEvent event) { public void onPortalTeleport(PlayerPortalEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId()); CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId());
MessagesUtil.sendDebugMessages("Player Teleport Event"); MessagesUtil.sendDebugMessages("Player Teleport Event");
@@ -155,21 +173,17 @@ public class PlayerGameListener implements Listener {
} }
} }
@EventHandler @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onPlayerHit(EntityDamageByEntityEvent event) { public void onPlayerHit(EntityDamageByEntityEvent event) {
if (event.isCancelled()) return;
Entity entity = event.getEntity(); Entity entity = event.getEntity();
if (event.getEntity().getEntityId() == event.getDamager().getEntityId()) event.setCancelled(true);
if (!entity.getPersistentDataContainer().has(new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "cosmeticMob"), PersistentDataType.SHORT)) if (!entity.getPersistentDataContainer().has(new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "cosmeticMob"), PersistentDataType.SHORT))
return; return;
event.setCancelled(true); event.setCancelled(true);
} }
@EventHandler @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerDamaged(EntityDamageEvent event) { public void onPlayerDamaged(EntityDamageEvent event) {
if (event.isCancelled()) return; if (!(event.getEntity() instanceof Player player)) return;
if (!(event.getEntity() instanceof Player)) return;
Player player = ((Player) event.getEntity()).getPlayer();
CosmeticUser user = CosmeticUsers.getUser(player); CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return; if (user == null) return;
if (user.getUserEmoteManager().isPlayingEmote()) { if (user.getUserEmoteManager().isPlayingEmote()) {
@@ -185,37 +199,30 @@ public class PlayerGameListener implements Listener {
} }
} }
@EventHandler @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerLook(PlayerMoveEvent event) { public void onPlayerLook(PlayerMoveEvent event) {
if (event.isCancelled()) return;
Player player = event.getPlayer(); Player player = event.getPlayer();
// TODO: Move to packets
CosmeticUser user = CosmeticUsers.getUser(player); CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return; if (user == null) return;
// Really need to look into optimization of this if (!Settings.isEmoteMoveCheck() && user.getUserEmoteManager().isPlayingEmote()) {
event.setCancelled(true);
return;
}
user.updateCosmetic(CosmeticSlot.BACKPACK); user.updateCosmetic(CosmeticSlot.BACKPACK);
user.updateCosmetic(CosmeticSlot.BALLOON); user.updateCosmetic(CosmeticSlot.BALLOON);
} }
@EventHandler @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerPoseChange(EntityPoseChangeEvent event) { public void onPlayerPoseChange(EntityPoseChangeEvent event) {
if (!(event.getEntity() instanceof Player)) return; if (!(event.getEntity() instanceof Player player)) return;
Player player = ((Player) event.getEntity()).getPlayer();
CosmeticUser user = CosmeticUsers.getUser(player); CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return; if (user == null || user.isInWardrobe()) return;
if (!user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) return; if (!user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) return;
Pose pose = event.getPose(); Pose pose = event.getPose();
if (pose.equals(Pose.STANDING)) { if (pose.equals(Pose.STANDING)) {
// #84, Riptides mess with backpacks // #84, Riptides mess with backpacks
ItemStack currentItem = player.getInventory().getItemInMainHand(); ItemStack currentItem = player.getInventory().getItemInMainHand();
if (currentItem != null) { if (currentItem.containsEnchantment(Enchantment.RIPTIDE)) return;
if (currentItem.hasItemMeta()) {
if (currentItem.containsEnchantment(Enchantment.RIPTIDE)) {
return;
}
}
}
if (!user.isBackpackSpawned()) { if (!user.isBackpackSpawned()) {
user.spawnBackpack((CosmeticBackpackType) user.getCosmetic(CosmeticSlot.BACKPACK)); user.spawnBackpack((CosmeticBackpackType) user.getCosmetic(CosmeticSlot.BACKPACK));
} }
@@ -226,11 +233,9 @@ public class PlayerGameListener implements Listener {
} }
} }
@EventHandler @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerArmorDamage(PlayerItemDamageEvent event) { public void onPlayerArmorDamage(PlayerItemDamageEvent event) {
// Possibly look into cancelling the event, then handling the damage on our own. // Possibly look into cancelling the event, then handling the damage on our own.
if (event.isCancelled()) return;
MessagesUtil.sendDebugMessages("PlayerItemDamageEvent"); MessagesUtil.sendDebugMessages("PlayerItemDamageEvent");
int slot = -1; int slot = -1;
@@ -247,7 +252,8 @@ public class PlayerGameListener implements Listener {
if (slot == -1) return; if (slot == -1) return;
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId()); CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId());
CosmeticSlot cosmeticSlot = InventoryUtils.BukkitCosmeticSlot(slot); if (user == null) return;
CosmeticSlot cosmeticSlot = HMCCInventoryUtils.BukkitCosmeticSlot(slot);
if (!user.hasCosmeticInSlot(cosmeticSlot)) { if (!user.hasCosmeticInSlot(cosmeticSlot)) {
MessagesUtil.sendDebugMessages("No cosmetic in " + cosmeticSlot); MessagesUtil.sendDebugMessages("No cosmetic in " + cosmeticSlot);
@@ -260,8 +266,8 @@ public class PlayerGameListener implements Listener {
}, 2); }, 2);
} }
@EventHandler @EventHandler(priority = EventPriority.LOW)
public void playerOffhandSwap(PlayerSwapHandItemsEvent event) { public void onPlayerOffhandSwap(PlayerSwapHandItemsEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId()); CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId());
if (user == null) return; if (user == null) return;
// Really need to look into optimization of this // Really need to look into optimization of this
@@ -273,10 +279,14 @@ public class PlayerGameListener implements Listener {
} }
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> { Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
user.updateCosmetic(CosmeticSlot.OFFHAND); user.updateCosmetic(CosmeticSlot.OFFHAND);
List<Player> viewers = HMCCPacketManager.getViewers(user.getEntity().getLocation());
if (viewers.isEmpty()) return;
viewers.remove(user.getPlayer());
PacketManager.equipmentSlotUpdate(user.getEntity().getEntityId(), EquipmentSlot.HAND, event.getPlayer().getInventory().getItemInMainHand(), viewers);
}, 2); }, 2);
} }
@EventHandler @EventHandler(priority = EventPriority.NORMAL)
public void onPlayerPickupItem(EntityPickupItemEvent event) { public void onPlayerPickupItem(EntityPickupItemEvent event) {
if (!(event.getEntity() instanceof Player)) return; if (!(event.getEntity() instanceof Player)) return;
CosmeticUser user = CosmeticUsers.getUser(event.getEntity().getUniqueId()); CosmeticUser user = CosmeticUsers.getUser(event.getEntity().getUniqueId());
@@ -284,9 +294,8 @@ public class PlayerGameListener implements Listener {
if (user.isInWardrobe()) event.setCancelled(true); if (user.isInWardrobe()) event.setCancelled(true);
} }
@EventHandler @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void playerInvisibility(EntityPotionEffectEvent event) { public void onPlayerPotionEffect(EntityPotionEffectEvent event) {
if (event.isCancelled()) return;
if (!event.getModifiedType().equals(PotionEffectType.INVISIBILITY)) return; if (!event.getModifiedType().equals(PotionEffectType.INVISIBILITY)) return;
if (!event.getEntityType().equals(EntityType.PLAYER)) return; if (!event.getEntityType().equals(EntityType.PLAYER)) return;
Player player = (Player) event.getEntity(); Player player = (Player) event.getEntity();
@@ -302,7 +311,7 @@ public class PlayerGameListener implements Listener {
} }
} }
@EventHandler @EventHandler(priority = EventPriority.LOW)
public void onMainHandSwitch(PlayerItemHeldEvent event) { public void onMainHandSwitch(PlayerItemHeldEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer()); CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
if (user == null) return; if (user == null) return;
@@ -311,7 +320,6 @@ public class PlayerGameListener implements Listener {
//NMSHandlers.getHandler().slotUpdate(event.getPlayer(), event.getPreviousSlot()); //NMSHandlers.getHandler().slotUpdate(event.getPlayer(), event.getPreviousSlot());
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> { Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
user.updateCosmetic(CosmeticSlot.MAINHAND); user.updateCosmetic(CosmeticSlot.MAINHAND);
user.updateCosmetic(CosmeticSlot.OFFHAND);
}, 2); }, 2);
// #84, Riptides mess with backpacks // #84, Riptides mess with backpacks
@@ -323,28 +331,104 @@ public class PlayerGameListener implements Listener {
} }
} }
@EventHandler @EventHandler(priority = EventPriority.LOW)
public void onPlayerDeath(PlayerDeathEvent event) { public void onPlayerDeath(PlayerDeathEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getEntity()); CosmeticUser user = CosmeticUsers.getUser(event.getEntity());
if (user == null) return; if (user == null) return;
if (user.isInWardrobe()) user.leaveWardrobe(); if (user.isInWardrobe()) user.leaveWardrobe();
if (Settings.getUnapplyOnDeath() && !event.getEntity().hasPermission("hmccosmetics.unapplydeath.bypass")) { if (Settings.isUnapplyOnDeath() && !event.getEntity().hasPermission("hmccosmetics.unapplydeath.bypass")) {
user.removeCosmetics(); user.removeCosmetics();
} }
} }
@EventHandler @EventHandler(priority = EventPriority.LOW)
public void onPlayerGamemodeSwitch(PlayerGameModeChangeEvent event) { public void onPlayerGamemodeSwitch(PlayerGameModeChangeEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer()); CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
if (user == null) return; if (user == null) return;
if (user.isInWardrobe()) user.leaveWardrobe(true);
if (Settings.isDisabledGamemodesEnabled()) {
if (Settings.getDisabledGamemodes().contains(event.getNewGameMode().toString())) {
user.hideCosmetics(CosmeticUser.HiddenReason.GAMEMODE);
} else {
if (user.getHiddenReason() != null && user.getHiddenReason().equals(CosmeticUser.HiddenReason.GAMEMODE)) {
user.showCosmetics();
}
}
}
if (Settings.isDestroyLooseCosmetics()) { if (Settings.isDestroyLooseCosmetics()) {
ItemStack[] equippedArmor = event.getPlayer().getInventory().getArmorContents(); ItemStack[] equippedArmor = event.getPlayer().getInventory().getArmorContents();
if (equippedArmor.length == 0) return; if (equippedArmor.length == 0) return;
for (ItemStack armor : equippedArmor) { for (ItemStack armor : equippedArmor) {
if (InventoryUtils.isCosmeticItem(armor)) armor.setAmount(0); if (HMCCInventoryUtils.isCosmeticItem(armor)) armor.setAmount(0);
}
}
}
@EventHandler(priority = EventPriority.LOW)
public void onPlayerCosmeticEquip(PlayerCosmeticPostEquipEvent event) {
CosmeticUser user = event.getUser();
if (user.isInWardrobe() && event.getCosmetic().getSlot().equals(CosmeticSlot.BALLOON)) {
CosmeticBalloonType cosmetic = (CosmeticBalloonType) event.getCosmetic();
Location npclocation = user.getWardrobeManager().getNpcLocation().clone().add(cosmetic.getBalloonOffset());
// We know that no other entity besides a regular player will be in the wardrobe
List<Player> viewer = List.of(user.getPlayer());
user.getBalloonManager().getPufferfish().spawnPufferfish(npclocation.clone().add(cosmetic.getBalloonOffset()), viewer);
HMCCPacketManager.sendLeashPacket(user.getBalloonManager().getPufferfishBalloonId(), user.getWardrobeManager().getNPC_ID(), viewer);
HMCCPacketManager.sendTeleportPacket(user.getBalloonManager().getPufferfishBalloonId(), npclocation, false, viewer);
user.getBalloonManager().getModelEntity().teleport(npclocation);
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerMounted(EntityMountEvent event) {
if (event.getEntity() instanceof Player player) {
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(HMCCosmeticsPlugin.getInstance(), user::respawnBackpack, 1);
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerDismounted(EntityDismountEvent event) {
if (event.getDismounted() instanceof Player player) {
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(HMCCosmeticsPlugin.getInstance(), user::respawnBackpack, 1);
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerVanish(HibiscusPlayerVanishEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
if (user == null) return;
user.hideCosmetics(CosmeticUser.HiddenReason.PLUGIN);
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerUnVanish(HibiscusPlayerUnVanishEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
if (user == null) return;
if (!user.getHidden()) return;
if (user.getHiddenReason().equals(CosmeticUser.HiddenReason.PLUGIN)) user.showCosmetics();
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onHookReload(HibiscusHookReload event) {
if (event.getHook() instanceof HookItemAdder hook) {
switch (event.getReloadType()) {
case INITIAL -> {
HMCCosmeticsPlugin.setup();
}
case RELOAD -> {
if (!Settings.isItemsAdderChangeReload()) return;
HMCCosmeticsPlugin.setup();
}
} }
} }
} }
@@ -361,11 +445,12 @@ public class PlayerGameListener implements Listener {
if (invTypeClicked != 0) return; if (invTypeClicked != 0) return;
// -999 is when a player clicks outside their inventory. https://wiki.vg/Inventory#Player_Inventory // -999 is when a player clicks outside their inventory. https://wiki.vg/Inventory#Player_Inventory
if (slotClicked == -999) return; if (slotClicked == -999) return;
if (!(event.getPlayer() instanceof Player)) return; if (event.getPlayer() == null) return;
CosmeticUser user = CosmeticUsers.getUser(player); CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return; if (user == null) return;
CosmeticSlot cosmeticSlot = InventoryUtils.NMSCosmeticSlot(slotClicked); if (user.isInWardrobe()) return;
CosmeticSlot cosmeticSlot = HMCCInventoryUtils.NMSCosmeticSlot(slotClicked);
if (cosmeticSlot == null) return; if (cosmeticSlot == null) return;
if (!user.hasCosmeticInSlot(cosmeticSlot)) return; if (!user.hasCosmeticInSlot(cosmeticSlot)) return;
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> user.updateCosmetic(cosmeticSlot), 1); Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> user.updateCosmetic(cosmeticSlot), 1);
@@ -381,7 +466,6 @@ public class PlayerGameListener implements Listener {
MessagesUtil.sendDebugMessages("Menu Initial "); MessagesUtil.sendDebugMessages("Menu Initial ");
Player player = event.getPlayer(); Player player = event.getPlayer();
if (event.getPlayer() == null) return; if (event.getPlayer() == null) return;
if (!(event.getPlayer() instanceof Player)) return;
int windowID = event.getPacket().getIntegers().read(0); int windowID = event.getPacket().getIntegers().read(0);
List<ItemStack> slotData = event.getPacket().getItemListModifier().read(0); List<ItemStack> slotData = event.getPacket().getItemListModifier().read(0);
@@ -392,9 +476,11 @@ public class PlayerGameListener implements Listener {
HashMap<Integer, ItemStack> items = new HashMap<>(); HashMap<Integer, ItemStack> items = new HashMap<>();
for (Cosmetic cosmetic : user.getCosmetics()) { if (!user.isInWardrobe()) {
if ((cosmetic instanceof CosmeticArmorType cosmeticArmorType)) { for (Cosmetic cosmetic : user.getCosmetics()) {
items.put(InventoryUtils.getPacketArmorSlot(cosmeticArmorType.getEquipSlot()), user.getUserCosmeticItem(cosmeticArmorType)); if ((cosmetic instanceof CosmeticArmorType cosmeticArmorType)) {
items.put(HMCCInventoryUtils.getPacketArmorSlot(cosmeticArmorType.getEquipSlot()), user.getUserCosmeticItem(cosmeticArmorType));
}
} }
} }
@@ -425,6 +511,31 @@ public class PlayerGameListener implements Listener {
}); });
} }
private void registerSlotChangeListener() {
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Server.SET_SLOT) {
@Override
public void onPacketSending(PacketEvent event) {
MessagesUtil.sendDebugMessages("SetSlot Initial ");
Player player = event.getPlayer();
if (event.getPlayer() == null) return;
int windowID = event.getPacket().getIntegers().read(0);
if (windowID != 0) return;
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
if (user.isInWardrobe()) return;
int slot = event.getPacket().getIntegers().read(2);
MessagesUtil.sendDebugMessages("SetSlot Slot " + slot);
if (slot == 45 && user.hasCosmeticInSlot(CosmeticSlot.OFFHAND) && player.getInventory().getItemInOffHand().getType().isAir()) {
event.getPacket().getItemModifier().write(0, user.getUserCosmeticItem(CosmeticSlot.OFFHAND));
}
}
});
}
private void registerPlayerEquipmentListener() { private void registerPlayerEquipmentListener() {
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Server.ENTITY_EQUIPMENT) { ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Server.ENTITY_EQUIPMENT) {
@Override @Override
@@ -433,17 +544,35 @@ public class PlayerGameListener implements Listener {
int entityID = event.getPacket().getIntegers().read(0); int entityID = event.getPacket().getIntegers().read(0);
// User // User
CosmeticUser user = CosmeticUsers.getUser(entityID); CosmeticUser user = CosmeticUsers.getUser(entityID);
if (user == null) { if (user == null) return;
return; if (user.isInWardrobe()) return;
}
List<com.comphenix.protocol.wrappers.Pair<EnumWrappers.ItemSlot, ItemStack>> armor = event.getPacket().getSlotStackPairLists().read(0); List<com.comphenix.protocol.wrappers.Pair<EnumWrappers.ItemSlot, ItemStack>> armor = event.getPacket().getSlotStackPairLists().read(0);
for (EquipmentSlot equipmentSlot : EquipmentSlot.values()) { for (int i = 0; i < armor.size(); i++) {
CosmeticArmorType cosmeticArmor = (CosmeticArmorType) user.getCosmetic(InventoryUtils.BukkitCosmeticSlot(equipmentSlot)); com.comphenix.protocol.wrappers.Pair<EnumWrappers.ItemSlot, ItemStack> pair = armor.get(i);
if (cosmeticArmor == null) continue; switch (pair.getFirst()) {
Pair<EnumWrappers.ItemSlot, ItemStack> pair = new Pair<>(InventoryUtils.itemBukkitSlot(cosmeticArmor.getEquipSlot()), cosmeticArmor.getItem()); case MAINHAND -> {
armor.add(pair); if (user.getPlayer() == event.getPlayer()) continue; // When a player scrolls real fast, it messes up the mainhand. This fixes it
armor.set(i, new Pair<>(pair.getFirst(), user.getPlayer().getInventory().getItemInMainHand()));
}
case OFFHAND -> {
if (Settings.isCosmeticForceOffhandCosmeticShow() && user.hasCosmeticInSlot(CosmeticSlot.OFFHAND)) {
ItemStack item = user.getUserCosmeticItem(CosmeticSlot.OFFHAND);
if (item == null) continue;
Pair<EnumWrappers.ItemSlot, ItemStack> offhandPair = new Pair<>(EnumWrappers.ItemSlot.OFFHAND, item);
armor.set(i, offhandPair);
}
}
default -> {
CosmeticArmorType cosmeticArmor = (CosmeticArmorType) user.getCosmetic(HMCCInventoryUtils.getItemSlotToCosmeticSlot(pair.getFirst()));
if (cosmeticArmor == null) continue;
ItemStack item = user.getUserCosmeticItem(cosmeticArmor);
if (item == null) continue;
Pair<EnumWrappers.ItemSlot, ItemStack> armorPair = new Pair<>(HMCCInventoryUtils.itemBukkitSlot(cosmeticArmor.getEquipSlot()), item);
armor.set(i, armorPair);
}
}
} }
event.getPacket().getSlotStackPairLists().write(0, armor); event.getPacket().getSlotStackPairLists().write(0, armor);
@@ -452,11 +581,32 @@ public class PlayerGameListener implements Listener {
}); });
} }
private void registerEntityStatusListener() {
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Server.ENTITY_STATUS) {
@Override
public void onPacketSending(PacketEvent event) {
int entityid = event.getPacket().getIntegers().read(0);
byte status = event.getPacket().getBytes().read(0);
MessagesUtil.sendDebugMessages("EntityStatus Initial " + entityid + " - " + status);
if (status != 55) return;
CosmeticUser user = CosmeticUsers.getUser(entityid);
if (user == null) {
MessagesUtil.sendDebugMessages("EntityStatus User is null");
return;
}
if (!user.hasCosmeticInSlot(CosmeticSlot.OFFHAND)) return;
event.setCancelled(true);
}
});
}
private void registerPlayerArmListener() { private void registerPlayerArmListener() {
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.ARM_ANIMATION) { ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.ARM_ANIMATION) {
@Override @Override
public void onPacketReceiving(PacketEvent event) { public void onPacketReceiving(PacketEvent event) {
if (!(event.getPlayer() instanceof Player)) return; if (event.getPlayer() == null) return;
Player player = event.getPlayer(); Player player = event.getPlayer();
CosmeticUser user = CosmeticUsers.getUser(player); CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return; if (user == null) return;
@@ -465,6 +615,7 @@ public class PlayerGameListener implements Listener {
return; return;
} }
if (!user.isInWardrobe()) return; if (!user.isInWardrobe()) return;
if (!user.getWardrobeManager().getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return;
Menu menu = Menus.getDefaultMenu(); Menu menu = Menus.getDefaultMenu();
if (menu == null) return; if (menu == null) return;
menu.openMenu(user); menu.openMenu(user);
@@ -477,9 +628,8 @@ public class PlayerGameListener implements Listener {
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.USE_ENTITY) { ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.USE_ENTITY) {
@Override @Override
public void onPacketReceiving(PacketEvent event) { public void onPacketReceiving(PacketEvent event) {
if (!(event.getPlayer() instanceof Player)) return; if (event.getPlayer() == null) return;
Player player = event.getPlayer(); CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return; if (user == null) return;
if (user.getUserEmoteManager().isPlayingEmote() || user.isInWardrobe()) { if (user.getUserEmoteManager().isPlayingEmote() || user.isInWardrobe()) {
event.setCancelled(true); event.setCancelled(true);
@@ -496,7 +646,11 @@ public class PlayerGameListener implements Listener {
MessagesUtil.sendDebugMessages("Look Packet "); MessagesUtil.sendDebugMessages("Look Packet ");
Player player = event.getPlayer(); Player player = event.getPlayer();
if (event.getPlayer() == null) return; if (event.getPlayer() == null) return;
if (!(event.getPlayer() instanceof Player)) return; CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
if (user.isBackpackSpawned()) {
user.getUserBackpackManager().getEntityManager().setRotation(Math.round(event.getPacket().getFloat().read(0)));
}
} }
}); });
} }
@@ -509,20 +663,29 @@ public class PlayerGameListener implements Listener {
MessagesUtil.sendDebugMessages("Position Packet "); MessagesUtil.sendDebugMessages("Position Packet ");
Player player = event.getPlayer(); Player player = event.getPlayer();
if (event.getPlayer() == null) return; if (event.getPlayer() == null) return;
if (!(event.getPlayer() instanceof Player)) return; CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
if (user.isBackpackSpawned()) {
// The yaw follows the head, which makes it look weird and do weird things when moving around
user.getUserBackpackManager().getEntityManager().teleport(new Location(player.getWorld(), event.getPacket().getDoubles().read(0), event.getPacket().getDoubles().read(1), event.getPacket().getDoubles().read(2), event.getPacket().getFloat().read(0), event.getPacket().getFloat().read(1)));
}
} }
}); });
} }
private void registerTeleportMovement() { private void registerTeleportMovement() {
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.TELEPORT_ACCEPT) { ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.POSITION_LOOK) {
@Override @Override
public void onPacketReceiving(PacketEvent event) { public void onPacketReceiving(PacketEvent event) {
// TODO: Finish // TODO: Finish
MessagesUtil.sendDebugMessages("Teleport Packet "); MessagesUtil.sendDebugMessages("Teleport Packet ");
Player player = event.getPlayer(); Player player = event.getPlayer();
if (event.getPlayer() == null) return; if (event.getPlayer() == null) return;
if (!(event.getPlayer() instanceof Player)) return; CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
if (user.isBackpackSpawned()) {
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> user.updateCosmetic(CosmeticSlot.BACKPACK));
}
} }
}); });
} }

View File

@@ -1,58 +0,0 @@
package com.hibiscusmc.hmccosmetics.nms;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
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 org.bukkit.Location;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.List;
public interface NMSHandler {
int getNextEntityId();
Entity getEntity(int entityId);
Entity getHMCArmorStand(Location loc);
ArmorStand getMEGEntity(Location loc);
Entity spawnBackpack(CosmeticUser user, CosmeticBackpackType cosmeticBackpackType);
Entity spawnHMCParticleCloud(Location location);
UserBalloonManager spawnBalloon(CosmeticUser user, CosmeticBalloonType cosmeticBalloonType);
void equipmentSlotUpdate(
int entityId,
CosmeticUser user,
CosmeticSlot cosmeticSlot,
List<Player> sendTo
);
void slotUpdate(
Player player,
int slot
);
void equipmentSlotUpdate(
int entityId,
org.bukkit.inventory.EquipmentSlot slot,
ItemStack item,
List<Player> sendTo
);
void hideNPCName(
Player player,
String NPCName);
default boolean getSupported () {
return false;
}
}

View File

@@ -1,48 +0,0 @@
package com.hibiscusmc.hmccosmetics.nms;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import java.lang.reflect.InvocationTargetException;
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", "v1_19_R3"};
private static NMSHandler handler;
private static String version;
public static NMSHandler getHandler() {
if (handler != null) {
return handler;
} else {
setup();
}
return handler;
}
public static String getVersion() {
return version;
}
public static void setup() {
if (handler != null) return;
final String packageName = HMCCosmeticsPlugin.getInstance().getServer().getClass().getPackage().getName();
String packageVersion = packageName.substring(packageName.lastIndexOf('.') + 1);
for (String selectedVersion : SUPPORTED_VERSION) {
if (!selectedVersion.contains(packageVersion)) {
continue;
}
MessagesUtil.sendDebugMessages(packageVersion + " has been detected.", Level.INFO);
version = packageVersion;
try {
handler = (NMSHandler) Class.forName("com.hibiscusmc.hmccosmetics.nms." + packageVersion + ".NMSHandler").getConstructor().newInstance();
return;
} catch (ClassNotFoundException | InvocationTargetException | InstantiationException |
IllegalAccessException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
}

View File

@@ -3,45 +3,61 @@ package com.hibiscusmc.hmccosmetics.user;
import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; 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.Settings;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings; import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot; import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.cosmetic.types.*; import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticMainhandType;
import com.hibiscusmc.hmccosmetics.user.manager.UserBackpackManager; import com.hibiscusmc.hmccosmetics.user.manager.UserBackpackManager;
import com.hibiscusmc.hmccosmetics.user.manager.UserBalloonManager; import com.hibiscusmc.hmccosmetics.user.manager.UserBalloonManager;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager; import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;
import com.hibiscusmc.hmccosmetics.user.manager.UserWardrobeManager; import com.hibiscusmc.hmccosmetics.user.manager.UserWardrobeManager;
import com.hibiscusmc.hmccosmetics.util.InventoryUtils; import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.PlayerUtils; import com.hibiscusmc.hmccosmetics.util.HMCCPlayerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager; import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import org.bukkit.*; import lombok.Getter;
import me.lojosho.hibiscuscommons.hooks.Hooks;
import me.lojosho.hibiscuscommons.util.InventoryUtils;
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.*; import org.bukkit.inventory.meta.*;
import org.bukkit.persistence.PersistentDataType; import org.bukkit.persistence.PersistentDataType;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
import org.jetbrains.annotations.Nullable;
import java.util.*; import java.util.*;
import java.util.logging.Level; import java.util.logging.Level;
public class CosmeticUser { public class CosmeticUser {
private UUID uniqueId; @Getter
private final UUID uniqueId;
private int taskId; private int taskId;
private HashMap<CosmeticSlot, Cosmetic> playerCosmetics = new HashMap<>(); private final HashMap<CosmeticSlot, Cosmetic> playerCosmetics = new HashMap<>();
private UserWardrobeManager userWardrobeManager; private UserWardrobeManager userWardrobeManager;
private UserBalloonManager userBalloonManager; private UserBalloonManager userBalloonManager;
@Getter
private UserBackpackManager userBackpackManager; private UserBackpackManager userBackpackManager;
private UserEmoteManager userEmoteManager; @Getter
private final UserEmoteManager userEmoteManager;
// Cosmetic Settings/Toggles // Cosmetic Settings/Toggles
private boolean hideCosmetics; private boolean hideCosmetics;
@Getter
private HiddenReason hiddenReason; private HiddenReason hiddenReason;
private HashMap<CosmeticSlot, Color> colors = new HashMap<>(); private final HashMap<CosmeticSlot, Color> colors = new HashMap<>();
public CosmeticUser(UUID uuid) { public CosmeticUser(UUID uuid) {
this.uniqueId = uuid; this.uniqueId = uuid;
@@ -54,6 +70,7 @@ public class CosmeticUser {
Runnable run = () -> { Runnable run = () -> {
MessagesUtil.sendDebugMessages("Tick[uuid=" + uniqueId + "]", Level.INFO); MessagesUtil.sendDebugMessages("Tick[uuid=" + uniqueId + "]", Level.INFO);
updateCosmetic(); updateCosmetic();
if (getHidden() && !getUserEmoteManager().isPlayingEmote()) MessagesUtil.sendActionBar(getPlayer(), "hidden-cosmetics");
}; };
int tickPeriod = Settings.getTickPeriod(); int tickPeriod = Settings.getTickPeriod();
@@ -69,19 +86,10 @@ public class CosmeticUser {
despawnBalloon(); despawnBalloon();
} }
public UUID getUniqueId() {
return this.uniqueId;
}
public Cosmetic getCosmetic(CosmeticSlot slot) { public Cosmetic getCosmetic(CosmeticSlot slot) {
return playerCosmetics.get(slot); return playerCosmetics.get(slot);
} }
@Deprecated
public Collection<Cosmetic> getCosmetic() {
return playerCosmetics.values();
}
public ImmutableCollection<Cosmetic> getCosmetics() { public ImmutableCollection<Cosmetic> getCosmetics() {
return ImmutableList.copyOf(playerCosmetics.values()); return ImmutableList.copyOf(playerCosmetics.values());
} }
@@ -115,6 +123,9 @@ public class CosmeticUser {
CosmeticBalloonType balloonType = (CosmeticBalloonType) cosmetic; CosmeticBalloonType balloonType = (CosmeticBalloonType) cosmetic;
spawnBalloon(balloonType); spawnBalloon(balloonType);
} }
// API
PlayerCosmeticPostEquipEvent postEquipEvent = new PlayerCosmeticPostEquipEvent(this, cosmetic);
Bukkit.getPluginManager().callEvent(postEquipEvent);
} }
public void removeCosmetics() { public void removeCosmetics() {
@@ -140,7 +151,7 @@ public class CosmeticUser {
despawnBalloon(); despawnBalloon();
} }
if (slot == CosmeticSlot.EMOTE) { if (slot == CosmeticSlot.EMOTE) {
if (getUserEmoteManager().isPlayingEmote()) getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.UNEQUIP);
} }
colors.remove(slot); colors.remove(slot);
playerCosmetics.remove(slot); playerCosmetics.remove(slot);
@@ -158,10 +169,7 @@ public class CosmeticUser {
public boolean hasCosmeticInSlot(Cosmetic cosmetic) { public boolean hasCosmeticInSlot(Cosmetic cosmetic) {
if (getCosmetic(cosmetic.getSlot()) == null) return false; if (getCosmetic(cosmetic.getSlot()) == null) return false;
if (cosmetic.getId() == getCosmetic(cosmetic.getSlot()).getId()) { return Objects.equals(cosmetic.getId(), getCosmetic(cosmetic.getSlot()).getId());
return true;
}
return false;
} }
public Set<CosmeticSlot> getSlotsWithCosmetics() { public Set<CosmeticSlot> getSlotsWithCosmetics() {
@@ -181,18 +189,41 @@ public class CosmeticUser {
} }
public void updateCosmetic() { public void updateCosmetic() {
MessagesUtil.sendDebugMessages("updateCosmetic (All) - start");
HashMap<EquipmentSlot, ItemStack> items = new HashMap<>();
for (Cosmetic cosmetic : getCosmetics()) { for (Cosmetic cosmetic : getCosmetics()) {
if (cosmetic instanceof CosmeticArmorType armorType) {
if (getUserEmoteManager().isPlayingEmote() || isInWardrobe()) return;
if (!Settings.isCosmeticForceOffhandCosmeticShow()
&& armorType.getEquipSlot().equals(EquipmentSlot.OFF_HAND)
&& !getPlayer().getInventory().getItemInOffHand().getType().isAir()) continue;
items.put(HMCCInventoryUtils.getEquipmentSlot(armorType.getSlot()), armorType.getItem(this));
continue;
}
updateCosmetic(cosmetic.getSlot()); updateCosmetic(cosmetic.getSlot());
} }
if (items.isEmpty() || getEntity() == null) return;
PacketManager.equipmentSlotUpdate(getEntity().getEntityId(), items, HMCCPlayerUtils.getNearbyPlayers(getEntity().getLocation()));
MessagesUtil.sendDebugMessages("updateCosmetic (All) - end - " + items.size());
}
public ItemStack getUserCosmeticItem(CosmeticSlot slot) {
Cosmetic cosmetic = getCosmetic(slot);
if (cosmetic == null) return new ItemStack(Material.AIR);
return getUserCosmeticItem(cosmetic);
} }
public ItemStack getUserCosmeticItem(Cosmetic cosmetic) { public ItemStack getUserCosmeticItem(Cosmetic cosmetic) {
ItemStack item = null; ItemStack item = null;
if (hideCosmetics) { if (hideCosmetics) {
if (cosmetic instanceof CosmeticBackpackType || cosmetic instanceof CosmeticBalloonType) return new ItemStack(Material.AIR); if (cosmetic instanceof CosmeticBackpackType || cosmetic instanceof CosmeticBalloonType) return new ItemStack(Material.AIR);
return getPlayer().getInventory().getItem(InventoryUtils.getEquipmentSlot(cosmetic.getSlot())); return getPlayer().getInventory().getItem(HMCCInventoryUtils.getEquipmentSlot(cosmetic.getSlot()));
} }
if (cosmetic instanceof CosmeticArmorType || cosmetic instanceof CosmeticMainhandType || cosmetic instanceof CosmeticBackpackType) { if (cosmetic instanceof CosmeticArmorType armorType) {
item = armorType.getItem(this, cosmetic.getItem());
}
if (cosmetic instanceof CosmeticBackpackType || cosmetic instanceof CosmeticMainhandType) {
item = cosmetic.getItem(); item = cosmetic.getItem();
} }
if (cosmetic instanceof CosmeticBalloonType) { if (cosmetic instanceof CosmeticBalloonType) {
@@ -202,12 +233,54 @@ public class CosmeticUser {
item = cosmetic.getItem(); item = cosmetic.getItem();
} }
} }
return getUserCosmeticItem(cosmetic, item);
}
@SuppressWarnings("deprecation")
public ItemStack getUserCosmeticItem(Cosmetic cosmetic, ItemStack item) {
if (item == null) { if (item == null) {
MessagesUtil.sendDebugMessages("GetUserCosemticUser Item is null"); //MessagesUtil.sendDebugMessages("GetUserCosemticUser Item is null");
return null; return new ItemStack(Material.AIR);
} }
if (item.hasItemMeta()) { if (item.hasItemMeta()) {
ItemMeta itemMeta = item.getItemMeta(); 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);
owner = Hooks.processPlaceholders(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);
texture = Hooks.processPlaceholders(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()) {
processedLore.add(Hooks.processPlaceholders(getPlayer(), loreLine));
}
}
if (itemMeta.hasDisplayName()) {
String displayName = itemMeta.getDisplayName();
itemMeta.setDisplayName(Hooks.processPlaceholders(getPlayer(), displayName));
}
itemMeta.setLore(processedLore);
if (colors.containsKey(cosmetic.getSlot())) { if (colors.containsKey(cosmetic.getSlot())) {
Color color = colors.get(cosmetic.getSlot()); Color color = colors.get(cosmetic.getSlot());
if (itemMeta instanceof LeatherArmorMeta leatherMeta) { if (itemMeta instanceof LeatherArmorMeta leatherMeta) {
@@ -218,18 +291,14 @@ public class CosmeticUser {
mapMeta.setColor(color); mapMeta.setColor(color);
} }
} }
itemMeta.getPersistentDataContainer().set(InventoryUtils.getCosmeticKey(), PersistentDataType.STRING, cosmetic.getId()); itemMeta.getPersistentDataContainer().set(HMCCInventoryUtils.getCosmeticKey(), PersistentDataType.STRING, cosmetic.getId());
itemMeta.getPersistentDataContainer().set(InventoryUtils.getOwnerKey(), PersistentDataType.STRING, getPlayer().getUniqueId().toString()); itemMeta.getPersistentDataContainer().set(InventoryUtils.getOwnerKey(), PersistentDataType.STRING, getEntity().getUniqueId().toString());
item.setItemMeta(itemMeta); item.setItemMeta(itemMeta);
} }
return item; return item;
} }
public UserBackpackManager getUserBackpackManager() {
return userBackpackManager;
}
public UserBalloonManager getBalloonManager() { public UserBalloonManager getBalloonManager() {
return this.userBalloonManager; return this.userBalloonManager;
} }
@@ -238,36 +307,37 @@ public class CosmeticUser {
return userWardrobeManager; return userWardrobeManager;
} }
public UserEmoteManager getUserEmoteManager() { public void enterWardrobe(boolean ignoreDistance, Wardrobe wardrobe) {
return userEmoteManager; if (wardrobe.hasPermission() && !getPlayer().hasPermission(wardrobe.getPermission())) {
} MessagesUtil.sendMessage(getPlayer(), "no-permission");
return;
public void enterWardrobe() { }
enterWardrobe(false); if (!wardrobe.canEnter(this) && !ignoreDistance) {
}
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) {
MessagesUtil.sendMessage(getPlayer(), "not-near-wardrobe"); MessagesUtil.sendMessage(getPlayer(), "not-near-wardrobe");
return; 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); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
} }
wardrobe = event.getWardrobe();
if (userWardrobeManager == null) { if (userWardrobeManager == null) {
userWardrobeManager = new UserWardrobeManager(this, exitLocation, viewingLocation, npcLocation); userWardrobeManager = new UserWardrobeManager(this, wardrobe);
userWardrobeManager.start(); userWardrobeManager.start();
} }
} }
public void leaveWardrobe() { public void leaveWardrobe() {
leaveWardrobe(false);
}
public void leaveWardrobe(boolean ejected) {
PlayerWardrobeLeaveEvent event = new PlayerWardrobeLeaveEvent(this); PlayerWardrobeLeaveEvent event = new PlayerWardrobeLeaveEvent(this);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
@@ -278,7 +348,7 @@ public class CosmeticUser {
getWardrobeManager().setWardrobeStatus(UserWardrobeManager.WardrobeStatus.STOPPING); getWardrobeManager().setWardrobeStatus(UserWardrobeManager.WardrobeStatus.STOPPING);
if (WardrobeSettings.isEnabledTransition()) { if (WardrobeSettings.isEnabledTransition() && !ejected) {
MessagesUtil.sendTitle( MessagesUtil.sendTitle(
getPlayer(), getPlayer(),
WardrobeSettings.getTransitionText(), WardrobeSettings.getTransitionText(),
@@ -297,21 +367,12 @@ public class CosmeticUser {
} }
public boolean isInWardrobe() { public boolean isInWardrobe() {
if (userWardrobeManager == null) return false; return userWardrobeManager != null;
return true;
}
public void toggleWardrobe() {
if (isInWardrobe()) {
leaveWardrobe();
} else {
enterWardrobe();
}
} }
public void spawnBackpack(CosmeticBackpackType cosmeticBackpackType) { public void spawnBackpack(CosmeticBackpackType cosmeticBackpackType) {
if (this.userBackpackManager != null) return; if (this.userBackpackManager != null) return;
this.userBackpackManager = new UserBackpackManager(this, cosmeticBackpackType.getBackpackType()); this.userBackpackManager = new UserBackpackManager(this);
userBackpackManager.spawnBackpack(cosmeticBackpackType); userBackpackManager.spawnBackpack(cosmeticBackpackType);
} }
@@ -322,26 +383,33 @@ public class CosmeticUser {
} }
public boolean isBackpackSpawned() { public boolean isBackpackSpawned() {
if (this.userBackpackManager == null) return false; return this.userBackpackManager != null;
return true; }
public boolean isBalloonSpawned() {
return this.userBalloonManager != null;
} }
public void spawnBalloon(CosmeticBalloonType cosmeticBalloonType) { public void spawnBalloon(CosmeticBalloonType cosmeticBalloonType) {
Player player = Bukkit.getPlayer(getUniqueId());
if (this.userBalloonManager != null) return; if (this.userBalloonManager != null) return;
this.userBalloonManager = NMSHandlers.getHandler().spawnBalloon(this, cosmeticBalloonType); org.bukkit.entity.Entity entity = getEntity();
List<Player> viewer = PlayerUtils.getNearbyPlayers(player); UserBalloonManager userBalloonManager1 = new UserBalloonManager(this, entity.getLocation());
viewer.add(player); userBalloonManager1.getModelEntity().teleport(entity.getLocation().add(cosmeticBalloonType.getBalloonOffset()));
userBalloonManager1.spawnModel(cosmeticBalloonType, getCosmeticColor(cosmeticBalloonType.getSlot()));
userBalloonManager1.addPlayerToModel(this, cosmeticBalloonType, getCosmeticColor(cosmeticBalloonType.getSlot()));
this.userBalloonManager = userBalloonManager1;
//this.userBalloonManager = NMSHandlers.getHandler().spawnBalloon(this, cosmeticBalloonType);
} }
public void despawnBalloon() { public void despawnBalloon() {
if (this.userBalloonManager == null) return; if (this.userBalloonManager == null) return;
List<Player> sentTo = PlayerUtils.getNearbyPlayers(getPlayer().getLocation()); List<Player> sentTo = HMCCPlayerUtils.getNearbyPlayers(getEntity().getLocation());
PacketManager.sendEntityDestroyPacket(userBalloonManager.getPufferfishBalloonId(), sentTo); HMCCPacketManager.sendEntityDestroyPacket(userBalloonManager.getPufferfishBalloonId(), sentTo);
this.userBalloonManager.remove(); this.userBalloonManager.remove();
this.userBalloonManager = null; this.userBalloonManager = null;
@@ -351,30 +419,54 @@ public class CosmeticUser {
if (!hasCosmeticInSlot(CosmeticSlot.BACKPACK)) return; if (!hasCosmeticInSlot(CosmeticSlot.BACKPACK)) return;
final Cosmetic cosmetic = getCosmetic(CosmeticSlot.BACKPACK); final Cosmetic cosmetic = getCosmetic(CosmeticSlot.BACKPACK);
despawnBackpack(); despawnBackpack();
if (hideCosmetics) return;
spawnBackpack((CosmeticBackpackType) cosmetic); spawnBackpack((CosmeticBackpackType) cosmetic);
MessagesUtil.sendDebugMessages("Respawned Backpack for " + getEntity().getName());
} }
public void respawnBalloon() { public void respawnBalloon() {
if (!hasCosmeticInSlot(CosmeticSlot.BALLOON)) return; if (!hasCosmeticInSlot(CosmeticSlot.BALLOON)) return;
final Cosmetic cosmetic = getCosmetic(CosmeticSlot.BALLOON); final Cosmetic cosmetic = getCosmetic(CosmeticSlot.BALLOON);
despawnBalloon(); despawnBalloon();
if (hideCosmetics) return;
spawnBalloon((CosmeticBalloonType) cosmetic); spawnBalloon((CosmeticBalloonType) cosmetic);
MessagesUtil.sendDebugMessages("Respawned Balloon for " + getEntity().getName());
} }
public void removeArmor(CosmeticSlot slot) { public void removeArmor(CosmeticSlot slot) {
PacketManager.equipmentSlotUpdate(getPlayer().getEntityId(), this, slot, PlayerUtils.getNearbyPlayers(getPlayer())); EquipmentSlot equipmentSlot = HMCCInventoryUtils.getEquipmentSlot(slot);
if (equipmentSlot == null) return;
if (getPlayer() != null) {
PacketManager.equipmentSlotUpdate(getEntity().getEntityId(), equipmentSlot, getPlayer().getInventory().getItem(equipmentSlot), HMCCPlayerUtils.getNearbyPlayers(getEntity().getLocation()));
} else {
HMCCPacketManager.equipmentSlotUpdate(getEntity().getEntityId(), this, slot, HMCCPlayerUtils.getNearbyPlayers(getEntity().getLocation()));
}
} }
/**
* This returns the player associated with the user. Some users may not have a player attached, ie, they are npcs
* wearing cosmetics through an addon. If you need to get locations, use getEntity instead.
* @return Player
*/
@Nullable
public Player getPlayer() { public Player getPlayer() {
return Bukkit.getPlayer(uniqueId); return Bukkit.getPlayer(uniqueId);
} }
/**
* This gets the entity associated with the user.
* @return Entity
*/
public Entity getEntity() {
return Bukkit.getEntity(uniqueId);
}
public Color getCosmeticColor(CosmeticSlot slot) { public Color getCosmeticColor(CosmeticSlot slot) {
return colors.get(slot); return colors.get(slot);
} }
public List<CosmeticSlot> getDyeableSlots() { public List<CosmeticSlot> getDyeableSlots() {
ArrayList<CosmeticSlot> dyableSlots = new ArrayList(); ArrayList<CosmeticSlot> dyableSlots = new ArrayList<>();
for (Cosmetic cosmetic : getCosmetics()) { for (Cosmetic cosmetic : getCosmetics()) {
if (cosmetic.isDyable()) dyableSlots.add(cosmetic.getSlot()); if (cosmetic.isDyable()) dyableSlots.add(cosmetic.getSlot());
@@ -384,9 +476,15 @@ public class CosmeticUser {
} }
public boolean canEquipCosmetic(Cosmetic cosmetic) { public boolean canEquipCosmetic(Cosmetic cosmetic) {
return canEquipCosmetic(cosmetic, false);
}
public boolean canEquipCosmetic(Cosmetic cosmetic, boolean ignoreWardrobe) {
if (!cosmetic.requiresPermission()) return true; if (!cosmetic.requiresPermission()) return true;
if (getPlayer().hasPermission(cosmetic.getPermission())) return true; if (isInWardrobe() && !ignoreWardrobe) {
return false; if (WardrobeSettings.isTryCosmeticsInWardrobe() && userWardrobeManager.getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return true;
}
return getPlayer().hasPermission(cosmetic.getPermission());
} }
public void hidePlayer() { public void hidePlayer() {
@@ -408,7 +506,7 @@ public class CosmeticUser {
} }
public void hideCosmetics(HiddenReason reason) { public void hideCosmetics(HiddenReason reason) {
if (hideCosmetics == true) return; if (hideCosmetics) return;
PlayerCosmeticHideEvent event = new PlayerCosmeticHideEvent(this, reason); PlayerCosmeticHideEvent event = new PlayerCosmeticHideEvent(this, reason);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
@@ -418,18 +516,19 @@ public class CosmeticUser {
hideCosmetics = true; hideCosmetics = true;
hiddenReason = reason; hiddenReason = reason;
if (hasCosmeticInSlot(CosmeticSlot.BALLOON)) { if (hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
getBalloonManager().removePlayerFromModel(getPlayer()); despawnBalloon();
getBalloonManager().sendRemoveLeashPacket(); //getBalloonManager().removePlayerFromModel(getPlayer());
//getBalloonManager().sendRemoveLeashPacket();
} }
if (hasCosmeticInSlot(CosmeticSlot.BACKPACK)) { if (hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
userBackpackManager.clearItems(); despawnBackpack();
} }
updateCosmetic(); updateCosmetic();
MessagesUtil.sendDebugMessages("HideCosmetics"); MessagesUtil.sendDebugMessages("HideCosmetics");
} }
public void showCosmetics() { public void showCosmetics() {
if (hideCosmetics == false) return; if (!hideCosmetics) return;
PlayerCosmeticShowEvent event = new PlayerCosmeticShowEvent(this); PlayerCosmeticShowEvent event = new PlayerCosmeticShowEvent(this);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
@@ -440,12 +539,14 @@ public class CosmeticUser {
hideCosmetics = false; hideCosmetics = false;
hiddenReason = HiddenReason.NONE; hiddenReason = HiddenReason.NONE;
if (hasCosmeticInSlot(CosmeticSlot.BALLOON)) { if (hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
if (!isBalloonSpawned()) respawnBalloon();
CosmeticBalloonType balloonType = (CosmeticBalloonType) getCosmetic(CosmeticSlot.BALLOON); CosmeticBalloonType balloonType = (CosmeticBalloonType) getCosmetic(CosmeticSlot.BALLOON);
getBalloonManager().addPlayerToModel(this, balloonType); getBalloonManager().addPlayerToModel(this, balloonType);
List<Player> viewer = PlayerUtils.getNearbyPlayers(getPlayer()); List<Player> viewer = HMCCPlayerUtils.getNearbyPlayers(getEntity().getLocation());
PacketManager.sendLeashPacket(getBalloonManager().getPufferfishBalloonId(), getPlayer().getEntityId(), viewer); HMCCPacketManager.sendLeashPacket(getBalloonManager().getPufferfishBalloonId(), getPlayer().getEntityId(), viewer);
} }
if (hasCosmeticInSlot(CosmeticSlot.BACKPACK)) { if (hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
if (!isBackpackSpawned()) respawnBackpack();
CosmeticBackpackType cosmeticBackpackType = (CosmeticBackpackType) getCosmetic(CosmeticSlot.BACKPACK); CosmeticBackpackType cosmeticBackpackType = (CosmeticBackpackType) getCosmetic(CosmeticSlot.BACKPACK);
ItemStack item = getUserCosmeticItem(cosmeticBackpackType); ItemStack item = getUserCosmeticItem(cosmeticBackpackType);
userBackpackManager.setItem(item); userBackpackManager.setItem(item);
@@ -458,10 +559,6 @@ public class CosmeticUser {
return this.hideCosmetics; return this.hideCosmetics;
} }
public HiddenReason getHiddenReason() {
return hiddenReason;
}
public enum HiddenReason { public enum HiddenReason {
NONE, NONE,
WORLDGUARD, WORLDGUARD,
@@ -469,6 +566,8 @@ public class CosmeticUser {
POTION, POTION,
ACTION, ACTION,
COMMAND, COMMAND,
EMOTE EMOTE,
GAMEMODE,
WORLD
} }
} }

View File

@@ -1,12 +1,12 @@
package com.hibiscusmc.hmccosmetics.user; package com.hibiscusmc.hmccosmetics.user;
import com.google.common.collect.HashBiMap; import com.google.common.collect.HashBiMap;
import com.hibiscusmc.hmccosmetics.util.ServerUtils; import com.hibiscusmc.hmccosmetics.util.HMCCServerUtils;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
public class CosmeticUsers { public class CosmeticUsers {
@@ -38,9 +38,13 @@ public class CosmeticUsers {
@Nullable @Nullable
public static CosmeticUser getUser(int entityId) { public static CosmeticUser getUser(int entityId) {
Entity entity = ServerUtils.getEntity(entityId); Entity entity = HMCCServerUtils.getEntity(entityId);
if (entity == null) return null; if (entity == null) return null;
if (entity.getType().equals(EntityType.PLAYER)) return null; if (!(entity instanceof Player player)) return null;
return COSMETIC_USERS.get(entity.getUniqueId()); return COSMETIC_USERS.get(player.getUniqueId());
}
public static Set<CosmeticUser> values() {
return COSMETIC_USERS.values();
} }
} }

View File

@@ -1,149 +1,150 @@
package com.hibiscusmc.hmccosmetics.user.manager; package com.hibiscusmc.hmccosmetics.user.manager;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot; import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType; import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import com.ticxo.modelengine.api.ModelEngineAPI; import com.ticxo.modelengine.api.ModelEngineAPI;
import com.ticxo.modelengine.api.model.ActiveModel; import lombok.Getter;
import com.ticxo.modelengine.api.model.ModeledEntity; import me.lojosho.hibiscuscommons.hooks.Hooks;
import org.bukkit.Location; import me.lojosho.hibiscuscommons.util.ServerUtils;
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.AreaEffectCloud; import org.bukkit.entity.Entity;
import org.bukkit.entity.ArmorStand; import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
public class UserBackpackManager { public class UserBackpackManager {
private boolean hideBackpack; @Getter
private ArmorStand invisibleArmorStand; private boolean backpackHidden;
private AreaEffectCloud particleCloud; @Getter
private int invisibleArmorStand;
private ArrayList<Integer> particleCloud = new ArrayList<>();
@Getter
private final CosmeticUser user; private final CosmeticUser user;
private BackpackType backpackType; @Getter
private UserEntity entityManager;
public UserBackpackManager(CosmeticUser user, BackpackType backpackType) { public UserBackpackManager(CosmeticUser user) {
this.user = user; this.user = user;
hideBackpack = false; this.backpackHidden = false;
this.backpackType = backpackType; this.invisibleArmorStand = ServerUtils.getNextEntityId();
this.entityManager = new UserEntity(user.getUniqueId());
this.entityManager.refreshViewers(user.getEntity().getLocation());
} }
public int getFirstArmorStandId() { public int getFirstArmorStandId() {
return invisibleArmorStand.getEntityId();
}
public ArmorStand getArmorStand() {
return invisibleArmorStand; return invisibleArmorStand;
} }
public void spawnBackpack(CosmeticBackpackType cosmeticBackpackType) { public void spawnBackpack(CosmeticBackpackType cosmeticBackpackType) {
MessagesUtil.sendDebugMessages("spawnBackpack Bukkit - Start"); MessagesUtil.sendDebugMessages("spawnBackpack Bukkit - Start");
if (getBackpackType().equals(BackpackType.NORMAL)) { spawn(cosmeticBackpackType);
spawnNormalBackpack(cosmeticBackpackType);
}
if (getBackpackType().equals(BackpackType.FIRST_PERSON)) {
spawnFirstPersonBackpack(cosmeticBackpackType);
}
} }
private void spawnNormalBackpack(CosmeticBackpackType cosmeticBackpackType) { private void spawn(CosmeticBackpackType cosmeticBackpackType) {
getEntityManager().setIds(List.of(invisibleArmorStand));
getEntityManager().teleport(user.getEntity().getLocation());
List<Player> outsideViewers = getEntityManager().getViewers();
HMCCPacketManager.sendEntitySpawnPacket(user.getEntity().getLocation(), getFirstArmorStandId(), EntityType.ARMOR_STAND, UUID.randomUUID(), getEntityManager().getViewers());
HMCCPacketManager.sendArmorstandMetadata(getFirstArmorStandId(), outsideViewers);
if (this.invisibleArmorStand != null) return; Entity entity = user.getEntity();
this.invisibleArmorStand = (ArmorStand) NMSHandlers.getHandler().spawnBackpack(user, cosmeticBackpackType); int[] passengerIDs = new int[entity.getPassengers().size() + 1];
if (cosmeticBackpackType.getModelName() != null && HMCCosmeticsPlugin.hasModelEngine()) { for (int i = 0; i < entity.getPassengers().size(); i++) {
if (ModelEngineAPI.api.getModelRegistry().getBlueprint(cosmeticBackpackType.getModelName()) == null) { passengerIDs[i] = entity.getPassengers().get(i).getEntityId();
}
passengerIDs[passengerIDs.length - 1] = this.getFirstArmorStandId();
ArrayList<Player> owner = new ArrayList<>();
if (user.getPlayer() != null) owner.add(user.getPlayer());
if (cosmeticBackpackType.isFirstPersonCompadible()) {
for (int i = particleCloud.size(); i < cosmeticBackpackType.getHeight(); i++) {
int entityId = ServerUtils.getNextEntityId();
HMCCPacketManager.sendEntitySpawnPacket(user.getEntity().getLocation(), entityId, EntityType.AREA_EFFECT_CLOUD, UUID.randomUUID());
HMCCPacketManager.sendCloudEffect(entityId, HMCCPacketManager.getViewers(user.getEntity().getLocation()));
this.particleCloud.add(entityId);
}
// Copied code from updating the backpack
for (int i = 0; i < particleCloud.size(); i++) {
if (i == 0) HMCCPacketManager.sendRidingPacket(entity.getEntityId(), particleCloud.get(i), owner);
else HMCCPacketManager.sendRidingPacket(particleCloud.get(i - 1), particleCloud.get(i) , owner);
}
HMCCPacketManager.sendRidingPacket(particleCloud.get(particleCloud.size() - 1), user.getUserBackpackManager().getFirstArmorStandId(), owner);
if (!user.getHidden()) PacketManager.equipmentSlotUpdate(user.getUserBackpackManager().getFirstArmorStandId(), EquipmentSlot.HEAD, user.getUserCosmeticItem(cosmeticBackpackType, cosmeticBackpackType.getFirstPersonBackpack()), owner);
}
PacketManager.equipmentSlotUpdate(getFirstArmorStandId(), EquipmentSlot.HEAD, user.getUserCosmeticItem(cosmeticBackpackType), outsideViewers);
HMCCPacketManager.sendRidingPacket(entity.getEntityId(), passengerIDs, outsideViewers);
// No one should be using ME because it barely works but some still use it, so it's here
if (cosmeticBackpackType.getModelName() != null && Hooks.isActiveHook("ModelEngine")) {
if (ModelEngineAPI.getBlueprint(cosmeticBackpackType.getModelName()) == null) {
MessagesUtil.sendDebugMessages("Invalid Model Engine Blueprint " + cosmeticBackpackType.getModelName(), Level.SEVERE); MessagesUtil.sendDebugMessages("Invalid Model Engine Blueprint " + cosmeticBackpackType.getModelName(), Level.SEVERE);
return; return;
} }
ModeledEntity modeledEntity = ModelEngineAPI.getOrCreateModeledEntity(invisibleArmorStand); /* TODO: Readd ModelEngine support
ActiveModel model = ModelEngineAPI.createActiveModel(ModelEngineAPI.getBlueprint(cosmeticBackpackType.getModelName())); ModeledEntity modeledEntity = ModelEngineAPI.createModeledEntity(new PacketBaseEntity(getFirstArmorStandId(), UUID.randomUUID(), entity.getLocation()));
model.setCanHurt(false);
modeledEntity.addModel(model, false);
}
MessagesUtil.sendDebugMessages("spawnBackpack Bukkit - Finish");
}
public void spawnFirstPersonBackpack(CosmeticBackpackType cosmeticBackpackType) {
if (this.invisibleArmorStand != null) return;
this.invisibleArmorStand = (ArmorStand) NMSHandlers.getHandler().spawnBackpack(user, cosmeticBackpackType);
this.particleCloud = (AreaEffectCloud) NMSHandlers.getHandler().spawnHMCParticleCloud(user.getPlayer().getLocation());
if (cosmeticBackpackType.getModelName() != null && HMCCosmeticsPlugin.hasModelEngine()) {
if (ModelEngineAPI.api.getModelRegistry().getBlueprint(cosmeticBackpackType.getModelName()) == null) {
MessagesUtil.sendDebugMessages("Invalid Model Engine Blueprint " + cosmeticBackpackType.getModelName(), Level.SEVERE);
return;
}
ModeledEntity modeledEntity = ModelEngineAPI.getOrCreateModeledEntity(invisibleArmorStand);
ActiveModel model = ModelEngineAPI.createActiveModel(ModelEngineAPI.getBlueprint(cosmeticBackpackType.getModelName())); ActiveModel model = ModelEngineAPI.createActiveModel(ModelEngineAPI.getBlueprint(cosmeticBackpackType.getModelName()));
model.setCanHurt(false); model.setCanHurt(false);
modeledEntity.addModel(model, false); modeledEntity.addModel(model, false);
*/
} }
MessagesUtil.sendDebugMessages("spawnBackpack Bukkit - Finish"); MessagesUtil.sendDebugMessages("spawnBackpack Bukkit - Finish");
} }
public void despawnBackpack() { public void despawnBackpack() {
if (invisibleArmorStand != null) { HMCCPacketManager.sendEntityDestroyPacket(invisibleArmorStand, getEntityManager().getViewers());
invisibleArmorStand.setHealth(0);
invisibleArmorStand.remove();
this.invisibleArmorStand = null;
}
if (particleCloud != null) { if (particleCloud != null) {
particleCloud.remove(); for (Integer entityId : particleCloud) {
HMCCPacketManager.sendEntityDestroyPacket(entityId, getEntityManager().getViewers());
}
this.particleCloud = null; this.particleCloud = null;
} }
} }
public void hideBackpack() { public void hideBackpack() {
if (user.getHidden()) return; if (user.getHidden()) return;
getArmorStand().getEquipment().clear(); //getArmorStand().getEquipment().clear();
hideBackpack = true; backpackHidden = true;
} }
public void showBackpack() { public void showBackpack() {
if (!hideBackpack) return; if (!backpackHidden) return;
CosmeticBackpackType cosmeticBackpackType = (CosmeticBackpackType) user.getCosmetic(CosmeticSlot.BACKPACK); CosmeticBackpackType cosmeticBackpackType = (CosmeticBackpackType) user.getCosmetic(CosmeticSlot.BACKPACK);
ItemStack item = user.getUserCosmeticItem(cosmeticBackpackType); ItemStack item = user.getUserCosmeticItem(cosmeticBackpackType);
getArmorStand().getEquipment().setHelmet(item); //getArmorStand().getEquipment().setHelmet(item);
hideBackpack = false; backpackHidden = false;
} }
public void setVisibility(boolean shown) { public void setVisibility(boolean shown) {
hideBackpack = shown; backpackHidden = shown;
} }
public BackpackType getBackpackType() { public ArrayList<Integer> getAreaEffectEntityId() {
return backpackType; return particleCloud;
}
public int getAreaEffectEntityId() {
return particleCloud.getEntityId();
}
public void teleportEffectEntity(Location location) {
particleCloud.teleport(location);
} }
public void setItem(ItemStack item) { public void setItem(ItemStack item) {
getArmorStand().getEquipment().setHelmet(item); PacketManager.equipmentSlotUpdate(getFirstArmorStandId(), EquipmentSlot.HEAD, item, getEntityManager().getViewers());
} }
public void clearItems() { public void clearItems() {
ItemStack item = new ItemStack(Material.AIR); ItemStack item = new ItemStack(Material.AIR);
getArmorStand().getEquipment().setHelmet(item); PacketManager.equipmentSlotUpdate(getFirstArmorStandId(), EquipmentSlot.HEAD, item, getEntityManager().getViewers());
}
public enum BackpackType {
NORMAL,
FIRST_PERSON // First person not yet implemented
} }
} }

View File

@@ -3,19 +3,24 @@ package com.hibiscusmc.hmccosmetics.user.manager;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings; import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType; import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.PlayerUtils; import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager;
import com.ticxo.modelengine.api.ModelEngineAPI; import com.ticxo.modelengine.api.ModelEngineAPI;
import com.ticxo.modelengine.api.entity.data.BukkitEntityData;
import com.ticxo.modelengine.api.model.ActiveModel; import com.ticxo.modelengine.api.model.ActiveModel;
import com.ticxo.modelengine.api.model.ModeledEntity; import com.ticxo.modelengine.api.model.ModeledEntity;
import lombok.Getter;
import me.lojosho.hibiscuscommons.hooks.Hooks;
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.ArmorStand; import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -25,21 +30,31 @@ import java.util.logging.Level;
public class UserBalloonManager { public class UserBalloonManager {
private CosmeticUser user;
@Getter
private BalloonType balloonType; private BalloonType balloonType;
private CosmeticBalloonType cosmeticBalloonType; private CosmeticBalloonType cosmeticBalloonType;
private final int balloonID; @Getter
private final UUID uniqueID; private UserBalloonPufferfish pufferfish;
private final ArmorStand modelEntity; private final ArmorStand modelEntity;
public UserBalloonManager(CosmeticUser user, @NotNull Location location) {
public UserBalloonManager(@NotNull Location location) { this.user = user;
this.uniqueID = UUID.randomUUID(); this.pufferfish = new UserBalloonPufferfish(user.getUniqueId(), NMSHandlers.getHandler().getNextEntityId(), UUID.randomUUID());
this.balloonID = NMSHandlers.getHandler().getNextEntityId(); this.modelEntity = location.getWorld().spawn(location, ArmorStand.class, (e) -> {
this.modelEntity = NMSHandlers.getHandler().getMEGEntity(location.add(Settings.getBalloonOffset())); e.setInvisible(true);
e.setGravity(false);
e.setSilent(true);
e.setInvulnerable(true);
e.setSmall(true);
e.setMarker(true);
e.setPersistent(false);
e.getPersistentDataContainer().set(new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "cosmeticMob"), PersistentDataType.SHORT, Short.valueOf("1"));
});
} }
public void spawnModel(@NotNull CosmeticBalloonType cosmeticBalloonType, Color color) { public void spawnModel(@NotNull CosmeticBalloonType cosmeticBalloonType, Color color) {
// redo this // redo this
if (cosmeticBalloonType.getModelName() != null && HMCCosmeticsPlugin.hasModelEngine()) { if (cosmeticBalloonType.getModelName() != null && Hooks.isActiveHook("ModelEngine")) {
balloonType = BalloonType.MODELENGINE; balloonType = BalloonType.MODELENGINE;
} else { } else {
if (cosmeticBalloonType.getItem() != null) { if (cosmeticBalloonType.getItem() != null) {
@@ -54,7 +69,7 @@ public class UserBalloonManager {
if (balloonType == BalloonType.MODELENGINE) { if (balloonType == BalloonType.MODELENGINE) {
String id = cosmeticBalloonType.getModelName(); String id = cosmeticBalloonType.getModelName();
MessagesUtil.sendDebugMessages("Attempting Spawning for " + id); MessagesUtil.sendDebugMessages("Attempting Spawning for " + id);
if (ModelEngineAPI.api.getModelRegistry().getBlueprint(id) == null) { if (ModelEngineAPI.getBlueprint(id) == null) {
MessagesUtil.sendDebugMessages("Invalid Model Engine Blueprint " + id, Level.SEVERE); MessagesUtil.sendDebugMessages("Invalid Model Engine Blueprint " + id, Level.SEVERE);
return; return;
} }
@@ -62,14 +77,19 @@ public class UserBalloonManager {
ActiveModel model = ModelEngineAPI.createActiveModel(ModelEngineAPI.getBlueprint(id)); ActiveModel model = ModelEngineAPI.createActiveModel(ModelEngineAPI.getBlueprint(id));
model.setCanHurt(false); model.setCanHurt(false);
modeledEntity.addModel(model, false); modeledEntity.addModel(model, false);
if (color != null) { if (color != null) {
modeledEntity.getModels().forEach((d, singleModel) -> { modeledEntity.getModels().forEach((d, singleModel) -> {
if (cosmeticBalloonType.isDyablePart(d)) { if (cosmeticBalloonType.isDyablePart(d)) {
singleModel.getRendererHandler().setColor(color); singleModel.setDefaultTint(color);
singleModel.getRendererHandler().update(); singleModel.getModelRenderer().sendToClient();
} }
}); });
} }
BukkitEntityData data = (BukkitEntityData) modeledEntity.getBase().getData();
data.setBlockedCullIgnoreRadius((double) Settings.getViewDistance());
data.getTracked().setPlayerPredicate(this::playerCheck);
return; return;
} }
if (balloonType == BalloonType.ITEM) { if (balloonType == BalloonType.ITEM) {
@@ -79,18 +99,19 @@ public class UserBalloonManager {
public void remove() { public void remove() {
if (balloonType == BalloonType.MODELENGINE) { if (balloonType == BalloonType.MODELENGINE) {
final ModeledEntity entity = ModelEngineAPI.api.getModeledEntity(modelEntity.getUniqueId()); final ModeledEntity entity = ModelEngineAPI.getModeledEntity(modelEntity);
if (entity == null) {
if (entity == null) return; MessagesUtil.sendDebugMessages("Balloon Removal Failed - Model Entity is Null");
return;
for (final Player player : entity.getRangeManager().getPlayerInRange()) {
entity.hideFromPlayer(player);
} }
entity.destroy(); entity.destroy();
MessagesUtil.sendDebugMessages("Balloon Model Engine Removal");
} }
modelEntity.remove(); modelEntity.remove();
cosmeticBalloonType = null; cosmeticBalloonType = null;
MessagesUtil.sendDebugMessages("Balloon Entity Removed");
} }
public void addPlayerToModel(final CosmeticUser user, final CosmeticBalloonType cosmeticBalloonType) { public void addPlayerToModel(final CosmeticUser user, final CosmeticBalloonType cosmeticBalloonType) {
@@ -99,14 +120,13 @@ public class UserBalloonManager {
public void addPlayerToModel(final CosmeticUser user, final CosmeticBalloonType cosmeticBalloonType, Color color) { public void addPlayerToModel(final CosmeticUser user, final CosmeticBalloonType cosmeticBalloonType, Color color) {
if (balloonType == BalloonType.MODELENGINE) { if (balloonType == BalloonType.MODELENGINE) {
final ModeledEntity model = ModelEngineAPI.api.getModeledEntity(modelEntity.getUniqueId()); final ModeledEntity model = ModelEngineAPI.getModeledEntity(modelEntity);
if (model == null) { if (model == null) {
spawnModel(cosmeticBalloonType, color); spawnModel(cosmeticBalloonType, color);
MessagesUtil.sendDebugMessages("model is null"); MessagesUtil.sendDebugMessages("model is null");
return; return;
} }
//if (model.getRangeManager().getPlayerInRange().contains(player)) return;
model.showToPlayer(user.getPlayer());
MessagesUtil.sendDebugMessages("Show to player"); MessagesUtil.sendDebugMessages("Show to player");
return; return;
} }
@@ -114,13 +134,11 @@ public class UserBalloonManager {
modelEntity.getEquipment().setHelmet(user.getUserCosmeticItem(cosmeticBalloonType)); modelEntity.getEquipment().setHelmet(user.getUserCosmeticItem(cosmeticBalloonType));
} }
} }
public void removePlayerFromModel(final Player player) { public void removePlayerFromModel(final Player viewer) {
if (balloonType == BalloonType.MODELENGINE) { if (balloonType == BalloonType.MODELENGINE) {
final ModeledEntity model = ModelEngineAPI.api.getModeledEntity(modelEntity.getUniqueId()); final ModeledEntity model = ModelEngineAPI.getModeledEntity(modelEntity);
if (model == null) return; if (model == null) return;
model.hideFromPlayer(player);
MessagesUtil.sendDebugMessages("Hidden from player"); MessagesUtil.sendDebugMessages("Hidden from player");
return; return;
} }
@@ -136,10 +154,10 @@ public class UserBalloonManager {
public int getPufferfishBalloonId() { public int getPufferfishBalloonId() {
return balloonID; return pufferfish.getPufferFishEntityId();
} }
public UUID getPufferfishBalloonUniqueId() { public UUID getPufferfishBalloonUniqueId() {
return uniqueID; return pufferfish.getUuid();
} }
public UUID getModelUnqiueId() { public UUID getModelUnqiueId() {
@@ -163,16 +181,17 @@ public class UserBalloonManager {
} }
public void sendRemoveLeashPacket(List<Player> viewer) { public void sendRemoveLeashPacket(List<Player> viewer) {
PacketManager.sendLeashPacket(getPufferfishBalloonId(), -1, viewer); HMCCPacketManager.sendLeashPacket(getPufferfishBalloonId(), -1, viewer);
} }
public void sendRemoveLeashPacket() { public void sendRemoveLeashPacket() {
PacketManager.sendLeashPacket(getPufferfishBalloonId(), -1, getLocation()); HMCCPacketManager.sendLeashPacket(getPufferfishBalloonId(), -1, getLocation());
} }
public void sendLeashPacket(int entityId) { public void sendLeashPacket(int entityId) {
if (cosmeticBalloonType == null) return; if (cosmeticBalloonType.isShowLead()) {
if (cosmeticBalloonType.isShowLead()) PacketManager.sendLeashPacket(getPufferfishBalloonId(), entityId, getLocation()); HMCCPacketManager.sendLeashPacket(getPufferfishBalloonId(), entityId, getLocation());
}
} }
public enum BalloonType { public enum BalloonType {
@@ -180,4 +199,21 @@ public class UserBalloonManager {
ITEM, ITEM,
NONE NONE
} }
private boolean playerCheck(final Player player) {
MessagesUtil.sendDebugMessages("playerCheck");
CosmeticUser viewer = CosmeticUsers.getUser(player.getUniqueId());
if (user.getPlayer() == player) {
return (!user.getHidden());
} else {
if (user.isInWardrobe()) return false;
MessagesUtil.sendDebugMessages("playerCheck - Not Same Player");
if (viewer != null && viewer.isInWardrobe()) {
MessagesUtil.sendDebugMessages("playerCheck - Viewer in Wardrobe");
return false;
}
}
return (!user.getHidden());
}
} }

View File

@@ -0,0 +1,75 @@
package com.hibiscusmc.hmccosmetics.user.manager;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.HMCCPlayerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class UserBalloonPufferfish extends UserEntity {
private int pufferFishEntityId;
private UUID uuid;
public UserBalloonPufferfish(UUID owner, int pufferFishEntityId, UUID uuid) {
super(owner);
this.pufferFishEntityId = pufferFishEntityId;
this.uuid = uuid;
}
public int getPufferFishEntityId() {
return pufferFishEntityId;
}
public UUID getUuid() {
return uuid;
}
public void hidePufferfish() {
HMCCPacketManager.sendEntityDestroyPacket(pufferFishEntityId, getViewers());
getViewers().clear();
}
public void spawnPufferfish(Location location, List<Player> sendTo) {
HMCCPacketManager.sendEntitySpawnPacket(location, pufferFishEntityId, EntityType.PUFFERFISH, uuid, sendTo);
HMCCPacketManager.sendInvisibilityPacket(pufferFishEntityId, sendTo);
}
@Override
public List<Player> refreshViewers(Location location) {
if (System.currentTimeMillis() - getViewerLastUpdate() <= 1000) return List.of(); //Prevents mass refreshes
ArrayList<Player> newPlayers = new ArrayList<>();
ArrayList<Player> removePlayers = new ArrayList<>();
List<Player> players = HMCCPlayerUtils.getNearbyPlayers(location);
for (Player player : players) {
CosmeticUser user = CosmeticUsers.getUser(player);
if (user != null && getOwner() != user.getUniqueId() && user.isInWardrobe()) { // Fixes issue where players in wardrobe would see other players cosmetics if they were not in wardrobe
removePlayers.add(player);
HMCCPacketManager.sendEntityDestroyPacket(getPufferFishEntityId(), List.of(player));
continue;
}
if (!getViewers().contains(player)) {
getViewers().add(player);
newPlayers.add(player);
continue;
}
// bad loopdy loops
for (Player viewerPlayer : getViewers()) {
if (!players.contains(viewerPlayer)) {
removePlayers.add(viewerPlayer);
HMCCPacketManager.sendEntityDestroyPacket(getPufferFishEntityId(), List.of(viewerPlayer));
}
}
}
getViewers().removeAll(removePlayers);
setViewerLastUpdate(System.currentTimeMillis());
return newPlayers;
}
}

View File

@@ -1,32 +1,40 @@
package com.hibiscusmc.hmccosmetics.user.manager; package com.hibiscusmc.hmccosmetics.user.manager;
import com.hibiscusmc.hmccosmetics.api.PlayerEmoteStartEvent; import com.hibiscusmc.hmccosmetics.api.events.PlayerEmoteStartEvent;
import com.hibiscusmc.hmccosmetics.api.PlayerEmoteStopEvent; import com.hibiscusmc.hmccosmetics.api.events.PlayerEmoteStopEvent;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticEmoteType; import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticEmoteType;
import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class UserEmoteManager { public class UserEmoteManager {
CosmeticUser user; private CosmeticUser user;
private UserEmoteModel model; private UserEmoteModel model;
private Entity textEntity;
public UserEmoteManager(CosmeticUser user) { public UserEmoteManager(CosmeticUser user) {
this.user = user; this.user = user;
} }
public void playEmote(@NotNull CosmeticEmoteType cosmeticEmoteType) { public void playEmote(String animationId) {
MessagesUtil.sendDebugMessages("playEmote " + cosmeticEmoteType.getAnimationId()); MessagesUtil.sendDebugMessages("playEmote " + animationId);
playEmote(cosmeticEmoteType.getAnimationId()); 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 (isPlayingEmote()) return;
if (user.isInWardrobe()) return; if (user.isInWardrobe()) return;
// API // API
PlayerEmoteStartEvent event = new PlayerEmoteStartEvent(user, animationId); PlayerEmoteStartEvent event = new PlayerEmoteStartEvent(user, emoteAnimation);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
@@ -34,7 +42,15 @@ public class UserEmoteManager {
// Internal // Internal
try { try {
model = new UserEmoteModel(user); model = new UserEmoteModel(user);
model.playAnimation(animationId); // Play animation id
if (emoteAnimation != null) {
model.playAnimation(emoteAnimation);
}
// Show the text
if (text != null && textEntity == null) {
// removed in 2.7.0
//textEntity = HMCCNMSHandlers.getHandler().spawnDisplayEntity(user.getPlayer().getLocation().add(0, 3, 0), text);
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -55,12 +71,24 @@ public class UserEmoteManager {
} }
// Internal // Internal
model.stopAnimation(); model.stopAnimation();
if (textEntity != null) {
textEntity.remove();
textEntity = null;
}
}
public void despawnTextEntity() {
if (textEntity != null) {
textEntity.remove();
textEntity = null;
}
} }
public enum StopEmoteReason { public enum StopEmoteReason {
SNEAK, SNEAK,
DAMAGE, DAMAGE,
CONNECTION, CONNECTION,
TELEPORT TELEPORT,
UNEQUIP
} }
} }

View File

@@ -2,16 +2,15 @@ package com.hibiscusmc.hmccosmetics.user.manager;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings; import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.HMCCServerUtils;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.ServerUtils; import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager;
import com.ticxo.playeranimator.api.model.player.PlayerModel; import com.ticxo.playeranimator.api.model.player.PlayerModel;
import me.lojosho.hibiscuscommons.util.ServerUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -30,15 +29,12 @@ public class UserEmoteModel extends PlayerModel {
public UserEmoteModel(@NotNull CosmeticUser user) { public UserEmoteModel(@NotNull CosmeticUser user) {
super(user.getPlayer()); super(user.getPlayer());
this.user = user; this.user = user;
armorStandId = NMSHandlers.getHandler().getNextEntityId(); armorStandId = ServerUtils.getNextEntityId();
getRangeManager().setRenderDistance(Settings.getViewDistance()); getRangeManager().setRenderDistance(Settings.getViewDistance());
} }
@Override @Override
public void playAnimation(@NotNull String id) { 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); super.playAnimation(id);
emotePlaying = id; emotePlaying = id;
@@ -46,39 +42,47 @@ public class UserEmoteModel extends PlayerModel {
// Add config option that either allows player to move or forces them into a spot. // Add config option that either allows player to move or forces them into a spot.
Player player = user.getPlayer(); Player player = user.getPlayer();
List<Player> viewer = Collections.singletonList(user.getPlayer()); List<Player> viewer = Collections.singletonList(user.getPlayer());
List<Player> outsideViewers = PacketManager.getViewers(player.getLocation()); List<Player> outsideViewers = HMCCPacketManager.getViewers(player.getLocation());
// Send equipment packet to the player as well (Fixes Optifine still rendering armor when emoting)
HMCCPacketManager.equipmentSlotUpdate(player, true, outsideViewers);
outsideViewers.remove(player); outsideViewers.remove(player);
PacketManager.equipmentSlotUpdate(player, true, outsideViewers);
Location newLocation = player.getLocation().clone();
newLocation.setPitch(0);
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;
}
user.getPlayer().setInvisible(true); user.getPlayer().setInvisible(true);
user.hideCosmetics(CosmeticUser.HiddenReason.EMOTE); user.hideCosmetics(CosmeticUser.HiddenReason.EMOTE);
originalGamemode = player.getGameMode(); originalGamemode = player.getGameMode();
PacketManager.sendEntitySpawnPacket(thirdPersonLocation, armorStandId, EntityType.ARMOR_STAND, UUID.randomUUID(), viewer); if (Settings.isEmoteCameraEnabled()) {
PacketManager.sendInvisibilityPacket(armorStandId, viewer); Location newLocation = player.getLocation().clone();
PacketManager.sendLookPacket(armorStandId, thirdPersonLocation, viewer); newLocation.setPitch(0);
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.isCosmeticEmoteBlockCheck() && thirdPersonLocation.getBlock().getType().isOccluding()) {
stopAnimation();
MessagesUtil.sendMessage(player, "emote-blocked");
return;
}
// Check if block below player is an air block
if (Settings.isEmoteAirCheck() && newLocation.clone().subtract(0, 1, 0).getBlock().getType().isAir()) {
stopAnimation();
MessagesUtil.sendMessage(player, "emote-blocked");
}
HMCCPacketManager.sendEntitySpawnPacket(thirdPersonLocation, armorStandId, EntityType.ARMOR_STAND, UUID.randomUUID(), viewer);
HMCCPacketManager.sendInvisibilityPacket(armorStandId, viewer);
HMCCPacketManager.sendLookPacket(armorStandId, thirdPersonLocation, viewer);
HMCCPacketManager.gamemodeChangePacket(player, 3);
HMCCPacketManager.sendCameraPacket(armorStandId, viewer);
}
PacketManager.gamemodeChangePacket(player, 3);
PacketManager.sendCameraPacket(armorStandId, viewer);
MessagesUtil.sendDebugMessages("playAnimation run"); MessagesUtil.sendDebugMessages("playAnimation run");
} }
@@ -104,19 +108,21 @@ public class UserEmoteModel extends PlayerModel {
if (player == null) return; if (player == null) return;
List<Player> viewer = Collections.singletonList(player); List<Player> viewer = Collections.singletonList(player);
List<Player> outsideViewers = PacketManager.getViewers(player.getLocation()); List<Player> outsideViewers = HMCCPacketManager.getViewers(player.getLocation());
// Send Equipment packet to all (Fixes Optifine Issue)
HMCCPacketManager.equipmentSlotUpdate(player, false, outsideViewers);
outsideViewers.remove(player); outsideViewers.remove(player);
int entityId = player.getEntityId(); int entityId = player.getEntityId();
PacketManager.sendCameraPacket(entityId, viewer); HMCCPacketManager.sendCameraPacket(entityId, viewer);
PacketManager.sendEntityDestroyPacket(armorStandId, viewer); HMCCPacketManager.sendEntityDestroyPacket(armorStandId, viewer);
if (this.originalGamemode != null) { if (this.originalGamemode != null) {
PacketManager.gamemodeChangePacket(player, ServerUtils.convertGamemode(this.originalGamemode)); HMCCPacketManager.gamemodeChangePacket(player, HMCCServerUtils.convertGamemode(this.originalGamemode));
player.setGameMode(this.originalGamemode); player.setGameMode(this.originalGamemode);
} }
if (user.getPlayer() != null) player.setInvisible(false); if (user.getPlayer() != null) player.setInvisible(false);
PacketManager.equipmentSlotUpdate(player, false, outsideViewers); user.getUserEmoteManager().despawnTextEntity();
user.showPlayer(); user.showPlayer();
user.showCosmetics(); user.showCosmetics();
}); });

View File

@@ -0,0 +1,97 @@
package com.hibiscusmc.hmccosmetics.user.manager;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.HMCCPlayerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class UserEntity {
@Getter
private UUID owner;
@Getter
private List<Player> viewers = new ArrayList<>();
@Getter @Setter
private Long viewerLastUpdate = 0L;
@Getter @Setter
private Long lastPositionUpdate = 0L;
@Getter @Setter
private List<Integer> ids = new ArrayList<>();
@Getter
private Location location;
public UserEntity(UUID owner) {
this.owner = owner;
}
public List<Player> refreshViewers() {
return refreshViewers(location);
}
public List<Player> refreshViewers(Location location) {
if (System.currentTimeMillis() - viewerLastUpdate <= 1000) return List.of(); //Prevents mass refreshes
ArrayList<Player> newPlayers = new ArrayList<>();
ArrayList<Player> removePlayers = new ArrayList<>();
List<Player> players = HMCCPlayerUtils.getNearbyPlayers(location);
for (Player player : players) {
CosmeticUser user = CosmeticUsers.getUser(player);
if (user != null && owner != user.getUniqueId() && user.isInWardrobe()) { // Fixes issue where players in wardrobe would see other players cosmetics if they were not in wardrobe
removePlayers.add(player);
HMCCPacketManager.sendEntityDestroyPacket(ids, List.of(player));
continue;
}
if (!viewers.contains(player)) {
viewers.add(player);
newPlayers.add(player);
continue;
}
// bad loopdy loops
for (Player viewerPlayer : viewers) {
if (!players.contains(viewerPlayer)) {
removePlayers.add(viewerPlayer);
HMCCPacketManager.sendEntityDestroyPacket(ids, List.of(viewerPlayer));
}
}
}
viewers.removeAll(removePlayers);
setViewerLastUpdate(System.currentTimeMillis());
return newPlayers;
}
public void teleport(Location location) {
if (this.getLocation() != null && this.getLocation().getWorld() == location.getWorld()) {
// Was thinking about using schedulers to just send the packet later... but that would be a lot of tasks and
// would probably cause more lag. Furthermore, the server "ticks" the cosmetics every second by defualt. So it's fine like this.
if (System.currentTimeMillis() - getLastPositionUpdate() <= Settings.getPacketEntityTeleportCooldown()) return;
}
this.location = location;
for (Integer entity : ids) {
HMCCPacketManager.sendTeleportPacket(entity, location, false, getViewers());
}
setLastPositionUpdate(System.currentTimeMillis());
}
public void setRotation(int yaw) {
setRotation(yaw, false);
}
public void setRotation(int yaw, boolean additonalPacket) {
location.setYaw(yaw);
for (Integer entity : ids) {
// First person backpacks need both packets to rotate properly, otherwise they look off
// Regular backpacks just need the look packet
if (additonalPacket) HMCCPacketManager.sendRotationPacket(entity, yaw, false, getViewers());
HMCCPacketManager.sendLookPacket(entity, location, getViewers());
}
}
}

View File

@@ -1,15 +1,21 @@
package com.hibiscusmc.hmccosmetics.user.manager; package com.hibiscusmc.hmccosmetics.user.manager;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; 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.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot; import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers; import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.ServerUtils; import com.hibiscusmc.hmccosmetics.util.HMCCServerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager; import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import lombok.Getter;
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
@@ -20,6 +26,7 @@ import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
@@ -32,28 +39,47 @@ import java.util.concurrent.atomic.AtomicInteger;
public class UserWardrobeManager { public class UserWardrobeManager {
@Getter
private final int NPC_ID; private final int NPC_ID;
@Getter
private final int ARMORSTAND_ID; private final int ARMORSTAND_ID;
@Getter
private final UUID WARDROBE_UUID; private final UUID WARDROBE_UUID;
@Getter
private String npcName; private String npcName;
@Getter
private GameMode originalGamemode; private GameMode originalGamemode;
@Getter
private final CosmeticUser user; private final CosmeticUser user;
@Getter
private final Wardrobe wardrobe;
@Getter
private final WardrobeLocation wardrobeLocation;
@Getter
private final Location viewingLocation; private final Location viewingLocation;
@Getter
private final Location npcLocation; private final Location npcLocation;
@Getter
private Location exitLocation; private Location exitLocation;
@Getter
private BossBar bossBar; private BossBar bossBar;
@Getter
private boolean active; private boolean active;
@Getter
private WardrobeStatus wardrobeStatus; private WardrobeStatus wardrobeStatus;
public UserWardrobeManager(CosmeticUser user, Location exitLocation, Location viewingLocation, Location npcLocation) { public UserWardrobeManager(CosmeticUser user, Wardrobe wardrobe) {
NPC_ID = NMSHandlers.getHandler().getNextEntityId(); NPC_ID = me.lojosho.hibiscuscommons.util.ServerUtils.getNextEntityId();
ARMORSTAND_ID = NMSHandlers.getHandler().getNextEntityId(); ARMORSTAND_ID = me.lojosho.hibiscuscommons.util.ServerUtils.getNextEntityId();
WARDROBE_UUID = UUID.randomUUID(); WARDROBE_UUID = UUID.randomUUID();
this.user = user; this.user = user;
this.exitLocation = exitLocation; this.wardrobe = wardrobe;
this.viewingLocation = viewingLocation; this.wardrobeLocation = wardrobe.getLocation();
this.npcLocation = npcLocation;
this.exitLocation = wardrobeLocation.getLeaveLocation();
this.viewingLocation = wardrobeLocation.getViewerLocation();
this.npcLocation = wardrobeLocation.getNpcLocation();
wardrobeStatus = WardrobeStatus.SETUP; wardrobeStatus = WardrobeStatus.SETUP;
} }
@@ -69,57 +95,72 @@ public class UserWardrobeManager {
user.hidePlayer(); user.hidePlayer();
List<Player> viewer = Collections.singletonList(player); List<Player> viewer = Collections.singletonList(player);
List<Player> outsideViewers = PacketManager.getViewers(viewingLocation); List<Player> outsideViewers = HMCCPacketManager.getViewers(viewingLocation);
outsideViewers.remove(player); outsideViewers.remove(player);
MessagesUtil.sendMessage(player, "opened-wardrobe"); MessagesUtil.sendMessage(player, "opened-wardrobe");
Runnable run = () -> { Runnable run = () -> {
// Armorstand // Armorstand
PacketManager.sendEntitySpawnPacket(viewingLocation, ARMORSTAND_ID, EntityType.ARMOR_STAND, UUID.randomUUID(), viewer); HMCCPacketManager.sendEntitySpawnPacket(viewingLocation, ARMORSTAND_ID, EntityType.ARMOR_STAND, UUID.randomUUID(), viewer);
PacketManager.sendInvisibilityPacket(ARMORSTAND_ID, viewer); HMCCPacketManager.sendArmorstandMetadata(ARMORSTAND_ID, viewer);
PacketManager.sendLookPacket(ARMORSTAND_ID, viewingLocation, viewer); HMCCPacketManager.sendLookPacket(ARMORSTAND_ID, viewingLocation, viewer);
// Player // Player
PacketManager.gamemodeChangePacket(player, 3); user.getPlayer().teleport(viewingLocation, PlayerTeleportEvent.TeleportCause.PLUGIN);
PacketManager.sendCameraPacket(ARMORSTAND_ID, viewer); user.getPlayer().setInvisible(true);
HMCCPacketManager.gamemodeChangePacket(player, 3);
HMCCPacketManager.sendCameraPacket(ARMORSTAND_ID, viewer);
// NPC // NPC
npcName = "WardrobeNPC-" + NPC_ID; npcName = "WardrobeNPC-" + NPC_ID;
while (npcName.length() > 16) { while (npcName.length() > 16) {
npcName = npcName.substring(16); npcName = npcName.substring(16);
} }
PacketManager.sendFakePlayerInfoPacket(player, NPC_ID, WARDROBE_UUID, npcName, viewer); HMCCPacketManager.sendFakePlayerInfoPacket(player, NPC_ID, WARDROBE_UUID, npcName, viewer);
// NPC 2 // NPC 2
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> { Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
PacketManager.sendFakePlayerSpawnPacket(npcLocation, WARDROBE_UUID, NPC_ID, viewer); if (!user.isInWardrobe()) return; // If a player exits the wardrobe right away, no need to spawn the NPC
HMCCPacketManager.sendFakePlayerSpawnPacket(npcLocation, WARDROBE_UUID, NPC_ID, viewer);
HMCCPacketManager.sendPlayerOverlayPacket(NPC_ID, viewer);
MessagesUtil.sendDebugMessages("Spawned Fake Player on " + npcLocation); MessagesUtil.sendDebugMessages("Spawned Fake Player on " + npcLocation);
NMSHandlers.getHandler().hideNPCName(player, npcName); NMSHandlers.getHandler().hideNPCName(player, npcName);
}, 4); }, 4);
// Location // Location
PacketManager.sendLookPacket(NPC_ID, npcLocation, viewer); HMCCPacketManager.sendLookPacket(NPC_ID, npcLocation, viewer);
PacketManager.sendRotationPacket(NPC_ID, npcLocation, true, viewer); HMCCPacketManager.sendRotationPacket(NPC_ID, npcLocation, true, viewer);
// Misc // Misc
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) { if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
user.getUserBackpackManager().getArmorStand().teleport(npcLocation.clone().add(0, 2, 0)); // Maybe null as backpack maybe despawned before entering
PacketManager.ridingMountPacket(NPC_ID, user.getUserBackpackManager().getFirstArmorStandId(), viewer); if (user.getUserBackpackManager() == null) user.respawnBackpack();
if (user.isBackpackSpawned()) {
user.getUserBackpackManager().getEntityManager().teleport(npcLocation.clone().add(0, 2, 0));
PacketManager.equipmentSlotUpdate(user.getUserBackpackManager().getFirstArmorStandId(), EquipmentSlot.HEAD, user.getUserCosmeticItem(user.getCosmetic(CosmeticSlot.BACKPACK)), viewer);
HMCCPacketManager.ridingMountPacket(NPC_ID, user.getUserBackpackManager().getFirstArmorStandId(), viewer);
}
} }
if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) { if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
user.getBalloonManager().sendRemoveLeashPacket(viewer); if (user.getBalloonManager() == null) user.respawnBalloon();
user.getBalloonManager().sendLeashPacket(NPC_ID); if (user.isBalloonSpawned()) {
//PacketManager.sendLeashPacket(VIEWER.getBalloonEntity().getModelId(), NPC_ID, viewer); CosmeticBalloonType cosmetic = (CosmeticBalloonType) user.getCosmetic(CosmeticSlot.BALLOON);
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); Location balloonLocation = npcLocation.clone().add(cosmetic.getBalloonOffset());
user.getBalloonManager().getModelEntity().teleport(npcLocation.clone().add(Settings.getBalloonOffset())); HMCCPacketManager.sendTeleportPacket(user.getBalloonManager().getPufferfishBalloonId(), balloonLocation, false, viewer);
user.getBalloonManager().getModelEntity().teleport(balloonLocation);
user.getBalloonManager().setLocation(balloonLocation);
}
} }
if (WardrobeSettings.getEnabledBossbar()) { if (WardrobeSettings.isEnabledBossbar()) {
float progress = WardrobeSettings.getBossbarProgress(); float progress = WardrobeSettings.getBossbarProgress();
Component message = MessagesUtil.processStringNoKey(WardrobeSettings.getBossbarText()); Component message = MessagesUtil.processStringNoKey(WardrobeSettings.getBossbarMessage());
bossBar = BossBar.bossBar(message, progress, WardrobeSettings.getBossbarColor(), WardrobeSettings.getBossbarOverlay()); bossBar = BossBar.bossBar(message, progress, WardrobeSettings.getBossbarColor(), WardrobeSettings.getBossbarOverlay());
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player); Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
@@ -127,6 +168,11 @@ public class UserWardrobeManager {
target.showBossBar(bossBar); target.showBossBar(bossBar);
} }
if (WardrobeSettings.isEnterOpenMenu()) {
Menu menu = Menus.getDefaultMenu();
if (menu != null) menu.openMenu(user);
}
this.active = true; this.active = true;
update(); update();
setWardrobeStatus(WardrobeStatus.RUNNING); setWardrobeStatus(WardrobeStatus.RUNNING);
@@ -153,7 +199,7 @@ public class UserWardrobeManager {
Player player = user.getPlayer(); Player player = user.getPlayer();
List<Player> viewer = Collections.singletonList(player); List<Player> viewer = Collections.singletonList(player);
List<Player> outsideViewers = PacketManager.getViewers(viewingLocation); List<Player> outsideViewers = HMCCPacketManager.getViewers(viewingLocation);
outsideViewers.remove(player); outsideViewers.remove(player);
if (player != null) MessagesUtil.sendMessage(player, "closed-wardrobe"); if (player != null) MessagesUtil.sendMessage(player, "closed-wardrobe");
@@ -161,26 +207,36 @@ public class UserWardrobeManager {
Runnable run = () -> { Runnable run = () -> {
this.active = false; 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 // NPC
if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) user.getBalloonManager().sendRemoveLeashPacket(); if (user.isBalloonSpawned()) user.getBalloonManager().sendRemoveLeashPacket();
PacketManager.sendEntityDestroyPacket(NPC_ID, viewer); // Success HMCCPacketManager.sendEntityDestroyPacket(NPC_ID, viewer); // Success
PacketManager.sendRemovePlayerPacket(player, WARDROBE_UUID, viewer); // Success HMCCPacketManager.sendRemovePlayerPacket(player, WARDROBE_UUID, viewer); // Success
// Player // Player
PacketManager.sendCameraPacket(player.getEntityId(), viewer); HMCCPacketManager.sendCameraPacket(player.getEntityId(), viewer);
user.getPlayer().setInvisible(false);
// Armorstand // Armorstand
PacketManager.sendEntityDestroyPacket(ARMORSTAND_ID, viewer); // Sucess HMCCPacketManager.sendEntityDestroyPacket(ARMORSTAND_ID, viewer); // Sucess
//PacketManager.sendEntityDestroyPacket(player.getEntityId(), viewer); // Success //PacketManager.sendEntityDestroyPacket(player.getEntityId(), viewer); // Success
if (WardrobeSettings.isForceExitGamemode()) { if (WardrobeSettings.isForceExitGamemode()) {
MessagesUtil.sendDebugMessages("Force Exit Gamemode " + WardrobeSettings.getExitGamemode()); MessagesUtil.sendDebugMessages("Force Exit Gamemode " + WardrobeSettings.getExitGamemode());
player.setGameMode(WardrobeSettings.getExitGamemode()); player.setGameMode(WardrobeSettings.getExitGamemode());
PacketManager.gamemodeChangePacket(player, ServerUtils.convertGamemode(WardrobeSettings.getExitGamemode())); // Success HMCCPacketManager.gamemodeChangePacket(player, HMCCServerUtils.convertGamemode(WardrobeSettings.getExitGamemode())); // Success
} else { } else {
MessagesUtil.sendDebugMessages("Original Gamemode " + this.originalGamemode); MessagesUtil.sendDebugMessages("Original Gamemode " + this.originalGamemode);
player.setGameMode(this.originalGamemode); player.setGameMode(this.originalGamemode);
PacketManager.gamemodeChangePacket(player, ServerUtils.convertGamemode(this.originalGamemode)); // Success HMCCPacketManager.gamemodeChangePacket(player, HMCCServerUtils.convertGamemode(this.originalGamemode)); // Success
} }
user.showPlayer(); user.showPlayer();
@@ -190,29 +246,22 @@ public class UserWardrobeManager {
} }
if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) { if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
user.respawnBalloon(); //user.respawnBalloon();
//PacketManager.sendLeashPacket(VIEWER.getBalloonEntity().getPufferfishBalloonId(), player.getEntityId(), viewer); //PacketManager.sendLeashPacket(VIEWER.getBalloonEntity().getPufferfishBalloonId(), player.getEntityId(), viewer);
} }
player.teleport(Objects.requireNonNullElseGet(exitLocation, () -> player.getWorld().getSpawnLocation())); player.teleport(Objects.requireNonNullElseGet(exitLocation, () -> player.getWorld().getSpawnLocation()), PlayerTeleportEvent.TeleportCause.PLUGIN);
if (WardrobeSettings.isEquipPumpkin()) { if (WardrobeSettings.isEquipPumpkin()) {
NMSHandlers.getHandler().equipmentSlotUpdate(user.getPlayer().getEntityId(), EquipmentSlot.HEAD, player.getInventory().getHelmet(), viewer); PacketManager.equipmentSlotUpdate(user.getPlayer().getEntityId(), EquipmentSlot.HEAD, player.getInventory().getHelmet(), viewer);
} }
if (WardrobeSettings.getEnabledBossbar()) { if (WardrobeSettings.isEnabledBossbar()) {
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player); Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
target.hideBossBar(bossBar); target.hideBossBar(bossBar);
} }
// For Wardrobe Temp Cosmetics
for (Cosmetic cosmetic : user.getCosmetics()) {
if (cosmetic.requiresPermission()) {
if (!player.hasPermission(cosmetic.getPermission())) user.removeCosmeticSlot(cosmetic.getSlot());
}
}
user.updateCosmetic(); user.updateCosmetic();
}; };
run.run(); run.run();
@@ -230,44 +279,49 @@ public class UserWardrobeManager {
this.cancel(); this.cancel();
return; return;
} }
MessagesUtil.sendDebugMessages("WardrobeUpdate[user= " + user.getUniqueId() + ",status=" + getWardrobeStatus() + "]"); MessagesUtil.sendDebugMessages("WardrobeUpdate[user=" + user.getUniqueId() + ",status=" + getWardrobeStatus() + "]");
List<Player> viewer = Collections.singletonList(player); List<Player> viewer = Collections.singletonList(player);
List<Player> outsideViewers = PacketManager.getViewers(viewingLocation); List<Player> outsideViewers = HMCCPacketManager.getViewers(viewingLocation);
outsideViewers.remove(player); outsideViewers.remove(player);
Location location = WardrobeSettings.getWardrobeLocation().clone(); Location location = npcLocation;
int yaw = data.get(); int yaw = data.get();
location.setYaw(yaw); location.setYaw(yaw);
PacketManager.sendLookPacket(NPC_ID, location, viewer); HMCCPacketManager.sendLookPacket(NPC_ID, location, viewer);
user.hidePlayer(); user.hidePlayer();
int rotationSpeed = WardrobeSettings.getRotationSpeed(); int rotationSpeed = WardrobeSettings.getRotationSpeed();
location.setYaw(ServerUtils.getNextYaw(yaw - 30, rotationSpeed)); location.setYaw(HMCCServerUtils.getNextYaw(yaw - 30, rotationSpeed));
PacketManager.sendRotationPacket(NPC_ID, location, true, viewer); HMCCPacketManager.sendRotationPacket(NPC_ID, location, true, viewer);
int nextyaw = ServerUtils.getNextYaw(yaw, rotationSpeed); int nextyaw = HMCCServerUtils.getNextYaw(yaw, rotationSpeed);
data.set(nextyaw); data.set(nextyaw);
for (CosmeticSlot slot : CosmeticSlot.values()) { for (CosmeticSlot slot : CosmeticSlot.values()) {
PacketManager.equipmentSlotUpdate(NPC_ID, user, slot, viewer); HMCCPacketManager.equipmentSlotUpdate(NPC_ID, user, slot, viewer);
} }
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) { if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK) && user.getUserBackpackManager() != null) {
PacketManager.sendTeleportPacket(user.getUserBackpackManager().getFirstArmorStandId(), location, false, viewer); HMCCPacketManager.sendTeleportPacket(user.getUserBackpackManager().getFirstArmorStandId(), location, false, viewer);
PacketManager.ridingMountPacket(NPC_ID, user.getUserBackpackManager().getFirstArmorStandId(), viewer); HMCCPacketManager.ridingMountPacket(NPC_ID, user.getUserBackpackManager().getFirstArmorStandId(), viewer);
user.getUserBackpackManager().getArmorStand().setRotation(nextyaw, 0); user.getUserBackpackManager().getEntityManager().setRotation(nextyaw);
PacketManager.sendEntityDestroyPacket(user.getUserBackpackManager().getFirstArmorStandId(), outsideViewers); HMCCPacketManager.sendEntityDestroyPacket(user.getUserBackpackManager().getFirstArmorStandId(), outsideViewers);
} }
if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) { if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON) && user.isBalloonSpawned()) {
PacketManager.sendTeleportPacket(user.getBalloonManager().getPufferfishBalloonId(), WardrobeSettings.getWardrobeLocation().add(Settings.getBalloonOffset()), false, viewer); // The two lines below broke, solved by listening to PlayerCosmeticPostEquipEvent
user.getBalloonManager().getModelEntity().teleport(WardrobeSettings.getWardrobeLocation().add(Settings.getBalloonOffset())); //PacketManager.sendTeleportPacket(user.getBalloonManager().getPufferfishBalloonId(), npcLocation.add(Settings.getBalloonOffset()), false, viewer);
//user.getBalloonManager().getModelEntity().teleport(npcLocation.add(Settings.getBalloonOffset()));
user.getBalloonManager().sendRemoveLeashPacket(outsideViewers); user.getBalloonManager().sendRemoveLeashPacket(outsideViewers);
PacketManager.sendEntityDestroyPacket(user.getBalloonManager().getModelId(), outsideViewers); if (user.getBalloonManager().getBalloonType() != UserBalloonManager.BalloonType.MODELENGINE) {
HMCCPacketManager.sendEntityDestroyPacket(user.getBalloonManager().getModelId(), outsideViewers);
}
user.getBalloonManager().sendLeashPacket(NPC_ID); user.getBalloonManager().sendLeashPacket(NPC_ID);
} }
if (WardrobeSettings.isEquipPumpkin()) { if (WardrobeSettings.isEquipPumpkin()) {
NMSHandlers.getHandler().equipmentSlotUpdate(user.getPlayer().getEntityId(), EquipmentSlot.HEAD, new ItemStack(Material.CARVED_PUMPKIN), viewer); PacketManager.equipmentSlotUpdate(user.getPlayer().getEntityId(), EquipmentSlot.HEAD, new ItemStack(Material.CARVED_PUMPKIN), viewer);
} else {
HMCCPacketManager.equipmentSlotUpdate(user.getPlayer(), true, viewer); // Optifine dumbassery
} }
} }
}; };
@@ -275,14 +329,6 @@ public class UserWardrobeManager {
runnable.runTaskTimer(HMCCosmeticsPlugin.getInstance(), 0, 2); runnable.runTaskTimer(HMCCosmeticsPlugin.getInstance(), 0, 2);
} }
public int getCameraId() {
return ARMORSTAND_ID;
}
public WardrobeStatus getWardrobeStatus() {
return wardrobeStatus;
}
public void setWardrobeStatus(WardrobeStatus status) { public void setWardrobeStatus(WardrobeStatus status) {
this.wardrobeStatus = status; this.wardrobeStatus = status;
} }
@@ -293,4 +339,5 @@ public class UserWardrobeManager {
RUNNING, RUNNING,
STOPPING, STOPPING,
} }
} }

View File

@@ -11,7 +11,7 @@ import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public class InventoryUtils { public class HMCCInventoryUtils {
/** /**
* Converts from the Bukkit item slots to ProtocolLib item slots. Will produce a null if an improper bukkit item slot is sent through * Converts from the Bukkit item slots to ProtocolLib item slots. Will produce a null if an improper bukkit item slot is sent through
@@ -52,6 +52,17 @@ public class InventoryUtils {
}; };
} }
public static CosmeticSlot getItemSlotToCosmeticSlot(final EnumWrappers.ItemSlot slot) {
return switch (slot) {
case HEAD -> CosmeticSlot.HELMET;
case CHEST -> CosmeticSlot.CHESTPLATE;
case LEGS -> CosmeticSlot.LEGGINGS;
case FEET -> CosmeticSlot.BOOTS;
case OFFHAND -> CosmeticSlot.OFFHAND;
case MAINHAND -> CosmeticSlot.MAINHAND;
};
}
public static CosmeticSlot BukkitCosmeticSlot(EquipmentSlot slot) { public static CosmeticSlot BukkitCosmeticSlot(EquipmentSlot slot) {
return switch (slot) { return switch (slot) {
case HAND -> CosmeticSlot.MAINHAND; case HAND -> CosmeticSlot.MAINHAND;
@@ -152,8 +163,4 @@ public class InventoryUtils {
public static NamespacedKey getCosmeticKey() { public static NamespacedKey getCosmeticKey() {
return new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "cosmetic"); return new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "cosmetic");
} }
public static NamespacedKey getOwnerKey() {
return new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "owner");
}
} }

View File

@@ -3,16 +3,15 @@ package com.hibiscusmc.hmccosmetics.util;
import com.comphenix.protocol.wrappers.WrappedGameProfile; import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.comphenix.protocol.wrappers.WrappedSignedProperty; import com.comphenix.protocol.wrappers.WrappedSignedProperty;
import com.hibiscusmc.hmccosmetics.config.Settings; import com.hibiscusmc.hmccosmetics.config.Settings;
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class PlayerUtils { public class HMCCPlayerUtils {
@Nullable @Nullable
public static WrappedSignedProperty getSkin(Player player) { public static WrappedSignedProperty getSkin(Player player) {
@@ -32,13 +31,6 @@ public class PlayerUtils {
@NotNull @NotNull
public static List<Player> getNearbyPlayers(@NotNull Location location) { public static List<Player> getNearbyPlayers(@NotNull Location location) {
List<Player> players = new ArrayList<>(); return PacketManager.getViewers(location, Settings.getViewDistance());
int viewDistance = Settings.getViewDistance();
for (Entity entity : location.getWorld().getNearbyEntities(location, viewDistance, viewDistance, viewDistance)) {
if (entity instanceof Player) {
players.add((Player) entity);
}
}
return players;
} }
} }

View File

@@ -1,11 +1,11 @@
package com.hibiscusmc.hmccosmetics.util; package com.hibiscusmc.hmccosmetics.util;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
import com.owen1212055.particlehelper.api.particle.MultiParticle; import com.owen1212055.particlehelper.api.particle.MultiParticle;
import com.owen1212055.particlehelper.api.particle.Particle; import com.owen1212055.particlehelper.api.particle.Particle;
import com.owen1212055.particlehelper.api.particle.types.*; import com.owen1212055.particlehelper.api.particle.types.*;
import com.owen1212055.particlehelper.api.particle.types.dust.transition.TransitionDustParticle; import com.owen1212055.particlehelper.api.particle.types.dust.transition.TransitionDustParticle;
import com.owen1212055.particlehelper.api.particle.types.note.MultiNoteParticle; import com.owen1212055.particlehelper.api.particle.types.note.MultiNoteParticle;
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
@@ -14,7 +14,7 @@ import org.jetbrains.annotations.Nullable;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Arrays; import java.util.Arrays;
public class ServerUtils { public class HMCCServerUtils {
private static String COLOR_CHAR = "&"; private static String COLOR_CHAR = "&";
@@ -36,6 +36,11 @@ public class ServerUtils {
return NMSHandlers.getHandler().getEntity(entityId); return NMSHandlers.getHandler().getEntity(entityId);
} }
/**
* This takes in a string like #FFFFFF to convert it into a Bukkit color
* @param colorStr
* @return
*/
public static Color hex2Rgb(String colorStr) { public static Color hex2Rgb(String colorStr) {
if (colorStr.startsWith("#")) return Color.fromRGB(Integer.valueOf(colorStr.substring(1), 16)); if (colorStr.startsWith("#")) return Color.fromRGB(Integer.valueOf(colorStr.substring(1), 16));
if (colorStr.startsWith("0x")) return Color.fromRGB(Integer.valueOf(colorStr.substring(2), 16)); if (colorStr.startsWith("0x")) return Color.fromRGB(Integer.valueOf(colorStr.substring(2), 16));
@@ -46,16 +51,22 @@ public class ServerUtils {
} }
return Color.WHITE; return Color.WHITE;
/* Old method }
try {
return Color.fromRGB( /**
Integer.valueOf(colorStr.substring(1, 3), 16), * This takes in a string like 55,49,181 to convert it into a Bukkit Color
Integer.valueOf(colorStr.substring(3, 5), 16), * @param colorStr
Integer.valueOf(colorStr.substring(5, 7), 16)); * @return
} catch (StringIndexOutOfBoundsException e) { */
return null; public static Color rgbToRgb(String colorStr) {
if (colorStr.contains(",")) {
String[] colors = colorStr.split(",", 3);
if (colors.length == 3) {
return Color.fromRGB(Integer.parseInt(colors[0]), Integer.parseInt(colors[1]), Integer.parseInt(colors[2]));
}
} }
*/
return Color.WHITE;
} }
// particle amount offsetxyz // particle amount offsetxyz
@@ -146,4 +157,13 @@ public class ServerUtils {
} }
return nextYaw; return nextYaw;
} }
public static boolean hasClass(String className) {
try {
Class.forName(className);
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
} }

View File

@@ -2,12 +2,10 @@ package com.hibiscusmc.hmccosmetics.util;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings; import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.hooks.Hooks;
import com.hibiscusmc.hmccosmetics.hooks.placeholders.HMCPlaceholderExpansion;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.misc.Adventure; import me.lojosho.hibiscuscommons.hooks.Hooks;
import me.clip.placeholderapi.PlaceholderAPI; import me.lojosho.hibiscuscommons.util.AdventureUtils;
import me.lojosho.shaded.configurate.ConfigurationNode;
import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@@ -17,7 +15,6 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import java.time.Duration; import java.time.Duration;
import java.util.HashMap; import java.util.HashMap;
@@ -26,14 +23,16 @@ import java.util.logging.Level;
public class MessagesUtil { public class MessagesUtil {
private static String prefix; private static String prefix;
private static final HashMap<String, String> messages = new HashMap<>(); private static final HashMap<String, String> MESSAGES = new HashMap<>();
public static void setup(@NotNull ConfigurationNode config) { public static void setup(@NotNull ConfigurationNode config) {
MESSAGES.clear();
prefix = config.node("prefix").getString(""); prefix = config.node("prefix").getString("");
for (ConfigurationNode node : config.childrenMap().values()) { for (ConfigurationNode node : config.childrenMap().values()) {
if (node.virtual()) continue; if (node.virtual()) continue;
if (node.empty()) continue; if (node.empty()) continue;
messages.put(node.key().toString(), node.getString()); MESSAGES.put(node.key().toString(), node.getString());
} }
} }
@@ -43,6 +42,7 @@ public class MessagesUtil {
public static void sendMessage(Player player, String key) { public static void sendMessage(Player player, String key) {
Component finalMessage = processString(player, key); Component finalMessage = processString(player, key);
if (finalMessage == null) return;
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player); Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
target.sendMessage(finalMessage); target.sendMessage(finalMessage);
@@ -58,6 +58,7 @@ public class MessagesUtil {
public static void sendMessage(Player player, String key, TagResolver placeholder) { public static void sendMessage(Player player, String key, TagResolver placeholder) {
Component finalMessage = processString(player, key, placeholder); Component finalMessage = processString(player, key, placeholder);
if (finalMessage == null) return;
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player); Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
target.sendMessage(finalMessage); target.sendMessage(finalMessage);
@@ -65,6 +66,7 @@ public class MessagesUtil {
public static void sendMessageNoKey(Player player, String message) { public static void sendMessageNoKey(Player player, String message) {
Component finalMessage = processStringNoKey(player, message); Component finalMessage = processStringNoKey(player, message);
if (finalMessage == null) return;
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player); Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
target.sendMessage(finalMessage); target.sendMessage(finalMessage);
@@ -72,6 +74,7 @@ public class MessagesUtil {
public static void sendActionBar(Player player, String key) { public static void sendActionBar(Player player, String key) {
Component finalMessage = processString(player, key); Component finalMessage = processString(player, key);
if (finalMessage == null) return;
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player); Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
target.sendActionBar(finalMessage); target.sendActionBar(finalMessage);
@@ -84,7 +87,7 @@ public class MessagesUtil {
public static void sendTitle(Player player, String message, int fadein, int stay, int fadeout) { public static void sendTitle(Player player, String message, int fadein, int stay, int fadeout) {
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player); Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
Title.Times times = Title.Times.times(Duration.ofMillis(WardrobeSettings.getTransitionFadeIn()), Duration.ofMillis(3000), Duration.ofMillis(1000)); Title.Times times = Title.Times.times(Duration.ofMillis(fadein), Duration.ofMillis(stay), Duration.ofMillis(fadeout));
Title title = Title.title(processStringNoKey(player, message), Component.empty(), times); Title title = Title.title(processStringNoKey(player, message), Component.empty(), times);
target.showTitle(title); target.showTitle(title);
@@ -96,15 +99,15 @@ public class MessagesUtil {
@Nullable @Nullable
public static Component processString(Player player, String key, TagResolver placeholders) { public static Component processString(Player player, String key, TagResolver placeholders) {
if (!messages.containsKey(key)) return null; if (!MESSAGES.containsKey(key)) return null;
if (messages.get(key) == null) return null; if (MESSAGES.get(key) == null) return null;
String message = messages.get(key); String message = MESSAGES.get(key);
if (Hooks.isActiveHook("PlaceholderAPI") && player != null) message = PlaceholderAPI.setPlaceholders(player, message); if (player != null) message = Hooks.processPlaceholders(player, message);
message = message.replaceAll("%prefix%", prefix); message = message.replaceAll("%prefix%", prefix);
if (placeholders != null ) { if (placeholders != null ) {
return Adventure.MINI_MESSAGE.deserialize(message, placeholders); return AdventureUtils.MINI_MESSAGE.deserialize(message, placeholders);
} }
return Adventure.MINI_MESSAGE.deserialize(message); return AdventureUtils.MINI_MESSAGE.deserialize(message);
} }
@NotNull @NotNull
@@ -120,16 +123,16 @@ public class MessagesUtil {
@NotNull @NotNull
public static Component processStringNoKey(Player player, String message, TagResolver placeholders) { public static Component processStringNoKey(Player player, String message, TagResolver placeholders) {
message = message.replaceAll("%prefix%", prefix); message = message.replaceAll("%prefix%", prefix);
if (Hooks.isActiveHook("PlaceholderAPI") && player != null) message = PlaceholderAPI.setPlaceholders(player, message); if (player != null) message = Hooks.processPlaceholders(player, message);
if (placeholders != null ) { if (placeholders != null ) {
return Adventure.MINI_MESSAGE.deserialize(message, placeholders); return AdventureUtils.MINI_MESSAGE.deserialize(message, placeholders);
} }
return Adventure.MINI_MESSAGE.deserialize(message); return AdventureUtils.MINI_MESSAGE.deserialize(message);
} }
public static String processStringNoKeyString(Player player, String message) { public static String processStringNoKeyString(Player player, String message) {
message = message.replaceAll("%prefix%", prefix); message = message.replaceAll("%prefix%", prefix);
if (Hooks.isActiveHook("PlaceholderAPI") && player != null) message = PlaceholderAPI.setPlaceholders(player, message); if (player != null) message = Hooks.processPlaceholders(player, message);
return message; return message;
} }
@@ -138,7 +141,7 @@ public class MessagesUtil {
} }
public static void sendDebugMessages(String message, Level level) { public static void sendDebugMessages(String message, Level level) {
if (!Settings.isDebugEnabled() && level == Level.INFO) return; if (!Settings.isDebugMode() && level == Level.INFO) return;
HMCCosmeticsPlugin.getInstance().getLogger().log(level, message); HMCCosmeticsPlugin.getInstance().getLogger().log(level, message);
} }
} }

View File

@@ -0,0 +1,5 @@
package com.hibiscusmc.hmccosmetics.util;
public record TranslationPair(String key, String value) {
}

View File

@@ -1,39 +1,40 @@
package com.hibiscusmc.hmccosmetics.util; package com.hibiscusmc.hmccosmetics.util;
import org.spongepowered.configurate.ConfigurationNode; import me.lojosho.hibiscuscommons.util.StringUtils;
import me.lojosho.shaded.configurate.ConfigurationNode;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
public class TranslationUtil { public class TranslationUtil {
private static HashMap<String, String> keys = new HashMap<>(); // unlocked-cosmetic -> true -> True
private static final HashMap<String, List<TranslationPair>> keys = new HashMap<>();
public static void setup(ConfigurationNode config) { public static void setup(ConfigurationNode config) {
// TODO: Finish this keys.clear();
/*
for (ConfigurationNode node : config.childrenMap().values()) { for (ConfigurationNode node : config.childrenMap().values()) {
HashMap<Pair> translableMessages = new HashMap<>(); ArrayList<TranslationPair> pairs = new ArrayList<>();
for (ConfigurationNode translatableMessage : node.childrenMap().values()) { for (ConfigurationNode translatableMessage : node.childrenMap().values()) {
translableMessages.put( new Pair<>(translatableMessage.key().toString(), translatableMessage.getString())) String key = translatableMessage.key().toString();
key = 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("setupTranslation key:" + node.key().toString() + " | " + node);
MessagesUtil.sendDebugMessages("Overall Key " + node.key().toString());
MessagesUtil.sendDebugMessages("Key '" + pair.key() + "' Value '" + pair.value() + "'");
} }
keys.put(node.key().toString().toLowerCase(), HashMap); keys.put(node.key().toString().toLowerCase(), pairs);
} }
*/
} }
public static String getTranslation(String key, String message) { public static String getTranslation(String key, String message) {
// TODO: Finish this List<TranslationPair> pairs = keys.get(key);
return message; for (TranslationPair pair : pairs) {
/* if (pair.key().equals(message)) return StringUtils.parseStringToString(pair.value());
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();
} }
return message; return message;
*/
} }
} }

View File

@@ -1,39 +0,0 @@
package com.hibiscusmc.hmccosmetics.util.builder;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.jetbrains.annotations.NotNull;
public class ColorBuilder {
public static boolean canBeColored(final Material material) {
return canBeColored(new ItemStack(material));
}
public static boolean canBeColored(final @NotNull ItemStack itemStack) {
final ItemMeta itemMeta = itemStack.getItemMeta();
return (itemMeta instanceof LeatherArmorMeta ||
itemMeta instanceof PotionMeta);
}
/**
* @param color armor color
* @return this
*/
public static ItemMeta color(ItemMeta itemMeta, final Color color) {
if (itemMeta instanceof final PotionMeta meta) {
meta.setColor(color);
}
if (itemMeta instanceof final LeatherArmorMeta meta) {
meta.setColor(color);
}
return itemMeta;
}
}

View File

@@ -1,215 +0,0 @@
package com.hibiscusmc.hmccosmetics.util.builder;
import com.hibiscusmc.hmccosmetics.util.misc.Placeholder;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ItemBuilder {
protected Material material;
protected int amount;
protected ItemMeta itemMeta;
/**
* @param material builder material
*/
ItemBuilder(final Material material) {
this.material = material;
this.itemMeta = Bukkit.getItemFactory().getItemMeta(material);
}
/**
* @param itemStack builder ItemStack
*/
ItemBuilder(final @NotNull ItemStack itemStack) {
this.material = itemStack.getType();
this.itemMeta = itemStack.hasItemMeta() ? itemStack.getItemMeta()
: Bukkit.getItemFactory().getItemMeta(this.material);
}
/**
* @param material builder material
* @return
*/
@Contract("_ -> new")
@NotNull
public static ItemBuilder from(final Material material) {
return new ItemBuilder(material);
}
/**
* @param itemStack builder ItemStack
* @return
*/
@Contract("_ -> new")
@NotNull
public static ItemBuilder from(final ItemStack itemStack) {
return new ItemBuilder(itemStack);
}
/**
* @param amount ItemStack amount
* @return this
*/
public ItemBuilder amount(final int amount) {
this.amount = Math.min(Math.max(1, amount), 64);
return this;
}
/**
* @param name ItemStack name
* @return this
*/
public ItemBuilder name(final String name) {
if (this.itemMeta == null) {
return this;
}
this.itemMeta.setDisplayName(name);
return this;
}
/**
* @param lore ItemStack lore
* @return this
*/
public ItemBuilder lore(final List<String> lore) {
if (this.itemMeta == null) {
return this;
}
this.itemMeta.setLore(lore);
return this;
}
public ItemBuilder papiPlaceholders(final Player player) {
this.lorePapiPlaceholders(player);
this.namePapiPlaceholders(player);
return this;
}
private void lorePapiPlaceholders(final Player player) {
if (this.itemMeta == null) {
return;
}
final List<String> newLore = new ArrayList<>();
final List<String> lore = this.itemMeta.getLore();
if (lore == null) {
return;
}
for (final String line : this.itemMeta.getLore()) {
newLore.add(Placeholder.applyPapiPlaceholders(player, line));
}
this.itemMeta.setLore(newLore);
}
private void namePapiPlaceholders(final Player player) {
if (this.itemMeta == null) {
return;
}
this.itemMeta.setDisplayName(
Placeholder.applyPapiPlaceholders(
player,
this.itemMeta.getDisplayName()
)
);
}
/**
* @param unbreakable whether the ItemStack is unbreakable
* @return this
*/
public ItemBuilder unbreakable(final boolean unbreakable) {
if (this.itemMeta == null) {
return this;
}
this.itemMeta.setUnbreakable(unbreakable);
return this;
}
public ItemBuilder glow(final boolean glow) {
if (this.itemMeta == null) {
return this;
}
if (glow) {
this.itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
this.itemMeta.addEnchant(Enchantment.LUCK, 1, true);
}
return this;
}
/**
* @param enchantments enchants to be added to the ItemStack
* @param ignoreLeveLRestrictions whether to ignore enchantment level restrictions
* @return this
*/
public ItemBuilder enchants(final Map<Enchantment, Integer> enchantments,
boolean ignoreLeveLRestrictions) {
if (this.itemMeta == null) {
return this;
}
enchantments.forEach((enchantment, level) -> this.itemMeta.addEnchant(enchantment, level,
ignoreLeveLRestrictions));
return this;
}
/**
* @param itemFlags ItemStack ItemFlags
* @return this
*/
public ItemBuilder itemFlags(final Set<ItemFlag> itemFlags) {
if (this.itemMeta == null) {
return this;
}
this.itemMeta.addItemFlags(itemFlags.toArray(new ItemFlag[0]));
return this;
}
/**
* @param modelData ItemStack modelData
* @return this
*/
public ItemBuilder modelData(final int modelData) {
if (this.itemMeta == null) {
return this;
}
this.itemMeta.setCustomModelData(modelData);
return this;
}
/**
* @return built ItemStack
*/
public ItemStack build() {
final ItemStack itemStack = new ItemStack(this.material, Math.max(this.amount, 1));
itemStack.setItemMeta(itemMeta);
return itemStack;
}
}

View File

@@ -1,18 +0,0 @@
package com.hibiscusmc.hmccosmetics.util.misc;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.standard.StandardTags;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
public class Adventure {
public static final LegacyComponentSerializer SERIALIZER = LegacyComponentSerializer.builder()
.hexColors()
.useUnusualXRepeatedCharacterHexFormat()
.build();
public static final MiniMessage MINI_MESSAGE = MiniMessage.builder().tags(
StandardTags.defaults()
).
build();
}

View File

@@ -1,75 +0,0 @@
package com.hibiscusmc.hmccosmetics.util.misc;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.jetbrains.annotations.NotNull;
public class Keys {
static HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
public static final NamespacedKey ITEM_KEY = new NamespacedKey(plugin, "cosmetic");
public static final NamespacedKey TOKEN_KEY = new NamespacedKey(plugin, "token-key");
public static void setKey(final @NotNull ItemStack itemStack) {
final ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta == null) {
return;
}
itemMeta.getPersistentDataContainer().set(ITEM_KEY, PersistentDataType.BYTE, (byte) 1);
itemStack.setItemMeta(itemMeta);
}
public static <T, Z> void setKey(
final @NotNull ItemStack itemStack,
final NamespacedKey key,
final PersistentDataType<T, Z> type,
final Z value) {
final ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta == null) {
return;
}
itemMeta.getPersistentDataContainer().set(key, type, value);
itemStack.setItemMeta(itemMeta);
}
public static boolean hasKey(final @NotNull ItemStack itemStack) {
final ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta == null) {
return false;
}
return itemMeta.getPersistentDataContainer().has(ITEM_KEY, PersistentDataType.BYTE);
}
public static <T, Z> boolean hasKey(final @NotNull ItemStack itemStack, final NamespacedKey key, final PersistentDataType<T, Z> type) {
final ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta == null) {
return false;
}
return itemMeta.getPersistentDataContainer().has(key, type);
}
@Nullable
public static <T, Z> Z getValue(final @NotNull ItemStack itemStack, final NamespacedKey key, final PersistentDataType<T, Z> type) {
final ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta == null) {
return null;
}
return itemMeta.getPersistentDataContainer().get(key, type);
}
}

View File

@@ -1,33 +0,0 @@
package com.hibiscusmc.hmccosmetics.util.misc;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
public class Placeholder {
public static final String PREFIX = "%prefix%";
public static final String TYPE = "%type%";
public static final String ITEM = "%item%";
public static final String FILE = "%file%";
public static final String PLAYER = "%player%";
public static final String ENABLED = "%enabled%";
public static final String ALLOWED = "%allowed%";
public static final String ID = "%id%";
/**
* @return message with placeholders applied
*/
public static String applyPapiPlaceholders(@Nullable final Player player,
final String message) {
/*
if (HookManager.getInstance().isEnabled(PAPIHook.class)) {
return HookManager.getInstance().getPapiHook().parse(player, message);
}
*/
return message;
}
}

View File

@@ -1,36 +0,0 @@
package com.hibiscusmc.hmccosmetics.util.misc;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.NotNull;
public class StringUtils {
/**
* @param parsed message to be parsed
* @return MiniMessage parsed string
*/
@NotNull
public static Component parse(final String parsed) {
return Adventure.MINI_MESSAGE.deserialize(parsed);
}
@NotNull
public static String parseStringToString(final String parsed) {
return Adventure.SERIALIZER.serialize(Adventure.MINI_MESSAGE.deserialize(parsed));
}
@NotNull
public static String formatArmorItemType(String type) {
type = type.toLowerCase();
final String[] parts = type.split(" ");
final String firstPart = parts[0].substring(0, 1).toUpperCase() + parts[0].substring(1);
if (parts.length == 1) {
return firstPart;
}
return firstPart + parts[1].substring(0, 1).toUpperCase() + parts[1].substring(1);
}
}

View File

@@ -1,13 +0,0 @@
package com.hibiscusmc.hmccosmetics.util.packets;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer;
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

@@ -1,35 +1,41 @@
package com.hibiscusmc.hmccosmetics.util.packets; package com.hibiscusmc.hmccosmetics.util.packets;
import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.*; import com.comphenix.protocol.wrappers.*;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.hibiscusmc.hmccosmetics.api.HMCCosmeticsAPI;
import com.hibiscusmc.hmccosmetics.config.Settings; import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot; import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers; import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
import com.hibiscusmc.hmccosmetics.util.PlayerUtils; import com.hibiscusmc.hmccosmetics.util.HMCCPlayerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.wrappers.WrapperPlayServerNamedEntitySpawn; import com.hibiscusmc.hmccosmetics.util.packets.wrappers.WrapperPlayServerNamedEntitySpawn;
import com.hibiscusmc.hmccosmetics.util.packets.wrappers.WrapperPlayServerPlayerInfo; import com.hibiscusmc.hmccosmetics.util.packets.wrappers.WrapperPlayServerPlayerInfo;
import com.hibiscusmc.hmccosmetics.util.packets.wrappers.WrapperPlayServerRelEntityMove; import com.hibiscusmc.hmccosmetics.util.packets.wrappers.WrapperPlayServerRelEntityMove;
import it.unimi.dsi.fastutil.ints.IntArrayList; import me.lojosho.hibiscuscommons.util.packets.PacketManager;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
public class PacketManager extends BasePacket { public class HMCCPacketManager extends PacketManager {
public static void sendEntitySpawnPacket(
final @NotNull Location location,
final int entityId,
final EntityType entityType,
final UUID uuid
) {
sendEntitySpawnPacket(location, entityId, entityType, uuid, getViewers(location));
}
public static void sendEntitySpawnPacket( public static void sendEntitySpawnPacket(
final @NotNull Location location, final @NotNull Location location,
@@ -50,39 +56,18 @@ public class PacketManager extends BasePacket {
for (Player p : sendTo) sendPacket(p, packet); for (Player p : sendTo) sendPacket(p, packet);
} }
public static void gamemodeChangePacket(
Player player,
int gamemode
) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.GAME_STATE_CHANGE);
packet.getGameStateIDs().write(0, 3);
// Tells what event this is. This is a change gamemode event.
packet.getFloat().write(0, (float) gamemode);
sendPacket(player, packet);
MessagesUtil.sendDebugMessages("Gamemode Change sent to " + player + " to be " + gamemode);
}
public static void ridingMountPacket(
int mountId,
int passengerId,
@NotNull List<Player> sendTo
) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.MOUNT);
packet.getIntegers().write(0, mountId);
packet.getIntegerArrays().write(0, new int[]{passengerId});
for (Player p : sendTo) sendPacket(p, packet);
}
public static void equipmentSlotUpdate( public static void equipmentSlotUpdate(
Player player, Player player,
boolean empty, boolean empty,
List<Player> sendTo List<Player> sendTo
) { ) {
HashMap<EquipmentSlot, ItemStack> items = new HashMap<>();
for (EquipmentSlot slot : EquipmentSlot.values()) { for (EquipmentSlot slot : EquipmentSlot.values()) {
ItemStack item = player.getInventory().getItem(slot); ItemStack item = player.getInventory().getItem(slot);
if (empty) item = new ItemStack(Material.AIR); if (empty) item = new ItemStack(Material.AIR);
NMSHandlers.getHandler().equipmentSlotUpdate(player.getEntityId(), slot, item, sendTo); items.put(slot, item);
} }
equipmentSlotUpdate(player.getEntityId(), items, sendTo);
} }
public static void equipmentSlotUpdate( public static void equipmentSlotUpdate(
@NotNull Player player, @NotNull Player player,
@@ -97,7 +82,7 @@ public class PacketManager extends BasePacket {
CosmeticSlot cosmeticSlot, CosmeticSlot cosmeticSlot,
List<Player> sendTo List<Player> sendTo
) { ) {
equipmentSlotUpdate(user.getPlayer().getEntityId(), user, cosmeticSlot, sendTo); equipmentSlotUpdate(user.getEntity().getEntityId(), user, cosmeticSlot, sendTo);
} }
public static void equipmentSlotUpdate( public static void equipmentSlotUpdate(
@@ -108,22 +93,28 @@ public class PacketManager extends BasePacket {
) { ) {
if (cosmeticSlot == CosmeticSlot.BACKPACK || cosmeticSlot == CosmeticSlot.BALLOON || cosmeticSlot == CosmeticSlot.EMOTE) return; if (cosmeticSlot == CosmeticSlot.BACKPACK || cosmeticSlot == CosmeticSlot.BALLOON || cosmeticSlot == CosmeticSlot.EMOTE) return;
NMSHandlers.getHandler().equipmentSlotUpdate(entityId, user, cosmeticSlot, sendTo); equipmentSlotUpdate(entityId, HMCCInventoryUtils.getEquipmentSlot(cosmeticSlot), user.getUserCosmeticItem(cosmeticSlot), sendTo);
} }
public static void armorStandMetaPacket( public static void sendArmorstandMetadata(
@NotNull Entity entity, int entityId,
List<Player> sendTo List<Player> sendTo
) { ) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
packet.getModifier().writeDefaults(); packet.getModifier().writeDefaults();
packet.getIntegers().write(0, entity.getEntityId()); packet.getIntegers().write(0, entityId);
WrappedDataWatcher metadata = new WrappedDataWatcher(); WrappedDataWatcher wrapper = new WrappedDataWatcher();
if (metadata == null) return;
// 0x10 & 0x20 if (HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1")) {
metadata.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x20); wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x20);
metadata.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x10); wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x10);
packet.getWatchableCollectionModifier().write(0, metadata.getWatchableObjects()); packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects());
} else {
final List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
wrappedDataValueList.add(new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0x20));
wrappedDataValueList.add(new WrappedDataValue(15, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0x10));
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
}
for (Player p : sendTo) sendPacket(p, packet); for (Player p : sendTo) sendPacket(p, packet);
} }
@@ -136,7 +127,7 @@ public class PacketManager extends BasePacket {
packet.getIntegers().write(0, entityId); packet.getIntegers().write(0, entityId);
WrappedDataWatcher wrapper = new WrappedDataWatcher(); WrappedDataWatcher wrapper = new WrappedDataWatcher();
if (NMSHandlers.getVersion().contains("v1_17_R1") || NMSHandlers.getVersion().contains("v1_18_R2") || NMSHandlers.getVersion().contains("v1_19_R1")) { if (HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1")) {
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x20); wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x20);
packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects()); packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects());
} else { } else {
@@ -145,17 +136,28 @@ public class PacketManager extends BasePacket {
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList); packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
} }
for (Player p : sendTo) sendPacket(p, packet); for (Player p : sendTo) sendPacket(p, packet);
} }
public static void sendLookPacket( public static void sendCloudEffect(
int entityId, int entityId,
@NotNull Location location, List<Player> sendTo
@NotNull List<Player> sendTo
) { ) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_HEAD_ROTATION); PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
packet.getModifier().writeDefaults();
packet.getIntegers().write(0, entityId); packet.getIntegers().write(0, entityId);
packet.getBytes().write(0, (byte) (location.getYaw() * 256.0F / 360.0F)); WrappedDataWatcher wrapper = new WrappedDataWatcher();
if (HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1")) {
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x20);
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(8, WrappedDataWatcher.Registry.get(Float.class)), 0f);
packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects());
} else {
final List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
wrappedDataValueList.add(new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0x20));
wrappedDataValueList.add(new WrappedDataValue(8, WrappedDataWatcher.Registry.get(Float.class), 0f));
//wrappedDataValueList.add(new WrappedDataValue(11, WrappedDataWatcher.Registry.get(Integer.class), 21));
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
}
for (Player p : sendTo) sendPacket(p, packet); for (Player p : sendTo) sendPacket(p, packet);
} }
@@ -218,6 +220,25 @@ public class PacketManager extends BasePacket {
sendRidingPacket(mountId, passengerId, getViewers(location)); sendRidingPacket(mountId, passengerId, getViewers(location));
} }
/**
* Mostly to deal with backpacks, this deals with entities riding other entities.
* @param mountId The entity that is the "mount", ex. a player
* @param passengerIds The entities that are riding the mount, ex. a armorstand for a backpack
* @param sendTo Whom to send the packet to
*/
public static void sendRidingPacket(
final int mountId,
final int[] passengerIds,
final @NotNull List<Player> sendTo
) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.MOUNT);
packet.getIntegers().write(0, mountId);
packet.getIntegerArrays().write(0, passengerIds);
for (final Player p : sendTo) {
sendPacket(p, packet);
}
}
/** /**
* Mostly to deal with backpacks, this deals with entities riding other entities. * Mostly to deal with backpacks, this deals with entities riding other entities.
* @param mountId The entity that is the "mount", ex. a player * @param mountId The entity that is the "mount", ex. a player
@@ -229,35 +250,7 @@ public class PacketManager extends BasePacket {
final int passengerId, final int passengerId,
final @NotNull List<Player> sendTo final @NotNull List<Player> sendTo
) { ) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.MOUNT); sendRidingPacket(mountId, new int[] {passengerId}, sendTo);
packet.getIntegers().write(0, mountId);
packet.getIntegerArrays().write(0, new int[]{passengerId});
for (final Player p : sendTo) {
sendPacket(p, packet);
}
}
/**
* Destroys an entity from a player
* @param entityId The entity to delete for a player
* @param sendTo The players the packet should be sent to
*/
public static void sendEntityDestroyPacket(final int entityId, @NotNull List<Player> sendTo) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY);
packet.getModifier().write(0, new IntArrayList(new int[]{entityId}));
for (final Player p : sendTo) sendPacket(p, packet);
}
/**
* Sends a camera packet
* @param entityId The Entity ID that camera will go towards
* @param sendTo The players that will be sent this packet
*/
public static void sendCameraPacket(final int entityId, @NotNull List<Player> sendTo) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.CAMERA);
packet.getIntegers().write(0, entityId);
for (final Player p : sendTo) sendPacket(p, packet);
MessagesUtil.sendDebugMessages(sendTo + " | " + entityId + " has had a camera packet on them!");
} }
/** /**
@@ -273,13 +266,17 @@ public class PacketManager extends BasePacket {
final int entityId, final int entityId,
final @NotNull List<Player> sendTo final @NotNull List<Player> sendTo
) { ) {
WrapperPlayServerNamedEntitySpawn wrapper = new WrapperPlayServerNamedEntitySpawn(); if (HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R3") || HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R1")) {
wrapper.setEntityID(entityId); WrapperPlayServerNamedEntitySpawn wrapper = new WrapperPlayServerNamedEntitySpawn();
wrapper.setPlayerUUID(uuid); wrapper.setEntityID(entityId);
wrapper.setPosition(location.toVector()); wrapper.setPlayerUUID(uuid);
wrapper.setPitch(location.getPitch()); wrapper.setPosition(location.toVector());
wrapper.setYaw(location.getYaw()); wrapper.setPitch(location.getPitch());
for (final Player p : sendTo) sendPacket(p, wrapper.getHandle()); wrapper.setYaw(location.getYaw());
for (final Player p : sendTo) sendPacket(p, wrapper.getHandle());
return;
}
sendEntitySpawnPacket(location, entityId, EntityType.PLAYER, uuid);
} }
/** /**
@@ -304,10 +301,10 @@ public class PacketManager extends BasePacket {
} }
WrappedGameProfile wrappedGameProfile = new WrappedGameProfile(uuid, name); WrappedGameProfile wrappedGameProfile = new WrappedGameProfile(uuid, name);
WrappedSignedProperty skinData = PlayerUtils.getSkin(skinnedPlayer); WrappedSignedProperty skinData = HMCCPlayerUtils.getSkin(skinnedPlayer);
if (skinData != null) wrappedGameProfile.getProperties().put("textures", skinData); if (skinData != null) wrappedGameProfile.getProperties().put("textures", skinData);
// For sor some reason 1.19.2 handles it on the 0 field index, every other verison handles it on the 1 // 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_19_R1")) { if (HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1")) {
info.getHandle().getPlayerInfoDataLists().write(0, Collections.singletonList(new PlayerInfoData( info.getHandle().getPlayerInfoDataLists().write(0, Collections.singletonList(new PlayerInfoData(
wrappedGameProfile, wrappedGameProfile,
0, 0,
@@ -350,9 +347,16 @@ public class PacketManager extends BasePacket {
packet.getModifier().writeDefaults(); packet.getModifier().writeDefaults();
packet.getIntegers().write(0, playerId); packet.getIntegers().write(0, playerId);
WrappedDataWatcher wrapper = new WrappedDataWatcher(); WrappedDataWatcher wrapper = new WrappedDataWatcher();
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(17, WrappedDataWatcher.Registry.get(Byte.class)), mask);
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x10); if (HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1")) {
packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects()); wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(17, WrappedDataWatcher.Registry.get(Byte.class)), mask);
packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects());
} else {
final List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
wrappedDataValueList.add(new WrappedDataValue(17, WrappedDataWatcher.Registry.get(Byte.class), mask));
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
}
for (final Player p : sendTo) { for (final Player p : sendTo) {
sendPacket(p, packet); sendPacket(p, packet);
} }
@@ -364,13 +368,15 @@ public class PacketManager extends BasePacket {
* @param uuid What is the fake player UUID * @param uuid What is the fake player UUID
* @param sendTo Whom to send the packet to * @param sendTo Whom to send the packet to
*/ */
@SuppressWarnings("deprecation")
public static void sendRemovePlayerPacket( public static void sendRemovePlayerPacket(
final Player player, final Player player,
final UUID uuid, final UUID uuid,
final List<Player> sendTo final List<Player> sendTo
) { ) {
if (NMSHandlers.getVersion().contains("v1_17_R1") || NMSHandlers.getVersion().contains("v1_18_R2") || NMSHandlers.getVersion().contains("v1_19_R1")) { if (HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1")) {
WrapperPlayServerPlayerInfo info = new WrapperPlayServerPlayerInfo(); WrapperPlayServerPlayerInfo info = new WrapperPlayServerPlayerInfo();
// Remove player is deprecated on 1.19.3+, but we still need to support 1.18.2
info.setAction(EnumWrappers.PlayerInfoAction.REMOVE_PLAYER); info.setAction(EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
String name = "Mannequin-" + player.getEntityId(); String name = "Mannequin-" + player.getEntityId();
@@ -396,51 +402,6 @@ public class PacketManager extends BasePacket {
sendLeashPacket(leashedEntity, entityId, getViewers(location)); sendLeashPacket(leashedEntity, entityId, getViewers(location));
} }
/**
* Sends a leash packet, useful for balloons!
* @param leashedEntity Entity being leashed (ex. a horse)
* @param entityId Entity this is affecting (ex. a player)
* @param sendTo Whom to send the packet to
*/
public static void sendLeashPacket(
final int leashedEntity,
final int entityId,
final @NotNull List<Player> sendTo
) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ATTACH_ENTITY);
packet.getIntegers().write(0, leashedEntity);
packet.getIntegers().write(1, entityId);
for (final Player p : sendTo) {
sendPacket(p, packet);
}
}
/**
* Used when a player is sent 8+ blocks.
* @param entityId Entity this affects
* @param location Location a player is being teleported to
* @param onGround If the packet is on the ground
* @param sendTo Whom to send the packet to
*/
public static void sendTeleportPacket(
final int entityId,
final @NotNull Location location,
boolean onGround,
final @NotNull List<Player> sendTo
) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT);
packet.getIntegers().write(0, entityId);
packet.getDoubles().write(0, location.getX());
packet.getDoubles().write(1, location.getY());
packet.getDoubles().write(2, location.getZ());
packet.getBytes().write(0, (byte) (location.getYaw() * 256.0F / 360.0F));
packet.getBytes().write(1, (byte) (location.getPitch() * 256.0F / 360.0F));
packet.getBooleans().write(0, onGround);
for (final Player p : sendTo) {
sendPacket(p, packet);
}
}
/** /**
* Sends a movement packet from one location to another * Sends a movement packet from one location to another
* @param entityId Entity this will affect * @param entityId Entity this will affect
@@ -468,23 +429,19 @@ public class PacketManager extends BasePacket {
} }
} }
public static void sendMovePacket(
final int entityId,
final Location from,
final Location to,
final boolean onGround
) {
sendMovePacket(entityId, from, to, onGround, getViewers(to));
}
@NotNull @NotNull
public static List<Player> getViewers(Location location) { public static List<Player> getViewers(Location location) {
ArrayList<Player> viewers = new ArrayList(); ArrayList<Player> viewers = new ArrayList<>();
if (Settings.getViewDistance() <= 0) { if (Settings.getViewDistance() <= 0) {
viewers.addAll(location.getWorld().getPlayers()); viewers.addAll(location.getWorld().getPlayers());
} else { } else {
viewers.addAll(PlayerUtils.getNearbyPlayers(location)); viewers.addAll(HMCCPlayerUtils.getNearbyPlayers(location));
} }
return viewers; return viewers;
} }
public static void sendPacket(Player player, PacketContainer packet) {
if (player == null) return;
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, null,false);
}
} }

View File

@@ -4,7 +4,7 @@ import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction; import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
import com.comphenix.protocol.wrappers.PlayerInfoData; import com.comphenix.protocol.wrappers.PlayerInfoData;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers; import com.hibiscusmc.hmccosmetics.api.HMCCosmeticsAPI;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@@ -26,7 +26,7 @@ public class WrapperPlayServerPlayerInfo extends AbstractPacket {
} }
public void setAction(PlayerInfoAction value) { public void setAction(PlayerInfoAction value) {
if (NMSHandlers.getVersion().contains("v1_17_R1") || NMSHandlers.getVersion().contains("v1_18_R2") || NMSHandlers.getVersion().contains("v1_19_R1")) { if (HMCCosmeticsAPI.getNMSVersion().contains("v1_17_R1") || HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1")) {
handle.getPlayerInfoAction().write(0, value); handle.getPlayerInfoAction().write(0, value);
return; return;
} }

View File

@@ -6,7 +6,7 @@ config-version: 1
default-menu: defaultmenu default-menu: defaultmenu
debug-mode: false debug-mode: false
database-settings: database-settings:
type: sqlite #MYSQL, SQLite, INTERNAL (not recommended!) type: sqlite #MYSQL, SQLite
mysql: mysql:
database: database database: database
password: cherryBomb password: cherryBomb
@@ -22,11 +22,37 @@ cosmetic-settings:
unapply-on-death: false # If when a player dies, their cosmetics should be unapplied. If this is true, use hmccosmetics.unapplydeath.bypass to bypass unapply-on-death: false # If when a player dies, their cosmetics should be unapplied. If this is true, use hmccosmetics.unapplydeath.bypass to bypass
force-permission-join: true # Checks a player permission if they can have a cosmetic when they join the server. force-permission-join: true # Checks a player permission if they can have a cosmetic when they join the server.
force-show-join: false # If the plugin should force show a player's cosmetics when they join the server.
# This is a list of worlds that cosmetics are hidden in. When a player enters one of these worlds, their cosmetics will be hidden.
disabled-worlds:
- "disabledworld"
disabled-gamemode:
enabled: true
# Which gamemodes should cosmetics be disabled for. This is useful for servers that have a creative world. All options are here, https://hub.spigotmc.org/javadocs/spigot/org/bukkit/GameMode.html
gamemodes:
- "SPECTATOR"
# This disables the entire internal emote system within the plugin. This option requires a restart.
emote-enable: true
emote-distance: -3 # This shows how far away the camera should be while a player is doing an emote. Negative is behind player. 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-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-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 emote-invincible: false # If the player should not take damage while doing an emote
# If a player should be put into camera mode when looking at an emote. Highly recommend keeping it as true.
emote-camera: true
# If a player should be able to move in an emote. This option really only affects if "emote-camera" is false
emote-move: false
# This make it so it always sends the riding packets for the backpack. This sends more packets but is more reliable for servers which modify player passengers.
backpack-force-riding-packet: false
# This helps reduce the amount of packets sent for packet entities, but reduces accuracy of the entity. This is in milliseconds. -1 to disable.
# This is useful for servers with a lot of backpacks, as they are passengers, which means the client will update their position automatically within an area where the entity is located.
entity-cooldown-teleport-packet: 500
# This forces the offhand to always show the cosmetic. False means it will only show when the slot is empty.
# There is a small visual blip for a tick when you put a new item in the offhand slot, hence why its disabled by default.
offhand-always-show: false
helmet-add-enchantments: false # If the plugin should keep enchants on helmets. This is useful as some enchantments are client side only. helmet-add-enchantments: false # If the plugin should keep enchants on helmets. This is useful as some enchantments are client side only.
chest-add-enchantments: false # If the plugin should keep enchants on chestplate. This is useful as some enchantments are client side only. chest-add-enchantments: false # If the plugin should keep enchants on chestplate. This is useful as some enchantments are client side only.
@@ -46,6 +72,25 @@ cosmetic-settings:
x: 0.5 x: 0.5
y: 3 y: 3
z: 0.5 z: 0.5
menu-settings:
shading:
# Below is the shading mechanism behind cosmetic items. This is a bit complicated, but it allows for a lot of customization.
# The shading is done through the title and by shifting textures around. This is done by offsets.
# Only Oraxen is support by default. Vanilla can't properly handle it without a lot of unicodes and ItemsAdder adds weird offsets and decolors it. (This is why it is disabled by default)
enabled: false # Default of menus having shading. This can be toggled individually in menus with "shading: true/false"
first-row-shift: "<s:-169>" # Oraxen: "<s:-169>"
sequent-row-shift: " <s:-169>" # Oraxen: " <s:-169>" (Space is important here!)
individual-column-shift: "<s:-3>" # Oraxen: "<s:-3>"
background: "<g:shade_row_<row>:colorable> " # Oraxen: "<g:shade_row_<row>:colorable>
clear-background: "<g:clear_row_<row>:colorable> " # Oraxen: "<g:clear_row_<row>:colorable> "
#These use MiniMessage for color! https://docs.advntr.dev/minimessage/format.html#color
equipped-cosmetic-color: "<yellow>"
equipable-cosmetic-color: "<green>"
locked-cosmetic-color: "<red>"
cosmetic-type:
# This allows you to specify if it should require a special click type for the interaction to work.
equip-click: "ANY" # ANY or ClickType, https://jd.papermc.io/paper/1.20/org/bukkit/event/inventory/ClickType.html
unequip-click: "ANY" # ANY or ClickType, https://jd.papermc.io/paper/1.20/org/bukkit/event/inventory/ClickType.html
dye-menu: dye-menu:
# If you use ItemsAdder, set this to "§f:offset_-8::dye_menu:" # If you use ItemsAdder, set this to "§f:offset_-8::dye_menu:"
# If you use Oraxen, set this to "<glyph:neg_shift_8><glyph:dye_menu>" # If you use Oraxen, set this to "<glyph:neg_shift_8><glyph:dye_menu>"
@@ -62,14 +107,17 @@ hook-settings:
# Requires restart to apply changes. # Requires restart to apply changes.
player-move-check: true player-move-check: true
wardrobe: wardrobe:
# spawn static wardrobe if in this radius of wardrobe-location
static-radius: 10
# how much yaw should change per tick, set to 0 for none # how much yaw should change per tick, set to 0 for none
rotation-speed: 3 rotation-speed: 3
# Applies a pumpkin for an overlay of the player while in the wardrobe. # Applies a pumpkin for an overlay of the player while in the wardrobe.
equip-pumpkin: false 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 # 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 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
menu-options:
enter-open-menu: false # If the menu should open when a player enters a wardrobe
gamemode-options: 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-enabled: false # Setting this to false will set the gamemode the player came in as. True sets to exit-gamemode gamemode
@@ -91,24 +139,28 @@ wardrobe:
title-fade-in: 1000 # milliseconds title-fade-in: 1000 # milliseconds
title-stay: 500 # milliseconds title-stay: 500 # milliseconds
title-fade-out: 1000 # milliseconds title-fade-out: 1000 # milliseconds
wardrobe-location: wardrobes:
world: "World" default:
x: 0 distance: -1 # Distance in blocks that a player can interact with the wardrobe. -1 to ignore.
y: 0 permission: "hmccosmetics.wardrobe.default" # Permission required to use the wardrobe.
z: 0 npc-location:
yaw: 0 world: "world"
pitch: 0 x: 0
viewer-location: y: 0
world: "World" z: 0
x: 5 yaw: 0
y: 0 pitch: 0
z: 5 viewer-location:
yaw: 0 world: "world"
pitch: 0 x: 5
leave-location: y: 0
world: "World" z: 5
x: 5 yaw: 0
y: 5 pitch: 0
z: 5 leave-location:
yaw: 0 world: "world"
pitch: 0 x: 5
y: 5
z: 5
yaw: 0
pitch: 0

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