9
0
mirror of https://github.com/HibiscusMC/HMCCosmetics.git synced 2025-12-19 15:09:19 +00:00

Compare commits

...

739 Commits

Author SHA1 Message Date
LoJoSho
35260d4abb Merge remote-tracking branch 'origin/remapped' into remapped 2024-04-27 09:06:34 -05:00
LoJoSho
2d44435d53 fix: hmccolor dye menu not processing through minimessage 2024-04-27 09:06:21 -05:00
LoJoSho
3d785bd157 version bump (2.7.3-DEV) 2024-04-27 09:04:39 -05:00
lucian929
c33cfbd302 fix: update default config to use proper input slots for color 2024-04-25 15:24:22 -04:00
LoJoSho
f5ed39e02c Merge remote-tracking branch 'origin/remapped' into remapped 2024-04-25 14:09:44 -05:00
LoJoSho
0c3af0e0cd version bump (2.7.2) 2024-04-25 14:09:22 -05:00
lucian929
f5a1a67e1e chore: remove emotes from defaultmenu 2024-04-25 14:13:47 -04:00
LoJoSho
ddc0a504fd fix: disabled worlds not checked if player teleports through portals 2024-04-25 12:12:27 -05:00
LoJoSho
de108753d5 clean: ignore cancelled teleportations 2024-04-02 22:04:40 -05:00
LoJoSho
b31e8b7a4b chore: more documentation for CosmeticUsers class 2024-04-02 22:02:51 -05:00
LoJoSho
383fdfa7f6 fix: no entity + backpack spawning causing NPE 2024-03-16 12:13:07 -05:00
LoJoSho
54e867ab0b Merge pull request #131 from HibiscusMC/allow-flight
fix: wardrobe kicking player if allowFlight not enabled in server.pro…
2024-03-11 08:40:46 -05:00
LoJoSho
068ed3eb70 fix: backpacks not reattaching after teleporting 2024-03-05 22:26:10 -06:00
LoJoSho
a203c60df1 fix: backpacks turning black when under blocks 2024-03-05 10:58:12 -06:00
LoJoSho
e13c3fccb4 fix: hidden flags being added async causing error 2024-02-25 17:51:06 -06:00
LoJoSho
add72e66c9 feat: hidden reasons now in lists, add disableall command (hides all players cosmetics) 2024-02-25 15:20:32 -06:00
LoJoSho
0e587feff0 fix: multiple schedulers when player has multiple loaded cosmetics 2024-02-21 12:42:57 -06:00
LoJoSho
27be86c419 fix: clean resources after sql usage 2024-02-20 13:53:10 -06:00
Boy
3d940d8468 fix: wardrobe kicking player if allowFlight not enabled in server.properties 2024-02-10 13:20:36 +01:00
LoJoSho
7515cdd137 refactor: getHidden to isHidden in CosmeticUser class, deprecate old method 2024-02-04 20:07:01 -06:00
LoJoSho
8e92f3e689 fix: hidden reasons for gamemodes + world not working, spawning entity cosmetics while hidden 2024-02-04 20:04:33 -06:00
LoJoSho
7c4b833d80 fix: tab autocomplete checks attempted before user loading causing NPE 2024-02-04 19:20:37 -06:00
LoJoSho
b291dc4c9f Merge remote-tracking branch 'origin/remapped' into remapped 2024-01-28 10:57:30 -06:00
LoJoSho
60b91df843 fix: balloons with head models pitch being affected by player 2024-01-28 10:56:49 -06:00
LoJoSho
56f380025d fix: equipped armor not showing after exiting wardrobe 2024-01-17 13:07:01 -06:00
LoJoSho
b3e0acbcbd feat: add config options to prevent damage while in the wardrobe 2024-01-17 12:45:04 -06:00
LoJoSho
e2d334db9d version bump (2.7.2-DEV) 2024-01-17 12:25:03 -06:00
LoJoSho
dffcf6213b fix: check if player is not null before running end wardrobe 2024-01-17 12:24:41 -06:00
Boy
485f5837f4 fix: bump HMCColor & implement API-changes 2024-01-14 01:55:34 +01:00
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
69de2fa178 version bump (2.3.1) 2023-05-09 14:20:23 -05:00
LoJoSho
cdcf904ac8 fix: cosmetic tpe gui items not processing placeholders 2023-05-08 12:23:20 -05:00
LoJoSho
80f9100bf0 fix: translation file generating 2023-05-08 12:22:57 -05:00
LoJoSho
751509ece4 version bump (2.3.1-DEV) 2023-05-08 12:22:46 -05:00
LoJoSho
a8ff8e6a7a Merge remote-tracking branch 'origin/remapped' into remapped 2023-05-08 09:50:55 -05:00
LoJoSho
f36d558e13 clean: updateCosmetic use proper method 2023-05-06 10:40:15 -05:00
LoJoSho
ab8ae8ee76 version bump (2.3.0) 2023-05-06 10:28:26 -05:00
LoJoSho
aca14f8a04 clean: config referenced wrong value in comments 2023-05-06 09:47:24 -05:00
LoJoSho
6ec13051bb clean: user tick debug message 2023-05-06 09:40:13 -05:00
LoJoSho
ebc7bfa30a feat: menu now passes int slot to gui item types 2023-05-06 09:37:54 -05:00
LoJoSho
e59717d61d feat: positive emote distances show camera facing player 2023-05-06 09:34:10 -05:00
LoJoSho
7f5a90b080 Merge pull request #105 from Craftinators/remapped
feat: allow for multiple emotes in one bbmodel file
2023-05-06 09:19:45 -05:00
LoJoSho
51d26a7983 Merge pull request #104 from HibiscusMC/2.3.0
Improved GUI configuration options (2.3.0)
2023-05-06 09:16:22 -05:00
Craftinators
d1d001fcf6 refactor(EmoteManager): move emote loading logic to EmoteManager class 2023-05-06 00:02:03 -04:00
Craftinators
79f33ca0d1 feat: allow for multiple emotes in one bbmodel file 2023-05-05 18:39:14 -04:00
LoJoSho
7f37937185 clean: removed method not needed 2023-05-05 16:34:01 -05:00
LoJoSho
0e9164a506 fix: multi-slot gui items actions not running 2023-05-05 16:23:03 -05:00
LoJoSho
91361a6373 feat: equipped and locked cosmetic item in gui 2023-05-05 14:38:54 -05:00
LoJoSho
cfe5f33a63 version bump (2.3.0-DEV) 2023-05-05 14:38:38 -05:00
LoJoSho
e50566e2cb feat: add hasCosmeticInSlot for cosmetic 2023-05-05 13:53:01 -05:00
LoJoSho
f793f4e67a Merge pull request #103 from Craftinators/main
chore: add contact link
2023-04-30 15:53:07 -05:00
Craftinators
b57428e3fe style: remove emoji from name 2023-04-30 14:13:21 -04:00
Craftinators
3137c45704 chore: add contact link
Add a contact link for general questions
2023-04-30 14:09:46 -04:00
LoJoSho
38c270558c fix: update PlayerAnimator to 1.2.6 for 1.19.4 support 2023-04-30 10:37:57 -05:00
LoJoSho
39a36fa73c Merge remote-tracking branch 'origin/remapped' into remapped
# Conflicts:
#	build.gradle.kts
2023-04-29 22:58:39 -05:00
LoJoSho
ae83355860 feat: add LibsDisguise hook, resolves #85 2023-04-29 22:57:40 -05:00
LoJoSho
60d910d148 Merge pull request #100 from Craftinators/remapped
Issue template changes
2023-04-29 12:09:21 -05:00
LoJoSho
251d227ddb Merge pull request #99 from mergu/denizen_item_support
Add support for Denizen items
2023-04-29 12:07:30 -05:00
LoJoSho
45e597c665 version bump (2.2.9-DEV) 2023-04-29 12:01:20 -05:00
Craftinators
f0e60903b5 chore: more PR description options 2023-04-29 12:55:31 -04:00
Craftinators
db49946e5e chore: add discord link at top 2023-04-29 12:49:10 -04:00
Craftinators
50ebc737e6 chore: fix 02-feature-request indent error 2023-04-29 12:47:25 -04:00
Craftinators
28d1775c86 chore: fix 02-feature_request syntax error 2023-04-29 12:46:49 -04:00
Craftinators
0a1a381ebc chore: update 02-feature_request 2023-04-29 12:45:58 -04:00
Craftinators
651067fb17 style: rename feature-request.yml 2023-04-29 12:40:43 -04:00
Craftinators
1f634d668e style: rename bug-report.yml 2023-04-29 12:40:14 -04:00
Craftinators
f5bf8c70b4 chore: modify text 2023-04-29 12:39:22 -04:00
Craftinators
f50731f83e chore: fix bug-report.yml validation errors 2023-04-29 12:36:29 -04:00
Craftinators
f44d916b32 chore: fix bug-report.yml syntax error 2023-04-29 12:34:17 -04:00
Craftinators
9cfb27da28 chore: update bug-report.yml 2023-04-29 12:33:03 -04:00
Mergu
b09bd35737 Add support for Denizen items 2023-04-29 11:56:17 -04:00
LoJoSho
b998cac5c8 clean: default earth day grabber had model field that was unused 2023-04-26 15:01:30 -05:00
LoJoSho
8b20207442 Merge remote-tracking branch 'origin/remapped' into remapped 2023-04-24 10:32:56 -05:00
LoJoSho
9b34ffebb8 version bump (2.2.8) 2023-04-23 15:44:28 -05:00
LoJoSho
3eaaf75bfb clean: removed persistant data container not being used 2023-04-23 15:42:54 -05:00
LoJoSho
c1bae96ad9 fix: cosmetic data container now contains cosmetic id 2023-04-23 15:42:31 -05:00
LoJoSho
ddb6f53655 fix: cancel event for clicking in HMCColor 2023-04-23 15:23:10 -05:00
LoJoSho
c37f52bbb1 feat: destroy loose items cover gamemode switch 2023-04-23 10:47:44 -05:00
LoJoSho
dd805f1860 feat: add cosmetics containing who they were generated for 2023-04-23 10:38:43 -05:00
LoJoSho
d9551f2827 clean: better debug messages in CosmeticUser 2023-04-22 19:09:49 -05:00
LoJoSho
1750a1bf5f fix: 1.19.2 fake player info packet issue 2023-04-22 19:05:22 -05:00
LoJoSho
d42f5ef5af fix: player still in wardrobe after death 2023-04-22 18:32:28 -05:00
LoJoSho
2ca940a929 fix: papi expansion does not persist 2023-04-22 16:31:52 -05:00
LoJoSho
36f33b54af fix: cosmetic null showing error 2023-04-22 16:27:05 -05:00
LoJoSho
d0b4be6db8 fix: wardrobe not ending with transition false 2023-04-22 16:22:18 -05:00
LoJoSho
4afa0bb538 clean: new debug messages 2023-04-22 16:21:02 -05:00
LoJoSho
201bcceaab fix: 1.19.3 fake info packet not properly casting in protocol lib 2023-04-20 14:12:25 -05:00
LoJoSho
92ad314ce1 version bump (2.2.8-DEV) 2023-04-20 14:12:05 -05:00
lucian929
b8962539e8 Add earth day cosmetics 2023-04-18 16:44:50 -04:00
LoJoSho
01db728b99 version bump (2.2.7) 2023-04-17 15:22:24 -05:00
LoJoSho
8525dda6f4 feat: add gamemode-options when exiting wardrobe 2023-04-17 15:21:16 -05:00
LoJoSho
e8f7f57e0b feat: Destroy loose cosmetics to remove unwanted cosmetics 2023-04-17 14:25:48 -05:00
LoJoSho
8c62b47d5b clean: remove unused loop 2023-04-17 10:51:56 -05:00
LoJoSho
2ab0b119e7 Merge remote-tracking branch 'origin/remapped' into remapped 2023-04-17 10:50:35 -05:00
LoJoSho
20d919c65e clean: improved animation variable 2023-04-17 10:50:28 -05:00
LoJoSho
bd41c5b9ff feat: Option to make lead invisible for balloons, resolves #95 2023-04-17 10:31:27 -05:00
LoJoSho
60aaf0cff6 feat: Equipped placeholder now takes type 2023-04-09 11:37:55 -05:00
LoJoSho
71c8f8171b fix: Standing does not readd backpack 2023-04-09 11:08:40 -05:00
LoJoSho
2bc4e3dd3f Merge pull request #93 from Craftinators/remapped
Remove `build` workflow
2023-04-06 16:43:18 -05:00
Craftinators
302eaa13c9 Merge branch 'HibiscusMC:remapped' into remapped 2023-04-06 17:40:17 -04:00
Craftinators
23ff51bab8 github: remove build workflow 2023-04-06 17:39:23 -04:00
LoJoSho
96ee695521 Merge pull request #92 from Craftinators/remapped
Minor Repository Changes
2023-04-06 16:33:24 -05:00
Craftinators
a9a587495a github: build workflow only fires on pr 2023-04-06 17:20:33 -04:00
Craftinators
0b69e20adc github: remove note from CONTRIBUTING.md 2023-04-06 01:46:43 -04:00
Craftinators
a08e531226 fix: contribution guide updates 2023-04-05 23:20:42 -04:00
Craftinators
1e27933573 github: add contribution guide 2023-04-05 22:07:16 -04:00
Craftinators
0b4815842f github: remove cache from build action 2023-04-05 19:47:30 -04:00
LoJoSho
cc6aec99e0 fix: NPE on player exit if user not created 2023-04-05 17:21:02 -05:00
Craftinators
b51bace9f5 fix: Feature Request add enhancement label 2023-04-05 13:09:08 -04:00
Craftinators
c70223a800 github: remove matrix versions >=18 2023-04-05 13:07:05 -04:00
Craftinators
36353b5693 github: expand java matrix to include versions 19 & 20 2023-04-05 12:54:30 -04:00
Craftinators
d4fc903c14 fix: revert to temurin 2023-04-05 12:45:14 -04:00
Craftinators
980d2d89df fix: oracle typo 2023-04-05 12:44:12 -04:00
Craftinators
c952a8ac08 github: try versions >17.0 2023-04-05 12:42:50 -04:00
Craftinators
a651c9b8da fix: remove java version matrix 2023-04-05 12:32:29 -04:00
Craftinators
c695e8b2f9 fix: distribution from orcale to temurin 2023-04-05 12:26:27 -04:00
Craftinators
ee72bc2ef5 fix: distribution issue 2023-04-05 12:24:58 -04:00
Craftinators
ebd47e9b56 fix: actions/setup-java@v3.6 -> actions/setup-java@v3 2023-04-05 12:20:41 -04:00
Craftinators
5cf5e7c543 github: add matrix samples 2023-04-05 12:18:54 -04:00
Craftinators
7f2d62b5e5 fix: add chmod permission changes 2023-04-05 11:45:50 -04:00
Craftinators
8d07f7cf9f github: add build workflow 2023-04-05 08:14:23 -04:00
LoJoSho
789db52b57 fix: player_move_check changed to player-move-check in configuration 2023-04-04 07:55:02 -05:00
LoJoSho
5fb3458a98 fix: player emoting then teleporting glitches out 2023-04-02 13:34:47 -05:00
LoJoSho
f6935ce60b Merge remote-tracking branch 'origin/remapped' into remapped 2023-04-02 12:54:50 -05:00
lucian929
b1eb592137 chore: update transition info for oraxen/itemsadder 2023-04-02 13:54:27 -04:00
LoJoSho
913f8ccdf7 version bump (2.2.7-DEV) 2023-04-02 12:39:23 -05:00
LoJoSho
3f951263b9 version bump (2.2.6) 2023-04-02 12:39:01 -05:00
LoJoSho
744fc87491 feat: add option to disable World Guard listener #87 2023-04-02 12:30:41 -05:00
LoJoSho
ca01a94502 feat: full 1.19.4 support 2023-04-02 12:00:31 -05:00
LoJoSho
879a58d1f4 clean: update test servers to 1.19.4 2023-04-02 11:59:32 -05:00
LoJoSho
aab40b68a7 clean: add md-5 repo for future plugins 2023-04-01 22:34:38 -05:00
LoJoSho
9533e2ec46 fix: add 1.19.4 in SUPPORTED_VERSIONS constant 2023-04-01 22:28:26 -05:00
LoJoSho
7b2e767cac fix: fixes #88 throwing runtime exception on reload 2023-04-01 22:27:38 -05:00
LoJoSho
4bdd000917 Merge remote-tracking branch 'origin/remapped' into remapped 2023-03-22 19:52:01 -05:00
LoJoSho
b397ae52f9 fix: check valid balloon entity before teleport 2023-03-22 19:51:56 -05:00
LoJoSho
40620f1daa Merge pull request #83 from Craftinators/hooks
Abstraction and Documentation of `/hooks` directory
2023-03-17 15:53:13 -05:00
Craftinators
4d8d43ee2a docs(Hooks): getActive -> isActive 2023-03-17 16:03:18 -04:00
Craftinators
4f8a32c3e8 docs(HMCPlaceholderExpansion): documented class 2023-03-17 16:01:55 -04:00
LoJoSho
1d303dee71 feat: add 1.19.4 nms support 2023-03-17 11:47:41 -05:00
LoJoSho
e9659ab1e8 version bump (2.2.6-DEV) 2023-03-17 11:27:32 -05:00
LoJoSho
ee917dbf32 fix: Riptide fixes #84 2023-03-17 11:25:08 -05:00
LoJoSho
2a275fe503 Merge remote-tracking branch 'origin/remapped' into remapped 2023-03-17 11:15:51 -05:00
LoJoSho
a5631cd2e4 fix: player during riptide have their backpack hidden #84 2023-03-17 11:15:04 -05:00
Craftinators
1ed1a2c41d docs(WGListener): documented class 2023-03-17 09:08:11 -04:00
Craftinators
c2bf0322a7 docs(WGHook): documented class 2023-03-17 09:06:37 -04:00
Craftinators
3f8f84735f docs(HookPlaceholderAPI): documented class 2023-03-17 08:58:39 -04:00
Craftinators
2fb28dda32 docs(HookSuperVanish): documented class 2023-03-17 08:54:17 -04:00
Craftinators
6192515550 docs(HookPremiumVanish): documented class 2023-03-17 08:54:10 -04:00
Craftinators
6fcf893bac docs: fixed wording 2023-03-17 08:53:37 -04:00
Craftinators
d0dfa19f2d docs(HookHMCColor): documented class 2023-03-17 08:53:09 -04:00
Craftinators
c3b4abea40 docs(HookCMI): documented class 2023-03-17 08:53:00 -04:00
Craftinators
a030d1272b docs(HookOraxen): documented class 2023-03-17 08:44:10 -04:00
Craftinators
d6c4b51b98 docs(HookMythic): documented class 2023-03-17 08:42:05 -04:00
Craftinators
a306d76c19 Merge remote-tracking branch 'origin/hooks' into hooks
# Conflicts:
#	common/src/main/java/com/hibiscusmc/hmccosmetics/hooks/items/HookMythic.java
2023-03-17 08:40:08 -04:00
Craftinators
1d51ee0711 docs(HookMythic): documented class 2023-03-17 08:39:53 -04:00
Craftinators
e340874270 docs(HookMythic): documented class 2023-03-17 08:37:52 -04:00
Craftinators
093b01d7ff docs(HookLooty): documented class 2023-03-16 18:43:52 -04:00
Craftinators
5b129cc254 docs(HookItemAdder): documented class 2023-03-16 18:40:50 -04:00
Craftinators
7a32697906 docs(HookHMCCosmetics): documented class 2023-03-16 17:55:53 -04:00
Craftinators
2ea272ee4a fix(Hook): abstraction and documentation of Hook 2023-03-16 17:39:58 -04:00
LoJoSho
9ebfc9748d Merge pull request #81 from Craftinators/docs
Documentation of `/api` directory
2023-03-16 14:22:06 -05:00
Craftinators
d1a2b6a016 docs(HMCCosmeticSetupEvent): fix documentation 2023-03-15 17:11:41 -04:00
Craftinators
af78424b07 refactor(PlayerMenuCloseEvent): event no longer cancellable 2023-03-15 15:31:25 -04:00
LoJoSho
c35546e536 Merge pull request #82 from Craftinators/remapped
PR template
2023-03-15 09:16:39 -05:00
Craftinators
7db03a2f8a fix: add colon 2023-03-15 08:39:27 -04:00
Craftinators
99f3765e6e github: add PR template 2023-03-15 08:36:02 -04:00
Craftinators
fae001a48f fix: disallow empty issues 2023-03-15 08:35:41 -04:00
Craftinators
1ccb35ad62 refactor: abstraction of menu related events 2023-03-15 08:05:15 -04:00
Craftinators
2b4e570172 clean(UserEmoteManager): remove unused import 2023-03-15 08:04:53 -04:00
Craftinators
965b6cc740 fix(PlayerCosmeticEvent): rename to PlayerCosmeticEvent 2023-03-15 08:04:28 -04:00
Craftinators
ffda4ba6f5 feat: new PlayerMenuOpenEvent class 2023-03-15 04:44:18 -04:00
Craftinators
df2da4fc89 docs(PlayerMenuOpenEvent): add class documentation 2023-03-15 04:43:50 -04:00
Craftinators
cea40033f9 docs(PlayerWardrobeLeaveEvent): add class documentation 2023-03-15 04:43:36 -04:00
Craftinators
42a01a44aa docs(PlayerWardrobeEnterEvent): add class documentation 2023-03-15 04:43:23 -04:00
Craftinators
17c07d0e01 docs(PlayerWardrobeLeaveEvent): documented class 2023-03-15 04:05:50 -04:00
Craftinators
ea4d088b04 docs(PlayerWardrobeEnterEvent): documented class 2023-03-15 04:05:39 -04:00
Craftinators
591198175a docs(PlayerMenuOpenEvent): documented class 2023-03-15 04:05:17 -04:00
Craftinators
be93369a8b docs(PlayerEmoteStopEvent): add class documentation 2023-03-15 03:58:33 -04:00
Craftinators
fd6553a52a docs(PlayerEmoteStopEvent): documented class 2023-03-15 03:57:44 -04:00
Craftinators
961f460ffb docs(PlayerEmoteStartEvent): documented class 2023-03-15 03:57:28 -04:00
Craftinators
eb925d9022 docs(HMCCosmeticSetupEvent): documented class 2023-03-15 01:45:07 -04:00
Craftinators
d05072eb2c fix(PlayerCosmeticShowEvent): remove unused import 2023-03-15 01:40:06 -04:00
Craftinators
f456ddf8a4 docs(PlayerCosmeticShowEvent): documented class 2023-03-15 01:39:00 -04:00
Craftinators
c395b68d6a docs(PlayerCosmeticRemoveEvent): documented class 2023-03-15 01:38:33 -04:00
Craftinators
fddd5d0311 docs(PlayerCosmeticHideEvent): updated documentation 2023-03-15 01:37:46 -04:00
Craftinators
f08c38ff1a docs(PlayerCosmeticEquipEvent): updated documentation 2023-03-15 01:34:58 -04:00
Craftinators
a4bd9108b1 docs(PlayerCosmeticHideEvent): documented class 2023-03-14 18:26:22 -04:00
Craftinators
de1377dc8f docs(PlayerCosmeticEquipEvent): @see when referring to classes 2023-03-14 18:25:47 -04:00
Craftinators
00ce32c528 docs(PlayerCosmeticEquipEvent): documented class 2023-03-14 15:48:18 -04:00
Craftinators
0ddcb12b31 feat: abstraction of PlayerCosmetic... styled events 2023-03-14 15:47:27 -04:00
LoJoSho
adadecfa19 Merge pull request #79 from Craftinators/remapped
`CosmeticUser.getCosmetics()` changes
2023-03-14 14:36:56 -05:00
Craftinators
ac35ef8b5d feat(CosmeticUser): preferred getCosmetics method 2023-03-13 23:56:02 -04:00
LoJoSho
65f1c72b8e fix: restarting server while player is emoting causes player to be invisible 2023-03-13 21:23:19 -05:00
Craftinators
178bff37f5 feat(CosmeticUser): new getPlayerCosmetics() 2023-03-13 15:15:13 -04:00
Craftinators
48b9d4fb41 fix(CosmeticUser): add back getCosmetic() as deprecated method 2023-03-13 15:05:19 -04:00
Craftinators
81d6583430 fix(CosmeticUser): keep mutable collection 2023-03-13 09:02:17 -04:00
Craftinators
0304c9ff44 fix(CosmeticUser): getCosmetics() changes 2023-03-13 08:59:23 -04:00
LoJoSho
bf591e708d fix: check if backpack armorstand is a valid entity before update 2023-03-12 15:52:53 -05:00
LoJoSho
14bbd111f9 version bump (2.2.5) 2023-03-12 12:03:18 -05:00
LoJoSho
2185c27be5 feat: add PlayerEmote api events 2023-03-12 12:00:33 -05:00
LoJoSho
aef9e24d28 feat: config options for emotes (damage-leave and invincible) 2023-03-12 12:00:18 -05:00
LoJoSho
d1a35b721e feat: Enchantments can be passed to cosmetic items 2023-03-12 11:40:08 -05:00
LoJoSho
17abd0c8cc feat: Improvements to emote block checking 2023-03-11 20:48:09 -06:00
LoJoSho
a907cd51b9 feat: Add CMI vanish support 2023-03-11 20:07:01 -06:00
LoJoSho
9f6c7db8fd fix: kicking while interacting in emote/wardrobe #76 2023-03-11 19:20:35 -06:00
LoJoSho
2ba83d8cc5 fix: default color being white 2023-03-10 16:06:51 -06:00
LoJoSho
40bf0e173e version bump (2.2.5-DEV) 2023-03-10 16:06:46 -06:00
LoJoSho
a757292b4b version bump (2.2.4) 2023-03-09 19:14:33 -06:00
LoJoSho
b41d466546 fix: action menu not using debug method 2023-03-09 19:09:42 -06:00
LoJoSho
135fdc94d4 fix: sound debug was wrong level 2023-03-09 19:08:21 -06:00
LoJoSho
d0092a2ffe clean: refactor spelling mistake in isBackpackSpawned 2023-03-02 19:19:45 -06:00
LoJoSho
acf31009d5 feat: backpack improvements 2023-03-02 19:19:08 -06:00
LoJoSho
981c6155e7 feat: add all to unapply command 2023-03-01 10:45:06 -06:00
LoJoSho
2ecc86fc7b fix: same issue as before but with cosmetic wardrobe flag 2023-03-01 10:27:27 -06:00
LoJoSho
2682428354 fix: worldguard flag hiding cosmetics when on allow 2023-03-01 10:21:40 -06:00
LoJoSho
df8ad26684 fix: Flying with elytra and teleporting with backpack causing NPE 2023-03-01 10:14:05 -06:00
LoJoSho
1f714c0153 -1 in wardrobe static radius now returns true 2023-03-01 10:09:18 -06:00
LoJoSho
0bfadad222 Reload IA on change option (Legacy IA hook option) 2023-03-01 10:02:27 -06:00
LoJoSho
a1c719fc50 version bump (2.2.4-DEV) 2023-03-01 10:02:05 -06:00
Craftinators
fe9812cd69 clean: suppress warnings 2023-03-01 08:56:49 -05:00
Craftinators
b9699b27c7 fix: spelling errors 2023-03-01 00:52:13 -05:00
Craftinators
2c5ddb542e clean: remove unused import 2023-03-01 00:44:27 -05:00
Craftinators
461642d64b clean: make Type abstract 2023-03-01 00:44:00 -05:00
Craftinators
37a8a2379d clean: add @NotNull & remove import 2023-02-28 22:25:13 -05:00
LoJoSho
e698392e40 Merge pull request #74 from Craftinators/remapped
`Action` Abstraction
2023-02-28 18:54:02 -06:00
Craftinators
e1357b265f clean: use final 2023-02-28 14:50:16 -05:00
Craftinators
a5475b0268 clean: prefer not to use var 2023-02-28 14:50:03 -05:00
Craftinators
60dba9efa6 fix: use parseFloat instead of valueOf 2023-02-28 14:41:46 -05:00
Craftinators
e2d3391070 clean: reduce nesting 2023-02-28 14:40:58 -05:00
Craftinators
aed34ec28d clean: reduce nesting 2023-02-28 14:35:08 -05:00
Craftinators
ae6d88ab56 clean: make Action abstract 2023-02-28 14:34:03 -05:00
LoJoSho
35be7283e9 Merge pull request #72 from Craftinators/remapped
`CosmeticType` Abstraction
2023-02-28 09:32:30 -06:00
Craftinators
224fcb83d9 clean: config to local 2023-02-28 01:03:11 -05:00
Craftinators
98934536be clean: make Cosmetic abstract 2023-02-28 01:02:52 -05:00
LoJoSho
5ac3712e56 Merge pull request #71 from Craftinators/remapped
Database structure changes
2023-02-27 21:57:40 -06:00
Craftinators
2d2d4e6d44 clean: remove TODO 2023-02-27 22:55:33 -05:00
Craftinators
4b1921b754 clean: try-with-resource to SuppressWarnings 2023-02-27 22:55:12 -05:00
Craftinators
8ca1d44375 clean: add error message 2023-02-27 15:36:50 -05:00
Craftinators
23c82cc6ed fix: additional null checks 2023-02-27 15:34:42 -05:00
Craftinators
2bf5280827 fix: reorder null checks 2023-02-27 15:29:50 -05:00
Craftinators
475a1e0ef1 fix: add Class.forName(...) back 2023-02-27 13:06:23 -05:00
Craftinators
ef4d53eb85 fix: throw error if file isn't created 2023-02-27 12:57:12 -05:00
Craftinators
97da4f7809 feat: add SQLData class 2023-02-27 12:53:51 -05:00
Craftinators
1622dac67f clean: cleanup openConnection() 2023-02-27 12:26:43 -05:00
Craftinators
fce1ec5042 refactor: use try-with-resources 2023-02-27 12:23:30 -05:00
Craftinators
060bcc95e1 clean: reorganize MySQLData 2023-02-27 12:20:26 -05:00
Craftinators
5aca80609a feat: make Data abstract 2023-02-27 12:11:09 -05:00
LoJoSho
7c1da21026 Refactoring and Misc changes in UserWardrobeManager 2023-02-25 10:48:39 -06:00
LoJoSho
52329a6de5 Move wardrobe lists to singleton list 2023-02-25 10:34:23 -06:00
LoJoSho
8cdef228e3 Add HMCColor to the internal hook system 2023-02-25 10:27:31 -06:00
LoJoSho
432d6d837a check if user has cosmetic permissions on wardrobe leave 2023-02-25 09:43:19 -06:00
LoJoSho
f42e8b2298 Refactor custom Armorstands and add HMcParticleCloud Entity 2023-02-25 09:39:27 -06:00
LoJoSho
107f5b9215 Merge remote-tracking branch 'origin/remapped' into remapped 2023-02-24 20:31:50 -06:00
LoJoSho
d303fcc45b Merge pull request #70 from Craftinators/remapped
clean: use preferred method
2023-02-24 20:31:31 -06:00
Craftinators
147be9ab7c clean: use preferred method 2023-02-24 21:22:25 -05:00
LoJoSho
7f91f9dbad set default database to SQLite 2023-02-24 20:09:07 -06:00
LoJoSho
63e538511b Merge pull request #69 from Craftinators/remapped
Major consistency changes
2023-02-24 19:48:40 -06:00
Craftinators
d0c8abc38c clean: add annotations 2023-02-24 17:51:48 -05:00
Craftinators
97a28b9e0c clean: remove unused imports 2023-02-24 17:47:21 -05:00
Craftinators
b5ae6e65a1 clean: annotation & variable modifier changes 2023-02-24 17:46:39 -05:00
Craftinators
0c7e740d7a clean: annotation & variable modifier changes 2023-02-24 16:46:23 -05:00
Craftinators
1b7462becc clean: several annotation & naming changes 2023-02-24 13:33:45 -05:00
Craftinators
d508ecd4c0 clean: cosmetic annotation changes 2023-02-24 12:21:53 -05:00
Craftinators
601d6f8a53 fix: break once "-s" flag found 2023-02-24 12:11:22 -05:00
Craftinators
44be4eceb8 clean: comment delete 2023-02-24 12:02:28 -05:00
Craftinators
8bebd57169 fix: event annotation changes 2023-02-24 12:00:14 -05:00
LoJoSho
8f426cef31 version bump (2.2.3) 2023-02-24 10:19:52 -06:00
LoJoSho
abce477f0d add cosmetic playEmote command 2023-02-24 10:19:39 -06:00
LoJoSho
985e797f83 remove annoying space 2023-02-24 09:03:20 -06:00
LoJoSho
8bc84cbdd2 Fix balloon teleport fix not checking if player has balloon 2023-02-24 09:02:16 -06:00
LoJoSho
894e4eef26 update default with correct dye menu name 2023-02-21 17:08:27 -06:00
LoJoSho
5995dabf6f Fix clicking in emote kicking players 2023-02-21 17:05:02 -06:00
LoJoSho
ed647b7e5d Fix for invalid player on emote command 2023-02-21 10:20:42 -06:00
LoJoSho
e378732d44 Fixed backpack model engine in wardrobe 2023-02-20 19:06:25 -06:00
LoJoSho
74eb5dd85a version bump (2.2.2) 2023-02-20 18:48:27 -06:00
LoJoSho
c9ba396c33 remove debug messages 2023-02-20 18:47:52 -06:00
LoJoSho
3967ac4fa5 rename viewer in wardrobe manager 2023-02-20 18:47:25 -06:00
LoJoSho
b1a35df7b5 condense if statements 2023-02-20 18:45:52 -06:00
LoJoSho
0e1c9b3f7e Backpack no longer equipped on fly or swim 2023-02-20 18:41:11 -06:00
LoJoSho
0238ac8fc4 Merge pull request #60 from HibiscusMC/modelengine_backpack
Model Engine Backpacks
2023-02-20 14:17:13 -06:00
LoJoSho
4d6baf0b0c offset backpack for ME backpack 2023-02-20 14:16:40 -06:00
LoJoSho
157fab6309 Merge branch 'remapped' into modelengine_backpack 2023-02-20 14:11:46 -06:00
lucian929
0a488a6791 Add Explorer Backpack Cosmetic 2023-02-17 10:38:56 -05:00
LoJoSho
1c9989e64a readd paper repo 2023-02-16 21:23:45 -06:00
LoJoSho
fb8dcf53e3 Merge branch 'remapped' into modelengine_backpack 2023-02-16 14:50:03 -06:00
LoJoSho
17179cbe35 version bump (2.2.1) 2023-02-16 14:44:54 -06:00
LoJoSho
f589696d19 update paper userdev 2023-02-16 14:43:28 -06:00
LoJoSho
68e87cba6f Merge pull request #61 from HibiscusMC/papi_fix
Fix for PAPI in menus
2023-02-15 17:00:21 -06:00
LoJoSho
63a0bdd0d5 Fix for PAPI in menus 2023-02-15 16:58:47 -06:00
LoJoSho
a01f35c53d Model Engine Backpacks 2023-02-15 16:46:03 -06:00
LoJoSho
a607f2dcbd Merge pull request #59 from HibiscusMC/tweaks
make dye menu slots configurable
2023-02-15 11:00:23 -06:00
Boy
7a9a002e25 make dye menu slots configurable 2023-02-15 12:56:32 +01:00
LoJoSho
fd50cd058a Merge pull request #58 from HibiscusMC/fix_looty
add missing hook initializer for Looty
2023-02-13 13:55:05 -06:00
Boy
970ca8227b add missing hook initializer 2023-02-13 19:04:10 +01:00
LoJoSho
e7fd3ac288 Merge pull request #57 from HibiscusMC/emotes
HMCC Emotes with PlayerAnimator
2023-02-12 13:12:51 -06:00
lucian929
51214964c4 Update default files 2023-02-12 12:58:57 -05:00
LoJoSho
4d4be789ae Merge remote-tracking branch 'origin/emotes' into emotes 2023-02-12 10:56:05 -06:00
LoJoSho
f2b276a2ef Premium + Super Vanish hook 2023-02-12 10:55:54 -06:00
LoJoSho
cf54f2b487 Premium + Super Vanish hook 2023-02-12 10:53:04 -06:00
LoJoSho
bae13c2e3c Create emote folder 2023-02-12 10:40:06 -06:00
LoJoSho
004f9ebef5 Fix rogue wardrobe runnable 2023-02-11 19:48:39 -06:00
LoJoSho
ad956259d0 move event cancel check 2023-02-11 16:13:34 -06:00
LoJoSho
65cebc3154 stop players picking items in wardrobe 2023-02-11 16:05:17 -06:00
LoJoSho
fb79293902 version bump (2.2.0) 2023-02-11 10:19:03 -06:00
LoJoSho
b49cebdec8 command improvements + /cosmetic emote playerName 2023-02-10 16:34:40 -06:00
LoJoSho
00cc3eef2c improve command handling and add permissions 2023-02-10 16:28:42 -06:00
LoJoSho
42bae598a6 offhand switch cancel 2023-02-10 16:10:06 -06:00
LoJoSho
b182e46b28 update api to 1.17 2023-02-10 16:03:15 -06:00
LoJoSho
6b6b0e385e fixed armor showing in emotes 2023-02-10 16:01:11 -06:00
LoJoSho
db60046701 More checks and does not save invisibility from emote 2023-02-10 11:30:41 -06:00
LoJoSho
300e2cffba Emote settings and messages 2023-02-10 10:49:57 -06:00
LoJoSho
d5983d8834 Made player stand still + fixed other players viewing nothing 2023-02-10 09:28:44 -06:00
LoJoSho
9e07f728e1 it works 2023-02-09 13:32:28 -06:00
LoJoSho
dcd38d86c5 latest changes 2023-02-08 17:14:03 -06:00
LoJoSho
d39110af6c emo work 2023-02-08 15:28:04 -06:00
LoJoSho
0f6fa3db8a reimplement dependencies that got missing in merge 2023-02-07 15:55:15 -06:00
LoJoSho
5aef04dee0 Complete overhaul of hooks 2023-02-07 15:54:21 -06:00
LoJoSho
a096f6c684 Merge remote-tracking branch 'origin/remapped' into remapped 2023-02-07 15:34:50 -06:00
LoJoSho
89825659a6 more refactoring 2023-02-07 15:04:17 -06:00
LoJoSho
6ba078dcc4 removed toggle method (unused) 2023-02-07 15:02:27 -06:00
LoJoSho
2e32b8d9d5 move wardrobe to a manager 2023-02-07 14:55:54 -06:00
LoJoSho
941f57af35 Merge pull request #53 from MineInAbyss/mia
LootyHook
2023-02-06 15:30:11 -06:00
LoJoSho
bdb52c0a32 Merge remote-tracking branch 'origin/remapped' into remapped 2023-02-06 14:54:17 -06:00
LoJoSho
a7170e09cf Add force-permission-join option 2023-02-06 14:53:52 -06:00
LoJoSho
8456d6a7ae Fixed balloons applied in wardrobe not having leashes 2023-02-06 14:28:34 -06:00
LoJoSho
08b28bc254 Exiting wardrobe balloon fixes 2023-02-06 14:04:17 -06:00
LoJoSho
c27a9ab2ad Internal wardrobe rework 2023-02-06 13:48:29 -06:00
LoJoSho
2bf618d8d3 ItemFlag rework 2023-02-06 13:46:51 -06:00
LoJoSho
6eb7c9243d Better locked lore handling 2023-02-06 13:11:06 -06:00
LoJoSho
c2b4fade42 Merge pull request #56 from HibiscusMC/defaultmenu
getDefaultMenu method
2023-02-06 10:44:32 -06:00
Boy
382eed9982 requested changes 2023-02-06 17:42:15 +01:00
Boy
498370cc8e replace old methods 2023-02-06 17:23:21 +01:00
Boy
fef5769e31 getDefaultMenu method 2023-02-06 14:17:18 +01:00
Boy
4aa1f9451d tweak oraxen hook for nullchecks 2023-02-06 00:03:01 +01:00
Boy
c7730429de improve looty hook check 2023-02-06 00:03:01 +01:00
Boy
73ccddf628 add softdepend 2023-02-06 00:03:01 +01:00
Boy
26b5472924 add looty support 2023-02-06 00:03:01 +01:00
LoJoSho
5ecfb08412 Refactor entities into managers 2023-02-05 12:28:37 -06:00
LoJoSho
8b223228ce Or statement should be And 2023-02-05 10:40:17 -06:00
LoJoSho
eb03acd959 version bump (2.1.3-SNAPSHOT) 2023-02-04 18:15:28 -06:00
LoJoSho
8e5b3d098c placeholder current causing npe 2023-02-04 18:02:29 -06:00
LoJoSho
a869120b62 misspells 2023-02-04 17:51:03 -06:00
LoJoSho
614892500c Version bump (2.1.2) 2023-02-03 13:16:38 -06:00
LoJoSho
872282f77a Fix publishing 2023-02-03 13:16:26 -06:00
LoJoSho
c0483bfefe Action Menu can override target menu permission with "-o" 2023-02-03 12:35:12 -06:00
LoJoSho
aecd40ba5a Hidden reason now saved in database 2023-02-03 12:19:34 -06:00
LoJoSho
c3db45cfc4 update checker more in align with HMCWraps 2023-02-02 22:26:30 -06:00
LoJoSho
99bc0a0756 Add color to apply command 2023-02-02 21:30:07 -06:00
LoJoSho
e9afd6deb8 Add ability to silent messages in command with -s 2023-02-02 21:25:29 -06:00
lucian929
0770ac456d Delete publish.yml 2023-02-02 17:44:16 -05:00
lucian929
327d602491 Fix repository link 2023-02-02 22:33:19 +00:00
LoJoSho
65f162c89c Update publish.yml 2023-02-02 15:51:24 -06:00
LoJoSho
e96d1f505e Update publish.yml 2023-02-02 15:48:08 -06:00
LoJoSho
2af1deb4c1 Update publish.yml 2023-02-02 15:42:59 -06:00
LoJoSho
d740989a01 add ia hook comment 2023-02-02 15:42:28 -06:00
LoJoSho
fdc0004b75 Repo workflow 2023-02-02 15:23:05 -06:00
LoJoSho
a1ac0a83e1 Merge remote-tracking branch 'origin/remapped' into remapped 2023-02-02 14:55:52 -06:00
LoJoSho
f51ac5969f Improve balloon handling through teleports 2023-02-02 14:52:52 -06:00
LoJoSho
3255f744a7 Add new color handling (Thanks Boy!) 2023-02-02 14:45:48 -06:00
lucian929
dfa5e85dcb Add description for dye-menu key in config 2023-02-02 08:14:58 -05:00
LoJoSho
e30451e972 check if user is created on potion effect event 2023-02-01 18:01:30 -06:00
LoJoSho
500b8ca0ce Condensed IA hook if statement 2023-02-01 16:45:38 -06:00
LoJoSho
c52718da58 Merge remote-tracking branch 'origin/remapped' into remapped 2023-02-01 16:28:38 -06:00
LoJoSho
1290750028 version bump (2.1.1) 2023-02-01 16:28:19 -06:00
LoJoSho
57d5e02275 Add more hidden reasons & show, hide, and toggle actions 2023-02-01 15:51:06 -06:00
LoJoSho
645fd25b82 Fixed ModelEngine being used when not present 2023-02-01 15:27:30 -06:00
LoJoSho
4b1c15f46f Fix ItemAdder reloaded HMCC dozens of times 2023-02-01 15:15:22 -06:00
LoJoSho
8bbe12ed84 Merge remote-tracking branch 'origin/remapped' into remapped
# Conflicts:
#	build.gradle.kts
2023-01-30 10:40:00 -06:00
lucian929
b96ae68f24 Merge pull request #47 from HibiscusMC/fix_dyeing
add dyeing support for potions and maps
2023-01-29 12:21:51 -05:00
Boy
3e5f698dbd revert slots 2023-01-29 18:20:56 +01:00
Boy
88632dce3f add dyeing support for potions and maps 2023-01-29 18:10:22 +01:00
LoJoSho
30f25b4a92 Rename license to license.md 2023-01-28 18:49:00 -06:00
LoJoSho
a385b341f7 Create license 2023-01-28 18:48:02 -06:00
lucian929
66c5fd86c5 Update default configurations for 2.1.0 2023-01-27 17:47:40 -05:00
LoJoSho
ff4f2b6ede moved NMS detection to info 2023-01-27 12:05:52 -06:00
LoJoSho
80eb333b39 fixed offhand item not immidently apply 2023-01-27 10:02:46 -06:00
LoJoSho
8b2b771a9b Fixes offhand cosmetics not appearing if applied via menus 2023-01-26 18:15:20 -06:00
LoJoSho
7873b3fe04 removed certain debug messages 2023-01-26 18:01:46 -06:00
LoJoSho
9854e77bf5 Ballons item now dye correctly 2023-01-26 16:24:21 -06:00
LoJoSho
cad78636d0 Version bump (2.1.0) 2023-01-25 17:10:27 -06:00
LoJoSho
14d256feed Add 1.17 NMS Support 2023-01-25 17:08:09 -06:00
LoJoSho
53163feb60 Add ability for lock names and lore #45 2023-01-24 19:23:03 -06:00
LoJoSho
caf168d29d Invisibility now hides cosmetics 2023-01-24 18:31:21 -06:00
LoJoSho
2a7686e6b7 particle fix 2023-01-24 18:17:00 -06:00
LoJoSho
5309c37902 Add particle action 2023-01-22 19:04:42 -06:00
LoJoSho
ea1b87c128 dyable balloons if no parts selected 2023-01-21 18:12:57 -06:00
LoJoSho
9d92ed0dda Add dyable parts to balloons 2023-01-21 18:06:25 -06:00
LoJoSho
e24d5697e7 Fixed issue with windows packet not preserving held item 2023-01-21 10:41:40 -06:00
LoJoSho
8c59b27302 Add color for bossbar in config 2023-01-20 20:03:52 -06:00
LoJoSho
df3544726d Add 1.18.2 Support 2023-01-20 17:31:25 -06:00
LoJoSho
27af0a6085 Add Equip and Unequip actions 2023-01-20 17:10:17 -06:00
LoJoSho
1db96c38d9 Add hidden reason to internal code 2023-01-20 17:03:44 -06:00
LoJoSho
d9b92d5336 Add sound action #43 2023-01-20 16:24:11 -06:00
LoJoSho
0905071dd2 Balloon rework for items as balloons 2023-01-20 16:08:28 -06:00
LoJoSho
d23f3e19d2 Moved ProtocolLib Repo 2022-11-16 13:38:02 -06:00
143 changed files with 7011 additions and 4319 deletions

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

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

View File

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

View File

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

View File

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

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

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

View File

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

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

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

1
.gitignore vendored
View File

@@ -23,7 +23,6 @@ atlassian-ide-plugin.xml
*.ctxt
# Package Files #
*.jar
*.war
*.nar
*.ear

View File

@@ -2,14 +2,13 @@ import net.minecrell.pluginyml.bukkit.BukkitPluginDescription
plugins {
id("java")
id("maven-publish")
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("net.minecrell.plugin-yml.bukkit") version "0.5.2"
id("net.minecrell.plugin-yml.bukkit") version "0.6.0"
}
group = "com.hibiscusmc"
version = "2.0.3"
version = "2.7.3-DEV"
allprojects {
apply(plugin = "java")
@@ -28,15 +27,13 @@ allprojects {
// ProtocolLib repo
maven("https://repo.dmulloy2.net/repository/public/") //ProtocolLib Repo, constantly down
maven("https://repo.mineinabyss.com/releases/")
maven("https://repo.mineinabyss.com/snapshots/")
// PlaceholderAPI
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
//Hikari
maven("https://mvnrepository.com/artifact/com.zaxxer/HikariCP")
// Citizens
maven("https://repo.citizensnpcs.co")
// Citizens & Denizen
maven("https://maven.citizensnpcs.co/repo")
// Worldguard
maven("https://maven.enginehub.org/repo/")
@@ -54,37 +51,59 @@ allprojects {
// UpdateChecker
maven("https://hub.jeff-media.com/nexus/repository/jeff-media-public/")
// ParticleHelper
maven("https://repo.bytecode.space/repository/maven-public/")
// PlayerAnimator
maven("https://mvn.lumine.io/repository/maven/")
// md-5 Repo
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 {
compileOnly(fileTree("${project.rootDir}/lib") { include("*.jar") })
compileOnly("com.mojang:authlib:1.5.25")
compileOnly("org.spigotmc:spigot-api:1.16.5-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("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.comphenix.protocol:ProtocolLib:5.1.0")
compileOnly("me.clip:placeholderapi:2.11.3")
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.2")
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT")
compileOnly("it.unimi.dsi:fastutil:8.5.11")
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 {
implementation(project(path = ":common"))
implementation(project(path = ":v1_19_R1", configuration = "reobf"))
implementation(project(path = ":v1_19_R2", 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")
}
tasks {
@@ -104,22 +123,15 @@ tasks {
}
runServer {
minecraftVersion("1.19.2")
minecraftVersion("1.20.4")
}
shadowJar {
dependsOn(":v1_19_R1:reobfJar")
dependsOn(":v1_19_R2:reobfJar")
mergeServiceFiles()
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.ticxo.playeranimator", "com.hisbiscusmc.hmccosmetics.playeranimator")
archiveFileName.set("HMCCosmeticsRemapped-${project.version}.jar")
dependencies {
@@ -144,15 +156,19 @@ tasks {
bukkit {
load = BukkitPluginDescription.PluginLoadOrder.POSTWORLD
main = "com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin"
apiVersion = "1.19"
apiVersion = "1.18"
authors = listOf("LoJoSho")
depend = listOf("ProtocolLib", "PlaceholderAPI")
softDepend = listOf("ModelEngine", "Oraxen", "ItemsAdder", "HMCColor", "WorldGuard", "MythicMobs")
depend = listOf("HibiscusCommons", "ProtocolLib")
softDepend = listOf("ModelEngine", "Oraxen", "ItemsAdder", "Geary", "HMCColor", "WorldGuard", "MythicMobs", "PlaceholderAPI", "SuperVanish", "PremiumVanish", "LibsDisguises", "Denizen", "MMOItems", "Eco")
version = "${project.version}"
loadBefore = listOf(
"Cosmin" // Fixes an issue with Cosmin loading before and taking /cosmetic, when messing with what we do.
)
commands {
register("cosmetic") {
description = "Base Cosmetic Command"
aliases = listOf("hmccosmetics", "cosmetics")
}
}
permissions {
@@ -174,7 +190,22 @@ bukkit {
register("hmccosmetics.cmd.menu") {
default = BukkitPluginDescription.Permission.Default.TRUE
}
register("hmccosmetics.cmd.setlocation") {
register("hmccosmetics.emote.shiftrun") {
default = BukkitPluginDescription.Permission.Default.TRUE
}
register("hmccosmetics.cmd.emote") {
default = BukkitPluginDescription.Permission.Default.TRUE
}
register("hmccosmetics.cmd.playemote") {
default = BukkitPluginDescription.Permission.Default.OP
}
register("hmccosmetics.cmd.playemote.other") {
default = BukkitPluginDescription.Permission.Default.OP
}
register("hmccosmetics.cmd.emote.other") {
default = BukkitPluginDescription.Permission.Default.OP
}
register("hmccosmetics.cmd.setwardrobesetting") {
default = BukkitPluginDescription.Permission.Default.OP
}
register("hmccosmetics.cmd.dataclear") {
@@ -213,6 +244,15 @@ bukkit {
register("hmccosmetics.unapplydeath.bypass") {
default = BukkitPluginDescription.Permission.Default.OP
}
register("hmccosmetics.cmd.disableall") {
default = BukkitPluginDescription.Permission.Default.OP
}
register("hmccosmetics.cmd.hiddenreasons") {
default = BukkitPluginDescription.Permission.Default.OP
}
register("hmccosmetics.cmd.clearhiddenreasons") {
default = BukkitPluginDescription.Permission.Default.OP
}
}
}
@@ -220,16 +260,3 @@ java {
toolchain.languageVersion.set(JavaLanguageVersion.of(17
))
}
publishing {
publications {
create<MavenPublication>("maven") {
groupId = "${project.group}"
artifactId = "${project.name}"
version = "${project.version}"
from(components["java"])
}
}
}

View File

@@ -1,32 +1,75 @@
plugins {
id("java")
}
dependencies {
compileOnly("com.mojang:authlib:1.5.25")
compileOnly("org.spigotmc:spigot-api:1.16.5-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.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.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")
id("maven-publish")
}
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(17
))
}
publishing {
val publishData = PublishData(project)
publications {
create<MavenPublication>("maven") {
groupId = "${rootProject.group}"
artifactId = "${rootProject.name}"
version = "${rootProject.version}"
from(components["java"])
}
}
repositories {
maven {
authentication {
credentials(PasswordCredentials::class) {
username = System.getenv("REPO_USERNAME")
password = System.getenv("REPO_PASSWORD")
}
}
name = "HibiscusMCRepository"
url = uri(publishData.getRepository())
}
}
}
class PublishData(private val project: Project) {
var type: Type = getReleaseType()
var hashLength: Int = 7
private fun getReleaseType(): Type {
val branch = getCheckedOutBranch()
return when {
branch.contentEquals("master") || branch.contentEquals("local") -> Type.RELEASE
branch.startsWith("dev") -> Type.DEV
else -> Type.SNAPSHOT
}
}
private fun getCheckedOutGitCommitHash(): String =
System.getenv("GITHUB_SHA")?.substring(0, hashLength) ?: "local"
private fun getCheckedOutBranch(): String =
System.getenv("GITHUB_REF")?.replace("refs/heads/", "") ?: "local"
fun getVersion(): String = getVersion(false)
fun getVersion(appendCommit: Boolean): String =
type.append(getVersionString(), appendCommit, getCheckedOutGitCommitHash())
private fun getVersionString(): String =
(rootProject.version as String).replace("-SNAPSHOT", "").replace("-DEV", "")
fun getRepository(): String = type.repo
enum class Type(private val append: String, val repo: String, private val addCommit: Boolean) {
RELEASE("", "https://repo.hibiscusmc.com/releases/", false),
DEV("-DEV", "https://repo.hibiscusmc.com/development/", true),
SNAPSHOT("-SNAPSHOT", "https://repo.hibiscusmc.com/snapshots/", true);
fun append(name: String, appendCommit: Boolean, commitHash: String): String =
name.plus(append).plus(if (appendCommit && addCommit) "-".plus(commitHash) else "")
}
}

View File

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

View File

@@ -1,80 +1,94 @@
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.CosmeticCommandTabComplete;
import com.hibiscusmc.hmccosmetics.config.DatabaseSettings;
import com.hibiscusmc.hmccosmetics.config.Settings;
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.Cosmetics;
import com.hibiscusmc.hmccosmetics.database.Database;
import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.hooks.PAPIHook;
import com.hibiscusmc.hmccosmetics.hooks.items.ItemHooks;
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.WGListener;
import com.hibiscusmc.hmccosmetics.listener.PaperPlayerGameListener;
import com.hibiscusmc.hmccosmetics.listener.PlayerConnectionListener;
import com.hibiscusmc.hmccosmetics.listener.PlayerGameListener;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.TranslationUtil;
import com.jeff_media.updatechecker.UpdateCheckSource;
import com.jeff_media.updatechecker.UpdateChecker;
import org.bstats.bukkit.Metrics;
import com.ticxo.playeranimator.PlayerAnimatorImpl;
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.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
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.nio.file.Path;
public final class HMCCosmeticsPlugin extends JavaPlugin {
public final class HMCCosmeticsPlugin extends HibiscusPlugin {
private static HMCCosmeticsPlugin instance;
private static boolean disable = false;
private static YamlConfigurationLoader configLoader;
private static final int pluginId = 13873;
public HMCCosmeticsPlugin() {
super(13873, 1879);
new HookHMCCosmetics();
}
@Override
public void onEnable() {
public void onStart() {
// Plugin startup logic
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
new UpdateChecker(this, UpdateCheckSource.POLYMART, "1879")
.setDownloadLink("https://polymart.org/resource/1879")
.checkEveryXHours(24)
.checkNow();
// File setup
if (!getDataFolder().exists()) {
saveDefaultConfig();
saveResource("translations.yml", false);
saveResource("messages.yml", false);
saveResource("cosmetics/defaultcosmetics.yml", false);
saveResource("menus/defaultmenu.yml", false);
saveDefaultConfig();
if (!Path.of(getDataFolder().getPath(), "messages.yml").toFile().exists()) saveResource("messages.yml", false);
if (!Path.of(getDataFolder().getPath(), "translations.yml").toFile().exists()) saveResource("translations.yml", false);
if (!Path.of(getDataFolder().getPath() + "/cosmetics/").toFile().exists()) saveResource("cosmetics/defaultcosmetics.yml", false);
if (!Path.of(getDataFolder().getPath() + "/menus/").toFile().exists()) saveResource("menus/defaultmenu.yml", false);
// Emote folder setup
File emoteFile = new File(getDataFolder().getPath() + "/emotes");
if (!emoteFile.exists()) emoteFile.mkdir();
// Player Animator
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();
// Commands
@@ -84,15 +98,15 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
// Listener
getServer().getPluginManager().registerEvents(new PlayerConnectionListener(), this);
getServer().getPluginManager().registerEvents(new PlayerGameListener(), this);
// Taken from PaperLib
if (HibiscusCommonsPlugin.isOnPaper()) {
getServer().getPluginManager().registerEvents(new PaperPlayerGameListener(), this);
}
// Database
new Database();
// PAPI
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
new PAPIHook().register();
}
if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null) {
// WorldGuard
if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null && Settings.isWorldGuardMoveCheck()) {
getServer().getPluginManager().registerEvents(new WGListener(), this);
}
}
@@ -106,12 +120,19 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
}
@Override
public void onDisable() {
disable = true;
for (Player player : Bukkit.getOnlinePlayers()) {
Database.save(player);
}
public void onEnd() {
// Plugin shutdown logic
for (Player player : Bukkit.getOnlinePlayers()) {
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) continue;
if (user.getUserEmoteManager().isPlayingEmote()) {
player.setInvisible(false);
}
if (user.isInWardrobe()) {
user.leaveWardrobe(true);
}
Database.save(user);
}
}
public static HMCCosmeticsPlugin getInstance() {
@@ -138,7 +159,7 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
WardrobeSettings.load(loader.load().node("wardrobe"));
DatabaseSettings.load(loader.load().node("database-settings"));
configLoader = loader;
} catch (ConfigurateException e) {
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -173,9 +194,6 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
throw new RuntimeException(e);
}
// ItemHooks
ItemHooks.setup();
// Cosmetics setup
Cosmetics.setup();
@@ -204,29 +222,21 @@ public final class HMCCosmeticsPlugin extends JavaPlugin {
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()));
}
}
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(Cosmetics.values().size() + " Cosmetics Successfully Setup");
getInstance().getLogger().info(Menus.getMenuNames().size() + " Menus Successfully Setup");
getInstance().getLogger().info(WardrobeSettings.getWardrobes().size() + " Wardrobes Successfully Setup");
getInstance().getLogger().info("Data storage is set to " + DatabaseSettings.getDatabaseType());
Bukkit.getPluginManager().callEvent(new HMCCosmeticSetupEvent());
}
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);
}
}
}

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,19 +1,26 @@
package com.hibiscusmc.hmccosmetics.command;
import com.hibiscusmc.hmccolor.HMCColorConfig;
import com.hibiscusmc.hmccolor.HMCColorContextKt;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.config.WardrobeLocation;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticEmoteType;
import com.hibiscusmc.hmccosmetics.database.Database;
import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.gui.special.DyeMenu;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.ServerUtils;
import com.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.TagResolver;
import org.apache.commons.lang3.EnumUtils;
@@ -26,13 +33,17 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
public class CosmeticCommand implements CommandExecutor {
// cosmetics apply cosmetics playerName
// 0 1 2
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String @NotNull [] args) {
boolean silent = false;
if (args.length == 0) {
if (!(sender instanceof Player)) {
// Console
@@ -44,7 +55,7 @@ public class CosmeticCommand implements CommandExecutor {
}
CosmeticUser user = CosmeticUsers.getUser(((Player) sender).getUniqueId());
Menu menu = Menus.getMenu(Settings.getDefaultMenu());
Menu menu = Menus.getDefaultMenu();
if (user == null) {
MessagesUtil.sendMessage(sender, "invalid-player");
@@ -62,49 +73,75 @@ public class CosmeticCommand implements CommandExecutor {
Player player = sender instanceof Player ? (Player) sender : null;
String firstArgs = args[0].toLowerCase();
if (sender.hasPermission("HMCCosmetics.cmd.silent") || sender.isOp()) {
for (String singleArg : args) {
if (singleArg.equalsIgnoreCase("-s")) {
silent = true;
break;
}
}
}
switch (firstArgs) {
case ("reload") -> {
if (!sender.hasPermission("HMCCosmetics.cmd.reload") || !sender.isOp()) {
MessagesUtil.sendMessage(sender, "no-permission");
if (!sender.hasPermission("HMCCosmetics.cmd.reload") && !sender.isOp()) {
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
HMCCosmeticsPlugin.setup();
MessagesUtil.sendMessage(sender, "reloaded");
if (!silent) MessagesUtil.sendMessage(sender, "reloaded");
return true;
}
case ("apply") -> {
if (!sender.hasPermission("hmccosmetics.cmd.apply")) {
MessagesUtil.sendMessage(sender, "no-permission");
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
Cosmetic cosmetic;
Color color = null;
if (sender instanceof Player) player = ((Player) sender).getPlayer();
if (sender.hasPermission("hmccosmetics.cmd.apply.other")) {
if (args.length >= 3) player = Bukkit.getPlayer(args[2]);
}
if (sender.hasPermission("hmccosmetics.cmd.apply.color")) {
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) {
color = colors.getBaseColor().getColor();
}
} else {
color = HMCCServerUtils.hex2Rgb(textColor);
}
}
}
if (args.length == 1) {
MessagesUtil.sendMessage(player, "not-enough-args");
if (!silent) MessagesUtil.sendMessage(player, "not-enough-args");
return true;
}
cosmetic = Cosmetics.getCosmetic(args[1]);
if (cosmetic == null) {
MessagesUtil.sendMessage(sender, "invalid-cosmetic");
if (!silent) MessagesUtil.sendMessage(sender, "invalid-cosmetic");
return true;
}
if (player == null) {
MessagesUtil.sendMessage(sender, "invalid-player");
if (!silent) MessagesUtil.sendMessage(sender, "invalid-player");
return true;
}
CosmeticUser user = CosmeticUsers.getUser(player);
if (!user.canEquipCosmetic(cosmetic)) {
MessagesUtil.sendMessage(player, "no-cosmetic-permission");
if (!silent) MessagesUtil.sendMessage(player, "no-cosmetic-permission");
return true;
}
@@ -113,84 +150,106 @@ public class CosmeticCommand implements CommandExecutor {
TagResolver.resolver(Placeholder.parsed("player", player.getName())),
TagResolver.resolver(Placeholder.parsed("cosmeticslot", cosmetic.getSlot().name())));
MessagesUtil.sendMessage(player, "equip-cosmetic", placeholders);
if (!silent) MessagesUtil.sendMessage(player, "equip-cosmetic", placeholders);
user.addPlayerCosmetic(cosmetic);
user.addPlayerCosmetic(cosmetic, color);
user.updateCosmetic(cosmetic.getSlot());
return true;
}
case ("unapply") -> {
if (!sender.hasPermission("hmccosmetics.cmd.unapply")) {
MessagesUtil.sendMessage(sender, "no-permission");
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
if (args.length == 1) {
MessagesUtil.sendMessage(player, "not-enough-args");
if (!silent) MessagesUtil.sendMessage(player, "not-enough-args");
return true;
}
CosmeticSlot cosmeticSlot = null;
if (sender instanceof Player) player = ((Player) sender).getPlayer();
if (sender.hasPermission("hmccosmetics.cmd.unapply.other")) {
if (args.length >= 3) player = Bukkit.getPlayer(args[2]);
}
if (!EnumUtils.isValidEnum(CosmeticSlot.class, args[1].toUpperCase())) {
MessagesUtil.sendMessage(sender, "invalid-slot");
return true;
}
cosmeticSlot = CosmeticSlot.valueOf(args[1].toUpperCase());
if (player == null) {
MessagesUtil.sendMessage(sender, "invalid-player");
if (!silent) MessagesUtil.sendMessage(sender, "invalid-player");
return true;
}
CosmeticUser user = CosmeticUsers.getUser(player);
if (user.getCosmetic(cosmeticSlot) == null) {
MessagesUtil.sendMessage(sender, "no-cosmetic-slot");
return true;
Set<CosmeticSlot> cosmeticSlots;
if (args[1].equalsIgnoreCase("all")) {
cosmeticSlots = user.getSlotsWithCosmetics();
} else {
if (!EnumUtils.isValidEnum(CosmeticSlot.class, args[1].toUpperCase())) {
if (!silent) MessagesUtil.sendMessage(sender, "invalid-slot");
return true;
}
cosmeticSlots = Set.of(CosmeticSlot.valueOf(args[1].toUpperCase()));
}
TagResolver placeholders =
TagResolver.resolver(Placeholder.parsed("cosmetic", user.getCosmetic(cosmeticSlot).getId()),
TagResolver.resolver(Placeholder.parsed("player", player.getName())),
TagResolver.resolver(Placeholder.parsed("cosmeticslot", cosmeticSlot.name())));
for (CosmeticSlot cosmeticSlot : cosmeticSlots) {
if (user.getCosmetic(cosmeticSlot) == null) {
if (!silent) MessagesUtil.sendMessage(sender, "no-cosmetic-slot");
continue;
}
MessagesUtil.sendMessage(player, "unequip-cosmetic", placeholders);
TagResolver placeholders =
TagResolver.resolver(Placeholder.parsed("cosmetic", user.getCosmetic(cosmeticSlot).getId()),
TagResolver.resolver(Placeholder.parsed("player", player.getName())),
TagResolver.resolver(Placeholder.parsed("cosmeticslot", cosmeticSlot.name())));
user.removeCosmeticSlot(cosmeticSlot);
user.updateCosmetic(cosmeticSlot);
if (!silent) MessagesUtil.sendMessage(player, "unequip-cosmetic", placeholders);
user.removeCosmeticSlot(cosmeticSlot);
user.updateCosmetic(cosmeticSlot);
}
return true;
}
case ("wardrobe") -> {
if (sender instanceof Player) player = ((Player) sender).getPlayer();
if (args.length == 1) {
if (!silent) MessagesUtil.sendMessage(player, "not-enough-args");
return true;
}
if (sender.hasPermission("hmccosmetics.cmd.wardrobe.other")) {
if (args.length >= 2) player = Bukkit.getPlayer(args[1]);
if (args.length >= 3) player = Bukkit.getPlayer(args[2]);
}
if (!sender.hasPermission("hmccosmetics.cmd.wardrobe")) {
MessagesUtil.sendMessage(sender, "no-permission");
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
if (player == null) {
MessagesUtil.sendMessage(sender, "invalid-player");
if (!silent) MessagesUtil.sendMessage(sender, "invalid-player");
return true;
}
if (!WardrobeSettings.getWardrobeNames().contains(args[1])) {
if (!silent) MessagesUtil.sendMessage(sender, "no-wardrobes");
return true;
}
Wardrobe wardrobe = WardrobeSettings.getWardrobe(args[1]);
CosmeticUser user = CosmeticUsers.getUser(player);
user.toggleWardrobe();
if (user.isInWardrobe()) {
user.leaveWardrobe();
} else {
user.enterWardrobe(false, wardrobe);
}
return true;
}
// cosmetic menu exampleMenu playerName
case ("menu") -> {
if (args.length == 1) return true;
if (!sender.hasPermission("hmccosmetics.cmd.menu")) {
MessagesUtil.sendMessage(sender, "no-permission");
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
Menu menu = Menus.getMenu(args[1]);
@@ -202,12 +261,12 @@ public class CosmeticCommand implements CommandExecutor {
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) {
MessagesUtil.sendMessage(sender, "invalid-player");
if (!silent) MessagesUtil.sendMessage(sender, "invalid-player");
return true;
}
if (menu == null) {
MessagesUtil.sendMessage(sender, "invalid-menu");
if (!silent) MessagesUtil.sendMessage(sender, "invalid-menu");
return true;
}
@@ -217,9 +276,8 @@ public class CosmeticCommand implements CommandExecutor {
case ("dataclear") -> {
if (args.length == 1) return true;
OfflinePlayer selectedPlayer = Bukkit.getOfflinePlayer(args[1]);
if (selectedPlayer == null) return true;
if (!sender.hasPermission("hmccosmetics.cmd.dataclear") && !sender.isOp()) {
MessagesUtil.sendMessage(sender, "no-permission");
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
Database.clearData(selectedPlayer.getUniqueId());
@@ -231,30 +289,30 @@ public class CosmeticCommand implements CommandExecutor {
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return true;
if (!sender.hasPermission("hmccosmetics.cmd.dye") && !sender.isOp()) {
MessagesUtil.sendMessage(sender, "no-permission");
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
if (args.length == 1) {
MessagesUtil.sendMessage(player, "not-enough-args");
if (!silent) MessagesUtil.sendMessage(player, "not-enough-args");
return true;
}
if (!EnumUtils.isValidEnum(CosmeticSlot.class, args[1])) {
MessagesUtil.sendMessage(player, "invalid-slot");
if (!silent) MessagesUtil.sendMessage(player, "invalid-slot");
return true;
}
CosmeticSlot slot = CosmeticSlot.valueOf(args[1]);
Cosmetic cosmetic = user.getCosmetic(slot);
if (args.length >= 3) {
if (!args[2].contains("#") || args[2].isEmpty()) {
MessagesUtil.sendMessage(player, "invalid-color");
if (args[2].isEmpty()) {
if (!silent) MessagesUtil.sendMessage(player, "invalid-color");
return true;
}
Color color = ServerUtils.hex2Rgb(args[2]);
Color color = HMCCServerUtils.hex2Rgb(args[2]);
if (color == null) {
MessagesUtil.sendMessage(player, "invalid-color");
if (!silent) MessagesUtil.sendMessage(player, "invalid-color");
return true;
}
user.addPlayerCosmetic(cosmetic, color); // #FFFFFF
@@ -262,35 +320,55 @@ public class CosmeticCommand implements CommandExecutor {
DyeMenu.openMenu(user, cosmetic);
}
}
case ("setlocation") -> {
if (!sender.hasPermission("hmccosmetics.cmd.setlocation")) {
MessagesUtil.sendMessage(sender, "no-permission");
case ("setwardrobesetting") -> {
if (!sender.hasPermission("hmccosmetics.cmd.setwardrobesetting")) {
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
if (player == null) return true;
if (args.length < 2) {
MessagesUtil.sendMessage(player, "not-enough-args");
if (args.length < 3) {
if (!silent) MessagesUtil.sendMessage(player, "not-enough-args");
return true;
}
Wardrobe wardrobe = WardrobeSettings.getWardrobe(args[1]);
if (wardrobe == null) {
wardrobe = new Wardrobe(args[1], new WardrobeLocation(null, null, null), null, -1);
WardrobeSettings.addWardrobe(wardrobe);
//MessagesUtil.sendMessage(player, "no-wardrobes");
//return true;
}
if (args[2].equalsIgnoreCase("npclocation")) {
WardrobeSettings.setNPCLocation(wardrobe, player.getLocation());
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-location");
return true;
}
if (args[1].equalsIgnoreCase("wardrobelocation")) {
WardrobeSettings.setWardrobeLocation(player.getLocation());
MessagesUtil.sendMessage(player, "set-wardrobe-location");
if (args[2].equalsIgnoreCase("viewerlocation")) {
WardrobeSettings.setViewerLocation(wardrobe, player.getEyeLocation());
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-viewing");
return true;
}
if (args[1].equalsIgnoreCase("viewerlocation")) {
WardrobeSettings.setViewerLocation(player.getLocation());
MessagesUtil.sendMessage(player, "set-wardrobe-viewing");
if (args[2].equalsIgnoreCase("leavelocation")) {
WardrobeSettings.setLeaveLocation(wardrobe, player.getLocation());
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-leaving");
return true;
}
if (args[1].equalsIgnoreCase("leavelocation")) {
WardrobeSettings.setLeaveLocation(player.getLocation());
MessagesUtil.sendMessage(player, "set-wardrobe-leaving");
return true;
if (args.length >= 4) {
if (args[2].equalsIgnoreCase("permission")) {
WardrobeSettings.setWardrobePermission(wardrobe, args[3]);
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-permission");
return true;
}
if (args[2].equalsIgnoreCase("distance")) {
WardrobeSettings.setWardrobeDistance(wardrobe, Integer.parseInt(args[3]));
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-distance");
return true;
}
}
}
case ("dump") -> {
@@ -298,14 +376,14 @@ public class CosmeticCommand implements CommandExecutor {
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return true;
if (!sender.hasPermission("HMCCosmetic.cmd.dump") && !sender.isOp()) {
MessagesUtil.sendMessage(sender, "no-permission");
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
player.sendMessage("Passengers -> " + player.getPassengers());
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
player.sendMessage("Backpack Location -> " + user.getBackpackEntity().getLocation());
player.sendMessage("Backpack Location -> " + user.getUserBackpackManager().getEntityManager().getLocation());
}
player.sendMessage("Cosmetics -> " + user.getCosmetic());
player.sendMessage("Cosmetics -> " + user.getCosmetics());
player.sendMessage("EntityId -> " + player.getEntityId());
return true;
}
@@ -316,19 +394,18 @@ public class CosmeticCommand implements CommandExecutor {
}
if (!sender.hasPermission("hmccosmetics.cmd.hide")) {
MessagesUtil.sendMessage(sender, "no-permission");
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
if (player == null) {
MessagesUtil.sendMessage(sender, "invalid-player");
if (!silent) MessagesUtil.sendMessage(sender, "invalid-player");
return true;
}
CosmeticUser user = CosmeticUsers.getUser(player);
MessagesUtil.sendMessage(sender, "hide-cosmetic");
user.hideCosmetics();
if (!silent) MessagesUtil.sendMessage(sender, "hide-cosmetic");
user.hideCosmetics(CosmeticUser.HiddenReason.COMMAND);
return true;
}
case ("show") -> {
@@ -338,36 +415,144 @@ public class CosmeticCommand implements CommandExecutor {
}
if (!sender.hasPermission("hmccosmetics.cmd.show")) {
MessagesUtil.sendMessage(sender, "no-permission");
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
if (player == null) {
MessagesUtil.sendMessage(sender, "invalid-player");
if (!silent) MessagesUtil.sendMessage(sender, "invalid-player");
return true;
}
CosmeticUser user = CosmeticUsers.getUser(player);
MessagesUtil.sendMessage(sender, "show-cosmetic");
user.showCosmetics();
if (!silent) MessagesUtil.sendMessage(sender, "show-cosmetic");
user.showCosmetics(CosmeticUser.HiddenReason.COMMAND);
return true;
}
case ("debug") -> {
if (!sender.hasPermission("hmccosmetics.cmd.debug")) {
MessagesUtil.sendMessage(sender, "no-permission");
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
if (Settings.getDebugMode()) {
if (Settings.isDebugMode()) {
Settings.setDebugMode(false);
MessagesUtil.sendMessage(sender, "debug-disabled");
if (!silent) MessagesUtil.sendMessage(sender, "debug-disabled");
} else {
Settings.setDebugMode(true);
MessagesUtil.sendMessage(sender, "debug-enabled");
if (!silent) MessagesUtil.sendMessage(sender, "debug-enabled");
}
}
case ("emote") -> {
if (!sender.hasPermission("hmccosmetics.cmd.emote")) {
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
if (sender.hasPermission("hmccosmetics.cmd.emote.other")) {
if (args.length >= 2) player = Bukkit.getPlayer(args[1]);
}
if (player == null) {
if (!silent) MessagesUtil.sendMessage(sender, "invalid-player");
return true;
}
CosmeticUser user = CosmeticUsers.getUser(player);
if (!user.hasCosmeticInSlot(CosmeticSlot.EMOTE)) {
if (!silent) MessagesUtil.sendMessage(sender, "emote-none");
return true;
}
CosmeticEmoteType cosmeticEmoteType = (CosmeticEmoteType) user.getCosmetic(CosmeticSlot.EMOTE);
cosmeticEmoteType.run(user);
return true;
}
case ("playemote") -> {
// /cosmetic playEmote <emoteId> [playerName]
if (!sender.hasPermission("hmccosmetics.cmd.playemote")) {
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
if (args.length < 2) {
if (!silent) MessagesUtil.sendMessage(player, "not-enough-args");
return true;
}
if (!EmoteManager.has(args[1])) {
MessagesUtil.sendDebugMessages("Did not contain " + args[1]);
if (!silent) MessagesUtil.sendMessage(sender, "emote-invalid");
return true;
}
if (sender.hasPermission("hmccosmetics.cmd.playemote.other")) {
if (args.length >= 3) player = Bukkit.getPlayer(args[2]);
}
if (player == null) {
if (!silent) MessagesUtil.sendMessage(sender, "invalid-player");
return true;
}
CosmeticUser user = CosmeticUsers.getUser(player);
user.getUserEmoteManager().playEmote(args[1]);
return true;
}
case "disableall" -> {
if (!sender.hasPermission("hmccosmetics.cmd.disableall")) {
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
if (args.length == 1) {
if (!silent) MessagesUtil.sendMessage(player, "not-enough-args");
return true;
}
if (args[1].equalsIgnoreCase("true")) {
Settings.setAllPlayersHidden(true);
for (CosmeticUser user : CosmeticUsers.values()) user.hideCosmetics(CosmeticUser.HiddenReason.DISABLED);
if (!silent) MessagesUtil.sendMessage(sender, "disabled-all");
} else if (args[1].equalsIgnoreCase("false")) {
Settings.setAllPlayersHidden(false);
for (CosmeticUser user : CosmeticUsers.values()) user.showCosmetics(CosmeticUser.HiddenReason.DISABLED);
if (!silent) MessagesUtil.sendMessage(sender, "enabled-all");
} else {
if (!silent) MessagesUtil.sendMessage(sender, "invalid-args");
}
return true;
}
case "hiddenreasons" -> {
if (!sender.hasPermission("hmccosmetics.cmd.hiddenreasons")) {
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
if (args.length >= 2) {
player = Bukkit.getPlayer(args[1]);
}
if (player == null) {
if (!silent) MessagesUtil.sendMessage(sender, "invalid-player");
return true;
}
CosmeticUser user = CosmeticUsers.getUser(player);
sender.sendMessage(user.getHiddenReasons().toString());
return true;
}
case "clearhiddenreasons" -> {
if (!sender.hasPermission("hmccosmetics.cmd.clearhiddenreasons")) {
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
return true;
}
if (args.length >= 2) {
player = Bukkit.getPlayer(args[1]);
}
if (player == null) {
if (!silent) MessagesUtil.sendMessage(sender, "invalid-player");
return true;
}
CosmeticUser user = CosmeticUsers.getUser(player);
user.clearHiddenReasons();
return true;
}
}
return true;
}

View File

@@ -1,12 +1,17 @@
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.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import me.lojosho.hibiscuscommons.hooks.Hooks;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -23,9 +28,9 @@ import java.util.List;
public class CosmeticCommandTabComplete implements TabCompleter {
@Nullable
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String @NotNull [] args) {
List<String> completions = new ArrayList<>();
List<String> finalCompletitons = new ArrayList<>();
List<String> finalCompletions = new ArrayList<>();
if (args.length == 1) {
if (hasPermission(sender, "hmccosmetics.cmd.apply")) completions.add("apply");
@@ -35,16 +40,22 @@ public class CosmeticCommandTabComplete implements TabCompleter {
if (hasPermission(sender, "hmccosmetics.cmd.wardrobe")) completions.add("wardrobe");
if (hasPermission(sender, "hmccosmetics.cmd.dataclear")) completions.add("dataclear");
if (hasPermission(sender, "hmccosmetics.cmd.dye")) completions.add("dye");
if (hasPermission(sender, "hmccosmetics.cmd.setlocation")) completions.add("setlocation");
if (hasPermission(sender, "hmccosmetics.cmd.setwardrobesetting")) completions.add("setwardrobesetting");
if (hasPermission(sender, "hmccosmetics.cmd.hide")) completions.add("hide");
if (hasPermission(sender, "hmccosmetics.cmd.show")) completions.add("show");
if (hasPermission(sender, "hmccosmetics.cmd.debug")) completions.add("debug");
if (hasPermission(sender, "hmccosmetics.cmd.emote")) completions.add("emote");
if (hasPermission(sender, "hmccosmetics.cmd.playemote")) completions.add("playemote");
if (hasPermission(sender, "hmccosmetics.cmd.disableall")) completions.add("disableall");
if (hasPermission(sender, "hmccosmetics.cmd.hiddenreasons")) completions.add("hiddenreasons");
if (hasPermission(sender, "hmccosmetics.cmd.clearhiddenreasons")) completions.add("clearhiddenreasons");
StringUtil.copyPartialMatches(args[0], completions, finalCompletitons);
StringUtil.copyPartialMatches(args[0], completions, finalCompletions);
}
if (!(sender instanceof Player)) return completions;
CosmeticUser user = CosmeticUsers.getUser(((Player) sender).getUniqueId());
if (user == null) return completions; // User hasn't loaded in yet, can't do proper checks
if (args.length == 2) {
String subcommand = args[0].toLowerCase();
@@ -53,32 +64,47 @@ public class CosmeticCommandTabComplete implements TabCompleter {
completions.addAll(applyCommandComplete(user, args));
}
case "unapply" -> {
for (Cosmetic cosmetic : user.getCosmetic()) {
for (Cosmetic cosmetic : user.getCosmetics()) {
completions.add(cosmetic.getSlot().toString().toUpperCase());
}
completions.add("ALL");
}
case "menu" -> {
for (Menu menu : Menus.getMenu()) {
if (menu.canOpen(user.getPlayer())) completions.add(menu.getId());
}
}
case "dataclear", "wardrobe", "hide", "show" -> {
case "dataclear", "hide", "show", "emote", "hiddenreasons", "clearhiddenreasons" -> {
for (Player player : Bukkit.getOnlinePlayers()) {
completions.add(player.getName());
}
}
case "disableall" -> {
completions.add("true");
completions.add("false");
}
case "wardrobe" -> {
for (Wardrobe wardrobe : WardrobeSettings.getWardrobes()) {
if (wardrobe.hasPermission()) {
if (user.getPlayer().hasPermission(wardrobe.getPermission())) completions.add(wardrobe.getId());
} else {
completions.add(wardrobe.getId());
}
}
}
case "dye" -> {
for (CosmeticSlot slot : user.getDyeableSlots()) {
completions.add(slot.name());
}
}
case "setlocation" -> {
completions.add("wardrobelocation");
completions.add("viewerlocation");
completions.add("leavelocation");
case "setwardrobesetting" -> {
for (Wardrobe wardrobe : WardrobeSettings.getWardrobes()) {
completions.add(wardrobe.getId());
}
}
case "playemote" -> completions.addAll(EmoteManager.getAllNames());
}
StringUtil.copyPartialMatches(args[1], completions, finalCompletitons);
StringUtil.copyPartialMatches(args[1], completions, finalCompletions);
}
if (args.length == 3) {
String subcommand = args[0].toLowerCase();
@@ -86,21 +112,39 @@ public class CosmeticCommandTabComplete implements TabCompleter {
case "dye" -> {
completions.add("#FFFFFF");
}
case "menu", "apply", "unapply" -> {
case "menu", "wardrobe", "apply", "unapply", "playemote" -> {
for (Player player : Bukkit.getOnlinePlayers()) {
completions.add(player.getName());
}
}
case "setwardrobesetting" -> {
completions.add("npclocation");
completions.add("viewerlocation");
completions.add("leavelocation");
completions.add("permission");
completions.add("distance");
}
}
StringUtil.copyPartialMatches(args[2], completions, finalCompletitons);
StringUtil.copyPartialMatches(args[2], completions, finalCompletions);
}
Collections.sort(finalCompletitons);
return finalCompletitons;
if (args.length == 4) {
String subcommand = args[0].toLowerCase();
switch (subcommand) {
case "apply" -> {
if (Hooks.isActiveHook("HMCColor")) completions.addAll(HMCColorContextKt.getHmcColor().getConfig().getColors().keySet());
completions.add("#FFFFFF");
}
}
StringUtil.copyPartialMatches(args[3], completions, finalCompletions);
}
Collections.sort(finalCompletions);
return finalCompletions;
}
private static List<String> applyCommandComplete(CosmeticUser user, String[] args) {
@NotNull
private static List<String> applyCommandComplete(CosmeticUser user, String @NotNull [] args) {
List<String> completitions = new ArrayList<>();
if (args.length == 2) {
@@ -119,7 +163,7 @@ public class CosmeticCommandTabComplete implements TabCompleter {
return completitions;
}
private boolean hasPermission(CommandSender sender, String permission) {
private boolean hasPermission(@NotNull CommandSender sender, String permission) {
if (sender.isOp()) return true;
if (sender.hasPermission(permission)) return true;
return false;

View File

@@ -1,10 +1,10 @@
package com.hibiscusmc.hmccosmetics.config;
import org.spongepowered.configurate.ConfigurationNode;
import lombok.Getter;
import me.lojosho.shaded.configurate.ConfigurationNode;
public class DatabaseSettings {
//private static final String DATABASE_SETTINGS_PATH = "cosmetic-settings";
private static final String DATABASE_TYPE_PATH = "type";
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 DELAY_LENGTH = "delay";
@Getter
private static String databaseType;
@Getter
private static String database;
@Getter
private static String password;
@Getter
private static String host;
@Getter
private static String username;
@Getter
private static int port;
@Getter
private static boolean enabledDelay;
@Getter
private static int delayLength;
public static void load(ConfigurationNode source) {
//ConfigurationNode databaseSettings = source.node(DATABASE_SETTINGS_PATH);
databaseType = source.node(DATABASE_TYPE_PATH).getString();
ConfigurationNode mySql = source.node(MYSQL_DATABASE_SETTINGS);
@@ -44,36 +50,4 @@ public class DatabaseSettings {
enabledDelay = delay.node(ENABLE_DELAY).getBoolean(false);
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,10 +1,16 @@
package com.hibiscusmc.hmccosmetics.config;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import lombok.Getter;
import lombok.Setter;
import me.lojosho.shaded.configurate.ConfigurationNode;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.util.Vector;
import org.spongepowered.configurate.ConfigurationNode;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
public class Settings {
@@ -12,37 +18,151 @@ public class Settings {
private static final String DEFAULT_MENU = "default-menu";
private static final String CONFIG_VERSION = "config-version";
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 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 PARTICLE_COUNT = "particle-count";
private static final String DYE_MENU_PATH = "dye-menu";
private static final String DYE_MENU_NAME = "title";
private static final String DYE_MENU_INPUT_SLOT = "input-slot";
private static final String DYE_MENU_OUTPUT_SLOT = "output-slot";
private static final String DEBUG_ENABLE_PETH = "debug-mode";
private static final String TICK_PERIOD_PATH = "tick-period";
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_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 HOOK_SETTING_PATH = "hook-settings";
private static final String HOOK_ITEMADDER_PATH = "itemsadder";
private static final String HOOK_RELOAD_CHANGE_PATH = "reload-on-change";
private static final String HOOK_WORLDGUARD_PATH = "worldguard";
private static final String HOOK_WG_MOVE_CHECK_PATH = "player-move-check";
private static final String HOOK_WG_MOVE_CHECK_PATH_LEGACY = "player_move_check";
private static final String COSMETIC_EMOTE_ENABLE = "emote-enable";
private static final String COSMETIC_EMOTE_CHECK_PATH = "emote-block-check";
private static final String COSMETIC_EMOTE_AIR_CHECK_PATH = "emote-air-check";
private static final String COSMETIC_EMOTE_DAMAGE_PATH = "emote-damage-leave";
private static final String COSMETIC_EMOTE_INVINCIBLE_PATH = "emote-invincible";
private static final String COSMETIC_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_CHESTPLATE_PATH = "chest-add-enchantments";
private static final String COSMETIC_ADD_ENCHANTS_LEGGINGS_PATH = "leggings-add-enchantments";
private static final String COSMETIC_ADD_ENCHANTS_BOOTS_PATH = "boots-add-enchantments";
private static final String COSMETIC_DESTROY_LOOSE_COSMETIC_PATH = "destroy-loose-cosmetics";
private static final String COSMETIC_BALLOON_HEAD_FORWARD_PATH = "balloon-head-forward";
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;
@Getter
private static String dyeMenuName;
@Getter
private static int dyeMenuInputSlot;
@Getter
private static int dyeMenuOutputSlot;
@Getter
private static int configVersion;
private static boolean requireEmptyHelmet;
private static boolean requireEmptyOffHand;
private static boolean requireEmptyChestPlate;
private static boolean requireEmptyPants;
private static boolean requireEmptyBoots;
@Getter
private static boolean debugMode;
@Getter
private static boolean unapplyOnDeath;
private static int lookDownPitch;
@Getter
private static boolean forcePermissionJoin;
@Getter
private static boolean forceShowOnJoin;
@Getter
private static boolean itemsAdderChangeReload;
@Getter
private static boolean worldGuardMoveCheck;
@Getter
private static boolean cosmeticEmoteBlockCheck;
@Getter
private static boolean addHelmetEnchants;
@Getter
private static boolean addChestplateEnchants;
@Getter
private static boolean addLeggingEnchants;
@Getter
private static boolean addBootsEnchants;
@Getter
private static boolean emoteAirCheck;
@Getter
private static boolean emoteDamageLeave;
@Getter
private static boolean emoteInvincible;
@Getter
private static boolean destroyLooseCosmetics;
@Getter
private static boolean backpackForceRidingEnabled;
@Getter
private static boolean cosmeticForceOffhandCosmeticShow;
@Getter
private static boolean emotesEnabled;
@Getter
private static boolean disabledGamemodesEnabled;
@Getter
private static boolean balloonHeadForward;
@Getter
private static List<String> disabledGamemodes;
@Getter
private static List<String> disabledWorlds;
@Getter
private static int viewDistance;
@Getter
private static int tickPeriod;
@Getter
private static int packetEntityTeleportCooldown;
@Getter
private static double emoteDistance;
@Getter
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;
@Getter @Setter
private static boolean allPlayersHidden;
public static void load(ConfigurationNode source) {
@@ -61,132 +181,102 @@ public class Settings {
ConfigurationNode cosmeticSettings = source.node(COSMETIC_SETTINGS_PATH);
requireEmptyHelmet = cosmeticSettings.node(REQUIRE_EMPTY_HELMET_PATH).getBoolean();
requireEmptyOffHand = cosmeticSettings.node(REQUIRE_EMPTY_OFF_HAND_PATH).getBoolean();
requireEmptyChestPlate = cosmeticSettings.node(REQUIRE_EMPTY_CHEST_PLATE_PATH).getBoolean();
requireEmptyPants = cosmeticSettings.node(REQUIRE_EMPTY_PANTS_PATH).getBoolean();
requireEmptyBoots = cosmeticSettings.node(REQUIRE_EMPTY_BOOTS_PATH).getBoolean();
unapplyOnDeath = cosmeticSettings.node(UNAPPLY_DEATH_PATH).getBoolean(false);
ConfigurationNode disabledGamemodeSettings = cosmeticSettings.node(DISABLED_GAMEMODE_PATH);
disabledGamemodesEnabled = disabledGamemodeSettings.node(ENABLED_PATH).getBoolean(true);
try {
disabledGamemodes = disabledGamemodeSettings.node(DISABLED_GAMEMODE_GAMEMODES_PATH).getList(String.class);
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);
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);
cosmeticEmoteBlockCheck = cosmeticSettings.node(COSMETIC_EMOTE_CHECK_PATH).getBoolean(true);
emoteAirCheck = cosmeticSettings.node(COSMETIC_EMOTE_AIR_CHECK_PATH).getBoolean(true);
emoteDamageLeave = cosmeticSettings.node(COSMETIC_EMOTE_DAMAGE_PATH).getBoolean(false);
emoteInvincible = cosmeticSettings.node(COSMETIC_EMOTE_INVINCIBLE_PATH).getBoolean(false);
destroyLooseCosmetics = cosmeticSettings.node(COSMETIC_DESTROY_LOOSE_COSMETIC_PATH).getBoolean(false);
backpackForceRidingEnabled = cosmeticSettings.node(COSMETIC_BACKPACK_FORCE_RIDING_PACKET_PATH).getBoolean(false);
addHelmetEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_HELMET_PATH).getBoolean(false);
addChestplateEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_CHESTPLATE_PATH).getBoolean(false);
addLeggingEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_LEGGINGS_PATH).getBoolean(false);
addBootsEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_BOOTS_PATH).getBoolean(false);
tickPeriod = cosmeticSettings.node(TICK_PERIOD_PATH).getInt(-1);
lookDownPitch = cosmeticSettings.node(LOOK_DOWN_PITCH_PATH).getInt();
viewDistance = cosmeticSettings.node(VIEW_DISTANCE_PATH).getInt();
viewDistance = cosmeticSettings.node(VIEW_DISTANCE_PATH).getInt(-3);
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);
balloonHeadForward = cosmeticSettings.node(COSMETIC_BALLOON_HEAD_FORWARD_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);
balloonOffset = loadVector(balloonSection);
ConfigurationNode dyeMenuSettings = source.node(DYE_MENU_PATH);
dyeMenuName = dyeMenuSettings.node(DYE_MENU_NAME).getString("Dye Menu");
dyeMenuInputSlot = dyeMenuSettings.node(DYE_MENU_INPUT_SLOT).getInt(19);
dyeMenuOutputSlot = dyeMenuSettings.node(DYE_MENU_OUTPUT_SLOT).getInt(25);
ConfigurationNode hookSettings = source.node(HOOK_SETTING_PATH);
ConfigurationNode itemsAdderSettings = hookSettings.node(HOOK_ITEMADDER_PATH);
itemsAdderChangeReload = itemsAdderSettings.node(HOOK_RELOAD_CHANGE_PATH).getBoolean(false);
ConfigurationNode worldGuardSettings = hookSettings.node(HOOK_WORLDGUARD_PATH);
worldGuardMoveCheck = worldGuardSettings.node(HOOK_WG_MOVE_CHECK_PATH).getBoolean(true);
// I messed up in release 2.2.6 and forgot to change player_move_check to player-move-check.
if (!worldGuardSettings.node(HOOK_WG_MOVE_CHECK_PATH_LEGACY).virtual()) {
MessagesUtil.sendDebugMessages("There is a deprecated way of using WG hook setting. Change player_move_check to player-move-check in your configuration to prevent issues in the future. ", Level.WARNING);
worldGuardMoveCheck = worldGuardSettings.node(HOOK_WG_MOVE_CHECK_PATH_LEGACY).getBoolean(true);
}
}
private static Vector loadVector(final ConfigurationNode config) {
public static Vector loadVector(final ConfigurationNode config) {
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) {
public static boolean getShouldAddEnchants(EquipmentSlot slot) {
switch (slot) {
case HEAD -> {
return requireEmptyHelmet;
return addHelmetEnchants;
}
case CHEST -> {
return requireEmptyChestPlate;
return addChestplateEnchants;
}
case LEGS -> {
return requireEmptyPants;
return addLeggingEnchants;
}
case FEET -> {
return requireEmptyBoots;
return addBootsEnchants;
}
case OFF_HAND -> {
return requireEmptyOffHand;
default -> {
return false;
}
}
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 boolean isDebugEnabled() {
return debugMode;
}
public static int getTickPeriod() {
return tickPeriod;
}
public static boolean getUnapplyOnDeath() {
return unapplyOnDeath;
}
public static boolean getDebugMode() {
return debugMode;
}
public static void setDebugMode(boolean newSetting) {
debugMode = newSetting;

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,34 +1,50 @@
package com.hibiscusmc.hmccosmetics.config;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.serializer.LocationSerializer;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
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 org.apache.commons.lang3.EnumUtils;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
import java.util.logging.Level;
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 DISPLAY_RADIUS_PATH = "display-radius";
private static final String PORTABLE_PATH = "portable";
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 SPAWN_DELAY_PATH = "spawn-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 OPEN_SOUND = "open-sound";
private static final String CLOSE_SOUND = "close-sound";
private static final String STATIC_LOCATION_PATH = "wardrobe-location";
private static final String NPC_LOCATION_PATH = "npc-location";
private static final String VIEWER_LOCATION_PATH = "viewer-location";
private static final String LEAVE_LOCATION_PATH = "leave-location";
private static final String EQUIP_PUMPKIN_WARDROBE = "equip-pumpkin";
private static final String TRY_COSMETICS_WARDROBE = "unchecked-wardrobe-cosmetics";
private static final String RETURN_LAST_LOCATION = "return-last-location";
private static final String DAMAGE_KICK_PATH = "damage-kicked";
private static final String PREVENT_DAMAGE_PATH = "prevent-damage";
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 FORCE_EXIT_GAMEMODE_PATH = "exit-gamemode-enabled";
private static final String EXIT_GAMEMODE_PATH = "exit-gamemode";
private static final String WARDROBES_PATH = "wardrobes";
private static final String PERMISSION_PATH = "permission";
private static final String DISTANCE_PATH = "distance";
private static final String BOSSBAR_PATH = "bossbar";
private static final String BOSSBAR_ENABLE_PATH = "enabled";
private static final String BOSSBAR_TEXT_PATH = "text";
@@ -44,39 +60,65 @@ public class WardrobeSettings {
private static final String TRANSITION_FADE_OUT_PATH = "title-fade-out";
private static ConfigurationNode configRoot;
@Getter
private static boolean disableOnDamage;
private static int displayRadius;
@Getter
private static boolean portable;
@Getter
private static boolean alwaysDisplay;
private static int staticRadius;
@Getter
private static int rotationSpeed;
@Getter
private static int spawnDelay;
@Getter
private static int despawnDelay;
@Getter
private static float bossbarProgress;
@Getter
private static boolean applyCosmeticsOnClose;
@Getter
private static boolean tryCosmeticsInWardrobe;
@Getter
private static boolean equipPumpkin;
@Getter
private static boolean returnLastLocation;
@Getter
private static boolean enabledBossbar;
private static Location wardrobeLocation;
private static Location viewerLocation;
private static Location leaveLocation;
@Getter
private static boolean enterOpenMenu;
@Getter
private static boolean forceExitGamemode;
@Getter
private static boolean damagedKicked;
@Getter
private static boolean preventDamage;
@Getter
private static GameMode exitGamemode;
private static HashMap<String, Wardrobe> wardrobes;
@Getter
private static String bossbarMessage;
@Getter
private static BossBar.Overlay bossbarOverlay;
@Getter
private static BossBar.Color bossbarColor;
@Getter
private static boolean enabledTransition;
@Getter
private static String transitionText;
@Getter
private static int transitionDelay;
@Getter
private static int transitionFadeIn;
@Getter
private static int transitionStay;
@Getter
private static int transitionFadeOut;
public static void load(ConfigurationNode source) {
configRoot = source;
disableOnDamage = source.node(DISABLE_ON_DAMAGE_PATH).getBoolean();
displayRadius = source.node(DISPLAY_RADIUS_PATH).getInt();
portable = source.node(PORTABLE_PATH).getBoolean();
staticRadius = source.node(STATIC_RADIUS_PATH).getInt();
alwaysDisplay = source.node(ALWAYS_DISPLAY_PATH).getBoolean();
rotationSpeed = source.node(ROTATION_SPEED_PATH).getInt();
spawnDelay = source.node(SPAWN_DELAY_PATH).getInt();
@@ -84,6 +126,16 @@ public class WardrobeSettings {
applyCosmeticsOnClose = source.node(APPLY_COSMETICS_ON_CLOSE).getBoolean();
equipPumpkin = source.node(EQUIP_PUMPKIN_WARDROBE).getBoolean();
returnLastLocation = source.node(RETURN_LAST_LOCATION).getBoolean(false);
tryCosmeticsInWardrobe = source.node(TRY_COSMETICS_WARDROBE).getBoolean(false);
damagedKicked = source.node(DAMAGE_KICK_PATH).getBoolean(false);
preventDamage = source.node(PREVENT_DAMAGE_PATH).getBoolean(true);
ConfigurationNode menuOptionsNode = source.node(WARDROBE_MENU_OPTIONS);
enterOpenMenu = menuOptionsNode.node(WARDROBE_ENTER_OPEN_MENU_PATH).getBoolean(false);
ConfigurationNode gamemodeNode = source.node(GAMEMODE_OPTIONS_PATH);
forceExitGamemode = gamemodeNode.node(FORCE_EXIT_GAMEMODE_PATH).getBoolean(false);
exitGamemode = GameMode.valueOf(gamemodeNode.node(EXIT_GAMEMODE_PATH).getString("SURVIVAL"));
ConfigurationNode bossBarNode = source.node(BOSSBAR_PATH);
enabledBossbar = bossBarNode.node(BOSSBAR_ENABLE_PATH).getBoolean(false);
@@ -109,175 +161,123 @@ public class WardrobeSettings {
transitionStay = transitionNode.node(TRANSITION_STAY_PATH).getInt(2000);
transitionFadeOut = transitionNode.node(TRANSITION_FADE_OUT_PATH).getInt(2000);
try {
wardrobeLocation = LocationSerializer.INSTANCE.deserialize(Location.class, source.node(STATIC_LOCATION_PATH));
MessagesUtil.sendDebugMessages("Wardrobe Location: " + wardrobeLocation);
viewerLocation = LocationSerializer.INSTANCE.deserialize(Location.class, source.node(VIEWER_LOCATION_PATH));
MessagesUtil.sendDebugMessages("Viewer Location: " + viewerLocation);
leaveLocation = Utils.replaceIfNull(LocationSerializer.INSTANCE.deserialize(Location.class, source.node(LEAVE_LOCATION_PATH)), viewerLocation);
} catch (SerializationException e) {
throw new RuntimeException(e);
wardrobes = new HashMap<>();
for (ConfigurationNode wardrobesNode : source.node(WARDROBES_PATH).childrenMap().values()) {
String id = wardrobesNode.key().toString();
try {
Location npcLocation = LocationSerializer.INSTANCE.deserialize(Location.class, wardrobesNode.node(NPC_LOCATION_PATH));
MessagesUtil.sendDebugMessages("Wardrobe Location: " + npcLocation);
Location viewerLocation = LocationSerializer.INSTANCE.deserialize(Location.class, wardrobesNode.node(VIEWER_LOCATION_PATH));
MessagesUtil.sendDebugMessages("Viewer Location: " + viewerLocation);
Location leaveLocation = Utils.replaceIfNull(LocationSerializer.INSTANCE.deserialize(Location.class, wardrobesNode.node(LEAVE_LOCATION_PATH)), viewerLocation);
MessagesUtil.sendDebugMessages("Leave Location: " + leaveLocation);
WardrobeLocation wardrobeLocation = new WardrobeLocation(npcLocation, viewerLocation, leaveLocation);
String permission = 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() {
return disableOnDamage;
public static Wardrobe getWardrobe(String key) {
return wardrobes.get(key);
}
public static int getDisplayRadius() {
return displayRadius;
public static Set<String> getWardrobeNames() {
return wardrobes.keySet();
}
public static boolean isPortable() {
return portable;
public static Collection<Wardrobe> getWardrobes() {
return wardrobes.values();
}
public static boolean isAlwaysDisplay() {
return alwaysDisplay;
public static void addWardrobe(Wardrobe wardrobe) {
wardrobes.put(wardrobe.getId(), wardrobe);
}
public static int getStaticRadius() {
return staticRadius;
public static void removeWardrobe(String id) {
wardrobes.remove(id);
}
public static int getRotationSpeed() {
return rotationSpeed;
}
public static int getSpawnDelay() {
return spawnDelay;
}
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 false;
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 void setWardrobeLocation(Location newLocation) {
wardrobeLocation = newLocation;
/**
* Sets where the NPC/Mannequin will spawn in the wardrobe
* @param newLocation
*/
public static void setNPCLocation(Wardrobe wardrobe, Location newLocation) {
wardrobe.getLocation().setNpcLocation(newLocation);
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
plugin.getConfig().set("wardrobe.wardrobe-location." + "world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.wardrobe-location." + "x", newLocation.getX());
plugin.getConfig().set("wardrobe.wardrobe-location." + "y", newLocation.getY());
plugin.getConfig().set("wardrobe.wardrobe-location." + "z", newLocation.getZ());
plugin.getConfig().set("wardrobe.wardrobe-location." + "yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.wardrobe-location." + "pitch", newLocation.getPitch());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "x", newLocation.getX());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "y", newLocation.getY());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "z", newLocation.getZ());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".npc-location." + "pitch", newLocation.getPitch());
/* Configuration sets suck
source.node(WORLD).set(loc.getWorld().getName());
source.node(X).set(loc.getX());
source.node(Y).set(loc.getY());
source.node(Z).set(loc.getZ());
source.node(YAW).set(loc.getYaw());
source.node(PITCH).set(loc.getPitch());
*/
HMCCosmeticsPlugin.getInstance().saveConfig();
plugin.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();
plugin.getConfig().set("wardrobe.viewer-location." + "world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.viewer-location." + "x", newLocation.getX());
plugin.getConfig().set("wardrobe.viewer-location." + "y", newLocation.getY());
plugin.getConfig().set("wardrobe.viewer-location." + "z", newLocation.getZ());
plugin.getConfig().set("wardrobe.viewer-location." + "yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.viewer-location." + "pitch", newLocation.getPitch());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.x", newLocation.getX());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.y", newLocation.getY());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.z", newLocation.getZ());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".viewer-location.pitch", newLocation.getPitch());
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();
plugin.getConfig().set("wardrobe.leave-location." + "world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.leave-location." + "x", newLocation.getX());
plugin.getConfig().set("wardrobe.leave-location." + "y", newLocation.getY());
plugin.getConfig().set("wardrobe.leave-location." + "z", newLocation.getZ());
plugin.getConfig().set("wardrobe.leave-location." + "yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.leave-location." + "pitch", newLocation.getPitch());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.world", newLocation.getWorld().getName());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.x", newLocation.getX());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.y", newLocation.getY());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.z", newLocation.getZ());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.yaw", newLocation.getYaw());
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".leave-location.pitch", newLocation.getPitch());
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,145 +0,0 @@
package com.hibiscusmc.hmccosmetics.config.serializer;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.hooks.items.ItemHooks;
import com.hibiscusmc.hmccosmetics.util.builder.ColorBuilder;
import com.hibiscusmc.hmccosmetics.util.misc.StringUtils;
import com.hibiscusmc.hmccosmetics.util.misc.Utils;
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 = ItemHooks.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);
}
}
if (!itemFlagsNode.virtual()) {
for (ConfigurationNode flagNode : itemFlagsNode.childrenMap().values()) {
if (ItemFlag.valueOf(flagNode.key().toString()) == null) continue;
itemMeta.addItemFlags(ItemFlag.valueOf(flagNode.key().toString()));
}
}
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())) {
itemMeta = ColorBuilder.color(itemMeta, Color.fromRGB(redNode.getInt(0), greenNode.getInt(0), blueNode.getInt(0)));
}
}
NamespacedKey key = new NamespacedKey(HMCCosmeticsPlugin.getInstance(), source.key().toString());
itemMeta.getPersistentDataContainer().set(key, PersistentDataType.STRING, source.key().toString());
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,83 +1,61 @@
package com.hibiscusmc.hmccosmetics.cosmetic;
import com.hibiscusmc.hmccosmetics.config.serializer.ItemSerializer;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
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.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import java.util.logging.Level;
public class Cosmetic {
public abstract class Cosmetic {
@Getter @Setter
private String id;
@Getter @Setter
private String permission;
private ItemStack item;
@Getter @Setter
private String material;
@Getter @Setter
private CosmeticSlot slot;
@Getter @Setter
private boolean dyable;
protected Cosmetic(String id, ConfigurationNode config) {
protected Cosmetic(String id, @NotNull ConfigurationNode config) {
this.id = id;
if (!config.node("permission").virtual()) {
this.permission = config.node("permission").getString();
} else {
this.permission = null;
}
if (!config.node("item").virtual()) this.item = generateItemStack(config.node("item"));
if (!config.node("item").virtual()) {
this.material = config.node("item", "material").getString();
this.item = generateItemStack(config.node("item"));
}
MessagesUtil.sendDebugMessages("Slot: " + config.node("slot").getString());
setSlot(CosmeticSlot.valueOf(config.node("slot").getString()));
setSlot(CosmeticSlot.valueOf(config.node("slot").getString()));
setDyable(config.node("dyeable").getBoolean(false));
MessagesUtil.sendDebugMessages("Dyeable " + dyable);
Cosmetics.addCosmetic(this);
}
public String getId() {
return this.id;
}
public String getPermission() {
return this.permission;
}
public CosmeticSlot getSlot() {
return this.slot;
}
public void setSlot(CosmeticSlot slot) {
this.slot = slot;
}
public void setPermission(String permission) {
this.permission = permission;
}
public boolean requiresPermission() {
if (permission == null) return false;
return true;
return permission != null;
}
public void setId(String id) {
this.id = id;
}
public void setDyable(boolean dyable) {
this.dyable = dyable;
}
public boolean isDyable() {
return this.dyable;
}
public void update(CosmeticUser user) {
// Override
}
public abstract void update(CosmeticUser user);
@Nullable
public ItemStack getItem() {

View File

@@ -8,5 +8,6 @@ public enum CosmeticSlot {
MAINHAND,
OFFHAND,
BACKPACK,
BALLOON
BALLOON,
EMOTE
}

View File

@@ -3,24 +3,27 @@ package com.hibiscusmc.hmccosmetics.cosmetic;
import com.google.common.collect.HashBiMap;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings;
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.cosmetic.types.*;
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.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Set;
import java.util.logging.Level;
import java.util.stream.Stream;
public class Cosmetics {
private static HashBiMap<String, Cosmetic> COSMETICS = HashBiMap.create();
private static final HashBiMap<String, Cosmetic> COSMETICS = HashBiMap.create();
public static void addCosmetic(Cosmetic cosmetic) {
COSMETICS.put(cosmetic.getId(), cosmetic);
@@ -34,14 +37,19 @@ public class Cosmetics {
COSMETICS.remove(cosmetic);
}
@Nullable
public static Cosmetic getCosmetic(String id) {
return COSMETICS.get(id);
}
@Contract(pure = true)
@NotNull
public static Set<Cosmetic> values() {
return COSMETICS.values();
}
@Contract(pure = true)
@NotNull
public static Set<String> keys() {
return COSMETICS.keySet();
}
@@ -63,23 +71,27 @@ public class Cosmetics {
File[] directoryListing = cosmeticFolder.listFiles();
if (directoryListing == null) return;
for (File child : directoryListing) {
if (child.toString().contains(".yml") || child.toString().contains(".yaml")) {
MessagesUtil.sendDebugMessages("Scanning " + child);
// Loads file
YamlConfigurationLoader loader = YamlConfigurationLoader.builder().path(child.toPath()).build();
CommentedConfigurationNode root;
try {
root = loader.load();
} catch (ConfigurateException e) {
throw new RuntimeException(e);
try (Stream<Path> walkStream = Files.walk(cosmeticFolder.toPath())) {
walkStream.filter(p -> p.toFile().isFile()).forEach(child -> {
if (child.toString().contains(".yml") || child.toString().contains(".yaml")) {
MessagesUtil.sendDebugMessages("Scanning " + child);
// Loads file
YamlConfigurationLoader loader = YamlConfigurationLoader.builder().path(child).build();
CommentedConfigurationNode root;
try {
root = loader.load();
} catch (ConfigurateException e) {
throw new RuntimeException(e);
}
setupCosmetics(root);
}
setupCosmetics(root);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
private static void setupCosmetics(CommentedConfigurationNode config) {
private static void setupCosmetics(@NotNull CommentedConfigurationNode config) {
for (ConfigurationNode cosmeticConfig : config.childrenMap().values()) {
try {
String id = cosmeticConfig.key().toString();
@@ -97,10 +109,11 @@ public class Cosmetics {
case BALLOON -> new CosmeticBalloonType(id, cosmeticConfig);
case BACKPACK -> new CosmeticBackpackType(id, cosmeticConfig);
case MAINHAND -> new CosmeticMainhandType(id, cosmeticConfig);
case EMOTE -> new CosmeticEmoteType(id, cosmeticConfig);
default -> new CosmeticArmorType(id, cosmeticConfig);
}
} catch (Exception e) {
if (Settings.isDebugEnabled()) e.printStackTrace();
if (Settings.isDebugMode()) e.printStackTrace();
}
}
}

View File

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

View File

@@ -1,39 +1,95 @@
package com.hibiscusmc.hmccosmetics.cosmetic.types;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
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.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.spongepowered.configurate.ConfigurationNode;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
public class CosmeticBackpackType extends Cosmetic {
ConfigurationNode config;
@Getter
private final String modelName;
@Getter
private int height = -1;
private ItemStack firstPersonBackpack;
public CosmeticBackpackType(String id, ConfigurationNode config) {
super(id, config);
this.config = config;
modelName = config.node("model").getString();
if (!config.node("firstperson-item").virtual()) {
this.firstPersonBackpack = generateItemStack(config.node("firstperson-item"));
this.height = config.node("height").getInt(5);
}
}
@Override
public void update(CosmeticUser user) {
Player player = Bukkit.getPlayer(user.getUniqueId());
Location loc = player.getLocation().clone();
public void update(@NotNull CosmeticUser user) {
Entity entity = Bukkit.getEntity(user.getUniqueId());
if (entity == null) return;
if (user.isInWardrobe()) return;
Location loc = entity.getLocation().clone().add(0, 2, 0);
if (loc.getWorld() != user.getBackpackEntity().getWorld()) {
user.getBackpackEntity().teleport(loc);
if (user.isInWardrobe() || !user.isBackpackSpawned()) return;
// 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.
List<Player> outsideViewers = user.getUserBackpackManager().getEntityManager().refreshViewers(loc);
user.getUserBackpackManager().getEntityManager().teleport(loc);
user.getUserBackpackManager().getEntityManager().setRotation((int) loc.getYaw(), isFirstPersonCompadible());
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.isHidden()) {
//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.getBackpackEntity().teleport(loc);
user.getUserBackpackManager().showBackpack();
}
PacketManager.sendRidingPacket(player.getEntityId(), user.getBackpackEntity().getEntityId(), loc);
public boolean isFirstPersonCompadible() {
return firstPersonBackpack != null;
}
user.getBackpackEntity().setRotation(loc.getYaw(), loc.getPitch());
user.showBackpack();
public ItemStack getFirstPersonBackpack() {
return firstPersonBackpack;
}
}

View File

@@ -2,56 +2,103 @@ package com.hibiscusmc.hmccosmetics.cosmetic.types;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.entities.BalloonEntity;
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.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import org.spongepowered.configurate.ConfigurationNode;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class CosmeticBalloonType extends Cosmetic {
private String modelName;
@Getter
private final String modelName;
@Getter
private List<String> dyableParts;
@Getter
private final boolean showLead;
@Getter
private Vector balloonOffset;
public CosmeticBalloonType(String id, ConfigurationNode config) {
super(id, config);
String modelId = config.node("model").getString();
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 {
if (!config.node("dyable-parts").virtual()) {
dyableParts = config.node("dyable-parts").getList(String.class);
}
} catch (SerializationException e) {
// Seriously?
throw new RuntimeException(e);
}
if (modelId != null) modelId = modelId.toLowerCase(); // ME only accepts lowercase
this.modelName = modelId;
}
@Override
public void update(CosmeticUser user) {
Player player = Bukkit.getPlayer(user.getUniqueId());
Location currentLocation = user.getBalloonEntity().getLocation().clone();
Location newLocation = player.getLocation().clone().add(Settings.getBalloonOffset()).clone();
if (player == null) return;
public void update(@NotNull CosmeticUser user) {
Entity entity = Bukkit.getEntity(user.getUniqueId());
UserBalloonManager userBalloonManager = user.getBalloonManager();
if (entity == null || userBalloonManager == null) return;
if (user.isInWardrobe()) return;
List<Player> viewer = PacketManager.getViewers(player.getLocation());
viewer.add(player);
BalloonEntity balloonEntity = user.getBalloonEntity();
if (player.getLocation().getWorld() != balloonEntity.getLocation().getWorld()) {
balloonEntity.getModelEntity().teleport(newLocation);
PacketManager.sendTeleportPacket(balloonEntity.getPufferfishBalloonId(), newLocation, false, viewer);
if (!userBalloonManager.getModelEntity().isValid()) {
user.respawnBalloon();
return;
}
Vector velocity = newLocation.clone().toVector().subtract(currentLocation.clone().toVector());
balloonEntity.setLocation(newLocation);
balloonEntity.setVelocity(velocity);
Location newLocation = entity.getLocation();
Location currentLocation = user.getBalloonManager().getLocation();
newLocation = newLocation.clone().add(getBalloonOffset());
if (Settings.isBalloonHeadForward()) newLocation.setPitch(0);
PacketManager.sendTeleportPacket(balloonEntity.getPufferfishBalloonId(), newLocation, false, viewer);
if (!user.getHidden()) PacketManager.sendLeashPacket(balloonEntity.getPufferfishBalloonId(), player.getEntityId(), viewer);
List<Player> viewer = HMCCPacketManager.getViewers(entity.getLocation());
if (entity.getLocation().getWorld() != userBalloonManager.getLocation().getWorld()) {
userBalloonManager.getModelEntity().teleport(newLocation);
HMCCPacketManager.sendTeleportPacket(userBalloonManager.getPufferfishBalloonId(), newLocation, false, viewer);
return;
}
Vector velocity = newLocation.toVector().subtract(currentLocation.toVector());
userBalloonManager.setVelocity(velocity.multiply(1.1));
userBalloonManager.setLocation(newLocation);
HMCCPacketManager.sendTeleportPacket(userBalloonManager.getPufferfishBalloonId(), newLocation, false, viewer);
HMCCPacketManager.sendLeashPacket(userBalloonManager.getPufferfishBalloonId(), entity.getEntityId(), viewer);
if (user.isHidden()) {
userBalloonManager.getPufferfish().hidePufferfish();
return;
}
if (!user.isHidden() && showLead) {
List<Player> sendTo = userBalloonManager.getPufferfish().refreshViewers(newLocation);
if (sendTo.isEmpty()) return;
user.getBalloonManager().getPufferfish().spawnPufferfish(newLocation, sendTo);
}
}
public String getModelName() {
return this.modelName;
public boolean isDyablePart(String name) {
// If player does not define parts, dye whole model
if (dyableParts == null) return true;
if (dyableParts.isEmpty()) return true;
return dyableParts.contains(name);
}
}

View File

@@ -0,0 +1,38 @@
package com.hibiscusmc.hmccosmetics.cosmetic.types;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import me.lojosho.shaded.configurate.ConfigurationNode;
import org.jetbrains.annotations.NotNull;
public class CosmeticEmoteType extends Cosmetic {
private final String animationId;
private final String text;
public CosmeticEmoteType(String id, ConfigurationNode config) {
super(id, config);
animationId = config.node("animation").getString();
text = config.node("text").getString();
MessagesUtil.sendDebugMessages("CosmeticEmoteType Animation id " + animationId);
}
@Override
public void update(CosmeticUser user) {
// Nothing
}
public void run(@NotNull CosmeticUser user) {
user.getUserEmoteManager().playEmote(this);
}
public String getAnimationId() {
return animationId;
}
public String getText() {
return text;
}
}

View File

@@ -2,10 +2,11 @@ package com.hibiscusmc.hmccosmetics.cosmetic.types;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.PlayerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager;
import com.hibiscusmc.hmccosmetics.util.HMCCPlayerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import me.lojosho.shaded.configurate.ConfigurationNode;
import org.bukkit.entity.Player;
import org.spongepowered.configurate.ConfigurationNode;
import org.jetbrains.annotations.NotNull;
public class CosmeticMainhandType extends Cosmetic {
@@ -14,10 +15,9 @@ public class CosmeticMainhandType extends Cosmetic {
}
@Override
public void update(CosmeticUser user) {
public void update(@NotNull CosmeticUser user) {
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,37 +2,34 @@ package com.hibiscusmc.hmccosmetics.database;
import com.hibiscusmc.hmccosmetics.config.DatabaseSettings;
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.SQLiteData;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import lombok.Getter;
import org.bukkit.entity.Player;
import java.util.UUID;
public class Database {
@Getter
private static Data data;
private static InternalData INTERNAL_DATA = new InternalData();
private static MySQLData MYSQL_DATA = new MySQLData();
private static SQLiteData SQLITE_DATA = new SQLiteData();
private static final MySQLData MYSQL_DATA = new MySQLData();
private static final SQLiteData SQLITE_DATA = new SQLiteData();
public Database() {
String databaseType = DatabaseSettings.getDatabaseType();
data = INTERNAL_DATA; // default
if (databaseType.equalsIgnoreCase("INTERNAL")) {
data = INTERNAL_DATA;
}
data = SQLITE_DATA; // default
if (databaseType.equalsIgnoreCase("MySQL")) {
data = MYSQL_DATA;
}
/* SQLite is the default database. Might change in the future, so keep code here in case.
if (databaseType.equalsIgnoreCase("sqlite")) {
data = SQLITE_DATA;
}
*/
MessagesUtil.sendDebugMessages("Database is " + data);
setup();
@@ -54,10 +51,6 @@ public class Database {
return data.get(uniqueId);
}
public static Data getData() {
return data;
}
public static void clearData(UUID uniqueId) {
data.clear(uniqueId);
}

View File

@@ -1,77 +1,145 @@
package com.hibiscusmc.hmccosmetics.database.types;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import org.apache.commons.lang3.EnumUtils;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.*;
public class Data {
public abstract class Data {
public void setup() {
// Override
}
public abstract void setup();
public void save(CosmeticUser user) {
// Override
}
public abstract void save(CosmeticUser user);
@Nullable
public CosmeticUser get(UUID uniqueId) {
// Override
return null;
}
public abstract CosmeticUser get(UUID uniqueId);
public abstract void clear(UUID uniqueId);
public void clear(UUID uniqueId) {
// Override
}
// BACKPACK=colorfulbackpack&RRGGBB,HELMET=niftyhat,BALLOON=colorfulballoon,CHESTPLATE=niftychestplate
public String steralizeData(CosmeticUser user) {
String data = "";
for (Cosmetic cosmetic : user.getCosmetic()) {
@NotNull
public final String serializeData(@NotNull CosmeticUser user) {
StringBuilder data = new StringBuilder();
if (user.isHidden()) {
for (CosmeticUser.HiddenReason reason : user.getHiddenReasons()) {
if (shouldHiddenSave(reason)) data.append("HIDDEN=").append(reason);
}
}
for (Cosmetic cosmetic : user.getCosmetics()) {
Color color = user.getCosmeticColor(cosmetic.getSlot());
String input = cosmetic.getSlot() + "=" + cosmetic.getId();
if (color != null) input = input + "&" + color.asRGB();
if (data.length() == 0) {
data = input;
if (data.isEmpty()) {
data.append(input);
continue;
}
data = data + "," + input;
data.append(",").append(input);
}
return data;
return data.toString();
}
public Map<CosmeticSlot, Map<Cosmetic, Color>> desteralizedata(String raw) {
public final Map<CosmeticSlot, Map<Cosmetic, Color>> deserializeData(CosmeticUser user, @NotNull String raw) {
return deserializeData(user, raw, Settings.isForcePermissionJoin());
}
@NotNull
public final Map<CosmeticSlot, Map<Cosmetic, Color>> deserializeData(CosmeticUser user, @NotNull String raw, boolean permissionCheck) {
Map<CosmeticSlot, Map<Cosmetic, Color>> cosmetics = new HashMap<>();
String[] rawData = raw.split(",");
ArrayList<CosmeticUser.HiddenReason> hiddenReason = new ArrayList<>();
for (String a : rawData) {
if (a == null || a.isEmpty()) continue;
String[] splitData = a.split("=");
CosmeticSlot slot = null;
Cosmetic cosmetic = null;
MessagesUtil.sendDebugMessages("First split (suppose slot) " + splitData[0]);
if (splitData[0].equalsIgnoreCase("HIDDEN")) {
if (EnumUtils.isValidEnum(CosmeticUser.HiddenReason.class, splitData[1])) {
if (Settings.isForceShowOnJoin()) continue;
hiddenReason.add(CosmeticUser.HiddenReason.valueOf(splitData[1]));
}
continue;
}
if (CosmeticSlot.valueOf(splitData[0]) != null) slot = CosmeticSlot.valueOf(splitData[0]);
if (splitData[1].contains("&")) {
String[] colorSplitData = splitData[1].split("&");
if (Cosmetics.hasCosmetic(colorSplitData[0])) cosmetic = Cosmetics.getCosmetic(colorSplitData[0]);
if (slot == null || cosmetic == null) continue;
if (permissionCheck && cosmetic.requiresPermission()) {
if (user.getPlayer() != null && !user.getPlayer().hasPermission(cosmetic.getPermission())) {
continue;
}
}
cosmetics.put(slot, Map.of(cosmetic, Color.fromRGB(Integer.parseInt(colorSplitData[1]))));
} else {
if (Cosmetics.hasCosmetic(splitData[1])) cosmetic = Cosmetics.getCosmetic(splitData[1]);
if (slot == null || cosmetic == null) continue;
if (permissionCheck && cosmetic.requiresPermission()) {
if (user.getPlayer() != null && !user.getPlayer().hasPermission(cosmetic.getPermission())) {
continue;
}
}
HashMap<Cosmetic, Color> cosmeticColorHashMap = new HashMap<>();
cosmeticColorHashMap.put(cosmetic, null);
cosmetics.put(slot, cosmeticColorHashMap);
}
}
MessagesUtil.sendDebugMessages("Hidden Reason: " + hiddenReason);
// if else this, if else that, if else I got to deal with this anymore i'll lose my mind
if (!hiddenReason.isEmpty()) {
for (CosmeticUser.HiddenReason reason : hiddenReason) user.silentlyAddHideFlag(reason);
} else {
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
// Handle gamemode check
if (user.getPlayer() != null && Settings.getDisabledGamemodes().contains(user.getPlayer().getGameMode().toString())) {
MessagesUtil.sendDebugMessages("Hiding Cosmetics due to gamemode");
user.hideCosmetics(CosmeticUser.HiddenReason.GAMEMODE);
return;
} else {
if (user.isHidden(CosmeticUser.HiddenReason.GAMEMODE)) {
MessagesUtil.sendDebugMessages("Join Gamemode Check: Showing Cosmetics");
user.showCosmetics(CosmeticUser.HiddenReason.GAMEMODE);
return;
}
}
// Handle world check
if (Settings.getDisabledWorlds().contains(user.getPlayer().getWorld().getName())) {
MessagesUtil.sendDebugMessages("Hiding Cosmetics due to world");
user.hideCosmetics(CosmeticUser.HiddenReason.WORLD);
} else {
if (user.isHidden(CosmeticUser.HiddenReason.WORLD)) {
MessagesUtil.sendDebugMessages("Join World Check: Showing Cosmetics");
user.showCosmetics(CosmeticUser.HiddenReason.WORLD);
}
}
if (Settings.isAllPlayersHidden()) {
user.hideCosmetics(CosmeticUser.HiddenReason.DISABLED);
}
});
}
return cosmetics;
}
private boolean shouldHiddenSave(CosmeticUser.HiddenReason reason) {
switch (reason) {
case EMOTE, NONE, GAMEMODE, WORLD, DISABLED -> {
return false;
}
default -> {
return true;
}
}
}
}

View File

@@ -1,65 +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;
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, steralizeData(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 = desteralizedata(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,18 +2,19 @@ package com.hibiscusmc.hmccosmetics.database.types;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.DatabaseSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.*;
import java.util.Map;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Properties;
import java.util.UUID;
public class MySQLData extends Data {
public class MySQLData extends SQLData {
// Connection Information
private String host;
@@ -22,6 +23,7 @@ public class MySQLData extends Data {
private String password;
private int port;
@Nullable
private Connection connection;
@Override
@@ -35,11 +37,12 @@ public class MySQLData extends Data {
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
try {
openConnection();
if (connection == null) throw new NullPointerException("Connection is null");
connection.prepareStatement("CREATE TABLE IF NOT EXISTS `COSMETICDATABASE` " +
"(UUID varchar(36) PRIMARY KEY, " +
"COSMETICS MEDIUMTEXT " +
");").execute();
} catch (SQLException e) {
} catch (SQLException | NullPointerException e) {
plugin.getLogger().severe("");
plugin.getLogger().severe("");
plugin.getLogger().severe("MySQL DATABASE CAN NOT BE REACHED.");
@@ -52,104 +55,63 @@ public class MySQLData extends Data {
throw new RuntimeException(e);
}
}
@Override
public void save(CosmeticUser user) {
Runnable run = () -> {
try {
PreparedStatement preparedSt = preparedStatement("REPLACE INTO COSMETICDATABASE(UUID,COSMETICS) VALUES(?,?);");
preparedSt.setString(1, user.getUniqueId().toString());
preparedSt.setString(2, steralizeData(user));
preparedSt.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}
};
if (!HMCCosmeticsPlugin.isDisable()) {
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), run);
} else {
run.run();
}
}
@Override
public CosmeticUser get(UUID uniqueId) {
CosmeticUser user = new CosmeticUser(uniqueId);
public void clear(UUID uniqueId) {
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), () -> {
PreparedStatement preparedSt = null;
try {
PreparedStatement preparedStatement = preparedStatement("SELECT * FROM COSMETICDATABASE WHERE UUID = ?;");
preparedStatement.setString(1, uniqueId.toString());
ResultSet rs = preparedStatement.executeQuery();
if (rs.next()) {
String rawData = rs.getString("COSMETICS");
Map<CosmeticSlot, Map<Cosmetic, Color>> cosmetics = desteralizedata(rawData);
for (Map<Cosmetic, Color> cosmeticColors : cosmetics.values()) {
for (Cosmetic cosmetic : cosmeticColors.keySet()) {
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
// This can not be async.
user.addPlayerCosmetic(cosmetic, cosmeticColors.get(cosmetic));
});
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
});
return user;
}
@Override
public void clear(UUID unqiueId) {
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), () -> {
try {
PreparedStatement preparedSt = preparedStatement("DELETE FROM COSMETICDATABASE WHERE UUID=?;");
preparedSt.setString(1, unqiueId.toString());
preparedSt = preparedStatement("DELETE FROM COSMETICDATABASE WHERE UUID=?;");
preparedSt.setString(1, uniqueId.toString());
preparedSt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (preparedSt != null) preparedSt.close();
} catch (SQLException e) {}
}
});
// TODO
}
private void openConnection() throws SQLException {
if (connection != null && !connection.isClosed()) {
return;
// Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), () -> {
// ...
// });
// connection = DriverManager.getConnection("jdbc:mysql://" + DatabaseSettings.getHost() + ":" + DatabaseSettings.getPort() + "/" + DatabaseSettings.getDatabase(), setupProperties());
// Connection isn't null AND Connection isn't closed :: return
try {
if (isConnectionOpen()) {
return;
} else if (connection != null) close(); // Close connection if still active
} catch (RuntimeException e) {
e.printStackTrace(); // If isConnectionOpen() throws error
}
//Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), () -> {
//close Connection if still active
if (connection != null) {
close();
}
//connect to database host
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database, setupProperties());
} catch (SQLException e) {
System.out.println(e.getMessage());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
//});
//connection = DriverManager.getConnection("jdbc:mysql://" + DatabaseSettings.getHost() + ":" + DatabaseSettings.getPort() + "/" + DatabaseSettings.getDatabase(), setupProperties());
// Connect to database host
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database, setupProperties());
} catch (SQLException e) {
System.out.println(e.getMessage());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public void close() {
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), () -> {
try {
if (connection == null) throw new NullPointerException("Connection is null");
connection.close();
} catch (SQLException e) {
} catch (SQLException | NullPointerException e) {
System.out.println(e.getMessage());
}
});
}
@NotNull
private Properties setupProperties() {
Properties props = new Properties();
props.put("user", user);
@@ -158,28 +120,27 @@ public class MySQLData extends Data {
return props;
}
private boolean isConnectionOpen() {
private boolean isConnectionOpen() throws RuntimeException {
try {
if (connection == null || connection.isClosed()) {
return false;
} else {
return true;
}
return connection != null && !connection.isClosed();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public PreparedStatement preparedStatement(String query) {
PreparedStatement ps = null;
if (!isConnectionOpen()) {
HMCCosmeticsPlugin.getInstance().getLogger().info("Connection is not open");
}
if (!isConnectionOpen()) MessagesUtil.sendDebugMessages("Connection is not open");
try {
if (connection == null) throw new NullPointerException("Connection is null");
ps = connection.prepareStatement(query);
} catch (SQLException e) {
} catch (SQLException | NullPointerException e) {
e.printStackTrace();
}
return ps;
}
}

View File

@@ -0,0 +1,85 @@
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 java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public abstract class SQLData extends Data {
@Override
@SuppressWarnings({"resource"}) // Duplicate is from deprecated InternalData
public CosmeticUser get(UUID uniqueId) {
CosmeticUser user = new CosmeticUser(uniqueId);
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), () -> {
PreparedStatement preparedStatement = null;
try {
preparedStatement = preparedStatement("SELECT * FROM COSMETICDATABASE WHERE UUID = ?;");
preparedStatement.setString(1, uniqueId.toString());
ResultSet rs = preparedStatement.executeQuery();
if (rs.next()) {
String rawData = rs.getString("COSMETICS");
Map<CosmeticSlot, Map<Cosmetic, Color>> cosmetics = deserializeData(user, rawData);
// Load cosmetics, put them into the addedCosmetic hashmap
HashMap<Cosmetic, Color> addedCosmetics = new HashMap<>();
for (Map<Cosmetic, Color> cosmeticColors : cosmetics.values()) {
for (Cosmetic cosmetic : cosmeticColors.keySet()) {
addedCosmetics.put(cosmetic, cosmeticColors.get(cosmetic));
}
}
// Run a task on the main thread, adding the cosmetics to the player
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
// This can not be async.
for (Cosmetic cosmetic : addedCosmetics.keySet()) {
user.addPlayerCosmetic(cosmetic, addedCosmetics.get(cosmetic));
}
});
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (preparedStatement != null) preparedStatement.close();
} catch (SQLException e) {}
}
});
return user;
}
@Override
@SuppressWarnings("resource")
public void save(CosmeticUser user) {
Runnable run = () -> {
PreparedStatement preparedSt = null;
try {
preparedSt = preparedStatement("REPLACE INTO COSMETICDATABASE(UUID,COSMETICS) VALUES(?,?);");
preparedSt.setString(1, user.getUniqueId().toString());
preparedSt.setString(2, serializeData(user));
preparedSt.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
try {
if (preparedSt != null) preparedSt.close();
} catch (SQLException e) {}
}
};
if (!HMCCosmeticsPlugin.getInstance().isDisabled()) {
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), run);
} else {
run.run();
}
}
public abstract PreparedStatement preparedStatement(String query);
}

View File

@@ -1,31 +1,31 @@
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 com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import java.io.File;
import java.io.IOException;
import java.sql.*;
import java.util.Map;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.UUID;
import java.util.logging.Level;
public class SQLiteData extends Data {
public class SQLiteData extends SQLData {
private Connection connection;
@Override
public void setup() {
File dataFolder = new File(HMCCosmeticsPlugin.getInstance().getDataFolder(), "database.db");
boolean exists = dataFolder.exists();
if (!dataFolder.exists()){
if (!exists) {
try {
dataFolder.createNewFile();
boolean created = dataFolder.createNewFile();
if (!created) throw new IOException("File didn't exist but now does");
} catch (IOException e) {
MessagesUtil.sendDebugMessages("File write error. Database will not work properly", Level.SEVERE);
}
@@ -39,123 +39,69 @@ public class SQLiteData extends Data {
"(UUID varchar(36) PRIMARY KEY, " +
"COSMETICS MEDIUMTEXT " +
");").execute();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public void save(CosmeticUser user) {
Runnable run = () -> {
try {
PreparedStatement preparedSt = preparedStatement("REPLACE INTO COSMETICDATABASE(UUID,COSMETICS) VALUES(?,?);");
preparedSt.setString(1, user.getUniqueId().toString());
preparedSt.setString(2, steralizeData(user));
preparedSt.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}
};
if (!HMCCosmeticsPlugin.isDisable()) {
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), run);
} else {
run.run();
}
}
@Override
public CosmeticUser get(UUID uniqueId) {
CosmeticUser user = new CosmeticUser(uniqueId);
@SuppressWarnings("resource")
public void clear(UUID uniqueId) {
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), () -> {
PreparedStatement preparedSt = null;
try {
PreparedStatement preparedStatement = preparedStatement("SELECT * FROM COSMETICDATABASE WHERE UUID = ?;");
preparedStatement.setString(1, uniqueId.toString());
ResultSet rs = preparedStatement.executeQuery();
if (rs.next()) {
String rawData = rs.getString("COSMETICS");
Map<CosmeticSlot, Map<Cosmetic, Color>> cosmetics = desteralizedata(rawData);
for (Map<Cosmetic, Color> cosmeticColors : cosmetics.values()) {
for (Cosmetic cosmetic : cosmeticColors.keySet()) {
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
// This can not be async.
user.addPlayerCosmetic(cosmetic, cosmeticColors.get(cosmetic));
});
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
});
return user;
}
@Override
public void clear(UUID unqiueId) {
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), () -> {
try {
PreparedStatement preparedSt = preparedStatement("DELETE FROM COSMETICDATABASE WHERE UUID=?;");
preparedSt.setString(1, unqiueId.toString());
preparedSt = preparedStatement("DELETE FROM COSMETICDATABASE WHERE UUID=?;");
preparedSt.setString(1, uniqueId.toString());
preparedSt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (preparedSt != null) preparedSt.close();
} catch (SQLException e) {}
}
});
}
private void openConnection() throws SQLException {
if (connection != null && !connection.isClosed()) {
return;
}
//Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), () -> {
// Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), () -> {
// ...
// });
// connection = DriverManager.getConnection("jdbc:mysql://" + DatabaseSettings.getHost() + ":" + DatabaseSettings.getPort() + "/" + DatabaseSettings.getDatabase(), setupProperties());
//close Connection if still active
if (connection != null) {
//close();
}
if (connection != null && !connection.isClosed()) return;
// Close Connection if still active
File dataFolder = new File(HMCCosmeticsPlugin.getInstance().getDataFolder(), "database.db");
//connect to database host
// Connect to database host
try {
Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection("jdbc:sqlite:" + dataFolder);
} catch (SQLException e) {
System.out.println(e.getMessage());
e.printStackTrace();
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
//});
//connection = DriverManager.getConnection("jdbc:mysql://" + DatabaseSettings.getHost() + ":" + DatabaseSettings.getPort() + "/" + DatabaseSettings.getDatabase(), setupProperties());
}
@Override
public PreparedStatement preparedStatement(String query) {
PreparedStatement ps = null;
if (!isConnectionOpen()) {
HMCCosmeticsPlugin.getInstance().getLogger().info("Connection is not open");
}
if (!isConnectionOpen()) MessagesUtil.sendDebugMessages("Connection is not open");
try {
ps = connection.prepareStatement(query);
} catch (SQLException e) {
e.printStackTrace();
}
return ps;
}
private boolean isConnectionOpen() {
try {
if (connection == null || connection.isClosed()) {
return false;
} else {
return true;
}
return connection != null && !connection.isClosed();
} catch (SQLException e) {
throw new RuntimeException(e);
}

View File

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

View File

@@ -1,121 +0,0 @@
package com.hibiscusmc.hmccosmetics.entities;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.ticxo.modelengine.api.ModelEngineAPI;
import com.ticxo.modelengine.api.model.ActiveModel;
import com.ticxo.modelengine.api.model.ModeledEntity;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import java.util.UUID;
import java.util.logging.Level;
// This includes the Pufferfish (The Pufferfish that's what the player leashes to) and the model (MEGEntity)
public class BalloonEntity {
private final int balloonID;
private final UUID uniqueID;
private final Entity modelEntity;
private ModeledEntity modeledEntity;
public BalloonEntity(Location location) {
this.uniqueID = UUID.randomUUID();
this.balloonID = NMSHandlers.getHandler().getNextEntityId();
this.modelEntity = NMSHandlers.getHandler().getMEGEntity(location.add(Settings.getBalloonOffset()));
}
public void spawnModel(final String id, Color color) {
MessagesUtil.sendDebugMessages("Attempting Spawning for " + id);
if (ModelEngineAPI.api.getModelRegistry().getBlueprint(id) == null) {
MessagesUtil.sendDebugMessages("Invalid Model Engine Blueprint " + id, Level.SEVERE);
return;
}
ModeledEntity modeledEntity = ModelEngineAPI.getOrCreateModeledEntity(modelEntity);
ActiveModel model = ModelEngineAPI.createActiveModel(ModelEngineAPI.getBlueprint(id));
model.setCanHurt(false);
modeledEntity.addModel(model, false);
if (color != null) {
modeledEntity.getModels().forEach((d, singleModel) -> {
singleModel.getRendererHandler().setColor(color);
singleModel.getRendererHandler().update();
});
}
this.modeledEntity = modeledEntity;
}
public void remove() {
final ModeledEntity entity = ModelEngineAPI.api.getModeledEntity(modelEntity.getUniqueId());
if (entity == null) return;
for (final Player player : entity.getRangeManager().getPlayerInRange()) {
entity.hideFromPlayer(player);
}
//ModelEngineAPI.removeModeledEntity(megEntity.getUniqueId());
entity.destroy();
modelEntity.remove();
}
public void addPlayerToModel(final Player player, final String id) {
addPlayerToModel(player, id, null);
}
public void addPlayerToModel(final Player player, final String id, Color color) {
final ModeledEntity model = ModelEngineAPI.api.getModeledEntity(modelEntity.getUniqueId());
if (model == null) {
spawnModel(id, color);
MessagesUtil.sendDebugMessages("model is null");
return;
}
//if (model.getRangeManager().getPlayerInRange().contains(player)) return;
model.showToPlayer(player);
MessagesUtil.sendDebugMessages("Show to player");
}
public void removePlayerFromModel(final Player player) {
final ModeledEntity model = ModelEngineAPI.api.getModeledEntity(modelEntity.getUniqueId());
if (model == null) return;
model.hideFromPlayer(player);
MessagesUtil.sendDebugMessages("Hidden from player");
}
public Entity getModelEntity() {
return this.modelEntity;
}
public int getPufferfishBalloonId() {
return balloonID;
}
public UUID getPufferfishBalloonUniqueId() {
return uniqueID;
}
public UUID getModelUnqiueId() {
return getModelEntity().getUniqueId();
}
public int getModelId() {
return getModelEntity().getEntityId();
}
public Location getLocation() {
return this.getModelEntity().getLocation();
}
public void setLocation(Location location) {
this.getModelEntity().teleport(location);
}
public void setVelocity(Vector vector) {
this.getModelEntity().setVelocity(vector);
}
}

View File

@@ -1,111 +1,74 @@
package com.hibiscusmc.hmccosmetics.gui;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.api.PlayerMenuOpenEvent;
import com.hibiscusmc.hmccosmetics.config.serializer.ItemSerializer;
import com.hibiscusmc.hmccosmetics.api.events.PlayerMenuOpenEvent;
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.Types;
import com.hibiscusmc.hmccosmetics.hooks.PAPIHook;
import com.hibiscusmc.hmccosmetics.gui.type.types.TypeCosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
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.guis.Gui;
import dev.triumphteam.gui.guis.GuiItem;
import me.clip.placeholderapi.PlaceholderAPI;
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 org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Menu {
private String id;
private String title;
private int rows;
private ConfigurationNode config;
private String permissionNode;
@Getter
private final String id;
@Getter
private final String title;
@Getter
private final int rows;
@Getter
private final ConfigurationNode config;
@Getter
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, ConfigurationNode config) {
public Menu(String id, @NotNull ConfigurationNode config) {
this.id = id;
this.config = config;
title = config.node("title").getString("chest");
rows = config.node("rows").getInt(1);
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);
}
public String getId() {
return id;
}
public String getTitle() {
return this.title;
}
public int getRows() {
return this.getRows();
}
public void openMenu(CosmeticUser user) {
openMenu(user, false);
}
public void openMenu(CosmeticUser user, boolean ignorePermission) {
Player player = user.getPlayer();
if (player == null) return;
if (!ignorePermission && !permissionNode.isEmpty()) {
if (!player.hasPermission(permissionNode) && !player.isOp()) {
MessagesUtil.sendMessage(player, "no-permission");
return;
}
}
final Component component = Adventure.MINI_MESSAGE.deserialize(Placeholder.applyPapiPlaceholders(player, this.title));
Gui gui = Gui.gui().
title(component).
rows(this.rows).
create();
gui.setDefaultClickAction(event -> event.setCancelled(true));
gui = getItems(user, gui);
Gui finalGui = gui;
PlayerMenuOpenEvent event = new PlayerMenuOpenEvent(user, this);
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
Bukkit.getPluginManager().callEvent(event);
});
if (event.isCancelled()) {
return;
}
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
finalGui.open(player);
});
//gui.open(player);
}
private Gui getItems(CosmeticUser user, Gui gui) {
Player player = user.getPlayer();
private void setupItems() {
for (ConfigurationNode config : config.node("items").childrenMap().values()) {
List<String> slotString = null;
List<String> slotString;
try {
slotString = config.node("slots").getList(String.class);
} catch (SerializationException e) {
@@ -118,62 +81,190 @@ public class Menu {
List<Integer> slots = getSlots(slotString);
if (slots == null) {
MessagesUtil.sendDebugMessages("Slot is null for " + config.key().toString());
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"));
//item = config.node("item").get(ItemStack.class);
} catch (SerializationException e) {
throw new RuntimeException(e);
}
if (item == null) {
MessagesUtil.sendDebugMessages("something went wrong! " + item);
MessagesUtil.sendDebugMessages("Something went wrong with the item creation for " + config.key().toString());
continue;
}
ItemStack originalItem = item.clone();
item = updateLore(player, item);
int priority = config.node("priority").getInt(1);
Type type = null;
if (!config.node("type").virtual()) {
String typeId = config.node("type").getString();
String typeId = config.node("type").getString("");
if (Types.isType(typeId)) type = Types.getType(typeId);
}
GuiItem guiItem = ItemBuilder.from(item).asGuiItem();
Type finalType = type;
guiItem.setAction(event -> {
final ClickType clickType = event.getClick();
if (finalType != null) finalType.run(user, config, clickType);
for (int i : slots) {
gui.updateItem(i, updateLore(player, originalItem.clone()));
MessagesUtil.sendDebugMessages("Updated slot " + i);
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)));
}
});
MessagesUtil.sendDebugMessages("Added " + slots + " as " + guiItem + " in the menu");
gui.setItem(slots, guiItem);
}
}
return gui;
}
private List<Integer> getSlots(List<String> slotString) {
public void openMenu(CosmeticUser user) {
openMenu(user, false);
}
public void openMenu(@NotNull CosmeticUser user, boolean ignorePermission) {
Player player = user.getPlayer();
if (player == null) return;
if (!ignorePermission && !permissionNode.isEmpty()) {
if (!player.hasPermission(permissionNode) && !player.isOp()) {
MessagesUtil.sendMessage(player, "no-permission");
return;
}
}
final Component component = AdventureUtils.MINI_MESSAGE.deserialize(Hooks.processPlaceholders(player, this.title));
Gui gui = Gui.gui()
.title(component)
.rows(this.rows)
.create();
gui.setDefaultClickAction(event -> event.setCancelled(true));
AtomicInteger taskid = new AtomicInteger(-1);
gui.setOpenGuiAction(event -> {
Runnable run = () -> {
if (gui.getInventory().getViewers().isEmpty() && taskid.get() != -1) {
Bukkit.getScheduler().cancelTask(taskid.get());
}
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);
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> Bukkit.getPluginManager().callEvent(event));
if (event.isCancelled()) return;
// Internal
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
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
});
}
private void updateMenu(CosmeticUser user, Gui gui) {
StringBuilder title = new StringBuilder(this.title);
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
}
boolean occupied = false;
if (items.containsKey(i)) {
// Handles the items
List<MenuItem> menuItems = items.get(i);
MenuItem item = menuItems.get(0);
updateItem(user, gui, i);
if (item.type() instanceof TypeCosmetic) {
Cosmetic cosmetic = Cosmetics.getCosmetic(item.itemConfig().node("cosmetic").getString(""));
if (cosmetic == null) continue;
if (user.hasCosmeticInSlot(cosmetic)) {
title.append(Settings.getEquippedCosmeticColor());
} else {
if (user.canEquipCosmetic(cosmetic, true)) {
title.append(Settings.getEquipableCosmeticColor());
} else {
title.append(Settings.getLockedCosmeticColor());
}
}
occupied = true;
}
}
if (occupied) {
title.append(Settings.getBackground().replaceAll("<row>", String.valueOf(row)));
} 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);
}
}
}
}
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
private List<Integer> getSlots(@NotNull List<String> slotString) {
List<Integer> slots = new ArrayList<>();
for (String a : slotString) {
if (a.contains("-")) {
String[] split = a.split("-");
int min = Integer.valueOf(split[0]);
int max = Integer.valueOf(split[1]);
int min = Integer.parseInt(split[0]);
int max = Integer.parseInt(split[1]);
slots.addAll(getSlots(min, max));
} else {
slots.add(Integer.valueOf(a));
@@ -183,6 +274,7 @@ public class Menu {
return slots;
}
@NotNull
private List<Integer> getSlots(int small, int max) {
List<Integer> slots = new ArrayList<>();
@@ -190,32 +282,17 @@ public class Menu {
return slots;
}
private ItemStack updateLore(Player player, ItemStack itemStack) {
if (itemStack.hasItemMeta()) {
List<String> processedLore = new ArrayList<>();
if (PAPIHook.isPAPIEnabled()) {
if (itemStack.getItemMeta().hasLore()) {
for (String loreLine : itemStack.getItemMeta().getLore()) {
processedLore.add(PlaceholderAPI.setPlaceholders(player, loreLine));
}
}
}
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.setLore(processedLore);
itemStack.setItemMeta(itemMeta);
}
return itemStack;
}
public String getPermissionNode() {
return permissionNode;
@Contract("_, _, _, _, _ -> param2")
@NotNull
private ItemStack getMenuItem(CosmeticUser user, Type type, ConfigurationNode config, ItemStack itemStack, int slot) {
if (!itemStack.hasItemMeta()) return itemStack;
return type.setItem(user, config, itemStack, slot);
}
public boolean canOpen(Player player) {
if (permissionNode.isEmpty()) return true;
if (player.isOp() || player.hasPermission(permissionNode)) return true;
return false;
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,35 +3,42 @@ package com.hibiscusmc.hmccosmetics.gui;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings;
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.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.stream.Stream;
public class Menus {
private static HashMap<String, Menu> MENUS = new HashMap<>();
private static final HashMap<String, Menu> MENUS = new HashMap<>();
public static void addMenu(Menu menu) {
MENUS.put(menu.getId().toUpperCase(), menu);
}
public static Menu getMenu(String id) {
public static Menu getMenu(@NotNull String id) {
return MENUS.get(id.toUpperCase());
}
@Contract(pure = true)
@NotNull
public static Collection<Menu> getMenu() {
return MENUS.values();
}
public static boolean hasMenu(String id) {
public static boolean hasMenu(@NotNull String id) {
return MENUS.containsKey(id.toUpperCase());
}
@@ -39,6 +46,9 @@ public class Menus {
return MENUS.containsValue(menu);
}
public static Menu getDefaultMenu() { return Menus.getMenu(Settings.getDefaultMenu()); }
@NotNull
public static List<String> getMenuNames() {
List<String> names = new ArrayList<>();
@@ -49,33 +59,39 @@ public class Menus {
return names;
}
public static Collection<Menu> values() {
return MENUS.values();
}
public static void setup() {
MENUS.clear();
File cosmeticFolder = new File(HMCCosmeticsPlugin.getInstance().getDataFolder() + "/menus");
if (!cosmeticFolder.exists()) cosmeticFolder.mkdir();
File[] directoryListing = cosmeticFolder.listFiles();
if (directoryListing == null) return;
for (File child : directoryListing) {
if (child.toString().contains(".yml") || child.toString().contains(".yaml")) {
MessagesUtil.sendDebugMessages("Scanning " + child);
// Loads file
YamlConfigurationLoader loader = YamlConfigurationLoader.builder().path(child.toPath()).build();
CommentedConfigurationNode root;
try {
root = loader.load();
} catch (ConfigurateException e) {
throw new RuntimeException(e);
// Recursive file lookup
try (Stream<Path> walkStream = Files.walk(cosmeticFolder.toPath())) {
walkStream.filter(p -> p.toFile().isFile()).forEach(child -> {
if (child.toString().endsWith("yml") || child.toString().endsWith("yaml")) {
MessagesUtil.sendDebugMessages("Scanning " + child);
// Loads file
YamlConfigurationLoader loader = YamlConfigurationLoader.builder().path(child).build();
CommentedConfigurationNode root;
try {
root = loader.load();
} catch (ConfigurateException 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) {
MessagesUtil.sendDebugMessages("Unable to create menu in " + child, Level.WARNING);
if (Settings.isDebugEnabled()) e.printStackTrace();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -1,12 +1,13 @@
package com.hibiscusmc.hmccosmetics.gui.action;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.jetbrains.annotations.NotNull;
public class Action {
public abstract class Action {
private String id;
private final String id;
public Action(String id) {
public Action(@NotNull String id) {
this.id = id.toUpperCase();
Actions.addAction(this);
}
@@ -15,7 +16,5 @@ public class Action {
return this.id;
}
public void run(CosmeticUser user, String raw) {
// Override
}
public abstract void run(CosmeticUser user, String raw);
}

View File

@@ -4,27 +4,36 @@ import com.hibiscusmc.hmccosmetics.gui.action.actions.*;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.List;
@SuppressWarnings("unused")
public class Actions {
private static HashMap<String, Action> actions = new HashMap<>();
private static final HashMap<String, Action> actions = new HashMap<>();
// [ID]
private static ActionMessage ACTION_MESSAGE = new ActionMessage();
private static ActionMenu ACTION_MENU = new ActionMenu();
private static ActionPlayerCommand ACTION_CONSOLE_COMMAND = new ActionPlayerCommand();
private static ActionConsoleCommand ACTION_PLAYER_COMMAND = new ActionConsoleCommand();
private static ActionCloseMenu ACTION_EXIT_MENU = new ActionCloseMenu();
private static final ActionMessage ACTION_MESSAGE = new ActionMessage();
private static final ActionMenu ACTION_MENU = new ActionMenu();
private static final ActionPlayerCommand ACTION_CONSOLE_COMMAND = new ActionPlayerCommand();
private static final ActionConsoleCommand ACTION_PLAYER_COMMAND = new ActionConsoleCommand();
private static final ActionCloseMenu ACTION_EXIT_MENU = new ActionCloseMenu();
private static final ActionSound ACTION_SOUND = new ActionSound();
private static final ActionEquip ACTION_EQUIP = new ActionEquip();
private static final ActionUnequip ACTION_UNEQUIP = new ActionUnequip();
private static final ActionParticle ACTION_PARTICLE = new ActionParticle();
private static final ActionCosmeticShow ACTION_SHOW = new ActionCosmeticShow();
private static final ActionCosmeticHide ACTION_HIDE = new ActionCosmeticHide();
private static final ActionCosmeticToggle ACTION_TOGGLE = new ActionCosmeticToggle();
public static Action getAction(String id) {
public static Action getAction(@NotNull String id) {
return actions.get(id.toUpperCase());
}
public static boolean isAction(String id) {
public static boolean isAction(@NotNull String id) {
return actions.containsKey(id.toUpperCase());
}
@@ -32,11 +41,11 @@ public class Actions {
actions.put(action.getId().toUpperCase(), action);
}
public static void runActions(CosmeticUser user, List<String> raw) {
public static void runActions(CosmeticUser user, @NotNull List<String> raw) {
for (String a : raw) {
String id = StringUtils.substringBetween(a, "[", "]").toUpperCase();
String message = StringUtils.substringAfter(a, "] ");
MessagesUtil.sendDebugMessages("ID is " + id + " // Message is " + message);
MessagesUtil.sendDebugMessages("ID is " + id + " // Raw Data is " + message);
if (isAction(id)) {
getAction(id).run(user, message);
} else {

View File

@@ -2,6 +2,7 @@ package com.hibiscusmc.hmccosmetics.gui.action.actions;
import com.hibiscusmc.hmccosmetics.gui.action.Action;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.jetbrains.annotations.NotNull;
public class ActionCloseMenu extends Action {
@@ -10,7 +11,7 @@ public class ActionCloseMenu extends Action {
}
@Override
public void run(CosmeticUser user, String raw) {
public void run(@NotNull CosmeticUser user, String raw) {
user.getPlayer().closeInventory();
}
}

View File

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

View File

@@ -0,0 +1,18 @@
package com.hibiscusmc.hmccosmetics.gui.action.actions;
import com.hibiscusmc.hmccosmetics.gui.action.Action;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.jetbrains.annotations.NotNull;
public class ActionCosmeticHide extends Action {
public ActionCosmeticHide() {
super("hide");
}
@Override
public void run(@NotNull CosmeticUser user, String raw) {
if (user.isHidden()) return;
user.hideCosmetics(CosmeticUser.HiddenReason.ACTION);
}
}

View File

@@ -0,0 +1,21 @@
package com.hibiscusmc.hmccosmetics.gui.action.actions;
import com.hibiscusmc.hmccosmetics.gui.action.Action;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.jetbrains.annotations.NotNull;
public class ActionCosmeticShow extends Action {
public ActionCosmeticShow() {
super("show");
}
@Override
public void run(@NotNull CosmeticUser user, String raw) {
if (!user.isHidden()) return;
// Do not hide if it's already off for WG
if (!user.isHidden(CosmeticUser.HiddenReason.ACTION) && !user.isHidden(CosmeticUser.HiddenReason.COMMAND)) return;
user.showCosmetics(CosmeticUser.HiddenReason.ACTION);
}
}

View File

@@ -0,0 +1,23 @@
package com.hibiscusmc.hmccosmetics.gui.action.actions;
import com.hibiscusmc.hmccosmetics.gui.action.Action;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.jetbrains.annotations.NotNull;
public class ActionCosmeticToggle extends Action {
public ActionCosmeticToggle() {
super("toggle");
}
@Override
public void run(@NotNull CosmeticUser user, String raw) {
if (user.isHidden()) {
if (!user.isHidden(CosmeticUser.HiddenReason.ACTION) && !user.isHidden(CosmeticUser.HiddenReason.COMMAND)) return;
user.showCosmetics(CosmeticUser.HiddenReason.ACTION);
return;
}
user.hideCosmetics(CosmeticUser.HiddenReason.ACTION);
}
}

View File

@@ -0,0 +1,21 @@
package com.hibiscusmc.hmccosmetics.gui.action.actions;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.gui.action.Action;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
public class ActionEquip extends Action {
public ActionEquip() {
super("equip");
}
@Override
public void run(CosmeticUser user, String raw) {
Cosmetic cosmetic = Cosmetics.getCosmetic(raw);
if (cosmetic == null) return;
user.addPlayerCosmetic(cosmetic);
}
}

View File

@@ -1,10 +1,12 @@
package com.hibiscusmc.hmccosmetics.gui.action.actions;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.gui.action.Action;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import java.util.logging.Level;
public class ActionMenu extends Action {
@@ -14,11 +16,22 @@ public class ActionMenu extends Action {
@Override
public void run(CosmeticUser user, String raw) {
boolean ignorePermission = false;
raw = raw.replaceAll(" ", ""); // Removes all spaces
if (raw.contains("-o")) {
raw = raw.replaceAll("-o", "");
ignorePermission = true;
}
if (!Menus.hasMenu(raw)) {
HMCCosmeticsPlugin.getInstance().getLogger().info("Invalid Action Menu -> " + raw);
MessagesUtil.sendDebugMessages("Invalid Action Menu -> " + raw, Level.WARNING);
return;
}
Menu menu = Menus.getMenu(raw);
menu.openMenu(user, true);
MessagesUtil.sendDebugMessages(raw + " | " + ignorePermission);
menu.openMenu(user, ignorePermission);
}
}

View File

@@ -3,6 +3,7 @@ package com.hibiscusmc.hmccosmetics.gui.action.actions;
import com.hibiscusmc.hmccosmetics.gui.action.Action;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import org.jetbrains.annotations.NotNull;
public class ActionMessage extends Action {
@@ -11,7 +12,7 @@ public class ActionMessage extends Action {
}
@Override
public void run(CosmeticUser user, String raw) {
public void run(@NotNull CosmeticUser user, String raw) {
MessagesUtil.sendMessageNoKey(user.getPlayer(), raw);
}
}

View File

@@ -0,0 +1,51 @@
package com.hibiscusmc.hmccosmetics.gui.action.actions;
import com.hibiscusmc.hmccosmetics.gui.action.Action;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.HMCCServerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
import com.owen1212055.particlehelper.api.particle.types.BlockDataParticle;
import com.owen1212055.particlehelper.api.particle.types.DestinationParticle;
import com.owen1212055.particlehelper.api.particle.types.velocity.VelocityParticle;
import com.owen1212055.particlehelper.api.particle.types.vibration.VibrationParticle;
import com.owen1212055.particlehelper.api.type.ParticleType;
import com.owen1212055.particlehelper.api.type.Particles;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class ActionParticle extends Action {
public ActionParticle() {
super("particle");
}
@Override
@SuppressWarnings("ConstantConditions")
public void run(CosmeticUser user, @NotNull String raw) {
String[] rawString = raw.split(" ");
ParticleType<?, ?> particleType = Particles.fromKey(NamespacedKey.minecraft(rawString[0].toLowerCase()));
if (particleType == null) {
MessagesUtil.sendDebugMessages("The particle " + rawString[0] + " does not exist!");
return;
}
// particleType.multi() should never be null, but particleType can be.
boolean multi = particleType.multi() != null;
var particle = multi ? particleType.multi() : particleType.single();
if (particle instanceof DestinationParticle || particle instanceof BlockDataParticle
|| particle instanceof VibrationParticle || particle instanceof VelocityParticle) {
MessagesUtil.sendDebugMessages("The particle " + rawString[0] + " is not supported by this action!");
return;
}
particle = HMCCServerUtils.addParticleValues(particle, rawString);
Location location = user.getPlayer().getLocation();
for (Player player : HMCCPacketManager.getViewers(location)) {
particle.compile().send(player, location);
}
}
}

View File

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

View File

@@ -0,0 +1,36 @@
package com.hibiscusmc.hmccosmetics.gui.action.actions;
import com.hibiscusmc.hmccosmetics.gui.action.Action;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.logging.Level;
public class ActionSound extends Action {
// [SOUND] minecraft:test 1 1
public ActionSound() {
super("sound");
}
@Override
public void run(@NotNull CosmeticUser user, @NotNull String raw) {
Player player = user.getPlayer();
String[] processedString = raw.split(" ");
String soundName = processedString[0];
float volume = 1;
float pitch = 1;
if (processedString.length > 2) {
volume = Float.parseFloat(processedString[1]);
pitch = Float.parseFloat(processedString[2]);
}
MessagesUtil.sendDebugMessages("Attempting to play " + soundName, Level.INFO);
player.playSound(player.getLocation(), soundName, volume, pitch);
}
}

View File

@@ -0,0 +1,21 @@
package com.hibiscusmc.hmccosmetics.gui.action.actions;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.gui.action.Action;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.apache.commons.lang3.EnumUtils;
public class ActionUnequip extends Action {
public ActionUnequip() {
super("unequip");
}
@Override
public void run(CosmeticUser user, String raw) {
if (!EnumUtils.isValidEnum(CosmeticSlot.class, raw)) return;
CosmeticSlot slot = CosmeticSlot.valueOf(raw);
user.removeCosmeticSlot(slot);
}
}

View File

@@ -1,13 +1,14 @@
package com.hibiscusmc.hmccosmetics.gui.special;
import com.hibiscusmc.hmccolor.HMCColorApi;
import com.hibiscusmc.hmccolor.gui.guis.Gui;
import com.hibiscusmc.hmccolor.gui.guis.GuiItem;
import com.hibiscusmc.hmccolor.shaded.gui.guis.Gui;
import com.hibiscusmc.hmccolor.shaded.gui.guis.GuiItem;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.misc.Placeholder;
import me.lojosho.hibiscuscommons.hooks.Hooks;
import me.lojosho.hibiscuscommons.util.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Material;
@@ -15,34 +16,39 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.MapMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.jetbrains.annotations.NotNull;
public class DyeMenu {
// Yes, I do know how tacted on this feels.
public static void openMenu(CosmeticUser user, Cosmetic cosmetic) {
public static void openMenu(@NotNull CosmeticUser user, Cosmetic cosmetic) {
Player player = user.getPlayer();
if (player == null) return;
if (!Hooks.isActiveHook("HMCColor")) {
addCosmetic(user, cosmetic, null);
return;
}
ItemStack originalItem = user.getUserCosmeticItem(cosmetic);
if (originalItem == null || !cosmetic.isDyable()) return;
Player player = user.getPlayer();
Gui gui = HMCColorApi.INSTANCE.colorMenu();
gui.updateTitle(Placeholder.applyPapiPlaceholders(player, Settings.getDyeMenuName()));
gui.setItem(19, new GuiItem(originalItem));
Gui gui = HMCColorApi.createColorMenu(player);
gui.updateTitle(Hooks.processPlaceholders(player, StringUtils.parseStringToString(Settings.getDyeMenuName())));
gui.setItem(Settings.getDyeMenuInputSlot(), new GuiItem(originalItem));
gui.setDefaultTopClickAction(event -> {
if (event.getSlot() == 25) {
ItemStack item = event.getInventory().getItem(25);
if (event.getSlot() == Settings.getDyeMenuOutputSlot()) {
ItemStack item = event.getInventory().getItem(Settings.getDyeMenuOutputSlot());
if (item == null) return;
ItemMeta meta = item.getItemMeta();
if (meta == null) return;
Color color = meta instanceof LeatherArmorMeta ? ((LeatherArmorMeta) meta).getColor() :
meta instanceof PotionMeta ? ((PotionMeta) meta).getColor() : null;
Color color = meta instanceof LeatherArmorMeta leatherMeta ? leatherMeta.getColor() :
meta instanceof PotionMeta potionMeta ? potionMeta.getColor() :
meta instanceof MapMeta mapMeta ? mapMeta.getColor() : null;
if (color == null) return;
//user.removeCosmeticSlot(cosmetic);
user.addPlayerCosmetic(cosmetic, color);
player.setItemOnCursor(new ItemStack(Material.AIR));
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), player::closeInventory, 2);
addCosmetic(user, cosmetic, color);
event.setCancelled(true);
} else event.setCancelled(true);
});
@@ -50,4 +56,14 @@ public class DyeMenu {
gui.setCloseGuiAction(event -> {});
gui.open(player);
}
private static void addCosmetic(@NotNull CosmeticUser user, Cosmetic cosmetic, Color color) {
Player player = user.getPlayer();
user.addPlayerCosmetic(cosmetic, color);
player.setItemOnCursor(new ItemStack(Material.AIR));
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
player.closeInventory();
user.updateCosmetic(cosmetic.getSlot());
}, 2);
}
}

View File

@@ -1,13 +1,13 @@
package com.hibiscusmc.hmccosmetics.gui.type;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import me.lojosho.shaded.configurate.ConfigurationNode;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.meta.ItemMeta;
import org.spongepowered.configurate.ConfigurationNode;
import org.bukkit.inventory.ItemStack;
public class Type {
public abstract class Type {
private String id;
private final String id;
public Type(String id) {
this.id = id;
@@ -21,12 +21,8 @@ public class Type {
public void run(CosmeticUser user, ConfigurationNode config) {
run(user, config, null);
}
public void run(CosmeticUser user, ConfigurationNode config, ClickType clickType) {
// Override
}
public ItemMeta setLore(CosmeticUser user, ConfigurationNode config, ItemMeta itemMeta) {
//TODO: Finish this
return null; // Override
}
public abstract void run(CosmeticUser user, ConfigurationNode config, ClickType clickType);
public abstract ItemStack setItem(CosmeticUser user, ConfigurationNode config, ItemStack itemStack, int slot);
}

View File

@@ -2,21 +2,22 @@ package com.hibiscusmc.hmccosmetics.gui.type;
import com.hibiscusmc.hmccosmetics.gui.type.types.TypeCosmetic;
import com.hibiscusmc.hmccosmetics.gui.type.types.TypeEmpty;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
public class Types {
private static HashMap<String, Type> types = new HashMap<>();
private static final HashMap<String, Type> types = new HashMap<>();
private static TypeCosmetic TYPE_COSMETIC = new TypeCosmetic();
private static TypeEmpty TYPE_EMPTY = new TypeEmpty();
public static Type getType(String id) {
public static Type getType(@NotNull String id) {
return types.get(id.toUpperCase());
}
public static boolean isType(String id) {
public static boolean isType(@NotNull String id) {
return types.containsKey(id.toUpperCase());
}

View File

@@ -1,43 +1,83 @@
package com.hibiscusmc.hmccosmetics.gui.type.types;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType;
import com.hibiscusmc.hmccosmetics.gui.action.Actions;
import com.hibiscusmc.hmccosmetics.gui.special.DyeMenu;
import com.hibiscusmc.hmccosmetics.gui.type.Type;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import me.lojosho.hibiscuscommons.config.serializer.ItemSerializer;
import me.lojosho.hibiscuscommons.hooks.Hooks;
import me.lojosho.shaded.configurate.ConfigurationNode;
import me.lojosho.shaded.configurate.serialize.SerializationException;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class TypeCosmetic extends Type {
public TypeCosmetic(String id) {
super(id);
}
public TypeCosmetic() {
super("cosmetic");
}
@Override
public void run(CosmeticUser user, ConfigurationNode config, ClickType clickType) {
if (config.node("cosmetic").virtual()) return;
public void run(CosmeticUser user, @NotNull ConfigurationNode config, ClickType clickType) {
MessagesUtil.sendDebugMessages("Running Cosmetic Click Type");
if (config.node("cosmetic").virtual()) {
MessagesUtil.sendDebugMessages("Cosmetic Config Field Virtual");
return;
}
String cosmeticName = config.node("cosmetic").getString();
Cosmetic cosmetic = Cosmetics.getCosmetic(cosmeticName);
Player player = user.getPlayer();
if (cosmetic == null) {
MessagesUtil.sendMessage(user.getPlayer(), "invalid-cosmetic");
MessagesUtil.sendDebugMessages("No Cosmetic Found");
MessagesUtil.sendMessage(player, "invalid-cosmetic");
return;
}
if (!user.canEquipCosmetic(cosmetic)) {
MessagesUtil.sendMessage(user.getPlayer(), "no-cosmetic-permission");
MessagesUtil.sendDebugMessages("No Cosmetic Permission");
MessagesUtil.sendMessage(player, "no-cosmetic-permission");
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<>();
ConfigurationNode actionConfig = config.node("actions");
MessagesUtil.sendDebugMessages("Running Actions");
try {
if (!actionConfig.node("any").virtual()) actionStrings.addAll(actionConfig.node("any").getList(String.class));
@@ -48,9 +88,15 @@ public class TypeCosmetic extends Type {
if (clickType.isRightClick()) {
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));
MessagesUtil.sendDebugMessages("on-unequip");
user.removeCosmeticSlot(cosmetic);
@@ -58,7 +104,7 @@ public class TypeCosmetic extends Type {
if (!actionConfig.node("on-equip").virtual()) actionStrings.addAll(actionConfig.node("on-equip").getList(String.class));
MessagesUtil.sendDebugMessages("on-equip");
// TODO: Redo this
if (cosmetic.isDyable()) {
if (cosmetic.isDyable() && Hooks.isActiveHook("HMCColor")) {
DyeMenu.openMenu(user, cosmetic);
} else {
user.addPlayerCosmetic(cosmetic);
@@ -68,9 +114,90 @@ public class TypeCosmetic extends Type {
Actions.runActions(user, actionStrings);
} catch (SerializationException e) {
throw new RuntimeException(e);
e.printStackTrace();
}
// Fixes issue with offhand cosmetics not appearing. Yes, I know this is dumb
Runnable run = () -> user.updateCosmetic(cosmetic.getSlot());
if (cosmetic instanceof CosmeticArmorType) {
if (((CosmeticArmorType) cosmetic).getEquipSlot().equals(EquipmentSlot.OFF_HAND)) {
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), run, 1);
}
}
run.run();
MessagesUtil.sendDebugMessages("Finished Type Click Run");
}
@Override
public ItemStack setItem(CosmeticUser user, @NotNull ConfigurationNode config, ItemStack itemStack, int slot) {
itemStack.setItemMeta(processLoreLines(user, itemStack.getItemMeta()));
if (config.node("cosmetic").virtual()) {
return itemStack;
}
String cosmeticName = config.node("cosmetic").getString();
Cosmetic cosmetic = Cosmetics.getCosmetic(cosmeticName);
if (cosmetic == null) {
return itemStack;
}
user.updateCosmetic(cosmetic.getSlot());
if (user.hasCosmeticInSlot(cosmetic) && !config.node("equipped-item").virtual()) {
MessagesUtil.sendDebugMessages("GUI Equipped Item");
ConfigurationNode equippedItem = config.node("equipped-item");
try {
if (equippedItem.node("material").virtual()) equippedItem.node("material").set(config.node("item", "material").getString());
} catch (SerializationException e) {
// Nothing >:)
}
try {
itemStack = ItemSerializer.INSTANCE.deserialize(ItemStack.class, equippedItem);
} catch (SerializationException e) {
throw new RuntimeException(e);
}
itemStack.setItemMeta(processLoreLines(user, itemStack.getItemMeta()));
return itemStack;
}
if (!user.canEquipCosmetic(cosmetic, true) && !config.node("locked-item").virtual()) {
MessagesUtil.sendDebugMessages("GUI Locked Item");
ConfigurationNode lockedItem = config.node("locked-item");
try {
if (lockedItem.node("material").virtual()) lockedItem.node("material").set(config.node("item", "material").getString());
} catch (SerializationException e) {
// Nothing >:)
}
try {
itemStack = ItemSerializer.INSTANCE.deserialize(ItemStack.class, lockedItem);
} catch (SerializationException e) {
throw new RuntimeException(e);
}
itemStack.setItemMeta(processLoreLines(user, itemStack.getItemMeta()));
return itemStack;
}
return itemStack;
}
@Contract("_, _ -> param2")
@NotNull
@SuppressWarnings("Duplicates")
private ItemMeta processLoreLines(CosmeticUser user, @NotNull ItemMeta itemMeta) {
List<String> processedLore = new ArrayList<>();
if (itemMeta.hasDisplayName()) {
itemMeta.setDisplayName(Hooks.processPlaceholders(user.getPlayer(), itemMeta.getDisplayName()));
}
if (itemMeta.hasLore()) {
for (String loreLine : itemMeta.getLore()) {
processedLore.add(Hooks.processPlaceholders(user.getPlayer(), loreLine));
}
}
if (itemMeta instanceof SkullMeta skullMeta) {
if (skullMeta.hasOwner()) {
skullMeta.setOwner(Hooks.processPlaceholders(user.getPlayer(), skullMeta.getOwner()));
}
}
itemMeta.setLore(processedLore);
return itemMeta;
}
}

View File

@@ -3,9 +3,14 @@ package com.hibiscusmc.hmccosmetics.gui.type.types;
import com.hibiscusmc.hmccosmetics.gui.action.Actions;
import com.hibiscusmc.hmccosmetics.gui.type.Type;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
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.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
@@ -13,7 +18,6 @@ import java.util.List;
public class TypeEmpty extends Type {
// This can be used as an example for making your own types.
public TypeEmpty() {
super("empty");
// This is an empty type, meaning, when a menu item has a type of "empty" it will run the code in the method run.
@@ -21,7 +25,7 @@ public class TypeEmpty extends Type {
// This is the code that's run when the item is clicked.
@Override
public void run(CosmeticUser user, ConfigurationNode config, ClickType clickType) {
public void run(CosmeticUser user, @NotNull ConfigurationNode config, ClickType clickType) {
List<String> actionStrings = new ArrayList<>(); // List where we keep the actions the server will execute.
ConfigurationNode actionConfig = config.node("actions"); // Configuration node that actions are under.
@@ -29,7 +33,7 @@ public class TypeEmpty extends Type {
try {
// This gets the actions with the item. We can add more, such as with the Cosmetic type, an equip and unequip action set.
// We add that to a List of Strings, before running those actions through the server. This is not the area where we deal
// with actions, mearly what should be done for each item.
// with actions, merely what should be done for each item.
if (!actionConfig.node("any").virtual()) actionStrings.addAll(actionConfig.node("any").getList(String.class));
if (clickType != null) {
@@ -39,6 +43,12 @@ public class TypeEmpty extends Type {
if (clickType.isRightClick()) {
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.
@@ -48,6 +58,33 @@ public class TypeEmpty extends Type {
}
}
@Override
@SuppressWarnings("Duplicates")
public ItemStack setItem(CosmeticUser user, ConfigurationNode config, @NotNull ItemStack itemStack, int slot) {
List<String> processedLore = new ArrayList<>();
ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta.hasDisplayName()) {
itemMeta.setDisplayName(Hooks.processPlaceholders(user.getPlayer(), itemMeta.getDisplayName()));
}
if (itemMeta.hasLore()) {
for (String loreLine : itemMeta.getLore()) {
processedLore.add(Hooks.processPlaceholders(user.getPlayer(), loreLine));
}
}
if (itemMeta instanceof SkullMeta skullMeta) {
if (skullMeta.hasOwner()) {
skullMeta.setOwner(Hooks.processPlaceholders(user.getPlayer(), skullMeta.getOwner()));
}
}
itemMeta.setLore(processedLore);
itemStack.setItemMeta(itemMeta);
return itemStack;
}
// That's it! Now, add it as a static in another one of your classes (such as your main class) and you are good to go.
// If you need help with that, check the Types class.
}

View File

@@ -1,166 +0,0 @@
package com.hibiscusmc.hmccosmetics.hooks;
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.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.TranslationUtil;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.OfflinePlayer;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
public class PAPIHook extends PlaceholderExpansion {
private static boolean papiEnabled = false;
public PAPIHook() {
papiEnabled = true;
}
@Override
public @NotNull String getIdentifier() {
return "HMCCosmetics";
}
@Override
public @NotNull String getAuthor() {
return "HibiscusMC";
}
@Override
public @NotNull String getVersion() {
return HMCCosmeticsPlugin.getInstance().getDescription().getVersion();
}
@Override
public String onRequest(OfflinePlayer player, String params) {
if (!player.isOnline()) return null;
CosmeticUser user = CosmeticUsers.getUser(player.getPlayer());
if (user == null) return null;
List<String> placeholderArgs = Arrays.asList(params.split("_", 3));
switch (placeholderArgs.get(0).toLowerCase()) {
case "using":
if (placeholderArgs == null) {
return null;
}
if (placeholderArgs.get(1) != null) {
Cosmetic cosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1));
if (user.getCosmetic(cosmetic.getSlot()).getId() == cosmetic.getId()) return "true";
return "false";
}
case "current":
if (placeholderArgs == null) {
return null;
}
if (placeholderArgs.get(1) != null) {
CosmeticSlot slot = CosmeticSlot.valueOf(placeholderArgs.get(1).toUpperCase());
if (slot == null) return null;
if (placeholderArgs.size() == 2) return user.getCosmetic(slot).getId();
switch (placeholderArgs.get(2).toLowerCase()) {
case "material" -> {
return getMaterial(user.getCosmetic(slot));
}
case "custommodeldata" -> {
return getModelData(user.getCosmetic(slot));
}
case "name" -> {
return getItemName(user.getCosmetic(slot));
}
case "lore" -> {
return getItemLore(user.getCosmetic(slot));
}
case "permission" -> {
return user.getCosmetic(slot).getPermission();
}
default -> {
return user.getCosmetic(slot).getId();
}
}
}
case "unlocked":
if (placeholderArgs == null) {
return null;
}
if (placeholderArgs.get(1) != null) {
Cosmetic cosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1));
if (cosmetic == null) {
Cosmetic secondAttemptCosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1) + "_" + placeholderArgs.get(2));
if (secondAttemptCosmetic == null) {
return "INVALID_COSMETIC";
} else {
cosmetic = secondAttemptCosmetic;
}
}
return TranslationUtil.getTranslation("unlockedCosmetic", String.valueOf(user.canEquipCosmetic(cosmetic)));
}
case "equipped":
if (placeholderArgs == null) {
return null;
}
if (placeholderArgs.get(1) != null) {
Cosmetic cosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1));
if (cosmetic == null) {
Cosmetic secondAttemptCosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1) + "_" + placeholderArgs.get(2));
if (secondAttemptCosmetic == null) {
return "INVALID_COSMETIC";
} else {
cosmetic = secondAttemptCosmetic;
}
}
if (user.getCosmetic(cosmetic.getSlot()) == null) return "false";
if (cosmetic.getId() == user.getCosmetic(cosmetic.getSlot()).getId()) {
return "true";
} else {
return "false";
}
}
case "wardrobe-enabled":
return String.valueOf(user.isInWardrobe());
}
return null;
}
public String getMaterial(Cosmetic cosmetic) {
ItemStack item = cosmetic.getItem();
if (item == null) return null;
return cosmetic.getItem().getType().toString();
}
public String getModelData(Cosmetic cosmetic) {
ItemStack item = cosmetic.getItem();
if (item == null) return null;
if (!item.hasItemMeta()) return null;
ItemMeta itemMeta = item.getItemMeta();
return String.valueOf(itemMeta.getCustomModelData());
}
public String getItemName(Cosmetic cosmetic) {
ItemStack item = cosmetic.getItem();
if (item == null) return null;
if (!item.hasItemMeta()) return null;
ItemMeta itemMeta = item.getItemMeta();
return itemMeta.getDisplayName();
}
public String getItemLore(Cosmetic cosmetic) {
ItemStack item = cosmetic.getItem();
if (item == null) return null;
if (item.hasItemMeta()) {
return String.valueOf(item.getItemMeta().getLore());
}
return null;
}
public static boolean isPAPIEnabled() {
return papiEnabled;
}
}

View File

@@ -1,21 +0,0 @@
package com.hibiscusmc.hmccosmetics.hooks.items;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
public class HMCCosmeticsHook extends ItemHook implements Listener {
public HMCCosmeticsHook() {
super("HMCCosmetics");
}
@Override
public ItemStack get(String itemid) {
Cosmetic cosmetic = Cosmetics.getCosmetic(itemid);
if (cosmetic == null) return null;
return cosmetic.getItem();
}
}

View File

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

View File

@@ -1,37 +0,0 @@
package com.hibiscusmc.hmccosmetics.hooks.items;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import dev.lone.itemsadder.api.CustomStack;
import dev.lone.itemsadder.api.Events.ItemsAdderLoadDataEvent;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
public class ItemAdderHook extends ItemHook implements Listener {
// I hate IA, this overcomplicate stuff is so unneeded if it just did its stuff when its needed.
private boolean enabled = false;
public ItemAdderHook() {
super("itemsadder");
}
@Override
public ItemStack get(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) {
this.enabled = true;
HMCCosmeticsPlugin.setup();
}
}

View File

@@ -1,33 +0,0 @@
package com.hibiscusmc.hmccosmetics.hooks.items;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
public class ItemHook implements Listener {
private String id;
private boolean active;
public ItemHook(String id) {
this.id = id;
active = false;
ItemHooks.addItemHook(this);
}
public ItemStack get(String itemid) {
return null;
// Override
}
public String getId() {
return id;
}
public void setActive(boolean active) {
this.active = active;
}
public boolean getActive() {
return this.active;
}
}

View File

@@ -1,57 +0,0 @@
package com.hibiscusmc.hmccosmetics.hooks.items;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import java.util.HashMap;
public class ItemHooks {
private static HashMap<String, ItemHook> itemHooks = new HashMap<>();
private static OraxenHook ORAXEN_HOOK = new OraxenHook();
private static ItemAdderHook ITEMADDER_HOOK = new ItemAdderHook();
private static MythicHook MYTHIC_HOOK = new MythicHook();
private static HMCCosmeticsHook HMCCOSMETIC_HOOK = new HMCCosmeticsHook();
public static ItemHook getItemHook(String id) {
return itemHooks.get(id.toLowerCase());
}
public static boolean isItemHook(String id) {
return itemHooks.containsKey(id.toLowerCase());
}
public static void addItemHook(ItemHook hook) {
itemHooks.put(hook.getId().toLowerCase(), hook);
}
public static void setup() {
for (ItemHook itemHook : itemHooks.values()) {
if (Bukkit.getPluginManager().getPlugin(itemHook.getId()) != null) {
HMCCosmeticsPlugin.getInstance().getServer().getPluginManager().registerEvents(itemHook, HMCCosmeticsPlugin.getInstance());
itemHook.setActive(true);
HMCCosmeticsPlugin.getInstance().getLogger().info("Successfully hooked into " + itemHook.getId());
}
}
}
public static ItemStack getItem(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;
ItemHook itemHook = getItemHook(split[0]);
if (!itemHook.getActive()) return null;
ItemStack item = itemHook.get(split[1]);
return item;
}
}

View File

@@ -1,16 +0,0 @@
package com.hibiscusmc.hmccosmetics.hooks.items;
import io.lumine.mythic.bukkit.MythicBukkit;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
public class MythicHook extends ItemHook implements Listener {
public MythicHook() {
super("mythicmobs");
}
@Override
public ItemStack get(String itemid) {
return MythicBukkit.inst().getItemManager().getItemStack(itemid);
}
}

View File

@@ -1,17 +0,0 @@
package com.hibiscusmc.hmccosmetics.hooks.items;
import io.th0rgal.oraxen.api.OraxenItems;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
public class OraxenHook extends ItemHook implements Listener {
public OraxenHook() {
super("oraxen");
}
@Override
public ItemStack get(String itemid) {
return OraxenItems.getItemById(itemid).build();
}
}

View File

@@ -0,0 +1,250 @@
package com.hibiscusmc.hmccosmetics.hooks.placeholders;
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.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.TranslationUtil;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.apache.commons.lang3.EnumUtils;
import org.bukkit.OfflinePlayer;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
/**
* A hook that integrates the plugin {@link me.clip.placeholderapi.PlaceholderAPIPlugin PlaceholderAPIPlugin}
*/
public class HMCPlaceholderExpansion extends PlaceholderExpansion {
private static boolean papiEnabled = false;
public HMCPlaceholderExpansion() {
papiEnabled = true;
}
@Override
@NotNull
public String getIdentifier() {
return "HMCCosmetics";
}
@Override
@NotNull
public String getAuthor() {
return "HibiscusMC";
}
@Override
@NotNull
public String getVersion() {
return HMCCosmeticsPlugin.getInstance().getDescription().getVersion();
}
@Override
public boolean persist() {
return true;
}
@Override
public String onRequest(@NotNull OfflinePlayer player, @NotNull String params) {
if (!player.isOnline()) return TranslationUtil.getTranslation("user-cosmetic", "offline");
CosmeticUser user = CosmeticUsers.getUser(player.getPlayer());
if (user == null) return TranslationUtil.getTranslation("user-cosmetic", "invalid-user");
List<String> placeholderArgs = Arrays.asList(params.split("_", 3));
switch (placeholderArgs.get(0).toLowerCase()) {
case "using":
if (placeholderArgs.size() >= 2) {
Cosmetic cosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1));
if (cosmetic == null) return "INVALID_COSMETIC";
Cosmetic currentCosmetic = user.getCosmetic(cosmetic.getSlot());
if (currentCosmetic == null) return TranslationUtil.getTranslation("using-cosmetic", String.valueOf(false)); // I hate this way of handling translations
if (currentCosmetic.getId() == cosmetic.getId()) return TranslationUtil.getTranslation("using-cosmetic", String.valueOf(true));
return TranslationUtil.getTranslation("using-cosmetic", String.valueOf(false));
}
case "current":
if (placeholderArgs.size() >= 2) {
CosmeticSlot slot = CosmeticSlot.valueOf(placeholderArgs.get(1).toUpperCase());
if (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();
String output;
switch (placeholderArgs.get(2).toLowerCase()) {
case "material" -> {
output = getMaterialName(user.getCosmetic(slot));
}
case "custommodeldata" -> {
output = getModelData(user.getCosmetic(slot));
}
case "name" -> {
output = getItemName(user.getCosmetic(slot));
}
case "lore" -> {
output = getItemLore(user.getCosmetic(slot));
}
case "permission" -> {
output = user.getCosmetic(slot).getPermission();
}
default -> {
output = user.getCosmetic(slot).getId();
}
}
if (output == null) output = "none";
return TranslationUtil.getTranslation("current-cosmetic", output);
}
case "unlocked":
if (placeholderArgs.size() >= 2) {
Cosmetic cosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1));
if (cosmetic == null) {
if (placeholderArgs.size() >= 3) {
Cosmetic secondAttemptCosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1) + "_" + placeholderArgs.get(2));
if (secondAttemptCosmetic == null) {
return "INVALID_COSMETIC";
} else {
cosmetic = secondAttemptCosmetic;
}
} else {
return "INVALID_COSMETIC";
}
}
return TranslationUtil.getTranslation("unlocked-cosmetic", String.valueOf(user.canEquipCosmetic(cosmetic, true)));
}
case "equipped":
if (placeholderArgs.size() >= 2) {
String args1 = placeholderArgs.get(1);
if (EnumUtils.isValidEnum(CosmeticSlot.class, args1.toUpperCase())) {
return TranslationUtil.getTranslation("equipped-cosmetic", String.valueOf(user.getCosmetic(CosmeticSlot.valueOf(args1.toUpperCase())) != null));
}
MessagesUtil.sendDebugMessages(args1);
Cosmetic cosmetic = Cosmetics.getCosmetic(args1);
if (cosmetic == null) {
if (placeholderArgs.size() == 3) {
Cosmetic secondAttemptCosmetic = Cosmetics.getCosmetic(placeholderArgs.get(1) + "_" + placeholderArgs.get(2));
if (secondAttemptCosmetic == null) {
return "INVALID_COSMETIC";
} else {
cosmetic = secondAttemptCosmetic;
}
} else {
return "INVALID_COSMETIC";
}
}
Cosmetic equippedCosmetic = user.getCosmetic(cosmetic.getSlot());
if (equippedCosmetic == null) return TranslationUtil.getTranslation("equipped-cosmetic", "false");
return TranslationUtil.getTranslation("equipped-cosmetic", String.valueOf(cosmetic.getId().equals(equippedCosmetic.getId())));
}
// %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":
return TranslationUtil.getTranslation("in-wardrobe", String.valueOf(user.isInWardrobe()));
}
return null;
}
/**
* Gets the name of the cosmetic item {@link org.bukkit.Material Material}
* @param cosmetic The cosmetic to get its {@link org.bukkit.Material Material}s name
* @return The name of the cosmetic item {@link org.bukkit.Material Material}
* @deprecated As of release 2.2.5+, use {@link #getMaterialName(Cosmetic)} instead
*/
@Deprecated
@Nullable
public String getMaterial(@NotNull Cosmetic cosmetic) {
ItemStack item = cosmetic.getItem();
if (item == null) return null;
return item.getType().toString();
}
/**
* Gets the name of the cosmetic item {@link org.bukkit.Material Material}
* @param cosmetic The cosmetic to get its {@link org.bukkit.Material Material}s name
* @return The name of the cosmetic item {@link org.bukkit.Material Material}
* @since 2.2.5
*/
@Nullable
public String getMaterialName(@NotNull Cosmetic cosmetic) {
ItemStack item = cosmetic.getItem();
if (item == null) return null;
return item.getType().toString();
}
/**
* Gets the cosmetic items custom model data
* @param cosmetic The cosmetic to get its custom model data
* @return The cosmetic items custom model data
*/
@Nullable
public String getModelData(@NotNull Cosmetic cosmetic) {
ItemStack item = cosmetic.getItem();
if (item == null) return null;
if (!item.hasItemMeta()) return null;
ItemMeta itemMeta = item.getItemMeta();
if (itemMeta == null) return null;
return String.valueOf(itemMeta.getCustomModelData());
}
/**
* Gets the cosmetic items display name
* @param cosmetic The cosmetic to get its items display name
* @return The cosmetic items display name
*/
@Nullable
public String getItemName(@NotNull Cosmetic cosmetic) {
ItemStack item = cosmetic.getItem();
if (item == null) return null;
if (!item.hasItemMeta()) return null;
ItemMeta itemMeta = item.getItemMeta();
if (itemMeta == null) return null;
if (!itemMeta.hasDisplayName()) return null;
return itemMeta.getDisplayName();
}
/**
* Gets the cosmetic items lore
* @param cosmetic The cosmetic to get its items lore
* @return The cosmetic items lore
*/
@Nullable
public String getItemLore(@NotNull Cosmetic cosmetic) {
ItemStack item = cosmetic.getItem();
if (item == null) return null;
if (item.hasItemMeta()) {
ItemMeta itemMeta = item.getItemMeta();
if (itemMeta == null) return null;
return String.valueOf(itemMeta.getLore());
}
return null;
}
}

View File

@@ -4,24 +4,39 @@ import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.flags.StringFlag;
import com.sk89q.worldguard.protection.flags.registry.FlagConflictException;
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
import java.util.logging.Level;
/**
* A hook that integrates the plugin {@link com.sk89q.worldguard.WorldGuard WorldGuard}
*/
public class WGHook {
/**
* @implNote Please use {@link #getCosmeticEnableFlag()} instead
*/
private static StateFlag COSMETIC_ENABLE_FLAG;
public static StateFlag COSMETIC_ENABLE_FLAG;
public static StateFlag COSMETIC_WARDROBE_FLAG;
private static StateFlag EMOTES_ENABLE_FLAG;
/**
* @implNote Please use {@link #getCosmeticWardrobeFlag()} instead
*/
private static StringFlag COSMETIC_WARDROBE_FLAG;
public WGHook() {
FlagRegistry registry = WorldGuard.getInstance().getFlagRegistry();
try {
StateFlag cosmeticFlag = new StateFlag("cosmetic-enable", false);
StateFlag wardrobeFlag = new StateFlag("cosmetic-wardrobe", false);
StateFlag emoteFlag = new StateFlag("emotes-enable", false);
StringFlag wardrobeFlag = new StringFlag("cosmetic-wardrobe");
registry.register(cosmeticFlag);
registry.register(emoteFlag);
registry.register(wardrobeFlag);
COSMETIC_ENABLE_FLAG = cosmeticFlag;
EMOTES_ENABLE_FLAG = emoteFlag;
COSMETIC_WARDROBE_FLAG = wardrobeFlag;
} catch (FlagConflictException e) {
Flag<?> existing = registry.get("cosmetic-enable");
@@ -35,11 +50,27 @@ public class WGHook {
}
}
/**
* Gets the cosmetic enable {@link StateFlag}
* @return The cosmetic enable {@link StateFlag}
*/
public static StateFlag getCosmeticEnableFlag() {
return COSMETIC_ENABLE_FLAG;
}
public static StateFlag getCosmeticWardrobeFlag() {
/**
* Gets the emotes enable {@link StateFlag}
* @return The emotes enable {@link StateFlag}
*/
public static StateFlag getEmotesEnableFlag() {
return EMOTES_ENABLE_FLAG;
}
/**
* Gets the cosmetic wardrobe {@link StateFlag}
* @return The cosmetic wardrobe {@link StateFlag}
*/
public static StringFlag getCosmeticWardrobeFlag() {
return COSMETIC_WARDROBE_FLAG;
}

View File

@@ -1,5 +1,8 @@
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.CosmeticUsers;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
@@ -9,33 +12,95 @@ import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.RegionContainer;
import com.sk89q.worldguard.protection.regions.RegionQuery;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.jetbrains.annotations.NotNull;
/**
* Contains {@link com.sk89q.worldguard.WorldGuard WorldGuard} related event listeners
*/
public class WGListener implements Listener {
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerMove(@NotNull PlayerMoveEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
if (user == null) return;
Location location = event.getPlayer().getLocation();
com.sk89q.worldedit.util.Location loc = BukkitAdapter.adapt(location);
RegionContainer region = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = region.createQuery();
ApplicableRegionSet set = query.getApplicableRegions(loc);
// TODO: Add more cosmetics
if (set.getRegions().size() == 0) {
user.showCosmetics();
ApplicableRegionSet set = getRegions(location);
if (user.isHidden()) {
if (set.getRegions().isEmpty()) {
user.showCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
}
}
for (ProtectedRegion protectedRegion : set.getRegions()) {
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticEnableFlag())) {
user.hideCosmetics();
if (protectedRegion.getFlags().get(WGHook.getCosmeticEnableFlag()).toString().equalsIgnoreCase("ALLOW")) {
user.showCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
return;
}
user.hideCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
return;
}
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticWardrobeFlag())) {
user.enterWardrobe();
if (!WardrobeSettings.getWardrobeNames().contains(protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString())) return;
Wardrobe wardrobe = WardrobeSettings.getWardrobe(protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString());
user.enterWardrobe(true, wardrobe);
}
}
}
@EventHandler(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.isHidden()) {
if (set.getRegions().isEmpty()) {
user.showCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
}
}
for (ProtectedRegion protectedRegion : set.getRegions()) {
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticEnableFlag())) {
if (protectedRegion.getFlags().get(WGHook.getCosmeticEnableFlag()).toString().equalsIgnoreCase("ALLOW")) {
user.showCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
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,27 +2,47 @@ package com.hibiscusmc.hmccosmetics.listener;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.DatabaseSettings;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.database.Database;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.jetbrains.annotations.NotNull;
public class PlayerConnectionListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoin(@NotNull PlayerJoinEvent event) {
if (event.getPlayer().isOp() || event.getPlayer().hasPermission("hmccosmetics.notifyupdate")) {
if (!HMCCosmeticsPlugin.getInstance().getLatestVersion().equalsIgnoreCase(HMCCosmeticsPlugin.getInstance().getDescription().getVersion()) && HMCCosmeticsPlugin.getInstance().getLatestVersion().isEmpty())
MessagesUtil.sendMessageNoKey(
event.getPlayer(),
"<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.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>!" +
"<br>"
);
}
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());
CosmeticUsers.addUser(user);
MessagesUtil.sendDebugMessages("Run User Join");
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> user.updateCosmetic(), 4);
// 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()) {
@@ -33,19 +53,18 @@ public class PlayerConnectionListener implements Listener {
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerQuit(@NotNull PlayerQuitEvent event) {
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 (!event.getPlayer().getPassengers().isEmpty()) {
for (Entity entity : event.getPlayer().getPassengers()) {
if (entity.getType() == EntityType.ARMOR_STAND) {
entity.remove();
}
}
}
if (user == null) return; // Player never initialized, don't do anything
if (user.isInWardrobe()) {
user.leaveWardrobe(true);
user.getPlayer().setInvisible(false);
}
if (user.getUserEmoteManager().isPlayingEmote()) {
user.getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.CONNECTION);
event.getPlayer().setInvisible(false);
}
if (user.isInWardrobe()) user.leaveWardrobe();
Database.save(user);
user.destroy();
CosmeticUsers.removeUser(user.getUniqueId());

View File

@@ -9,34 +9,52 @@ import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.Pair;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.api.events.PlayerCosmeticPostEquipEvent;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
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.CosmeticEmoteType;
import com.hibiscusmc.hmccosmetics.gui.Menu;
import com.hibiscusmc.hmccosmetics.gui.Menus;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
import com.hibiscusmc.hmccosmetics.util.InventoryUtils;
import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;
import com.hibiscusmc.hmccosmetics.user.manager.UserWardrobeManager;
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
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.Color;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.Pose;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.entity.*;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.*;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.spigotmc.event.entity.EntityDismountEvent;
import org.spigotmc.event.entity.EntityMountEvent;
import java.util.*;
@@ -45,25 +63,36 @@ public class PlayerGameListener implements Listener {
public PlayerGameListener() {
registerInventoryClickListener();
registerMenuChangeListener();
registerEntityStatusListener();
registerPlayerEquipmentListener();
registerPlayerArmListener();
registerEntityUseListener();
registerSlotChangeListener();
//registerLookMovement();
//registerMoveListener();
//registerTeleportMovement();
}
@EventHandler
@EventHandler(priority = EventPriority.LOW)
public void onPlayerClick(@NotNull InventoryClickEvent event) {
if (event.getClick() != ClickType.SHIFT_LEFT && event.getClick() != ClickType.SHIFT_RIGHT) return;
// || !event.getClickedInventory().getType().equals(InventoryType.PLAYER)
if (event.getClick().isShiftClick()) return;
MessagesUtil.sendDebugMessages("inventoryclickevent");
//if (event.getSlotType() != InventoryType.SlotType.ARMOR) return;
CosmeticUser user = CosmeticUsers.getUser(event.getWhoClicked().getUniqueId());
if (user == null) return;
ItemStack item = event.getCurrentItem();
if (item == null) return;
if (Settings.isDestroyLooseCosmetics() && HMCCInventoryUtils.isCosmeticItem(event.getCurrentItem())) {
MessagesUtil.sendDebugMessages("remvoe item");
event.getWhoClicked().getInventory().removeItem(event.getCurrentItem());
}
EquipmentSlot slot = getArmorSlot(item.getType());
if (slot == null) return;
CosmeticSlot cosmeticSlot = InventoryUtils.BukkitCosmeticSlot(slot);
CosmeticSlot cosmeticSlot = HMCCInventoryUtils.BukkitCosmeticSlot(slot);
if (cosmeticSlot == null) return;
if (!user.hasCosmeticInSlot(cosmeticSlot)) return;
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
@@ -72,18 +101,22 @@ public class PlayerGameListener implements Listener {
MessagesUtil.sendDebugMessages("Event fired, updated cosmetic " + cosmeticSlot);
}
@EventHandler
@EventHandler(priority = EventPriority.LOW)
public void onPlayerShift(PlayerToggleSneakEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId());
if (!event.isSneaking()) return;
if (user == null) return;
if (event.isSneaking()) {
user.getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.SNEAK);
}
if (!event.isSneaking()) return;
if (!user.isInWardrobe()) return;
user.leaveWardrobe();
}
@EventHandler
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerTeleport(PlayerTeleportEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId());
@@ -93,27 +126,34 @@ public class PlayerGameListener implements Listener {
return;
}
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
user.hideBackpack();
user.getBackpackEntity().teleport(event.getTo());
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
user.updateCosmetic();
}, 2);
if (user.isInWardrobe()) {
user.leaveWardrobe();
}
if (event.getCause().equals(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL) || event.getCause().equals(PlayerTeleportEvent.TeleportCause.END_PORTAL)) return;
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 {
user.showCosmetics(CosmeticUser.HiddenReason.WORLD);
}
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK) && user.getUserBackpackManager() != null) {
user.respawnBackpack();
}
if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
user.respawnBalloon();
}
user.updateCosmetic();
}, 2);
if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
user.updateCosmetic(CosmeticSlot.BALLOON);
}, 2);
if (event.getCause().equals(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL) || event.getCause().equals(PlayerTeleportEvent.TeleportCause.END_PORTAL)) return;
if (user.getUserEmoteManager().isPlayingEmote()) {
user.getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.TELEPORT);
}
}
@EventHandler
public void portalTeleport(PlayerPortalEvent event) {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPortalTeleport(PlayerPortalEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId());
MessagesUtil.sendDebugMessages("Player Teleport Event");
@@ -122,41 +162,89 @@ public class PlayerGameListener implements Listener {
return;
}
final Cosmetic cosmetic = user.getCosmetic(CosmeticSlot.BALLOON);
final Color color = user.getCosmeticColor(CosmeticSlot.BALLOON);
user.removeCosmeticSlot(CosmeticSlot.BALLOON);
if (Settings.getDisabledWorlds().contains(user.getEntity().getLocation().getWorld().getName())) {
user.hideCosmetics(CosmeticUser.HiddenReason.WORLD);
} else {
user.showCosmetics(CosmeticUser.HiddenReason.WORLD);
}
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
user.addPlayerCosmetic(cosmetic, color);
user.updateCosmetic();
}, 4);
if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
user.despawnBalloon();
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
user.spawnBalloon((CosmeticBalloonType) user.getCosmetic(CosmeticSlot.BALLOON));
user.updateCosmetic();
}, 4);
}
}
@EventHandler
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onPlayerHit(EntityDamageByEntityEvent event) {
if (event.isCancelled()) return;
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))
return;
event.setCancelled(true);
}
@EventHandler
public void onPlayerLook(PlayerMoveEvent event) {
// TODO: Move to packets
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId());
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerDamaged(EntityDamageEvent event) {
if (!(event.getEntity() instanceof Player player)) return;
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
// Really need to look into optimization of this
if (user.getUserEmoteManager().isPlayingEmote()) {
if (Settings.isEmoteInvincible()) {
event.setCancelled(true);
}
if (Settings.isEmoteDamageLeave()) {
user.getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.DAMAGE);
}
}
if (user.isInWardrobe()) {
if (WardrobeSettings.isPreventDamage()) {
event.setCancelled(true);
return;
}
if (WardrobeSettings.isDamagedKicked()) user.leaveWardrobe();
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerLook(PlayerMoveEvent event) {
Player player = event.getPlayer();
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
if (!Settings.isEmoteMoveCheck() && user.getUserEmoteManager().isPlayingEmote()) {
event.setCancelled(true);
return;
}
user.updateCosmetic(CosmeticSlot.BACKPACK);
user.updateCosmetic(CosmeticSlot.BALLOON);
}
@EventHandler
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerPoseChange(EntityPoseChangeEvent event) {
if (!(event.getEntity() instanceof Player player)) return;
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null || user.isInWardrobe()) return;
if (!user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) return;
Pose pose = event.getPose();
if (pose.equals(Pose.STANDING)) {
// #84, Riptides mess with backpacks
ItemStack currentItem = player.getInventory().getItemInMainHand();
if (currentItem.containsEnchantment(Enchantment.RIPTIDE)) return;
if (!user.isBackpackSpawned()) {
user.spawnBackpack((CosmeticBackpackType) user.getCosmetic(CosmeticSlot.BACKPACK));
}
return;
}
if (pose.equals(Pose.SLEEPING) || pose.equals(Pose.SWIMMING) || pose.equals(Pose.FALL_FLYING) || pose.equals(Pose.SPIN_ATTACK)) {
user.despawnBackpack();
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerArmorDamage(PlayerItemDamageEvent event) {
// Possibly look into cancelling the event, then handling the damage on our own.
if (event.isCancelled()) return;
MessagesUtil.sendDebugMessages("PlayerItemDamageEvent");
int slot = -1;
@@ -173,7 +261,8 @@ public class PlayerGameListener implements Listener {
if (slot == -1) return;
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)) {
MessagesUtil.sendDebugMessages("No cosmetic in " + cosmeticSlot);
@@ -186,17 +275,52 @@ public class PlayerGameListener implements Listener {
}, 2);
}
@EventHandler
public void playerOffhandSwap(PlayerSwapHandItemsEvent event) {
@EventHandler(priority = EventPriority.LOW)
public void onPlayerOffhandSwap(PlayerSwapHandItemsEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId());
if (user == null) return;
// Really need to look into optimization of this
if (user.hasCosmeticInSlot(CosmeticSlot.EMOTE) && event.getPlayer().isSneaking() && event.getPlayer().hasPermission("hmccosmetics.emote.shiftrun")) {
CosmeticEmoteType cosmeticEmoteType = (CosmeticEmoteType) user.getCosmetic(CosmeticSlot.EMOTE);
cosmeticEmoteType.run(user);
event.setCancelled(true);
return;
}
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
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);
}
@EventHandler
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerPickupItem(EntityPickupItemEvent event) {
if (!(event.getEntity() instanceof Player)) return;
CosmeticUser user = CosmeticUsers.getUser(event.getEntity().getUniqueId());
if (user == null) return;
if (user.isInWardrobe()) event.setCancelled(true);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerPotionEffect(EntityPotionEffectEvent event) {
if (!event.getModifiedType().equals(PotionEffectType.INVISIBILITY)) return;
if (!event.getEntityType().equals(EntityType.PLAYER)) return;
Player player = (Player) event.getEntity();
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
if (event.getAction().equals(EntityPotionEffectEvent.Action.ADDED)) {
user.hideCosmetics(CosmeticUser.HiddenReason.POTION);
return;
}
if (event.getAction().equals(EntityPotionEffectEvent.Action.CLEARED) || event.getAction().equals(EntityPotionEffectEvent.Action.REMOVED)) {
user.showCosmetics(CosmeticUser.HiddenReason.POTION);
return;
}
}
@EventHandler(priority = EventPriority.LOW)
public void onMainHandSwitch(PlayerItemHeldEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
if (user == null) return;
@@ -205,20 +329,117 @@ public class PlayerGameListener implements Listener {
//NMSHandlers.getHandler().slotUpdate(event.getPlayer(), event.getPreviousSlot());
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
user.updateCosmetic(CosmeticSlot.MAINHAND);
user.updateCosmetic(CosmeticSlot.OFFHAND);
}, 2);
// #84, Riptides mess with backpacks
ItemStack currentItem = event.getPlayer().getInventory().getItem(event.getNewSlot());
if (currentItem == null) return;
if (!currentItem.hasItemMeta()) return;
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK) && currentItem.containsEnchantment(Enchantment.RIPTIDE)) {
user.despawnBackpack();
}
}
@EventHandler
@EventHandler(priority = EventPriority.LOW)
public void onPlayerDeath(PlayerDeathEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getEntity());
if (user == null) return;
if (Settings.getUnapplyOnDeath() && !event.getEntity().hasPermission("hmccosmetics.unapplydeath.bypass")) {
if (user.isInWardrobe()) user.leaveWardrobe();
if (Settings.isUnapplyOnDeath() && !event.getEntity().hasPermission("hmccosmetics.unapplydeath.bypass")) {
user.removeCosmetics();
}
}
@EventHandler(priority = EventPriority.LOW)
public void onPlayerGamemodeSwitch(PlayerGameModeChangeEvent event) {
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
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 {
user.showCosmetics(CosmeticUser.HiddenReason.GAMEMODE);
}
}
if (Settings.isDestroyLooseCosmetics()) {
ItemStack[] equippedArmor = event.getPlayer().getInventory().getArmorContents();
if (equippedArmor.length == 0) return;
for (ItemStack armor : equippedArmor) {
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.isHidden()) return;
user.showCosmetics(CosmeticUser.HiddenReason.PLUGIN);
}
@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();
}
}
}
}
private void registerInventoryClickListener() {
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.WINDOW_CLICK) {
@Override
@@ -231,11 +452,12 @@ public class PlayerGameListener implements Listener {
if (invTypeClicked != 0) return;
// -999 is when a player clicks outside their inventory. https://wiki.vg/Inventory#Player_Inventory
if (slotClicked == -999) return;
if (!(event.getPlayer() instanceof Player)) return;
if (event.getPlayer() == null) return;
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
CosmeticSlot cosmeticSlot = InventoryUtils.NMSCosmeticSlot(slotClicked);
if (user.isInWardrobe()) return;
CosmeticSlot cosmeticSlot = HMCCInventoryUtils.NMSCosmeticSlot(slotClicked);
if (cosmeticSlot == null) return;
if (!user.hasCosmeticInSlot(cosmeticSlot)) return;
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> user.updateCosmetic(cosmeticSlot), 1);
@@ -251,7 +473,6 @@ public class PlayerGameListener implements Listener {
MessagesUtil.sendDebugMessages("Menu Initial ");
Player player = event.getPlayer();
if (event.getPlayer() == null) return;
if (!(event.getPlayer() instanceof Player)) return;
int windowID = event.getPacket().getIntegers().read(0);
List<ItemStack> slotData = event.getPacket().getItemListModifier().read(0);
@@ -262,9 +483,11 @@ public class PlayerGameListener implements Listener {
HashMap<Integer, ItemStack> items = new HashMap<>();
for (Cosmetic cosmetic : user.getCosmetic()) {
if ((cosmetic instanceof CosmeticArmorType cosmeticArmorType)) {
items.put(InventoryUtils.getPacketArmorSlot(cosmeticArmorType.getEquipSlot()), user.getUserCosmeticItem(cosmeticArmorType));
if (!user.isInWardrobe()) {
for (Cosmetic cosmetic : user.getCosmetics()) {
if ((cosmetic instanceof CosmeticArmorType cosmeticArmorType)) {
items.put(HMCCInventoryUtils.getPacketArmorSlot(cosmeticArmorType.getEquipSlot()), user.getUserCosmeticItem(cosmeticArmorType));
}
}
}
@@ -278,6 +501,7 @@ public class PlayerGameListener implements Listener {
}
}
packet.getItemListModifier().write(0, slotData);
packet.getItemModifier().write(0, event.getPacket().getItemModifier().read(0));
event.setPacket(packet);
MessagesUtil.sendDebugMessages("Menu Fired, updated cosmetics " + " on slotdata " + windowID + " with " + slotData.size());
/*
@@ -294,27 +518,68 @@ 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() {
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Server.ENTITY_EQUIPMENT) {
@Override
public void onPacketSending(PacketEvent event) {
MessagesUtil.sendDebugMessages("equipment packet is activated");
Player player = event.getPlayer(); // Player that's sent
int entityID = event.getPacket().getIntegers().read(0);
// User
CosmeticUser user = CosmeticUsers.getUser(entityID);
if (user == null) {
MessagesUtil.sendDebugMessages("equipment packet is activated - user null");
return;
}
if (user == null) return;
if (user.isInWardrobe()) return;
List<com.comphenix.protocol.wrappers.Pair<EnumWrappers.ItemSlot, ItemStack>> armor = event.getPacket().getSlotStackPairLists().read(0);
for (EquipmentSlot equipmentSlot : EquipmentSlot.values()) {
CosmeticArmorType cosmeticArmor = (CosmeticArmorType) user.getCosmetic(InventoryUtils.BukkitCosmeticSlot(equipmentSlot));
if (cosmeticArmor == null) continue;
Pair<EnumWrappers.ItemSlot, ItemStack> pair = new Pair<>(InventoryUtils.itemBukkitSlot(cosmeticArmor.getEquipSlot()), cosmeticArmor.getItem());
armor.add(pair);
for (int i = 0; i < armor.size(); i++) {
com.comphenix.protocol.wrappers.Pair<EnumWrappers.ItemSlot, ItemStack> pair = armor.get(i);
switch (pair.getFirst()) {
case MAINHAND -> {
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);
@@ -323,16 +588,42 @@ 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() {
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.ARM_ANIMATION) {
@Override
public void onPacketReceiving(PacketEvent event) {
if (!(event.getPlayer() instanceof Player)) return;
if (event.getPlayer() == null) return;
Player player = event.getPlayer();
CosmeticUser user = CosmeticUsers.getUser(player);
if (user == null) return;
if (user.getUserEmoteManager().isPlayingEmote()) {
event.setCancelled(true);
return;
}
if (!user.isInWardrobe()) return;
Menu menu = Menus.getMenu(Settings.getDefaultMenu());
if (!user.getWardrobeManager().getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return;
Menu menu = Menus.getDefaultMenu();
if (menu == null) return;
menu.openMenu(user);
event.setCancelled(true);
@@ -340,6 +631,20 @@ public class PlayerGameListener implements Listener {
});
}
private void registerEntityUseListener() {
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.USE_ENTITY) {
@Override
public void onPacketReceiving(PacketEvent event) {
if (event.getPlayer() == null) return;
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
if (user == null) return;
if (user.getUserEmoteManager().isPlayingEmote() || user.isInWardrobe()) {
event.setCancelled(true);
}
}
});
}
private void registerLookMovement() {
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.LOOK) {
@Override
@@ -348,7 +653,11 @@ public class PlayerGameListener implements Listener {
MessagesUtil.sendDebugMessages("Look Packet ");
Player player = event.getPlayer();
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)));
}
}
});
}
@@ -361,20 +670,29 @@ public class PlayerGameListener implements Listener {
MessagesUtil.sendDebugMessages("Position Packet ");
Player player = event.getPlayer();
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() {
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
public void onPacketReceiving(PacketEvent event) {
// TODO: Finish
MessagesUtil.sendDebugMessages("Teleport Packet ");
Player player = event.getPlayer();
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,55 +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.entities.BalloonEntity;
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
import org.bukkit.Location;
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 getInvisibleArmorstand(Location loc);
Entity getMEGEntity(Location loc);
Entity spawnBackpack(CosmeticUser user, CosmeticBackpackType cosmeticBackpackType);
BalloonEntity 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,49 +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_19_R1", "v1_19_R2"};
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.SEVERE);
version = packageVersion;
try {
//Class.forName("org.bukkit.craftbukkit." + version + ".block.CraftBlock").getName();
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

@@ -1,8 +1,11 @@
package com.hibiscusmc.hmccosmetics.user;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.api.*;
import com.hibiscusmc.hmccosmetics.api.events.*;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
@@ -10,54 +13,62 @@ 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.entities.BalloonEntity;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
import com.hibiscusmc.hmccosmetics.util.InventoryUtils;
import com.hibiscusmc.hmccosmetics.user.manager.UserBackpackManager;
import com.hibiscusmc.hmccosmetics.user.manager.UserBalloonManager;
import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;
import com.hibiscusmc.hmccosmetics.user.manager.UserWardrobeManager;
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.PlayerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager;
import com.hibiscusmc.hmccosmetics.util.HMCCPlayerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
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.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.*;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.scheduler.BukkitTask;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.logging.Level;
public class CosmeticUser {
private UUID uniqueId;
@Getter
private final UUID uniqueId;
private int taskId;
private HashMap<CosmeticSlot, Cosmetic> playerCosmetics = new HashMap<>();
private Wardrobe wardrobe;
private ArmorStand invisibleArmorstand;
private BalloonEntity balloonEntity;
private final HashMap<CosmeticSlot, Cosmetic> playerCosmetics = new HashMap<>();
private UserWardrobeManager userWardrobeManager;
private UserBalloonManager userBalloonManager;
@Getter
private UserBackpackManager userBackpackManager;
@Getter
private final UserEmoteManager userEmoteManager;
// Cosmetic Settings/Toggles
private boolean hideBackpack;
private boolean hideCosmetics;
private HashMap<CosmeticSlot, Color> colors = new HashMap<>();
public CosmeticUser() {
// Empty
}
private final ArrayList<HiddenReason> hiddenReason = new ArrayList<>();
private final HashMap<CosmeticSlot, Color> colors = new HashMap<>();
public CosmeticUser(UUID uuid) {
this.uniqueId = uuid;
userEmoteManager = new UserEmoteManager(this);
tick();
}
private void tick() {
// Occasionally updates the entity cosmetics
Runnable run = () -> {
MessagesUtil.sendDebugMessages("tick " + uniqueId, Level.INFO);
MessagesUtil.sendDebugMessages("Tick[uuid=" + uniqueId + "]", Level.INFO);
updateCosmetic();
if (isHidden() && !getUserEmoteManager().isPlayingEmote()) MessagesUtil.sendActionBar(getPlayer(), "hidden-cosmetics");
};
int tickPeriod = Settings.getTickPeriod();
@@ -73,27 +84,12 @@ public class CosmeticUser {
despawnBalloon();
}
public UUID getUniqueId() {
return this.uniqueId;
}
public Cosmetic getCosmetic(CosmeticSlot slot) {
return playerCosmetics.get(slot);
}
public Collection<Cosmetic> getCosmetic() {
return playerCosmetics.values();
}
public int getArmorstandId() {
return invisibleArmorstand.getEntityId();
}
public Entity getBackpackEntity() {
return this.invisibleArmorstand;
}
public BalloonEntity getBalloonEntity() {
return this.balloonEntity;
public ImmutableCollection<Cosmetic> getCosmetics() {
return ImmutableList.copyOf(playerCosmetics.values());
}
public void addPlayerCosmetic(Cosmetic cosmetic) {
@@ -115,23 +111,21 @@ public class CosmeticUser {
playerCosmetics.put(cosmetic.getSlot(), cosmetic);
if (color != null) colors.put(cosmetic.getSlot(), color);
MessagesUtil.sendDebugMessages("addPlayerCosmetic " + cosmetic.getId());
if (cosmetic.getSlot() == CosmeticSlot.BACKPACK) {
CosmeticBackpackType backpackType = (CosmeticBackpackType) cosmetic;
spawnBackpack(backpackType);
MessagesUtil.sendDebugMessages("addPlayerCosmetic spawnBackpack " + cosmetic.getId());
MessagesUtil.sendDebugMessages("addPlayerCosmetic[id=" + cosmetic.getId() + "]");
if (!isHidden()) {
if (cosmetic.getSlot() == CosmeticSlot.BACKPACK) {
CosmeticBackpackType backpackType = (CosmeticBackpackType) cosmetic;
spawnBackpack(backpackType);
MessagesUtil.sendDebugMessages("addPlayerCosmetic[spawnBackpack,id=" + cosmetic.getId() + "]");
}
if (cosmetic.getSlot() == CosmeticSlot.BALLOON) {
CosmeticBalloonType balloonType = (CosmeticBalloonType) cosmetic;
spawnBalloon(balloonType);
}
}
if (cosmetic.getSlot() == CosmeticSlot.BALLOON) {
CosmeticBalloonType balloonType = (CosmeticBalloonType) cosmetic;
spawnBalloon(balloonType);
}
}
public void toggleCosmetic(Cosmetic cosmetic) {
if (hasCosmeticInSlot(cosmetic.getSlot())) {
removeCosmeticSlot(cosmetic.getSlot());
return;
}
addPlayerCosmetic(cosmetic);
// API
PlayerCosmeticPostEquipEvent postEquipEvent = new PlayerCosmeticPostEquipEvent(this, cosmetic);
Bukkit.getPluginManager().callEvent(postEquipEvent);
}
public void removeCosmetics() {
@@ -156,6 +150,9 @@ public class CosmeticUser {
if (slot == CosmeticSlot.BALLOON) {
despawnBalloon();
}
if (slot == CosmeticSlot.EMOTE) {
if (getUserEmoteManager().isPlayingEmote()) getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.UNEQUIP);
}
colors.remove(slot);
playerCosmetics.remove(slot);
removeArmor(slot);
@@ -170,6 +167,15 @@ public class CosmeticUser {
return playerCosmetics.containsKey(slot);
}
public boolean hasCosmeticInSlot(Cosmetic cosmetic) {
if (getCosmetic(cosmetic.getSlot()) == null) return false;
return Objects.equals(cosmetic.getId(), getCosmetic(cosmetic.getSlot()).getId());
}
public Set<CosmeticSlot> getSlotsWithCosmetics() {
return Set.copyOf(playerCosmetics.keySet());
}
public void updateCosmetic(CosmeticSlot slot) {
if (getCosmetic(slot) == null) {
return;
@@ -183,17 +189,41 @@ public class CosmeticUser {
}
public void updateCosmetic() {
for (Cosmetic cosmetic : playerCosmetics.values()) {
MessagesUtil.sendDebugMessages("updateCosmetic (All) - start");
HashMap<EquipmentSlot, ItemStack> items = new HashMap<>();
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());
}
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) {
ItemStack item = null;
if (hideCosmetics) {
return getPlayer().getInventory().getItem(InventoryUtils.getEquipmentSlot(cosmetic.getSlot()));
if (!hiddenReason.isEmpty()) {
if (cosmetic instanceof CosmeticBackpackType || cosmetic instanceof CosmeticBalloonType) return new ItemStack(Material.AIR);
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();
}
if (cosmetic instanceof CosmeticBalloonType) {
@@ -203,54 +233,122 @@ public class CosmeticUser {
item = cosmetic.getItem();
}
}
return getUserCosmeticItem(cosmetic, item);
}
@SuppressWarnings("deprecation")
public ItemStack getUserCosmeticItem(Cosmetic cosmetic, ItemStack item) {
if (item == null) {
MessagesUtil.sendDebugMessages("GetUserCosemticUser Item is null");
return null;
//MessagesUtil.sendDebugMessages("GetUserCosemticUser Item is null");
return new ItemStack(Material.AIR);
}
if (item.hasItemMeta()) {
ItemMeta itemMeta = item.getItemMeta();
if (itemMeta instanceof LeatherArmorMeta) {
if (colors.containsKey(cosmetic.getSlot())) {
((LeatherArmorMeta) itemMeta).setColor(colors.get(cosmetic.getSlot()));
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())) {
Color color = colors.get(cosmetic.getSlot());
if (itemMeta instanceof LeatherArmorMeta leatherMeta) {
leatherMeta.setColor(color);
} else if (itemMeta instanceof PotionMeta potionMeta) {
potionMeta.setColor(color);
} else if (itemMeta instanceof MapMeta mapMeta) {
mapMeta.setColor(color);
}
}
itemMeta.getPersistentDataContainer().set(HMCCInventoryUtils.getCosmeticKey(), PersistentDataType.STRING, cosmetic.getId());
itemMeta.getPersistentDataContainer().set(InventoryUtils.getOwnerKey(), PersistentDataType.STRING, getEntity().getUniqueId().toString());
item.setItemMeta(itemMeta);
}
return item;
}
public void enterWardrobe() {
if (!WardrobeSettings.inDistanceOfStatic(getPlayer().getLocation())) {
public UserBalloonManager getBalloonManager() {
return this.userBalloonManager;
}
public UserWardrobeManager getWardrobeManager() {
return userWardrobeManager;
}
public void enterWardrobe(boolean ignoreDistance, Wardrobe wardrobe) {
if (wardrobe.hasPermission() && !getPlayer().hasPermission(wardrobe.getPermission())) {
MessagesUtil.sendMessage(getPlayer(), "no-permission");
return;
}
if (!wardrobe.canEnter(this) && !ignoreDistance) {
MessagesUtil.sendMessage(getPlayer(), "not-near-wardrobe");
return;
}
PlayerWardrobeEnterEvent event = new PlayerWardrobeEnterEvent(this);
if (!wardrobe.getLocation().hasAllLocations()) {
MessagesUtil.sendMessage(getPlayer(), "wardrobe-not-setup");
return;
}
PlayerWardrobeEnterEvent event = new PlayerWardrobeEnterEvent(this, wardrobe);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
wardrobe = event.getWardrobe();
if (wardrobe == null) {
wardrobe = new Wardrobe(this);
wardrobe.start();
if (userWardrobeManager == null) {
userWardrobeManager = new UserWardrobeManager(this, wardrobe);
userWardrobeManager.start();
}
}
public Wardrobe getWardrobe() {
return wardrobe;
public void leaveWardrobe() {
leaveWardrobe(false);
}
public void leaveWardrobe() {
public void leaveWardrobe(boolean ejected) {
PlayerWardrobeLeaveEvent event = new PlayerWardrobeLeaveEvent(this);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
if (!getWardrobe().getWardrobeStatus().equals(Wardrobe.WardrobeStatus.RUNNING)) return;
MessagesUtil.sendDebugMessages("Leaving Wardrobe");
if (!getWardrobeManager().getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return;
getWardrobe().setWardrobeStatus(Wardrobe.WardrobeStatus.STOPPING);
getWardrobeManager().setWardrobeStatus(UserWardrobeManager.WardrobeStatus.STOPPING);
if (WardrobeSettings.isEnabledTransition()) {
if (WardrobeSettings.isEnabledTransition() && !ejected) {
MessagesUtil.sendTitle(
getPlayer(),
WardrobeSettings.getTransitionText(),
@@ -259,99 +357,118 @@ public class CosmeticUser {
WardrobeSettings.getTransitionFadeOut()
);
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
wardrobe.end();
wardrobe = null;
userWardrobeManager.end();
userWardrobeManager = null;
}, WardrobeSettings.getTransitionDelay());
} else {
userWardrobeManager.end();
userWardrobeManager = null;
}
}
public boolean isInWardrobe() {
if (wardrobe == null) return false;
return true;
}
public void toggleWardrobe() {
if (isInWardrobe()) {
leaveWardrobe();
} else {
enterWardrobe();
}
return userWardrobeManager != null;
}
public void spawnBackpack(CosmeticBackpackType cosmeticBackpackType) {
MessagesUtil.sendDebugMessages("spawnBackpack Bukkit - Start");
Player player = Bukkit.getPlayer(getUniqueId());
if (this.invisibleArmorstand != null) return;
this.invisibleArmorstand = (ArmorStand) NMSHandlers.getHandler().spawnBackpack(this, cosmeticBackpackType);
MessagesUtil.sendDebugMessages("spawnBackpack Bukkit - Finish");
}
public void spawnBalloon(CosmeticBalloonType cosmeticBalloonType) {
Player player = Bukkit.getPlayer(getUniqueId());
if (this.balloonEntity != null) return;
this.balloonEntity = NMSHandlers.getHandler().spawnBalloon(this, cosmeticBalloonType);
List<Player> viewer = PlayerUtils.getNearbyPlayers(player);
viewer.add(player);
PacketManager.sendLeashPacket(getBalloonEntity().getPufferfishBalloonId(), player.getEntityId(), viewer);
}
public void despawnBalloon() {
if (this.balloonEntity == null) return;
List<Player> sentTo = PlayerUtils.getNearbyPlayers(getPlayer().getLocation());
PacketManager.sendEntityDestroyPacket(balloonEntity.getPufferfishBalloonId(), sentTo);
this.balloonEntity.remove();
this.balloonEntity = null;
if (this.userBackpackManager != null) return;
this.userBackpackManager = new UserBackpackManager(this);
userBackpackManager.spawnBackpack(cosmeticBackpackType);
}
public void despawnBackpack() {
Player player = Bukkit.getPlayer(getUniqueId());
if (invisibleArmorstand == null) return;
invisibleArmorstand.setHealth(0);
invisibleArmorstand.remove();
this.invisibleArmorstand = null;
if (userBackpackManager == null) return;
userBackpackManager.despawnBackpack();
userBackpackManager = null;
}
public boolean isBackpackSpawned() {
return this.userBackpackManager != null;
}
public boolean isBalloonSpawned() {
return this.userBalloonManager != null;
}
public void spawnBalloon(CosmeticBalloonType cosmeticBalloonType) {
if (this.userBalloonManager != null) return;
org.bukkit.entity.Entity entity = getEntity();
UserBalloonManager userBalloonManager1 = new UserBalloonManager(this, entity.getLocation());
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() {
if (this.userBalloonManager == null) return;
List<Player> sentTo = HMCCPlayerUtils.getNearbyPlayers(getEntity().getLocation());
HMCCPacketManager.sendEntityDestroyPacket(userBalloonManager.getPufferfishBalloonId(), sentTo);
this.userBalloonManager.remove();
this.userBalloonManager = null;
}
public void respawnBackpack() {
if (!hasCosmeticInSlot(CosmeticSlot.BACKPACK)) return;
final Cosmetic cosmetic = getCosmetic(CosmeticSlot.BACKPACK);
despawnBackpack();
if (!hiddenReason.isEmpty()) return;
spawnBackpack((CosmeticBackpackType) cosmetic);
MessagesUtil.sendDebugMessages("Respawned Backpack for " + getEntity().getName());
}
public void respawnBalloon() {
if (!hasCosmeticInSlot(CosmeticSlot.BALLOON)) return;
final Cosmetic cosmetic = getCosmetic(CosmeticSlot.BALLOON);
despawnBalloon();
if (!hiddenReason.isEmpty()) return;
spawnBalloon((CosmeticBalloonType) cosmetic);
MessagesUtil.sendDebugMessages("Respawned Balloon for " + getEntity().getName());
}
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() {
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) {
return colors.get(slot);
}
public List<CosmeticSlot> getDyeableSlots() {
ArrayList<CosmeticSlot> dyableSlots = new ArrayList();
ArrayList<CosmeticSlot> dyableSlots = new ArrayList<>();
for (Cosmetic cosmetic : getCosmetic()) {
for (Cosmetic cosmetic : getCosmetics()) {
if (cosmetic.isDyable()) dyableSlots.add(cosmetic.getSlot());
}
@@ -359,9 +476,15 @@ public class CosmeticUser {
}
public boolean canEquipCosmetic(Cosmetic cosmetic) {
return canEquipCosmetic(cosmetic, false);
}
public boolean canEquipCosmetic(Cosmetic cosmetic, boolean ignoreWardrobe) {
if (!cosmetic.requiresPermission()) return true;
if (getPlayer().hasPermission(cosmetic.getPermission())) return true;
return false;
if (isInWardrobe() && !ignoreWardrobe) {
if (WardrobeSettings.isTryCosmeticsInWardrobe() && userWardrobeManager.getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return true;
}
return getPlayer().hasPermission(cosmetic.getPermission());
}
public void hidePlayer() {
@@ -382,70 +505,98 @@ public class CosmeticUser {
}
}
public void hideBackpack() {
if (hideBackpack == true) return;
if (hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
invisibleArmorstand.getEquipment().clear();
hideBackpack = true;
}
}
public void showBackpack() {
if (hideBackpack == false) return;
if (hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
CosmeticBackpackType cosmeticBackpackType = (CosmeticBackpackType) getCosmetic(CosmeticSlot.BACKPACK);
ItemStack item = getUserCosmeticItem(cosmeticBackpackType);
invisibleArmorstand.getEquipment().setHelmet(item);
hideBackpack = false;
}
}
public void hideCosmetics() {
if (hideCosmetics == true) return;
PlayerCosmeticHideEvent event = new PlayerCosmeticHideEvent(this);
public void hideCosmetics(HiddenReason reason) {
PlayerCosmeticHideEvent event = new PlayerCosmeticHideEvent(this, reason);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
hideCosmetics = true;
if (!hiddenReason.contains(reason)) hiddenReason.add(reason);
if (hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
getBalloonEntity().removePlayerFromModel(getPlayer());
List<Player> viewer = PlayerUtils.getNearbyPlayers(getPlayer());
PacketManager.sendLeashPacket(getBalloonEntity().getPufferfishBalloonId(), -1, viewer);
despawnBalloon();
//getBalloonManager().removePlayerFromModel(getPlayer());
//getBalloonManager().sendRemoveLeashPacket();
}
if (hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
invisibleArmorstand.getEquipment().clear();
despawnBackpack();
}
updateCosmetic();
MessagesUtil.sendDebugMessages("HideCosmetics");
}
public void showCosmetics() {
if (hideCosmetics == false) return;
/**
* This is used to silently add a hidden flag to the user. This will not trigger any events or checks, nor do anything else
* @param reason
*/
public void silentlyAddHideFlag(HiddenReason reason) {
if (!hiddenReason.contains(reason)) hiddenReason.add(reason);
}
public void showCosmetics(HiddenReason reason) {
if (hiddenReason.isEmpty()) return;
PlayerCosmeticShowEvent event = new PlayerCosmeticShowEvent(this);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
hideCosmetics = false;
hiddenReason.remove(reason);
if (isHidden()) return;
if (hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
if (!isBalloonSpawned()) respawnBalloon();
CosmeticBalloonType balloonType = (CosmeticBalloonType) getCosmetic(CosmeticSlot.BALLOON);
getBalloonEntity().addPlayerToModel(getPlayer(), balloonType.getModelName());
List<Player> viewer = PlayerUtils.getNearbyPlayers(getPlayer());
PacketManager.sendLeashPacket(getBalloonEntity().getPufferfishBalloonId(), getPlayer().getEntityId(), viewer);
getBalloonManager().addPlayerToModel(this, balloonType);
List<Player> viewer = HMCCPlayerUtils.getNearbyPlayers(getEntity().getLocation());
HMCCPacketManager.sendLeashPacket(getBalloonManager().getPufferfishBalloonId(), getPlayer().getEntityId(), viewer);
}
if (hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
if (!isBackpackSpawned()) respawnBackpack();
CosmeticBackpackType cosmeticBackpackType = (CosmeticBackpackType) getCosmetic(CosmeticSlot.BACKPACK);
ItemStack item = getUserCosmeticItem(cosmeticBackpackType);
invisibleArmorstand.getEquipment().setHelmet(item);
userBackpackManager.setItem(item);
}
updateCosmetic();
MessagesUtil.sendDebugMessages("ShowCosmetics");
}
/**
* This method is deprecated and will be removed in the future. Use {@link #isHidden()} instead.
* @return
*/
@Deprecated(since = "2.7.2-DEV", forRemoval = true)
public boolean getHidden() {
return this.hideCosmetics;
return !hiddenReason.isEmpty();
}
public boolean isHidden() {
return !hiddenReason.isEmpty();
}
public boolean isHidden(HiddenReason reason) {
return hiddenReason.contains(reason);
}
public List<HiddenReason> getHiddenReasons() {
return hiddenReason;
}
public void clearHiddenReasons() {
hiddenReason.clear();
}
public enum HiddenReason {
NONE,
WORLDGUARD,
PLUGIN,
POTION,
ACTION,
COMMAND,
EMOTE,
GAMEMODE,
WORLD,
DISABLED
}
}

View File

@@ -1,46 +1,83 @@
package com.hibiscusmc.hmccosmetics.user;
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.EntityType;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
import java.util.UUID;
public class CosmeticUsers {
private static HashBiMap<UUID, CosmeticUser> COSMETIC_USERS = HashBiMap.create();
private static final HashBiMap<UUID, CosmeticUser> COSMETIC_USERS = HashBiMap.create();
public static void addUser(CosmeticUser user) {
/**
* Adds a user to the Hashmap of stored CosmeticUsers. This will not override an entry if it already exists. If you need to override, delete then add.
* @param user The user to add to the HashMap.
*/
public static void addUser(@NotNull CosmeticUser user) {
if (COSMETIC_USERS.containsKey(user.getUniqueId())) return; // do not add if already exists
COSMETIC_USERS.put(user.getUniqueId(), user);
}
/**
* Removes a CosmeticUser from the Hashmap
* @param uuid The UUID to remove.
*/
public static void removeUser(UUID uuid) {
COSMETIC_USERS.remove(uuid);
}
public static void removeUser(CosmeticUser user) {
COSMETIC_USERS.remove(user);
/**
* Removes a CosmeticUser from the hashmap by their CosmeticUser method
* @param user The user to be removed (will get their UUID from this class)
*/
public static void removeUser(@NotNull CosmeticUser user) {
COSMETIC_USERS.remove(user.getUniqueId());
}
/**
* This method allows you to get a CosmeticUser from their UUID. If you are using not internally, HIGHLY recommend to use the API implementation of this.
* @param uuid The UUID of the user that you wish to lookup.
* @return Returns the user if there is a valid user, returns null if not.
*/
@Nullable
public static CosmeticUser getUser(UUID uuid) {
return COSMETIC_USERS.get(uuid);
}
/**
* This method allows you to get a CosmeticUser from just using the player class. This just allows you to have a bit less boilerplate.
* @param player The player to lookup (will take their UUID from the class)
* @return Returns the user if there is a vlaid user, returns null if not.
*/
@Nullable
public static CosmeticUser getUser(Player player) {
public static CosmeticUser getUser(@NotNull Player player) {
return COSMETIC_USERS.get(player.getUniqueId());
}
/**
* This method gets the CosmeticUser from an entity id (said entity must be a player). This is not ideal, as it requires the plugin to go through all entities, but it's a possibility.
* @param entityId The entity ID in an integer.
* @return The cosmetic user if there is an entity id associated with that.
*/
@Nullable
public static CosmeticUser getUser(int entityId) {
Entity entity = ServerUtils.getEntity(entityId);
Entity entity = HMCCServerUtils.getEntity(entityId);
if (entity == null) return null;
if (entity.getType().equals(EntityType.PLAYER)) return null;
return COSMETIC_USERS.get(entity.getUniqueId());
if (!(entity instanceof Player player)) return null;
return COSMETIC_USERS.get(player.getUniqueId());
}
/**
* Gets all the values for CosmeticUsers to allow you to iterate over everyone.
* @return CosmeticUsers in a set. This will never be null, but might be empty.
*/
@NotNull
public static Set<CosmeticUser> values() {
return COSMETIC_USERS.values();
}
}

View File

@@ -1,289 +0,0 @@
package com.hibiscusmc.hmccosmetics.user;
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
import com.hibiscusmc.hmccosmetics.config.Settings;
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
import com.hibiscusmc.hmccosmetics.nms.NMSHandlers;
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
import com.hibiscusmc.hmccosmetics.util.ServerUtils;
import com.hibiscusmc.hmccosmetics.util.packets.PacketManager;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
public class Wardrobe {
private int NPC_ID;
private String npcName;
private UUID WARDROBE_UUID;
private int ARMORSTAND_ID;
private GameMode originalGamemode;
private CosmeticUser VIEWER;
private Location viewingLocation;
private Location npcLocation;
private Location exitLocation;
private BossBar bossBar;
private boolean active;
private WardrobeStatus wardrobeStatus;
public Wardrobe(CosmeticUser user) {
NPC_ID = NMSHandlers.getHandler().getNextEntityId();
ARMORSTAND_ID = NMSHandlers.getHandler().getNextEntityId();
WARDROBE_UUID = UUID.randomUUID();
VIEWER = user;
wardrobeStatus = WardrobeStatus.SETUP;
}
public void start() {
setWardrobeStatus(WardrobeStatus.STARTING);
Player player = VIEWER.getPlayer();
this.originalGamemode = player.getGameMode();
if (WardrobeSettings.isReturnLastLocation()) {
this.exitLocation = player.getLocation().clone();
} else {
this.exitLocation = WardrobeSettings.getLeaveLocation();
}
viewingLocation = WardrobeSettings.getViewerLocation();
npcLocation = WardrobeSettings.getWardrobeLocation();
VIEWER.hidePlayer();
List<Player> viewer = List.of(player);
List<Player> outsideViewers = PacketManager.getViewers(viewingLocation);
outsideViewers.remove(player);
MessagesUtil.sendMessage(player, "opened-wardrobe");
Runnable run = () -> {
// Armorstand
PacketManager.sendEntitySpawnPacket(viewingLocation, ARMORSTAND_ID, EntityType.ARMOR_STAND, UUID.randomUUID(), viewer);
PacketManager.sendInvisibilityPacket(ARMORSTAND_ID, viewer);
PacketManager.sendLookPacket(ARMORSTAND_ID, viewingLocation, viewer);
// Player
PacketManager.gamemodeChangePacket(player, 3);
PacketManager.sendCameraPacket(ARMORSTAND_ID, viewer);
// NPC
npcName = "WardrobeNPC-" + NPC_ID;
while (npcName.length() > 16) {
npcName = npcName.substring(16);
}
PacketManager.sendFakePlayerInfoPacket(player, NPC_ID, WARDROBE_UUID, npcName, viewer);
// NPC 2
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
PacketManager.sendFakePlayerSpawnPacket(npcLocation, WARDROBE_UUID, NPC_ID, viewer);
MessagesUtil.sendDebugMessages("Spawned Fake Player on " + npcLocation);
NMSHandlers.getHandler().hideNPCName(player, npcName);
}, 4);
// Location
PacketManager.sendLookPacket(NPC_ID, npcLocation, viewer);
PacketManager.sendRotationPacket(NPC_ID, npcLocation, true, viewer);
// Misc
if (VIEWER.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
PacketManager.ridingMountPacket(NPC_ID, VIEWER.getBackpackEntity().getEntityId(), viewer);
}
if (VIEWER.hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
PacketManager.sendLeashPacket(VIEWER.getBalloonEntity().getPufferfishBalloonId(), -1, viewer);
PacketManager.sendLeashPacket(VIEWER.getBalloonEntity().getPufferfishBalloonId(), NPC_ID, viewer); // This needs a possible fix
//PacketManager.sendLeashPacket(VIEWER.getBalloonEntity().getModelId(), NPC_ID, viewer);
PacketManager.sendTeleportPacket(VIEWER.getBalloonEntity().getPufferfishBalloonId(), npcLocation.clone().add(Settings.getBalloonOffset()), false, viewer);
PacketManager.sendTeleportPacket(VIEWER.getBalloonEntity().getModelId(), npcLocation.clone().add(Settings.getBalloonOffset()), false, viewer);
}
if (WardrobeSettings.getEnabledBossbar()) {
float progress = WardrobeSettings.getBossbarProgress();
Component message = MessagesUtil.processStringNoKey(WardrobeSettings.getBossbarText());
bossBar = BossBar.bossBar(message, progress, WardrobeSettings.getBossbarColor(), WardrobeSettings.getBossbarOverlay());
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
target.showBossBar(bossBar);
}
this.active = true;
update();
setWardrobeStatus(WardrobeStatus.RUNNING);
};
if (WardrobeSettings.isEnabledTransition()) {
MessagesUtil.sendTitle(
VIEWER.getPlayer(),
WardrobeSettings.getTransitionText(),
WardrobeSettings.getTransitionFadeIn(),
WardrobeSettings.getTransitionStay(),
WardrobeSettings.getTransitionFadeOut()
);
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), run, WardrobeSettings.getTransitionDelay());
} else {
run.run();
}
}
public void end() {
setWardrobeStatus(WardrobeStatus.STOPPING);
Player player = VIEWER.getPlayer();
List<Player> viewer = List.of(player);
List<Player> outsideViewers = PacketManager.getViewers(viewingLocation);
outsideViewers.remove(player);
MessagesUtil.sendMessage(player, "closed-wardrobe");
Runnable run = () -> {
this.active = false;
// NPC
if (VIEWER.hasCosmeticInSlot(CosmeticSlot.BALLOON)) PacketManager.sendLeashPacket(VIEWER.getBalloonEntity().getModelId(), -1, viewer);
PacketManager.sendEntityDestroyPacket(NPC_ID, viewer); // Success
PacketManager.sendRemovePlayerPacket(player, WARDROBE_UUID, viewer); // Success
// Player
PacketManager.sendCameraPacket(player.getEntityId(), viewer);
PacketManager.gamemodeChangePacket(player, ServerUtils.convertGamemode(this.originalGamemode)); // Success
// Armorstand
PacketManager.sendEntityDestroyPacket(ARMORSTAND_ID, viewer); // Sucess
//PacketManager.sendEntityDestroyPacket(player.getEntityId(), viewer); // Success
player.setGameMode(this.originalGamemode);
VIEWER.showPlayer();
if (VIEWER.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
VIEWER.respawnBackpack();
//PacketManager.ridingMountPacket(player.getEntityId(), VIEWER.getBackpackEntity().getEntityId(), viewer);
}
if (VIEWER.hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
VIEWER.respawnBalloon();
//PacketManager.sendLeashPacket(VIEWER.getBalloonEntity().getPufferfishBalloonId(), player.getEntityId(), viewer);
}
if (exitLocation == null) {
player.teleport(player.getWorld().getSpawnLocation());
} else {
player.teleport(exitLocation);
}
if (WardrobeSettings.isEquipPumpkin()) {
NMSHandlers.getHandler().equipmentSlotUpdate(VIEWER.getPlayer().getEntityId(), EquipmentSlot.HEAD, player.getInventory().getHelmet(), viewer);
}
if (WardrobeSettings.getEnabledBossbar()) {
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
target.hideBossBar(bossBar);
}
VIEWER.updateCosmetic();
};
run.run();
}
public void update() {
final AtomicInteger data = new AtomicInteger();
BukkitRunnable runnable = new BukkitRunnable() {
@Override
public void run() {
if (active == false) {
MessagesUtil.sendDebugMessages("Active is false");
this.cancel();
return;
}
MessagesUtil.sendDebugMessages("Update ");
List<Player> viewer = List.of(VIEWER.getPlayer());
List<Player> outsideViewers = PacketManager.getViewers(viewingLocation);
outsideViewers.remove(VIEWER.getPlayer());
Location location = WardrobeSettings.getWardrobeLocation().clone();
int yaw = data.get();
location.setYaw(yaw);
PacketManager.sendLookPacket(NPC_ID, location, viewer);
VIEWER.hidePlayer();
int rotationSpeed = WardrobeSettings.getRotationSpeed();
location.setYaw(getNextYaw(yaw - 30, rotationSpeed));
PacketManager.sendRotationPacket(NPC_ID, location, true, viewer);
int nextyaw = getNextYaw(yaw, rotationSpeed);
data.set(nextyaw);
for (CosmeticSlot slot : CosmeticSlot.values()) {
PacketManager.equipmentSlotUpdate(NPC_ID, VIEWER, slot, viewer);
}
if (VIEWER.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
PacketManager.sendTeleportPacket(VIEWER.getArmorstandId(), location, false, viewer);
PacketManager.ridingMountPacket(NPC_ID, VIEWER.getBackpackEntity().getEntityId(), viewer);
VIEWER.getBackpackEntity().setRotation(nextyaw, 0);
PacketManager.sendEntityDestroyPacket(VIEWER.getArmorstandId(), outsideViewers);
}
if (VIEWER.hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
PacketManager.sendTeleportPacket(VIEWER.getBalloonEntity().getPufferfishBalloonId(), WardrobeSettings.getWardrobeLocation().add(Settings.getBalloonOffset()), false, viewer);
VIEWER.getBalloonEntity().getModelEntity().teleport(WardrobeSettings.getWardrobeLocation().add(Settings.getBalloonOffset()));
PacketManager.sendLeashPacket(VIEWER.getBalloonEntity().getPufferfishBalloonId(), -1, outsideViewers);
PacketManager.sendEntityDestroyPacket(VIEWER.getBalloonEntity().getModelId(), outsideViewers);
//PacketManager.sendLeashPacket(VIEWER.getBalloonEntity().getModelId(), NPC_ID, viewer); // Pufferfish goes away for some reason?
}
if (WardrobeSettings.isEquipPumpkin()) {
NMSHandlers.getHandler().equipmentSlotUpdate(VIEWER.getPlayer().getEntityId(), EquipmentSlot.HEAD, new ItemStack(Material.CARVED_PUMPKIN), viewer);
}
}
};
runnable.runTaskTimer(HMCCosmeticsPlugin.getInstance(), 0, 2);
}
private static int getNextYaw(final int current, final int rotationSpeed) {
int nextYaw = current + rotationSpeed;
if (nextYaw > 179) {
nextYaw = (current + rotationSpeed) - 358;
return nextYaw;
}
return nextYaw;
}
public int getArmorstandId() {
return ARMORSTAND_ID;
}
public WardrobeStatus getWardrobeStatus() {
return wardrobeStatus;
}
public void setWardrobeStatus(WardrobeStatus status) {
this.wardrobeStatus = status;
}
public enum WardrobeStatus {
SETUP,
STARTING,
RUNNING,
STOPPING,
}
}

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