Compare commits

..
271 Commits
Author SHA1 Message Date
Elikill58 6435ea0dad Upgrade to 2.6.2 2024-11-07 22:08:05 +01:00
Elikill58 4e7b14e618 Fix for spigot versions 2024-11-07 21:55:43 +01:00
Elikill58 c9ea8061c8 Fix auto selection 2024-11-07 20:16:18 +01:00
Elikill58 4b966f056e Begin of own formatter 2024-11-07 19:28:23 +01:00
Elikill58 3a2d0ee44d Add placeholders 2024-09-09 11:15:12 +02:00
Elikill58 5ee9cca3d7 Duplicated variable name... 2024-09-04 10:12:16 +02:00
Elikill58 e21f236a09 Prevent IncompatibleClassChangeError error 2024-09-04 10:09:12 +02:00
Elikill58 554dd8ad39 Change for actions 2024-09-03 19:48:05 +02:00
Elikill58 b7a60f1352 Use JDK 21 2024-08-27 23:36:15 +02:00
Elikill58 b8e5e213ae Upgrade github action for pull request 2024-08-27 23:23:07 +02:00
Elikill58 08101a8d18 Upgrade github actions 2024-08-27 23:22:32 +02:00
Elikill58 4ccb543869 Make pull 2024-08-27 22:43:21 +02:00
Elikill58 153667135b Prevent some error on 1.20.6 and 1.21 2024-08-27 22:43:14 +02:00
Elikill58 00ca8ac11b Prevent error 2024-08-23 14:03:47 +02:00
Elikill58 44867e86d8 Merge branch 'v2' of https://github.com/dadus33-plugins/ChatItem into v2 2024-08-20 21:14:51 +02:00
Elikill58 36148b5969 Prevent error with items 2024-08-20 21:14:42 +02:00
Elikill58 103ef2a4f2 Prevent error with unsignedContent 2024-08-20 18:07:01 +02:00
Elikill58 40f67cc41f Upgrade to snapshot 2024-08-20 18:06:32 +02:00
dependabot[bot] df555f7151 Bump com.discordsrv:discordsrv from 1.27.0 to 1.28.1 (#139)
Bumps com.discordsrv:discordsrv from 1.27.0 to 1.28.1.

---
updated-dependencies:
- dependency-name: com.discordsrv:discordsrv
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-12 10:27:03 +02:00
dependabot[bot] c76c35974c Bump com.viaversion:viaversion-api from 5.0.2 to 5.0.3 (#140)
Bumps com.viaversion:viaversion-api from 5.0.2 to 5.0.3.

---
updated-dependencies:
- dependency-name: com.viaversion:viaversion-api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-12 10:23:27 +02:00
Elikill58 81f9711019 Fix typo on config 2024-08-04 21:19:48 +02:00
dependabot[bot] 4edccde81c Bump com.github.MilkBowl:VaultAPI from 1.7 to 1.7.1 (#137)
Bumps [com.github.MilkBowl:VaultAPI](https://github.com/MilkBowl/VaultAPI) from 1.7 to 1.7.1.
- [Release notes](https://github.com/MilkBowl/VaultAPI/releases)
- [Commits](https://github.com/MilkBowl/VaultAPI/compare/1.7...1.7.1)

---
updated-dependencies:
- dependency-name: com.github.MilkBowl:VaultAPI
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-04 21:15:17 +02:00
dependabot[bot] eac6d1c68a Bump com.viaversion:viaversion-api from 4.10.2 to 5.0.2 (#138)
Bumps com.viaversion:viaversion-api from 4.10.2 to 5.0.2.

---
updated-dependencies:
- dependency-name: com.viaversion:viaversion-api
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-04 21:15:09 +02:00
Elikill58 1914174e42 Upgrade to 2.6.1 2024-08-04 21:12:56 +02:00
Elikill58 4a7f37451a Fix click not included 2024-08-04 11:07:52 +02:00
Elikill58 4d90a80788 Change for paper management 2024-08-04 11:03:57 +02:00
Elikill58 3713ad41af Fix Paper wrong hvoer/click 2024-08-01 23:11:40 +02:00
Elikill58 b8ba6eac69 Changes for adventure 2024-08-01 23:08:15 +02:00
Elikill58 25f8b585b0 Clean imports 2024-07-31 10:27:41 +02:00
Elikill58 746b3b58a0 Fix for some color codes and issues 2024-07-31 10:27:29 +02:00
Elikill58 89f61e0178 Fix wrong paper behavior and end seperator 2024-07-28 01:30:17 +02:00
Elikill58 9d7de56889 Changes for colors 2024-07-28 00:39:16 +02:00
Elikill58 5fb210e841 Add Essentials support 2024-07-26 22:10:35 +02:00
Elikill58 0a9af0d430 Changes for translation 2024-07-26 00:04:29 +02:00
Elikill58 37681d8b27 Add warn 2024-07-25 23:38:23 +02:00
Elikill58 79e03e97bd Fix placeholders not fully removed 2024-07-25 23:35:22 +02:00
Elikill58 db08be3fa8 Fix cmd reload 2024-07-25 22:52:38 +02:00
Elikill58 4133f30701 Prevent init issue with older versions 2024-07-22 23:32:23 +02:00
Elikill58 08434a5df2 Remove auto from inv 2024-07-22 23:25:57 +02:00
Elikill58 ae825569cf Fix Adventure component for newer versions 2024-07-22 23:23:09 +02:00
Elikill58 1a4f95cd80 Fix color issues 2024-07-22 21:05:21 +02:00
Elikill58 4edc061969 Upgrade to snapshot 2024-07-15 23:10:03 +02:00
Elikill58 e508790d9f Upgrade to 2.6 2024-07-13 23:28:20 +02:00
Elikill58 c26259f5e7 Fix error with not json things 2024-07-10 21:23:48 +02:00
Elikill58 62bf8b07fb Fix wrong action 2024-07-08 21:14:51 +02:00
Elikill58 bd93d3e610 Fix wrong key 2024-07-06 10:24:44 +02:00
Elikill58 c0a37084ce Fix ec and inv for packet manager 2024-07-06 01:05:07 +02:00
Elikill58 0f42e22da9 Fix coloring 2024-07-05 20:23:50 +02:00
Elikill58 5e10bb4450 Fix #135 (Wrong spelling of useful) 2024-07-04 16:43:35 +02:00
Elikill58 b88a1ca83e Change for leaded managers 2024-07-03 22:48:04 +02:00
Elikill58 05ae520cf1 Remake of AdventureComponentManager 2024-07-03 22:13:15 +02:00
Elikill58 76123c895d Add vault support and changes for papermc things 2024-06-25 10:33:40 +02:00
Elikill58 4284497bf5 Add more replacers 2024-06-22 11:40:41 +02:00
Elikill58 62a7b10142 Change how the message is send on paper 2024-06-22 11:35:45 +02:00
Elikill58 cd341109de Try to fix for new versions 2024-06-20 20:43:57 +02:00
Elikill58 68fb201855 Changing debug messages 2024-06-16 14:34:23 +02:00
Elikill58 baa4eab53f Fix 1.20.6 detection for spigot 2024-06-16 11:26:16 +02:00
Elikill58 20c5fc3e45 Change for pufferfish and some paper versions 2024-06-16 11:14:37 +02:00
Elikill58 818cd535bb Update EcoEnchants deps 2024-06-15 16:06:19 +02:00
Elikill58 1107b7fe90 Add MVdWPlaceholders 2024-06-15 15:47:00 +02:00
Elikill58 bed3a87c09 Add placeholders 2024-06-15 15:31:42 +02:00
Elikill58 499d0eb93c Possible fix for wrong versions 2024-06-12 19:47:49 +02:00
Elikill58 913d04b96a Don't add formatting as color 2024-05-24 09:31:47 +02:00
Elikill58 497c317d3f Add paper namer 2024-05-24 09:28:28 +02:00
Elikill58 c9d8d52406 Fix NPE for paper 2024-05-24 09:23:13 +02:00
Elikill58 38f8e47b92 Fix for empty items 2024-05-20 22:57:59 +02:00
Elikill58 6fb80712be Fix #133 2024-05-20 22:52:16 +02:00
Elikill58 00ef83bd67 Change for things 2024-05-20 20:49:10 +02:00
Elikill58 1615bdf739 Merge branch 'v2' of https://github.com/Dadus33-plugins/ChatItem into v2 2024-05-16 13:59:13 +02:00
Elikill58 09854352a1 Make cooldown available for everyone 2024-05-16 13:59:07 +02:00
dependabot[bot] c6585bb94a Bump com.viaversion:viaversion-api from 4.10.0 to 4.10.2 (#132)
Bumps com.viaversion:viaversion-api from 4.10.0 to 4.10.2.

---
updated-dependencies:
- dependency-name: com.viaversion:viaversion-api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-13 23:26:49 +02:00
Elikill58 1e359523fa Merge branch 'v2' of https://github.com/Dadus33-plugins/ChatItem into v2 2024-05-13 23:26:15 +02:00
Elikill58 885f6b9d7a Fix format code not interpreted 2024-05-13 23:26:09 +02:00
dependabot[bot] f2a49e2f3a Bump com.viaversion:viaversion-api from 4.9.3 to 4.10.0 (#130)
Bumps com.viaversion:viaversion-api from 4.9.3 to 4.10.0.

---
updated-dependencies:
- dependency-name: com.viaversion:viaversion-api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-29 09:28:43 +02:00
Elikill58 7c8b61c6eb Fix paper item not fully showed 2024-04-26 19:05:18 +02:00
Elikill58 f502cfa548 Remove warning for paper 2024-04-25 21:44:22 +02:00
Elikill58 fcef1245d6 Upgrade to snapshot 2024-04-25 20:10:42 +02:00
Elikill58 b6c4ad0170 Better support for 'all' new manager 2024-04-25 20:10:23 +02:00
Elikill58 a97710b2c4 Fix conflict with v1 2024-04-25 20:03:49 +02:00
Elikill58 64642cdc58 Added text 2024-04-25 19:20:20 +02:00
Elikill58 9ac6e7abbc Added new paper manager, fix #125 2024-04-25 18:43:34 +02:00
Elikill58 fddf389169 Fix building 2024-04-24 20:38:51 +02:00
Kevin D 3006a7857c [docs] fix wording in readme (#129)
* Fix wording in readme

* Fix a small issue with my changes!
2024-04-24 14:46:16 +02:00
dependabot[bot] e370723a82 Bump com.viaversion:viaversion-api from 4.9.2 to 4.9.3 (#124)
Bumps com.viaversion:viaversion-api from 4.9.2 to 4.9.3.

---
updated-dependencies:
- dependency-name: com.viaversion:viaversion-api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-22 09:01:17 +02:00
dependabot[bot] 2a496b9a1a Bump com.discordsrv:discordsrv from 1.26.2 to 1.27.0 (#115)
Bumps com.discordsrv:discordsrv from 1.26.2 to 1.27.0.

---
updated-dependencies:
- dependency-name: com.discordsrv:discordsrv
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-22 09:00:25 +02:00
daniel-skopek 655304bd52 Fixed putting items from inventory to the GUI (again) (#128)
* Fixed putting items from inventory to the GUI
2024-04-22 08:59:56 +02:00
Elikill58 0081c616d3 [Included in release] Fix #127 2024-04-17 00:00:02 +02:00
Elikill58 824cf62e4c Upgrade to 2.5.1 2024-04-16 22:40:12 +02:00
Elikill58 8f5c90557f Put expire time in config 2024-04-16 22:37:54 +02:00
Elikill58 7e6cb9910c Hide inventory cmd with uuid 2024-04-16 22:30:30 +02:00
Elikill58 0e6f35804d Fix shulker with too many items 2024-04-16 21:53:06 +02:00
Elikill58 fbcfbceaa4 Fix #126 2024-04-09 19:41:37 +02:00
Elikill58 4a6d46d1da Prevent plugin with same name 2024-03-26 20:44:49 +01:00
Elikill58 8779653211 Fix packet size 2024-03-26 20:42:33 +01:00
Elikill58 c4c511315a Change how adventure is 2024-03-06 21:23:18 +01:00
Elikill58 bcc0bbdd2a Upgrade to snapshot 2024-02-09 22:01:14 +01:00
Elikill58 ffe1bb8b44 Add missing placeholder 2024-02-09 20:04:13 +01:00
Elikill58 64cdccc2d1 Add debug 2024-02-09 19:59:34 +01:00
Elikill58 920a055f02 Change how adventure send msg 2024-02-09 19:58:56 +01:00
Elikill58 4d524244d6 Prevent NPE when getting item 2024-02-04 14:35:15 +01:00
daniel-skopek 429e4a597c Fixed putting items from inventory to the GUI (#121) 2024-02-04 14:31:20 +01:00
Elikill58 5a310e3f60 Upgrade to 2.5 2024-01-30 22:50:31 +01:00
Elikill58 58c5f4607f Merge branch 'v2' of https://github.com/dadus33-plugins/ChatItem into v2 2024-01-27 18:34:53 +01:00
Elikill58 b436c73f47 Fix ecoenchants support 2024-01-27 18:34:46 +01:00
Elikill58 806ceea250 Change for adventure 2024-01-25 22:24:27 +01:00
Elikill58 9a4ef0fe5b Fix some issue with primitive 2024-01-23 20:21:51 +01:00
Elikill58 241f80ca3c Fix strange EC 2024-01-22 19:27:01 +01:00
Elikill58 710bbf3163 Prevent inventory click 2024-01-14 12:11:18 +01:00
Elikill58 4ee561c18f Try to send message using discord srv 2024-01-13 11:34:00 +01:00
Elikill58 17754f2dfe Inv and ec for others managers 2024-01-11 22:25:28 +01:00
Elikill58 6a683508d4 Prevent & Fix #114 2024-01-11 22:05:02 +01:00
Elikill58 bcc8ac08f2 Begin of #31 2024-01-11 22:02:35 +01:00
dependabot[bot] 429a664e81 Bump com.willfp:eco from 6.65.5 to 6.66.1 (#109)
Bumps [com.willfp:eco](https://github.com/Auxilor/eco) from 6.65.5 to 6.66.1.
- [Release notes](https://github.com/Auxilor/eco/releases)
- [Commits](https://github.com/Auxilor/eco/compare/6.65.5...6.66.1)

---
updated-dependencies:
- dependency-name: com.willfp:eco
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-11 08:32:27 +01:00
dependabot[bot] 49dadb897a Bump com.viaversion:viaversion-api from 4.8.1 to 4.9.2 (#113)
Bumps com.viaversion:viaversion-api from 4.8.1 to 4.9.2.

---
updated-dependencies:
- dependency-name: com.viaversion:viaversion-api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-11 08:31:55 +01:00
Elikill58 3cf54d39a1 Fix #111 2023-12-10 17:33:15 +01:00
Elikill58 187d1212f5 Upgrade to snapshot 2023-12-10 17:27:55 +01:00
Elikill58 d3776e161f Fix #112 2023-12-10 17:27:30 +01:00
Elikill58 010ea46ff2 Add reset color 2023-12-10 11:27:31 +01:00
Elikill58 db8119affd Do not listen on useless thing 2023-11-16 19:28:57 +01:00
Elikill58 484a6b46a0 Merge branch 'v2' of https://github.com/dadus33-plugins/ChatItem into v2 2023-11-06 00:43:33 +01:00
Elikill58 a48f259b99 Fix for 1.20.2 2023-11-06 00:43:27 +01:00
Elikill58 2b9ae264fd Little internal changes 2023-11-05 23:52:00 +01:00
dependabot[bot] 207b066ecb Bump com.github.Auxilor:EcoEnchants from 10.36.1 to 10.39.1 (#105)
Bumps [com.github.Auxilor:EcoEnchants](https://github.com/Auxilor/EcoEnchants) from 10.36.1 to 10.39.1.
- [Release notes](https://github.com/Auxilor/EcoEnchants/releases)
- [Commits](https://github.com/Auxilor/EcoEnchants/compare/10.36.1...10.39.1)

---
updated-dependencies:
- dependency-name: com.github.Auxilor:EcoEnchants
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 11:08:13 +01:00
Elikill58 587432269a Upgrade to 2.4.9 2023-10-09 23:36:05 +02:00
dependabot[bot] a080e18571 Bump EcoEnchants 10.36.1 (#99)
Bumps [com.github.Auxilor:EcoEnchants](https://github.com/Auxilor/EcoEnchants) from 10.35.3 to 10.36.1.
- [Release notes](https://github.com/Auxilor/EcoEnchants/releases)
- [Commits](https://github.com/Auxilor/EcoEnchants/compare/10.35.3...10.36.1)

---
updated-dependencies:
- dependency-name: com.github.Auxilor:EcoEnchants
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-09 13:57:20 +02:00
dependabot[bot] 7b758882be Bump ProtocolLib to 5.1.0 (#90)
Bumps com.comphenix.protocol:ProtocolLib from 5.0.0 to 5.1.0.

---
updated-dependencies:
- dependency-name: com.comphenix.protocol:ProtocolLib
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-09 13:57:09 +02:00
dependabot[bot] beafc6a635 Bump com.viaversion:viaversion-api from 4.7.0 to 4.8.1 (#102)
Bumps com.viaversion:viaversion-api from 4.7.0 to 4.8.1.

---
updated-dependencies:
- dependency-name: com.viaversion:viaversion-api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-09 13:54:52 +02:00
dependabot[bot] 0da4039b70 Bump com.willfp:eco from 6.65.4 to 6.65.5 (#95)
Bumps [com.willfp:eco](https://github.com/Auxilor/eco) from 6.65.4 to 6.65.5.
- [Release notes](https://github.com/Auxilor/eco/releases)
- [Commits](https://github.com/Auxilor/eco/compare/6.65.4...6.65.5)

---
updated-dependencies:
- dependency-name: com.willfp:eco
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-18 08:16:24 +02:00
dependabot[bot] b89e18b149 Bump com.github.Auxilor:EcoEnchants from 10.35.2 to 10.35.3 (#94)
Bumps [com.github.Auxilor:EcoEnchants](https://github.com/Auxilor/EcoEnchants) from 10.35.2 to 10.35.3.
- [Release notes](https://github.com/Auxilor/EcoEnchants/releases)
- [Commits](https://github.com/Auxilor/EcoEnchants/compare/10.35.2...10.35.3)

---
updated-dependencies:
- dependency-name: com.github.Auxilor:EcoEnchants
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-18 08:15:43 +02:00
Elikill58 07243fbf91 Fix wrong key 2023-09-17 21:59:43 +02:00
Elikill58 4b90aaa070 Prevent no end in message 2023-09-17 11:32:53 +02:00
Elikill58 9d74eb067a Fix #93 2023-09-14 15:56:58 +02:00
dependabot[bot] c51f62a9fb Bump com.github.Auxilor:EcoEnchants from 10.26.5 to 10.35.2 (#92)
Bumps [com.github.Auxilor:EcoEnchants](https://github.com/Auxilor/EcoEnchants) from 10.26.5 to 10.35.2.
- [Release notes](https://github.com/Auxilor/EcoEnchants/releases)
- [Commits](https://github.com/Auxilor/EcoEnchants/compare/10.26.5...10.35.2)

---
updated-dependencies:
- dependency-name: com.github.Auxilor:EcoEnchants
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-14 15:51:07 +02:00
Elikill58 badddd29ed Prevent NPE 2023-08-07 13:01:56 +02:00
Elikill58 d188289e84 Add option for broadcast and show, and change for tab 2023-08-07 11:27:11 +02:00
dependabot[bot] 1b9fd3bf90 Bump com.willfp:eco from 6.65.3 to 6.65.4 (#85)
Bumps com.willfp:eco from 6.65.3 to 6.65.4.

---
updated-dependencies:
- dependency-name: com.willfp:eco
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-07 08:34:36 +02:00
dependabot[bot] 0d98b4408e Bump com.github.Auxilor:EcoEnchants from 10.26.2 to 10.26.5 (#87)
Bumps com.github.Auxilor:EcoEnchants from 10.26.2 to 10.26.5.

---
updated-dependencies:
- dependency-name: com.github.Auxilor:EcoEnchants
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-07 08:34:27 +02:00
dependabot[bot] 769abab65c Bump com.github.Auxilor:EcoEnchants from 10.25.1 to 10.26.2 (#84)
Bumps com.github.Auxilor:EcoEnchants from 10.25.1 to 10.26.2.

---
updated-dependencies:
- dependency-name: com.github.Auxilor:EcoEnchants
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-31 08:14:07 +02:00
Elikill58 78311f60b4 upgrade to snapshot 2023-07-26 19:44:51 +02:00
Elikill58 bd31b5791c Fix for 1.15- players 2023-07-26 19:44:24 +02:00
Elikill58 cd5cfa47ec Fix error with json 2023-07-26 19:27:37 +02:00
Elikill58 d31bdbef68 Remove one import 2023-07-26 19:01:12 +02:00
Elikill58 a82b50b1d0 Fix #78 2023-07-24 11:34:04 +02:00
dependabot[bot] 912bbcf371 Bump com.willfp:eco from 6.65.2 to 6.65.3 (#83)
Bumps com.willfp:eco from 6.65.2 to 6.65.3.

---
updated-dependencies:
- dependency-name: com.willfp:eco
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-24 11:27:03 +02:00
dependabot[bot] af5d63ea93 Bump com.github.Auxilor:EcoEnchants from 10.23.1 to 10.25.1 (#82)
Bumps [com.github.Auxilor:EcoEnchants](https://github.com/Auxilor/EcoEnchants) from 10.23.1 to 10.25.1.
- [Release notes](https://github.com/Auxilor/EcoEnchants/releases)
- [Commits](https://github.com/Auxilor/EcoEnchants/compare/10.23.1...10.25.1)

---
updated-dependencies:
- dependency-name: com.github.Auxilor:EcoEnchants
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-24 11:26:56 +02:00
Elikill58 69681553c8 Fix 1.18 issue 2023-07-20 20:05:58 +02:00
Elikill58 3f6856ddab Fix invocation error 2023-07-20 19:22:39 +02:00
Elikill58 9d55208563 Change ChatControl support 2023-07-19 20:27:14 +02:00
Elikill58 2b8ce53553 Upgrade to 2.4.8 2023-07-17 21:22:52 +02:00
dependabot[bot] 6b157320c4 Bump eco from 6.65.1 to 6.65.2 (#80)
Bumps [eco](https://github.com/Auxilor/eco) from 6.65.1 to 6.65.2.
- [Release notes](https://github.com/Auxilor/eco/releases)
- [Commits](https://github.com/Auxilor/eco/compare/6.65.1...6.65.2)

---
updated-dependencies:
- dependency-name: com.willfp:eco
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-17 07:53:03 +02:00
dependabot[bot] ba3da92061 Bump HexNicks from 3.1.0 to 3.1.1 (#81)
Bumps [HexNicks](https://github.com/MajekDev/HexNicks) from 3.1.0 to 3.1.1.
- [Release notes](https://github.com/MajekDev/HexNicks/releases)
- [Changelog](https://github.com/MajekDev/HexNicks/blob/main/CHANGELOG.md)
- [Commits](https://github.com/MajekDev/HexNicks/compare/v3.1.0...v3.1.1)

---
updated-dependencies:
- dependency-name: com.github.MajekDev:HexNicks
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-17 07:52:44 +02:00
Elikill58 dc6ce9c260 Change dep 2023-07-15 20:42:07 +02:00
Elikill58 cf45b8e436 Fix EcoEnchants v10 support 2023-07-15 12:05:00 +02:00
Elikill58 fc8966dab0 Change permissions 2023-06-17 18:18:49 +02:00
Elikill58 c537e72a27 Update versions 2023-06-16 10:26:32 +02:00
Elikill58 dee359a37d Upgrade to snapshot 2023-06-16 09:36:05 +02:00
Elikill58 34f67345e2 Add support for 1.20 2023-06-16 09:35:37 +02:00
Elikill58 d937f5d89e Change discord link in config 2023-06-16 09:09:53 +02:00
Elikill58 856a5f182f Fix error with 1.20 2023-06-16 09:08:52 +02:00
dependabot[bot] 6653b9c057 Bump viaversion-api from 4.6.2 to 4.7.0 (#77)
Bumps viaversion-api from 4.6.2 to 4.7.0.

---
updated-dependencies:
- dependency-name: com.viaversion:viaversion-api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-12 17:43:35 +02:00
Elikill58 0b60780fe2 Merge branch 'v2' of https://github.com/dadus33-plugins/ChatItem into v2 2023-06-05 19:59:17 +02:00
Elikill58 a16b2ea462 Don't use one componentManager 2023-06-05 19:59:10 +02:00
Magnetite 05771d975c Add support for hexnicks 3 (#76)
* Add support for hexnicks 3

* Remove empty line
2023-05-31 13:48:25 +02:00
Elikill58 417b63e86d [Include in release] Change default config 2023-05-23 08:12:33 +02:00
Elikill58 01da231510 [Include in release] Quick fix typo for lang 2023-05-23 07:37:17 +02:00
dependabot[bot] 5e2559c1ee Bump ProtocolLib from 5.0.0-SNAPSHOT to 5.0.0 (#75)
Bumps ProtocolLib from 5.0.0-SNAPSHOT to 5.0.0.

---
updated-dependencies:
- dependency-name: com.comphenix.protocol:ProtocolLib
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-15 18:34:59 +02:00
Elikill58 0bb784f7f2 Fix for v2 colors 2023-05-15 18:33:48 +02:00
Elikill58 eef3bf80c8 Fix wrong version check 2023-05-14 21:04:56 +02:00
Elikill58 2d97d5fd45 Upgrade to 2.4.7 2023-05-09 18:53:00 +02:00
Elikill58 32e71bc683 Fix chatitem select 2023-05-09 18:51:59 +02:00
Elikill58 31c08cbb37 Add select of manager 2023-05-06 12:49:11 +02:00
Elikill58 084cc40f88 Fix second message 2023-05-06 11:19:43 +02:00
Elikill58 c322fb2eec Fix double item in chat 2023-05-06 10:30:05 +02:00
Elikill58 4e90d96f48 Fix v1 issue #74 2023-04-30 22:42:14 +02:00
Elikill58 828a8e3824 Add chatmanager support 2023-04-30 22:24:29 +02:00
Elikill58 7da5adf264 Update gitignore 2023-04-30 22:12:01 +02:00
Elikill58 513185de26 Fix unknow version 2023-04-10 11:25:25 +02:00
Elikill58 2f17aa897a Prevent obj can't be created 2023-04-10 11:10:18 +02:00
Elikill58 dd2359f96d Change for TAB 2023-04-10 10:54:43 +02:00
Elikill58 8799aa6fc0 Fix storage 2023-04-10 10:50:18 +02:00
Elikill58 4dfe50038b Fix failed to find lang 2023-04-10 10:46:29 +02:00
Elikill58 51c4311233 Fix for item/block and for chatitem links 2023-04-07 09:30:24 +02:00
Elikill58 72557594eb Fix for not found constructor 2023-04-07 09:24:10 +02:00
Elikill58 708e995ac7 Add items in langs 2023-04-05 22:17:24 +02:00
Elikill58 589318ea8d Re-add EcoEnchant support for v8 2023-04-05 21:55:55 +02:00
Elikill58 17e9edbd53 Add translation into inventory 2023-04-04 22:49:22 +02:00
Elikill58 f5124f749f Add complete translation system 2023-04-04 22:10:01 +02:00
Elikill58 fe10f7ca5b Change readme 2023-04-03 22:24:23 +02:00
dependabot[bot] d590b66630 Bump discordsrv from 1.26.0 to 1.26.2 (#71)
Bumps discordsrv from 1.26.0 to 1.26.2.

---
updated-dependencies:
- dependency-name: com.discordsrv:discordsrv
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-03 22:13:17 +02:00
dependabot[bot] e68b843f73 Bump viaversion-api from 4.6.1 to 4.6.2 (#72)
Bumps viaversion-api from 4.6.1 to 4.6.2.

---
updated-dependencies:
- dependency-name: com.viaversion:viaversion-api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-03 22:12:56 +02:00
Elikill58 2cf594f9ed Fix PCM 2023-04-02 17:15:21 +02:00
Elikill58 1b33b42e94 Fix error 2023-04-01 14:37:12 +02:00
Elikill58 77ba7e65ce Re-add some managers 2023-04-01 14:31:42 +02:00
Elikill58 7375f970af Fix error while changing packet 2023-03-30 22:46:35 +02:00
Elikill58 870d9052a0 Fix double item 2023-03-28 19:13:33 +02:00
Elikill58 4ea4aa43bf Upgrade kyori's adventure thing 2023-03-26 15:30:45 +02:00
Elikill58 39ffa60e7a Prevent the error 2023-03-21 17:44:39 +01:00
dependabot[bot] fc1c9b0019 Bump EcoEnchants from 9.17.5 to 9.17.7 (#68)
Bumps [EcoEnchants](https://github.com/Auxilor/EcoEnchants) from 9.17.5 to 9.17.7.
- [Release notes](https://github.com/Auxilor/EcoEnchants/releases)
- [Commits](https://github.com/Auxilor/EcoEnchants/compare/9.17.5...9.17.7)

---
updated-dependencies:
- dependency-name: com.willfp:EcoEnchants
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-20 22:35:04 +01:00
dependabot[bot] ed3ad9db85 Bump viaversion-api from 4.5.1 to 4.6.1 (#69)
Bumps viaversion-api from 4.5.1 to 4.6.1.

---
updated-dependencies:
- dependency-name: com.viaversion:viaversion-api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-20 22:34:44 +01:00
dependabot[bot] c38d68d081 Bump ChatControl-Free from master-SNAPSHOT to 5.9.5 (#70)
Bumps [ChatControl-Free](https://github.com/kangarko/ChatControl-Free) from master-SNAPSHOT to 5.9.5.
- [Release notes](https://github.com/kangarko/ChatControl-Free/releases)
- [Commits](https://github.com/kangarko/ChatControl-Free/commits/5.9.5)

---
updated-dependencies:
- dependency-name: com.github.kangarko:ChatControl-Free
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-20 22:34:33 +01:00
Elikill58 352dcb82b7 Add ChatContorl into plugin dep 2023-03-16 21:42:20 +01:00
Elikill58 7981ccaa1e Fix cooldown for v1 and chatcontrol support 2023-03-16 21:41:56 +01:00
Elikill58 e5444216ce Merge branch 'v2' of https://github.com/dadus33-plugins/ChatItem into v2 2023-03-15 23:55:02 +01:00
dependabot[bot] 207159bb17 Bump EcoEnchants from 9.17.3 to 9.17.5 (#67)
Bumps [EcoEnchants](https://github.com/Auxilor/EcoEnchants) from 9.17.3 to 9.17.5.
- [Release notes](https://github.com/Auxilor/EcoEnchants/releases)
- [Commits](https://github.com/Auxilor/EcoEnchants/compare/9.17.3...9.17.5)

---
updated-dependencies:
- dependency-name: com.willfp:EcoEnchants
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-15 13:55:04 +01:00
dependabot[bot] 32d4d3556d Bump opennbt from 1.4 to 1.5 (#66)
Bumps [opennbt](https://github.com/Steveice10/OpenNBT) from 1.4 to 1.5.
- [Release notes](https://github.com/Steveice10/OpenNBT/releases)
- [Commits](https://github.com/Steveice10/OpenNBT/compare/1.4...1.5)

---
updated-dependencies:
- dependency-name: com.github.GeyserMC:opennbt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-15 13:54:56 +01:00
Elikill58 9102b6a11f Change default config 2023-03-10 19:00:11 +01:00
Elikill58 587d6bbb93 Fix #16 2023-03-10 18:57:19 +01:00
Elikill58 9ea5d6ffb7 Quick change for SCM 2023-03-10 18:25:14 +01:00
Elikill58 7ac7369a7f Update how bugged clients are managed 2023-03-09 21:18:36 +01:00
Elikill58 d548b68c8a Prevent error for 1.12- version 2023-03-07 21:17:52 +01:00
dependabot[bot] 92f4118015 Bump EcoEnchants from 9.17.1 to 9.17.3 (#64)
Bumps [EcoEnchants](https://github.com/Auxilor/EcoEnchants) from 9.17.1 to 9.17.3.
- [Release notes](https://github.com/Auxilor/EcoEnchants/releases)
- [Commits](https://github.com/Auxilor/EcoEnchants/compare/9.17.1...9.17.3)

---
updated-dependencies:
- dependency-name: com.willfp:EcoEnchants
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-07 20:17:00 +01:00
Elikill58 3cae31998e Remove one logger 2023-03-07 18:10:50 +01:00
Elikill58 396b8ccc05 Possible way to remove coloring 2023-03-07 18:10:16 +01:00
Elikill58 70fece6c4f Prevent re-adding content 2023-03-07 17:42:26 +01:00
Elikill58 7ad2f1923e Fix end of message removed 2023-03-05 13:47:10 +01:00
Elikill58 f1796cee43 Add new filter 2023-03-05 10:38:27 +01:00
Elikill58 e460940fcd Fx something not filtered 2023-03-04 20:39:36 +01:00
Elikill58 26b71376b1 Upgrade to 2.4.6 2023-02-27 22:59:58 +01:00
Elikill58 9b25f2e0ae Fix control 2023-02-27 17:39:50 +01:00
dependabot[bot] cd40bc0894 Bump EcoEnchants from 9.17.0 to 9.17.1 (#63)
Bumps [EcoEnchants](https://github.com/Auxilor/EcoEnchants) from 9.17.0 to 9.17.1.
- [Release notes](https://github.com/Auxilor/EcoEnchants/releases)
- [Commits](https://github.com/Auxilor/EcoEnchants/compare/9.17.0...9.17.1)

---
updated-dependencies:
- dependency-name: com.willfp:EcoEnchants
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-21 18:08:33 +01:00
dependabot[bot] 06493ab38c Bump EcoEnchants from 9.16.0 to 9.17.0 (#62)
Bumps [EcoEnchants](https://github.com/Auxilor/EcoEnchants) from 9.16.0 to 9.17.0.
- [Release notes](https://github.com/Auxilor/EcoEnchants/releases)
- [Commits](https://github.com/Auxilor/EcoEnchants/compare/9.16.0...9.17.0)

---
updated-dependencies:
- dependency-name: com.willfp:EcoEnchants
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-13 21:00:23 +01:00
Elikill58 5c3519171e Change for string 2023-02-13 20:59:48 +01:00
Elikill58 ca6982d7b0 Clean for empty lines 2023-02-11 16:19:06 +01:00
dependabot[bot] 1c5a8dbdcc Bump EcoEnchants from 9.15.0 to 9.16.0 (#61)
Bumps [EcoEnchants](https://github.com/Auxilor/EcoEnchants) from 9.15.0 to 9.16.0.
- [Release notes](https://github.com/Auxilor/EcoEnchants/releases)
- [Commits](https://github.com/Auxilor/EcoEnchants/compare/9.15.0...9.16.0)

---
updated-dependencies:
- dependency-name: com.willfp:EcoEnchants
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-30 12:26:33 +01:00
Elikill58 0cf3c25b2c Prevent NPE 2023-01-27 10:04:47 +01:00
Elikill58 d0122a123e Update few things 2023-01-26 10:49:59 +01:00
dependabot[bot] 5493d76d00 Bump EcoEnchants from 9.14.4 to 9.15.0 (#56)
Bumps [EcoEnchants](https://github.com/Auxilor/EcoEnchants) from 9.14.4 to 9.15.0.
- [Release notes](https://github.com/Auxilor/EcoEnchants/releases)
- [Commits](https://github.com/Auxilor/EcoEnchants/compare/9.14.4...9.15.0)

---
updated-dependencies:
- dependency-name: com.willfp:EcoEnchants
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-09 17:54:58 +01:00
Elikill58 7fc535ffc6 Introduce chat object (#57)
* Refactor how manager check messages

* Rename config variables

* Fix searching chat id

* Remove some debug lines

* Change default config

* Fix for empty recipients
2023-01-09 17:54:46 +01:00
Elikill58 8b9f9a2842 Merge branch 'v2' of https://github.com/dadus33-plugins/ChatItem into v2 2023-01-03 17:10:38 +01:00
Elikill58 c60ade6a9c Skip mmo item wrong val 2023-01-03 17:10:27 +01:00
dependabot[bot] a0265599f6 Bump EcoEnchants from 9.14.3 to 9.14.4 (#55)
Bumps [EcoEnchants](https://github.com/Auxilor/EcoEnchants) from 9.14.3 to 9.14.4.
- [Release notes](https://github.com/Auxilor/EcoEnchants/releases)
- [Commits](https://github.com/Auxilor/EcoEnchants/compare/9.14.3...9.14.4)

---
updated-dependencies:
- dependency-name: com.willfp:EcoEnchants
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-02 11:12:09 +01:00
dependabot[bot] 9f45069c08 Bump EcoEnchants from 9.13.0-all to 9.14.3 (#54)
Bumps EcoEnchants from 9.13.0-all to 9.14.3.

---
updated-dependencies:
- dependency-name: com.willfp:EcoEnchants
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-26 23:44:33 +01:00
Elikill58 f3b95ad32d Prevent trying to save file 2022-12-18 11:28:33 +01:00
dependabot[bot] 444d58900e Bump viaversion-api from 4.3.0 to 4.5.1 (#50)
Bumps viaversion-api from 4.3.0 to 4.5.1.

---
updated-dependencies:
- dependency-name: com.viaversion:viaversion-api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-12 21:10:16 +01:00
Elikill58 72f239b293 Fix ComponentNMS 2022-12-12 21:09:11 +01:00
Elikill58 6bc0b919c5 Be able to continue to next manager 2022-12-10 12:53:07 +01:00
Elikill58 4864272c34 Multiple quick fix 2022-12-10 12:49:23 +01:00
Elikill58 a421e6e167 Be able to use direct base component object 2022-12-09 10:56:26 +01:00
Elikill58 76c6bafea7 Fix for children and adventure 2022-12-09 10:43:53 +01:00
Elikill58 f50dd5a1f8 Update adventure support 2022-12-09 00:04:41 +01:00
Elikill58 0dbc6c14bb Fix wrong var used 2022-12-07 21:41:41 +01:00
Elikill58 1d41b02f79 Fix #46 2022-12-07 18:02:07 +01:00
Elikill58 ec278c7d08 Update versions 2022-12-07 17:15:57 +01:00
dependabot[bot] 5729dbf4a6 Bump discordsrv from 1.25.1 to 1.26.0 (#48)
Bumps [discordsrv](https://github.com/DiscordSRV/DiscordSRV) from 1.25.1 to 1.26.0.
- [Release notes](https://github.com/DiscordSRV/DiscordSRV/releases)
- [Commits](https://github.com/DiscordSRV/DiscordSRV/compare/v1.25.1...v1.26.0)

---
updated-dependencies:
- dependency-name: com.discordsrv:discordsrv
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-07 16:05:38 +01:00
Elikill58 4129b52dc5 Update workflow versions 2022-12-07 16:05:22 +01:00
Elikill58 55c9cc6673 Update ViaVersion (Fix #49) 2022-12-07 16:04:14 +01:00
dependabot[bot] 59e75770fb Bump netty-all from 4.1.53.Final to 4.1.58.Final (#47)
Bumps netty-all from 4.1.53.Final to 4.1.58.Final.

---
updated-dependencies:
- dependency-name: io.netty:netty-all
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-07 16:01:30 +01:00
Elikill58 d6ce0c62ff Delete travis file 2022-12-07 16:00:45 +01:00
Elikill58 0ef13e39ae Add dependabot 2022-12-07 15:59:28 +01:00
Elikill58 26b0837784 Temporary remove EcoEnchants support to prevent error 2022-12-07 15:58:18 +01:00
Elikill58 1f3a510411 Remove log4j unused thing 2022-12-07 15:29:46 +01:00
Elikill58 039d5fb6d5 Remove name showed 2022-12-07 14:54:20 +01:00
Elikill58 048fe69204 Missing one change 2022-12-04 23:28:39 +01:00
Elikill58 358c574153 Maybe fix empty extra 2022-12-04 23:27:18 +01:00
Elikill58 efa0a345f9 Add more loggers 2022-12-04 22:58:53 +01:00
Elikill58 78670bf8ec Fix multiple send 2022-11-19 08:58:36 +01:00
Elikill58 a47b93ea1a Upgrade to snapshot 2022-11-16 19:11:17 +01:00
Elikill58 f4d56b56e1 Fix double name 2022-11-16 19:10:51 +01:00
Elikill58 3eb54bb4d6 Fix mistake 2022-11-15 12:09:23 +01:00
Elikill58 a0f54df9b7 Fix color codes 2022-11-15 12:07:22 +01:00
Elikill58 80a000cee7 Update NMS behavior 2022-11-15 11:56:13 +01:00
Elikill58 8bd6bed5fb rename components 2022-11-15 11:11:42 +01:00
Elikill58 ba5e8d9935 Complete refactor of String ComponentGetter 2022-11-15 11:10:39 +01:00
Elikill58 8d6b3e7987 Quickly change for some extra/text things 2022-11-14 23:13:27 +01:00
Elikill58 3fd14b3bdb Upgrade to 2.4.5 2022-10-18 19:40:45 +02:00
Elikill58 6c3784e662 Fix multiple quick issues 2022-10-12 17:27:34 +02:00
Elikill58 6256de065e Change base component 2022-10-03 16:10:59 +02:00
Elikill58 4c1d64f04c Fix v1 detection in v2 2022-09-26 09:20:34 +02:00
Elikill58 4475f19268 Upgrade to snapshot 2022-09-14 15:50:01 +02:00
Elikill58 2b5065dbec Update multiple things into v1 2022-09-14 15:49:27 +02:00
Elikill58 ba54582f7f Fix only first line take in count 2022-08-30 12:31:08 +02:00
227 changed files with 5791 additions and 3598 deletions

No files matched your search

+12
View File
@@ -0,0 +1,12 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "maven"
directory: "/"
schedule:
interval: "weekly"
+7 -7
View File
@@ -10,21 +10,21 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
name: Checkout repo
- name: Set up JDK 17 (LTS)
uses: actions/setup-java@v2
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'adopt'
java-version: '21'
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn install --file pom.xml
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v3
name: Upload Artifact
with:
name: ChatItem.jar
path: target/ChatItem-*.jar
path: target/ChatItem-*.jar
+6 -6
View File
@@ -10,20 +10,20 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
name: Checkout repo
- name: Set up JDK 17 (LTS)
uses: actions/setup-java@v2
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'adopt'
java-version: '21'
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn install --file pom.xml
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
name: Upload Artifact
with:
name: ChatItem.jar
+3 -1
View File
@@ -6,4 +6,6 @@ target/
dependency-reduced-pom.xml
.classpath
.project
.settings/
.settings/
/.apt_generated/
/.apt_generated_tests/
-2
View File
@@ -1,2 +0,0 @@
language: java
script: "mvn clean package -DskipTests"
+25 -1
View File
@@ -1,5 +1,29 @@
# ChatItem [![Build Status](https://travis-ci.org/dadus33/ChatItem.svg?branch=master)](https://travis-ci.org/dadus33/ChatItem) [![Help Chat](https://img.shields.io/badge/chat-on_discord-7289da.svg)](https://discord.gg/eQJbVJt)
# ChatItem
The official repository of the ChatItem Spigot/Bukkit plugin.
You can:
- [Download latest dev build](https://nightly.link/dadus33-plugins/ChatItem/workflows/build/v2/ChatItem.jar.zip)
- [ ![Come on discord](https://img.shields.io/badge/chat-on_discord-7289da.svg) ](https://discord.gg/yng5PPf62h)
- [Check the wiki](https://github.com/dadus33-plugins/ChatItem/wiki)
# Item doesn't show up well in chat
You can do `/chatitem admin` then select one of the other paper items in the menu. It will change how the plugin tries to display items in chat.
**If you still have an issue, please do**:
1) Do `/chatitem admin` then select on "Debug" item at top right
2) Try to use ChatItem in chat
3) Come on discord [here](https://discord.gg/yng5PPf62h) or in private message: `Elikill58#0743`
4) Send the **full file `logs/latest.log`**
PS: Yes you can disable the debug behavior after.
# Building
Building this is simple as we use Maven.
To build it, simply clone this repository and then run `mvn clean install`.
You can add the parameter `export_dir` to set the URL where the JAR will be exported.
+76 -38
View File
@@ -5,8 +5,8 @@
<modelVersion>4.0.0</modelVersion>
<groupId>me.dadus33</groupId>
<artifactId>chatitem</artifactId>
<version>2.4.4</version>
<artifactId>ChatItem</artifactId>
<version>2.6.2</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -52,15 +52,27 @@
<repository>
<id>Scarsz-Nexus</id>
<url>https://nexus.scarsz.me/content/groups/public/</url>
</repository>
</repository>
<repository>
<id>PaperMC</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository>
<id>mvdw-software</id>
<url>http://repo.mvdw-software.be/content/groups/public/</url>
</repository>
<repository>
<id>essentials-snapshots</id>
<url>https://repo.essentialsx.net/snapshots/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.17-R0.1-SNAPSHOT</version>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.21-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -70,18 +82,6 @@
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
@@ -97,13 +97,13 @@
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>5.0.0-SNAPSHOT</version>
<version>5.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>us.myles</groupId>
<artifactId>viaversion</artifactId>
<version>3.0.0</version>
<groupId>com.viaversion</groupId>
<artifactId>viaversion-api</artifactId>
<version>5.0.3</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -115,37 +115,37 @@
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.53.Final</version>
<version>4.1.58.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.GeyserMC</groupId>
<artifactId>opennbt</artifactId>
<version>1.4</version>
<version>1.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>dev.majek</groupId>
<artifactId>HexNicks</artifactId>
<version>2.2.1</version>
<version>3.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.11.0</version>
<version>4.17.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-bungeecord</artifactId>
<version>4.1.0</version>
<scope>compile</scope>
<artifactId>adventure-platform-bukkit</artifactId>
<version>4.3.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.discordsrv</groupId>
<artifactId>discordsrv</artifactId>
<version>1.25.1</version>
<version>1.28.1</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -154,6 +154,48 @@
<version>8.57.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.Auxilor</groupId>
<artifactId>EcoEnchants</artifactId>
<version>12.5.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.ryderbelserion</groupId>
<artifactId>ChatManager</artifactId>
<version>3.7.7</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.willfp</groupId>
<artifactId>eco</artifactId>
<version>6.66.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.11.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>be.maximvdw</groupId>
<artifactId>MVdWPlaceholderAPI</artifactId>
<version>3.1.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.MilkBowl</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.essentialsx</groupId>
<artifactId>EssentialsX</artifactId>
<version>2.21.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
@@ -162,10 +204,6 @@
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>plugin.yml</include>
<include>config.yml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
@@ -183,7 +221,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
@@ -198,8 +236,8 @@
<shadedPattern>me.dadus33.libs.gson</shadedPattern>
</relocation>
<relocation>
<pattern>net.kyori.adventure.text.serializer.bungeecord</pattern>
<shadedPattern>me.dadus33.libs.kyori.serializer.bungeecord</shadedPattern>
<pattern>com.github.steveice10.opennbt</pattern>
<shadedPattern>me.dadus33.libs.opennbt</shadedPattern>
</relocation>
</relocations>
<filters>
@@ -223,7 +261,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<version>3.3.0</version>
<configuration>
<outputDirectory>${export_dir}</outputDirectory>
</configuration>
+16
View File
@@ -0,0 +1,16 @@
package me.dadus33.chatitem;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
public class C {
public static TextComponent text(String s) {
return LegacyComponentSerializer.legacySection().deserialize(s);
}
public static String string(Component c) {
return LegacyComponentSerializer.legacySection().serialize(c);
}
}
+235 -163
View File
@@ -1,199 +1,271 @@
package me.dadus33.chatitem;
import com.google.common.base.Strings;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.chatmanager.v1.PacketEditingChatManager;
import me.dadus33.chatitem.chatmanager.v2.ChatListenerChatManager;
import me.dadus33.chatitem.commands.CIReloadCommand;
import me.dadus33.chatitem.commands.ChatItemCommand;
import me.dadus33.chatitem.filters.Log4jFilter;
import me.dadus33.chatitem.itemnamer.NamerManager;
import me.dadus33.chatitem.listeners.InventoryListener;
import me.dadus33.chatitem.listeners.JoinListener;
import me.dadus33.chatitem.playernamer.PlayerNamerManager;
import me.dadus33.chatitem.utils.SemVer;
import me.dadus33.chatitem.utils.Storage;
import me.dadus33.chatitem.utils.Utils;
import me.dadus33.chatitem.utils.Version;
import org.bukkit.ChatColor;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.StringJoiner;
import java.util.concurrent.CompletableFuture;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.*;
import com.google.common.base.Strings;
import me.dadus33.chatitem.chatmanager.ChatEventListener;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.chatmanager.v1.PacketEditingChatManager;
import me.dadus33.chatitem.chatmanager.v2.ChatListenerChatManager;
import me.dadus33.chatitem.chatmanager.v3.PaperChatManager;
import me.dadus33.chatitem.chatmanager.v4.OwnManager;
import me.dadus33.chatitem.commands.CIReloadCommand;
import me.dadus33.chatitem.commands.ChatItemCommand;
import me.dadus33.chatitem.hook.ChatControlSupport;
import me.dadus33.chatitem.hook.ChatManagerSupport;
import me.dadus33.chatitem.hook.ecoenchants.EcoEnchantsSupport;
import me.dadus33.chatitem.hook.placeholders.EssentialsPlaceholdersHook;
import me.dadus33.chatitem.hook.placeholders.IPlaceholders;
import me.dadus33.chatitem.hook.placeholders.MVdWPlaceholderAPIHook;
import me.dadus33.chatitem.hook.placeholders.OwnPlaceholder;
import me.dadus33.chatitem.hook.placeholders.PlaceholderAPIHook;
import me.dadus33.chatitem.hook.placeholders.VaultPlaceholderHook;
import me.dadus33.chatitem.invsee.InvShower;
import me.dadus33.chatitem.itemnamer.NamerManager;
import me.dadus33.chatitem.listeners.InventoryListener;
import me.dadus33.chatitem.listeners.JoinListener;
import me.dadus33.chatitem.listeners.TranslationInventoryListener;
import me.dadus33.chatitem.platform.IPlatform;
import me.dadus33.chatitem.platform.hook.PaperPlatform;
import me.dadus33.chatitem.platform.hook.SpigotPlatform;
import me.dadus33.chatitem.playernamer.PlayerNamerManager;
import me.dadus33.chatitem.utils.ReflectionUtils;
import me.dadus33.chatitem.utils.SemVer;
import me.dadus33.chatitem.utils.Utils;
import me.dadus33.chatitem.utils.Version;
public class ChatItem extends JavaPlugin {
public final static int CFG_VER = 13;
public static boolean discordSrvSupport = false, ecoEnchantsSupport = false, hasNewVersion = false;
private static ChatItem instance;
private final String brandChannelName = Version.getVersion().isNewerOrEquals(Version.V1_13) ? "minecraft:brand" : "MC|Brand";
private final List<ChatManager> chatManager = new ArrayList<>();
private Log4jFilter filter;
private Storage storage;
private static final List<IPlaceholders> PLACEHOLDERS = new ArrayList<>();
public static List<IPlaceholders> getPlaceholders() {
return PLACEHOLDERS;
}
public static String replace(Player p, String text) {
for(IPlaceholders ip : getPlaceholders())
text = ip.replace(p, text);
return text;
}
private static final IPlatform platform = Utils.IS_PAPER ? new PaperPlatform() : new SpigotPlatform();
public static IPlatform getPlatform() {
return platform;
}
public final static int CFG_VER = 13;
public static boolean discordSrvSupport = false, hasNewVersion = false;
private static ChatItem instance;
private final String brandChannelName = Version.getVersion().isNewerOrEquals(Version.V1_13) ? "minecraft:brand" : "MC|Brand";
private final List<ChatManager> chatManager = new ArrayList<>();
private Storage storage;
public static void reload(CommandSender sender) {
ChatItem pl = getInstance();
if (pl.getConfig().getKeys(false).isEmpty())
pl.saveDefaultConfig();
pl.reloadConfig();
String oldChatManager = pl.storage.MANAGER;
pl.storage = new Storage(pl.getConfig());
pl.chooseManagers();
pl.filter.setStorage(pl.storage);
if (!pl.storage.RELOAD_MESSAGE.isEmpty())
sender.sendMessage(pl.storage.RELOAD_MESSAGE);
if (!oldChatManager.equalsIgnoreCase(pl.storage.MANAGER))
sender.sendMessage(ChatColor.GOLD + "Changing the manager with command reloading CAN produce issue. It's mostly suggested to restart after finding the better manager for you.");
}
public static void reload(CommandSender sender) {
ChatItem pl = getInstance();
if (pl.getConfig().getKeys(false).isEmpty())
pl.saveDefaultConfig();
pl.reloadConfig();
pl.storage = new Storage(pl.getConfig());
//pl.chooseManagers();
Translation.load(pl);
InvShower.getInvShower().clear();
if(sender != null) {
if (!pl.storage.messageReload.isEmpty())
sender.sendMessage(pl.storage.messageReload);
}
ChatManager.setTesting(null);
}
public static ChatItem getInstance() {
return instance;
}
public static ChatItem getInstance() {
return instance;
}
public static void debug(String msg) {
if (getInstance().getStorage().DEBUG)
getInstance().getLogger().info("[Debug] " + msg.replace(ChatManager.SEPARATOR, 'S'));
}
public static void debug(String msg) {
if (getInstance().getStorage().debug)
getInstance().getLogger().info("[Debug] " + msg.replace(ChatManager.SEPARATOR, 'S').replace(ChatManager.SEPARATOR_END, 'E'));
}
public static boolean hasDebug() {
return getInstance().getStorage().debug;
}
private void chooseManagers() {
this.chatManager.forEach((cm) -> cm.unload(this));
this.chatManager.clear();
PluginManager pm = getServer().getPluginManager();
String managerName = getStorage().MANAGER;
private void chooseManagers() {
this.chatManager.forEach((cm) -> cm.unload(this));
this.chatManager.clear();
this.chatManager.add(new PacketEditingChatManager(this));
this.chatManager.add(new ChatListenerChatManager(this));
if(Utils.IS_PAPER) {
this.chatManager.add(new PaperChatManager(this));
this.chatManager.add(new OwnManager());
}
String managerName = getStorage().manager;
switch (managerName.toLowerCase(Locale.ROOT)) {
case "both":
this.chatManager.add(new PacketEditingChatManager(this));
this.chatManager.add(new ChatListenerChatManager(this));
getLogger().info("Manager automatically chosen: " + getVisualChatManagers());
break;
case "auto":
if (getPluginThatRequirePacket().stream().map(pm::getPlugin).anyMatch(Objects::nonNull) && Version.getVersion().isNewerThan(Version.V1_7))
this.chatManager.add(new PacketEditingChatManager(this));
else
this.chatManager.add(new ChatListenerChatManager(this));
getLogger().info("Manager automatically chosen: " + getVisualChatManagers());
break;
case "packet":
this.chatManager.add(new PacketEditingChatManager(this));
getLogger().info("Manager chosen: " + getVisualChatManagers());
break;
case "chat":
this.chatManager.add(new ChatListenerChatManager(this));
getLogger().info("Manager chosen: " + getVisualChatManagers());
break;
default:
getLogger().severe("----- WARN -----");
getLogger().severe("Failed to find manager: " + managerName + ".");
getLogger().severe("Please reset your config and/or check wiki for more information");
getLogger().severe("Using default manager: chat.");
getLogger().severe("----- WARN -----");
this.chatManager.add(new ChatListenerChatManager(this));
break;
}
switch (managerName.toLowerCase(Locale.ROOT)) {
case "both":
case "all":
case "auto":
getLogger().info("Manager automatically chosen: " + getVisualChatManagers());
break;
case "paper":
case "packet":
case "chat":
getLogger().info("Manager chosen: " + getVisualChatManagers());
break;
default:
getLogger().severe("----- WARN -----");
getLogger().severe("Failed to find manager: " + managerName + ".");
getLogger().severe("Please reset your config and/or check wiki for more information");
getLogger().severe("Using default manager: chat.");
getLogger().severe("----- WARN -----");
break;
}
this.chatManager.forEach((cm) -> cm.load(this, getStorage()));
this.chatManager.forEach((cm) -> cm.load(this, getStorage()));
NamerManager.load(this);
PlayerNamerManager.load(this);
}
NamerManager.load(this);
PlayerNamerManager.load(this);
}
private List<String> getPluginThatRequirePacket() {
return Arrays.asList("DeluxeChat", "HexNicks", "VentureChat");
}
public static List<String> getPluginThatRequirePacket() {
return Arrays.asList("DeluxeChat", "HexNicks", "VentureChat", "ItemsAdder");
}
@Override
public void onEnable() {
//Save the instance (we're basically a singleton)
instance = this;
getLogger().info("Detected server version: " + Version.getVersion().name().toLowerCase());
@Override
public void onEnable() {
// Save the instance (we're basically a singleton)
instance = this;
getLogger().info("Detected server version: " + Version.getVersion().name().toLowerCase() + " (Platform: " + getPlatform().getName() + ")");
//Load config
saveDefaultConfig();
storage = new Storage(getConfig());
// Load config
if (!new File(getDataFolder(), "config.yml").exists()) {
getLogger().info("--------------");
getLogger().info("");
getLogger().info("Welcome on ChatItem !");
getLogger().info("If you need help for setup, USE: /chatitem select");
getLogger().info("Then follow steps.");
getLogger().info("");
getLogger().info("--------------");
saveDefaultConfig();
}
storage = new Storage(getConfig());
//Commands
loadCommand(getCommand("cireload"), new CIReloadCommand());
loadCommand(getCommand("chatitem"), new ChatItemCommand());
// Commands
loadCommand(getCommand("cireload"), new CIReloadCommand());
loadCommand(getCommand("chatitem"), new ChatItemCommand());
// events
PluginManager pm = getServer().getPluginManager();
pm.registerEvents(new JoinListener(), this);
pm.registerEvents(new InventoryListener(), this);
// events
PluginManager pm = getServer().getPluginManager();
pm.registerEvents(new JoinListener(), this);
pm.registerEvents(new InventoryListener(), this);
pm.registerEvents(new TranslationInventoryListener(), this);
pm.registerEvents(new ChatEventListener(), this);
chooseManagers();
chooseManagers();
//Initialize Log4J filter (remove ugly console messages)
filter = new Log4jFilter(storage);
StringJoiner plugins = new StringJoiner(", ");
if (pm.isPluginEnabled("DiscordSRV")) {
discordSrvSupport = true;
plugins.add("DiscordSRV");
}
if (pm.isPluginEnabled("ChatControl") && ReflectionUtils.isClassExist("org.mineacademy.chatcontrol.settings.Settings")) {
ChatControlSupport.init(this);
plugins.add("ChatControl");
}
if (pm.isPluginEnabled("ChatManager") && ReflectionUtils.isClassExist("me.h1dd3nxn1nja.chatmanager.Main")) {
ChatManagerSupport.init(this);
plugins.add("ChatManager");
}
if (pm.isPluginEnabled("EcoEnchants") && EcoEnchantsSupport.load()) {
plugins.add("EcoEnchants");
}
if (pm.isPluginEnabled("PlaceholderAPI")) {
plugins.add("PlaceholderAPI");
PLACEHOLDERS.add(new PlaceholderAPIHook());
}
if (pm.isPluginEnabled("Essentials")) {
plugins.add("Essentials");
PLACEHOLDERS.add(new EssentialsPlaceholdersHook());
}
if (pm.isPluginEnabled("MVdWPlaceholderAPI")) {
plugins.add("MVdWPlaceholderAPI");
PLACEHOLDERS.add(new MVdWPlaceholderAPIHook());
}
if (pm.isPluginEnabled("Vault")) {
plugins.add("Vault");
PLACEHOLDERS.add(new VaultPlaceholderHook());
}
StringJoiner plugins = new StringJoiner(", ");
if (pm.getPlugin("DiscordSRV") != null) {
discordSrvSupport = true;
plugins.add("DiscordSRV");
}
if (plugins.length() > 0)
getLogger().info("Load " + plugins.toString() + " support.");
if (pm.getPlugin("EcoEnchants") != null) {
ecoEnchantsSupport = true;
plugins.add("EcoEnchants");
}
if(plugins.length() > 0)
getLogger().info("Load " + plugins.toString() + " support.");
PLACEHOLDERS.add(new OwnPlaceholder());
Translation.load(this);
getServer().getMessenger().registerIncomingPluginChannel(this, brandChannelName, (chan, p, msg) -> {
String client = new String(msg).substring(1);
ChatItem.debug("Detected client " + client + " for " + p.getName());
ItemPlayer.getPlayer(p).setClientName(client);
});
getServer().getMessenger().registerIncomingPluginChannel(this, brandChannelName, (chan, p, msg) -> ItemPlayer.getPlayer(p).setClientName(new String(msg).substring(1)));
if (storage.CHECK_UPDATE) {
getServer().getScheduler().runTaskAsynchronously(this, () -> {
String urlName = "https://api.spigotmc.org/legacy/update.php?resource=19064";
String content = Utils.getFromURL(urlName);
if (Strings.isNullOrEmpty(content))
return;
SemVer currentVersion = SemVer.parse(getDescription().getVersion());
if (currentVersion == null)
return;
SemVer latestVersion = SemVer.parse(content);
if (latestVersion != null && latestVersion.isNewerThan(currentVersion)) {
hasNewVersion = !content.equalsIgnoreCase(getDescription().getVersion());
if (hasNewVersion) {
getLogger().info(storage.JOIN_UPDATE_MESSAGE);
}
}
});
}
}
if (storage.checkUpdate) {
CompletableFuture.runAsync(() -> {
String urlName = "https://api.spigotmc.org/legacy/update.php?resource=19064";
String content = Utils.getFromURL(urlName);
if (Strings.isNullOrEmpty(content))
return;
SemVer currentVersion = SemVer.parse(getPlatform().getPluginVersion(this));
if (currentVersion == null)
return;
SemVer latestVersion = SemVer.parse(content);
if (latestVersion != null && latestVersion.isNewerThan(currentVersion)) {
hasNewVersion = !content.equalsIgnoreCase(getPlatform().getPluginVersion(this));
if (hasNewVersion)
getLogger().info(storage.updateMessage);
}
});
}
}
public void loadCommand(PluginCommand cmd, Object obj) {
if (obj instanceof CommandExecutor)
cmd.setExecutor((CommandExecutor) obj);
if (obj instanceof TabCompleter)
cmd.setTabCompleter((TabCompleter) obj);
}
public void loadCommand(PluginCommand cmd, Object obj) {
if (obj instanceof CommandExecutor)
cmd.setExecutor((CommandExecutor) obj);
if (obj instanceof TabCompleter)
cmd.setTabCompleter((TabCompleter) obj);
}
public Storage getStorage() {
return storage;
}
public Storage getStorage() {
return storage;
}
public List<ChatManager> getChatManager() {
return chatManager;
}
public List<ChatManager> getChatManager() {
return chatManager;
}
public boolean isManagerEnabled(String id) {
for (ChatManager cm : chatManager) {
if(cm.getId().equalsIgnoreCase(id))
return true;
}
return false;
}
public String getVisualChatManagers() {
StringJoiner sj = new StringJoiner(", ");
for (ChatManager cm : chatManager) {
sj.add(cm.getName() + " (" + cm.getId() + ")");
}
return sj.toString();
}
public String getVisualChatManagers() {
StringJoiner sj = new StringJoiner(", ");
for (ChatManager cm : chatManager) {
sj.add(cm.getName() + " (" + cm.getId() + ")");
}
return sj.toString();
}
public boolean isHasNewVersion() {
return hasNewVersion;
}
public boolean isHasNewVersion() {
return hasNewVersion;
}
}
@@ -73,7 +73,7 @@ public class ItemPlayer {
}
public boolean isBuggedClient() {
return getVersion().equals(Version.V1_7) && getClientName().toLowerCase().contains("lunarclient");
return (getVersion().equals(Version.V1_7) && getClientName().toLowerCase().contains("lunarclient")) || (!getVersion().isNewerOrEquals(Version.V1_15) && Version.getVersion().isNewerOrEquals(Version.V1_16));
}
@Override
@@ -0,0 +1,69 @@
package me.dadus33.chatitem;
import java.util.List;
import me.dadus33.chatitem.chatmanager.ChatManager;
public enum ItemSlot {
HAND(true, "", false),
HELMET(false, "helmet", false),
CHESTPLATE(false, "chestplate", false),
LEGGINGS(false, "leggings", false),
BOOTS(false, "boots", false),
INVENTORY(false, "inventory", true),
ENDERCHEST(false, "enderchest", true);
private final boolean basic, command;
private final String key;
private ItemSlot(boolean basic, String key, boolean command) {
this.basic = basic;
this.command = command;
this.key = key;
}
public boolean isBasic() {
return basic;
}
public boolean isCommand() {
return command;
}
public List<String> getPlaceholders() {
return ChatItem.getInstance().getConfig().getStringList(basic ? "general.placeholders" : "general.other-placeholders." + key + ".keys");
}
public boolean isEnabled() {
return basic || ChatItem.getInstance().getConfig().getBoolean("general.other-placeholders." + key + ".enabled", true);
}
public boolean isDenyIfNoItem() {
return ChatItem.getInstance().getConfig().getBoolean("general" + (basic ? "" : ".other-placeholders." + key) + ".deny-if-no-item", true);
}
public boolean hasPlaceholders(String message) {
for (String rep : getPlaceholders()) {
if (message.contains(rep)) {
return true;
}
}
return false;
}
public String replacePlaceholdersToSeparator(String message) {
for(String rep : getPlaceholders())
message = message.replace(rep, Character.toString(ChatManager.SEPARATOR));
return message;
}
public static ItemSlot getItemSlotFromMessage(String message) {
for(ItemSlot slot : ItemSlot.values()) {
if(slot.isEnabled() && slot.hasPlaceholders(message)) {
return slot;
}
}
return null;
}
}
@@ -0,0 +1,91 @@
package me.dadus33.chatitem;
import java.util.List;
import java.util.stream.Collectors;
import org.bukkit.configuration.file.FileConfiguration;
import me.dadus33.chatitem.utils.Colors;
public class Storage {
public String handName, nameFormat, amountFormat, commandFormat, manager, permissionName, buggedClientAction, language;
public final String messageNoPermission, messageDeny, messageReload, messageCooldown, messageLimit, messageIgnoredItem;
public final String SECONDS, minutes, hours;
public final String updateMessage, updateHover;
public final List<String> tooltipHand, tooltipBuggedClient, ignoredItems;
public boolean colorIfColored, addAmountForced, letMessageThrough, debug, handDisabled, showNoPermissionMessage, checkUpdate, permissionEnabled, cmdBroadcast, cmdShow, discordSrvSendMsg;
public int configVersion, limit, cooldown;
private FileConfiguration conf;
public Storage(FileConfiguration cnf) {
this.conf = cnf;
configVersion = conf.getInt("config-version", 13);
checkConfigVersion();
this.manager = conf.getString("manager", "auto");
if(manager == "both")
manager = "all";
language = conf.getString("general.language", "en_gb");
debug = conf.getBoolean("debug", false);
nameFormat = color(conf.getString("general.name-format", "&b&l&o{name} {amount}&r"));
amountFormat = color(conf.getString("general.amount-format", "x{times}"));
commandFormat = color(conf.getString("general.command-format", "&6%name%'s item is %item%"));
colorIfColored = conf.getBoolean("general.color-if-already-colored", true);
letMessageThrough = conf.getBoolean("general.let-message-through", true);
addAmountForced = conf.getBoolean("general.force-add-amount", true);
limit = conf.getInt("general.limit", 8);
cooldown = conf.getInt("general.cooldown", 60);
showNoPermissionMessage = conf.getBoolean("general.show-no-permission-message.normal", true);
permissionEnabled = conf.getBoolean("general.permission.enabled", false);
permissionName = conf.getString("general.permission.name", "chatitem.use");
handDisabled = conf.getBoolean("general.hand.disabled", false);
handName = color(conf.getString("general.hand.name", "&b&l&o{display-name}&b&l&o's hand"));
tooltipHand = conf.getStringList("general.hand.tooltip").stream().map(Storage::color).collect(Collectors.toList());
buggedClientAction = conf.getString("general.bugged_client.action", "show_both");
tooltipBuggedClient = conf.getStringList("general.bugged_client.tooltip").stream().map(Storage::color).collect(Collectors.toList());
ignoredItems = conf.getStringList("general.ignored_items");
checkUpdate = conf.getBoolean("general.check-update", true);
cmdShow = conf.getBoolean("general.sub-commands.broadcast", true);
cmdBroadcast = conf.getBoolean("general.sub-commands.show", true);
messageDeny = color(conf.getString("messages.deny-message", "&c&lYou have no item in hand!"));
messageReload = color(conf.getString("messages.reload-success", "&b&lSuccessful reload!"));
messageNoPermission = color(conf.getString("messages.no-permission", "&c&lI'm sorry, but you are not allowed to use the placeholder in chat!"));
messageCooldown = color(conf.getString("messages.cooldown-message", "&c&lYou can only use items in chat once a minute! You have {remaining} left!"));
updateMessage = color(conf.getString("messages.join-update.message", "&cA new version of ChatItem is available. &aClick here to download."));
updateHover = color(conf.getString("messages.join-update.hover", "&6Click to go to spigot page !"));
messageLimit = color(conf.getString("messages.limit-message", "&c&lYou can only add 8 item placeholders per message!"));
messageIgnoredItem = color(conf.getString("messages.ignored-item", "&cThis item is not allowed to be showed."));
discordSrvSendMsg = conf.getBoolean("discord-srv-send-our", true);
SECONDS = color(conf.getString("messages.seconds", " seconds"));
minutes = color(conf.getString("messages.minutes", " minutes"));
hours = color(conf.getString("messages.hours", " hours"));
colorStringList(tooltipHand);
}
public static String color(String s) {
return s == null || s.isEmpty() ? s : Colors.translateAlternateColorCodes('&', s);
}
private static void colorStringList(List<String> input) {
for (int i = 0; i < input.size(); ++i) {
input.set(i, color(input.get(i)));
}
}
private void checkConfigVersion() {
int latestVersion = ChatItem.CFG_VER;
if (latestVersion != configVersion) {
ChatItem pl = ChatItem.getInstance();
pl.getLogger().warning("ChatItem detected an older or invalid configuration file. Replacing it with the default config...");
performOverwrite();
conf = pl.getConfig();
pl.getLogger().warning("Replacement complete!");
}
}
private void performOverwrite() {
ChatItem.getInstance().saveResource("config.yml", true);
}
}
@@ -0,0 +1,124 @@
package me.dadus33.chatitem;
import java.io.File;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.inventory.ItemStack;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import me.dadus33.chatitem.utils.Utils;
@SuppressWarnings("deprecation")
public class Translation {
private static File folder;
private static YamlConfiguration legacy, allLangsConfig;
private static JsonObject messages;
private static HashMap<String, String> allLangs = new HashMap<>();
public static void load(ChatItem pl) {
folder = new File(pl.getDataFolder(), "lang");
if (!folder.exists())
folder.mkdir();
legacy = Utils.copyLoadFile(folder, "legacy.yml", "lang/legacy.yml");
allLangsConfig = Utils.copyLoadFile(pl.getDataFolder(), "langs.yml", "langs.yml");
allLangsConfig.getStringList("all").forEach(langKey -> {
try {
JsonObject content = JsonParser.parseReader(new InputStreamReader(pl.getResource("lang/" + langKey + ".json"))).getAsJsonObject();
allLangs.put(langKey, content.get("language.name").getAsString() + " (" + content.get("language.region").getAsString() + ")");
} catch (Exception e) {
pl.getLogger().severe("Failed to load lang with key " + langKey + " : " + e.getMessage() + " (" + e.getStackTrace()[0].toString() + ")");
}
});
allLangs = allLangs.entrySet().stream().sorted(Entry.comparingByValue()).collect(Collectors.toMap(Entry::getKey, Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
loadLang(pl.getStorage().language);
}
public static HashMap<String, String> getAllLangs() {
return allLangs;
}
public static JsonObject getMessages() {
return messages;
}
public static String getMessage(String key) {
JsonElement result = messages.get(key);
return result == null ? "" : result.getAsString();
}
public static void loadLang(String lang) {
ChatItem pl = ChatItem.getInstance();
File langFile = new File(folder, lang + ".json");
if (!langFile.exists()) {
if (pl.getResource("lang/" + lang + ".json") != null) {
Utils.copyFile("lang/" + lang + ".json", langFile);
} else {
pl.getLogger().severe("Failed to find lang file for " + lang);
if(lang != "en_gb")
loadLang("en_gb");
return;
}
}
try {
messages = JsonParser.parseReader(new FileReader(langFile)).getAsJsonObject();
} catch (Exception e) {
e.printStackTrace();
}
pl.getLogger().info("Loaded translation for " + lang + ".");
}
public static String get(ItemStack item) {
String key = (item.getType().isBlock() ? "block" : "item") + ".minecraft." + item.getType().name().toLowerCase();
if (messages != null && messages.has(key)) {
return messages.get(key).getAsString();
} else
ChatItem.debug("Failed to find translation for " + key);
return legacy.getString(item.getType().name() + "." + item.getDurability(), item.getType().name().toLowerCase().replace("_", " "));
}
public static String getOr(ItemStack item, String def) {
String key = (item.getType().isBlock() ? "block" : "item") + ".minecraft." + item.getType().name().toLowerCase();
if (messages != null && messages.has(key)) {
return messages.get(key).getAsString();
} else
ChatItem.debug("Failed to find translation for " + key);
return legacy.getString(item.getType().name() + "." + item.getDurability(), def);
}
protected void thisMethodShouldNotBeUsed_InsteadToUpdateLangFileFromLocalInstall() throws Exception {
File dir = new File("dir/to/result");
File folder = new File("C:\\Dir\\To\\AppData\\Roaming\\.minecraft\\assets");// here we are looking for 1.19
JsonObject json = JsonParser.parseReader(new FileReader(new File(folder, "indexes/1.19.json"))).getAsJsonObject().get("objects").getAsJsonObject();
for (String key : json.keySet()) {
if (key.startsWith("minecraft/lang")) { // only lang files
String lang = key.toString().replace("minecraft/lang/", "");
String hash = json.get(key).getAsJsonObject().get("hash").getAsString();
File langFile = new File(folder, "objects/" + hash.substring(0, 2) + "/" + hash);
JsonObject langs = JsonParser.parseReader(new FileReader(langFile)).getAsJsonObject();
for (String langKey : new ArrayList<>(langs.keySet())) {
if (!(langKey.startsWith("block.") || langKey.startsWith("language"))) { // only what we want
langs.remove(langKey); // removing not needed
}
}
File langDir = new File(dir, lang);
Files.write(langDir.toPath(), Arrays.asList(langs.toString()));
System.out.println("Copied " + lang); // using sysout as it's made for basic java, not mc
}
}
}
}
@@ -0,0 +1,97 @@
package me.dadus33.chatitem.chatmanager;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.bukkit.entity.Player;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.ItemPlayer;
import me.dadus33.chatitem.ItemSlot;
import me.dadus33.chatitem.utils.Utils;
public class Chat {
private static int actualId = 0;
private static final List<Chat> CHAT = new ArrayList<>();
public static Optional<Chat> getChat(int id) {
synchronized (CHAT) {
CHAT.removeIf(Chat::isOld);
return CHAT.stream().filter(o -> o.getId() == id).findFirst();
}
}
public static Chat create(Player p, String message, ChatAction action) {
return new Chat(actualId++, p, message, action);
}
public static Chat getFrom(String message) {
boolean found = false;
String id = "";
for(char c : ChatManager.fixSeparator(message).toCharArray()) {
if(c == ChatManager.SEPARATOR)
found = true;
else if(c == ChatManager.SEPARATOR_END)
break;
else if(found)
id += c;
}
ChatItem.debug("Search in " + message + ", id found: " + id);
return (id != "" && Utils.isInteger(id)) ? Chat.getChat(Integer.parseInt(id)).orElse(null) : null;
}
private final long time;
private final int id;
private final Player p;
private final String message;
private final ChatAction action;
public Chat(int id, Player p, String message, ChatAction action) {
this.time = System.currentTimeMillis();
this.id = id;
this.p = p;
this.message = message;
this.action = action;
CHAT.add(this);
}
public long getTime() {
return time;
}
public int getId() {
return id;
}
public Player getPlayer() {
return p;
}
public String getMessage() {
return message;
}
public ItemSlot getSlot() {
return action.getSlot();
}
public ChatAction getAction() {
return action;
}
public ItemPlayer getItemPlayer() {
return ItemPlayer.getPlayer(getPlayer());
}
private boolean isOld() {
return System.currentTimeMillis() > time + 10000;
}
public void remove() {
CHAT.remove(this);
}
@Override
public String toString() {
return "Chat{id=" + id + ",message=" + message + ",time=" + time + "}";
}
}
@@ -0,0 +1,54 @@
package me.dadus33.chatitem.chatmanager;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import me.dadus33.chatitem.ItemSlot;
public class ChatAction {
private boolean isItem;
private ItemSlot slot;
private String command;
private ItemStack item;
private Player origin;
public ChatAction(ItemSlot slot, Player origin, ItemStack item) {
this.slot = slot;
this.item = item == null ? new ItemStack(Material.AIR) : item;
this.origin = origin;
this.isItem = true;
}
public ChatAction(ItemSlot slot, Player origin, String command) {
this.slot = slot;
this.command = command;
this.origin = origin;
this.isItem = false;
}
public Player getOrigin() {
return origin;
}
public ItemSlot getSlot() {
return slot;
}
public boolean isItem() {
return isItem;
}
public String getCommand() {
return command;
}
public boolean hasCommand() {
return command != null && command != "";
}
public ItemStack getItem() {
return item == null ? new ItemStack(Material.AIR) : item;
}
}
@@ -0,0 +1,52 @@
package me.dadus33.chatitem.chatmanager;
import static me.dadus33.chatitem.chatmanager.ChatManager.SEPARATOR;
import static me.dadus33.chatitem.chatmanager.ChatManager.SEPARATOR_END;
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.AsyncPlayerChatEvent;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.ItemSlot;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.utils.Utils;
@SuppressWarnings("deprecation")
public class ChatEventListener implements Listener {
private Storage getStorage() {
return ChatItem.getInstance().getStorage();
}
@EventHandler(priority = EventPriority.LOWEST)
public void onChat(AsyncPlayerChatEvent e) {
if (ChatManager.containsSeparator(e.getMessage())) { // If the BELL character is found, we have to remove it
e.setMessage(ChatManager.removeSeparator(e.getMessage()));
}
Player p = e.getPlayer();
String oldMsg = e.getMessage();
ItemSlot slot = ItemSlot.getItemSlotFromMessage(e.getMessage());
if (slot == null) {
ChatItem.debug("(general) not found placeholders in: " + e.getMessage());
return;
}
ChatAction action = ChatManager.getChatAction(slot, p);
if(!ChatManager.canUsePlaceholder(p, action, slot, e))
return;
String s = slot.replacePlaceholdersToSeparator(e.getMessage());
if (Utils.countMatches(s, Character.toString(ChatManager.SEPARATOR)) > getStorage().limit) {
e.setCancelled(true);
if (!getStorage().messageLimit.isEmpty())
p.sendMessage(getStorage().messageLimit);
return;
}
Chat c = Chat.create(p, oldMsg, action);
ChatItem.debug("(general) Set placeholder to message " + c);
e.setMessage(s.replace(Character.toString(ChatManager.SEPARATOR), SEPARATOR + Integer.toString(c.getId()) + SEPARATOR_END));
e.setFormat(e.getFormat().replace(oldMsg, e.getMessage())); // set own message for plugin that already put the message into the format
}
}
@@ -1,28 +1,42 @@
package me.dadus33.chatitem.chatmanager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import javax.annotation.Nullable;
import org.bukkit.ChatColor;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.ShulkerBox;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.inventory.meta.ItemMeta;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.hook.EcoEnchantsSupport;
import me.dadus33.chatitem.ItemSlot;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.hook.ecoenchants.EcoEnchantsSupport;
import me.dadus33.chatitem.invsee.InvShower;
import me.dadus33.chatitem.invsee.hook.EnderChestShower;
import me.dadus33.chatitem.invsee.hook.PlayerInventoryShower;
import me.dadus33.chatitem.itemnamer.NamerManager;
import me.dadus33.chatitem.utils.Colors;
import me.dadus33.chatitem.utils.ItemUtils;
import me.dadus33.chatitem.utils.Storage;
import me.dadus33.chatitem.utils.Messages;
import me.dadus33.chatitem.utils.Utils;
import me.dadus33.chatitem.utils.Version;
@SuppressWarnings("deprecation")
public abstract class ChatManager {
public static String inTest = null;
private final static HashMap<UUID, Long> COOLDOWNS = new HashMap<>();
private final static HashMap<UUID, Long> LAST_INFO_MESSAGE = new HashMap<>();
private final static String NAME = "{name}";
@@ -31,37 +45,35 @@ public abstract class ChatManager {
private final static String LEFT = "{remaining}";
public final static char SEPARATOR = ((char) 0x0007);
public final static String SEPARATOR_STR = "\\u0007";
public final static char SEPARATOR_END = ((char) 0x0003);
public final static String SEPARATOR_END_STR = "\\u0003";
public static String removeSeparator(String message) {
return fixSeparator(message).replace(Character.toString(SEPARATOR), "").replace(Character.toString(SEPARATOR_END), "");
}
public static String replaceSeparator(Chat chat, String message, String replacement) {
return fixSeparator(message).replace(Character.toString(SEPARATOR) + (chat != null ? chat.getId() : "") + Character.toString(SEPARATOR_END), replacement);
}
public static String fixSeparator(String s) {
return s.replace(ChatManager.SEPARATOR_STR, Character.toString(ChatManager.SEPARATOR));
return s == null ? "" : s.replace(SEPARATOR_STR, Character.toString(SEPARATOR)).replace(SEPARATOR_END_STR, Character.toString(SEPARATOR_END));
}
public static boolean equalsSeparator(String s) {
return s.equalsIgnoreCase(SEPARATOR_STR) || s.equalsIgnoreCase(Character.toString(SEPARATOR));
return s != null && (s.equalsIgnoreCase(SEPARATOR_STR) || s.equalsIgnoreCase(Character.toString(SEPARATOR)));
}
public static boolean containsSeparator(String s) {
return s.contains(SEPARATOR_STR) || s.contains(Character.toString(SEPARATOR));
return s != null && (s.contains(SEPARATOR_STR) || s.contains(Character.toString(SEPARATOR)));
}
public static boolean endsWithSeparator(String s) {
return s.endsWith(SEPARATOR_STR) || s.endsWith(Character.toString(SEPARATOR));
public static boolean equalsSeparatorEnd(String s) {
return s != null && (s.equalsIgnoreCase(SEPARATOR_END_STR) || s.equalsIgnoreCase(Character.toString(SEPARATOR_END)));
}
public static String[] splitWithSeparator(String msg) {
List<String> list = new ArrayList<>();
String current = "";
for(String s : msg.split("")) {
if(equalsSeparator(s)) {
if(!current.isEmpty())
list.add(current);
current = "";
} else
current += s;
}
if(!current.isEmpty())
list.add(current);
return list.toArray(new String[] {});
public static boolean containsSeparatorEnd(String s) {
return s != null && (s.contains(SEPARATOR_END_STR) || s.contains(Character.toString(SEPARATOR_END)));
}
protected Storage s;
@@ -83,7 +95,7 @@ public abstract class ChatManager {
}
public abstract void unload(ChatItem pl);
/**
* Get the item in hand as usable one.<br>
* Will include, in lore, all informations from other plugins.
@@ -91,65 +103,88 @@ public abstract class ChatManager {
* @param p the player
* @return the usable item
*/
public static ItemStack getUsableItem(Player p) {
ItemStack item = HandItem.getBetterItem(p).clone();
if(ChatItem.ecoEnchantsSupport) {
List<String> addLore = EcoEnchantsSupport.getLores(item);
if(!addLore.isEmpty()) {
ItemMeta meta = item.getItemMeta();
List<String> lores = meta.hasLore() ? meta.getLore() : new ArrayList<>();
for(int i = 0; i < addLore.size(); i++)
lores.add(i, addLore.get(i));
meta.setLore(lores);
item.setItemMeta(meta);
ChatItem.debug("Added " + addLore.size() + " lores from EcoEnchants");
} else
ChatItem.debug("No lore to add from EcoEnchants");
public static ItemStack getUsableItem(Player p, ItemSlot slot) {
if (slot == null)
return null;
ItemStack betterItem = HandItem.getBetterItem(p, slot);
if (betterItem == null)
return null;
ItemStack item = betterItem.clone();
if (slot.isDenyIfNoItem() && ItemUtils.isEmpty(item))
return null;
if (EcoEnchantsSupport.hasSupport()) {
item = EcoEnchantsSupport.manageItem(item);
} else if (item.hasItemMeta()) {
ItemMeta meta = item.getItemMeta();
if (meta instanceof BookMeta) { // filtering written books
BookMeta bm = (BookMeta) item.getItemMeta();
bm.setPages(Collections.emptyList());
item.setItemMeta(bm);
} else if (meta instanceof BlockStateMeta && Version.getVersion().isNewerOrEquals(Version.V1_9)) { // if it's a block
BlockStateMeta bsm = (BlockStateMeta) item.getItemMeta();
if (bsm.hasBlockState() && bsm.getBlockState() instanceof ShulkerBox) {
ShulkerBox sb = (ShulkerBox) bsm.getBlockState();
for (ItemStack itemInv : sb.getInventory()) {
ItemUtils.stripData(itemInv);
}
bsm.setBlockState(sb);
}
item.setItemMeta(bsm);
}
}
return item;
}
public static ChatAction getChatAction(ItemSlot slot, Player p) {
if (slot.isCommand()) {
UUID uuid = UUID.randomUUID();
InvShower.add(uuid.toString(), slot == ItemSlot.INVENTORY ? new PlayerInventoryShower(p) : new EnderChestShower(p));
return new ChatAction(slot, p, "/chatitem seeinv " + uuid.toString());
}
return new ChatAction(slot, p, getUsableItem(p, slot));
}
/**
* Get all lores lines of an item, to replace the show_item action which is not working with ViaBackwards
* Get all lores lines of an item, to replace the show_item action which is not
* working with ViaBackwards
*
* @param item the item to get lines from
* @return all lores
*/
public static List<String> getMaxLinesFromItem(Player p, ItemStack item) {
public static List<String> getMaxLinesFromItem(Player viewer, ItemStack item) {
List<String> lines = new ArrayList<>();
if (item.hasItemMeta()) {
ItemMeta meta = item.getItemMeta();
lines.add(meta.hasDisplayName() ? meta.getDisplayName()
: NamerManager.getName(p, item, ChatItem.getInstance().getStorage()));
lines.add(NamerManager.getName(viewer, item, ChatItem.getInstance().getStorage()));
if (meta.hasEnchants()) {
meta.getEnchants().forEach((enchant, lvl) -> {
lines.add(ChatColor.RESET + Utils.getEnchantName(enchant) + " " + Utils.toRoman(lvl));
lines.add(Colors.RESET + Utils.getEnchantName(enchant) + " " + Utils.toRoman(lvl));
});
}
if (meta.hasLore())
lines.addAll(meta.getLore());
} else {
lines.add(NamerManager.getName(p, item, ChatItem.getInstance().getStorage()));
lines.add(NamerManager.getName(viewer, item, ChatItem.getInstance().getStorage()));
}
return lines;
}
/**
* Get the name of item according to player & config<br>
* Prefer use {@link #getNameOfItem(Player, ItemStack, Storage)} if you want take in count the empty item
*
* @param p the player
* @param item the item
* @param c the config
* @return the name of item
* Prefer use {@link #getNameOfItem(Player, ItemStack, Storage)} if you want
* take in count the empty item
*
* @param viewer the player
* @param item the item
* @param c the config
* @return the name of item
*/
public static String styleItem(Player p, ItemStack item, Storage c) {
String replacer = c.NAME_FORMAT;
String amount = c.AMOUNT_FORMAT;
boolean dname = item.hasItemMeta() && item.getItemMeta().hasDisplayName();
public static String styleItem(Player viewer, ItemStack item, Storage c) {
String replacer = c.nameFormat;
String amount = c.amountFormat;
if (item.getAmount() == 1) {
if (c.FORCE_ADD_AMOUNT) {
if (c.addAmountForced) {
amount = amount.replace(TIMES, "1");
replacer = replacer.replace(AMOUNT, amount);
} else {
@@ -159,60 +194,62 @@ public abstract class ChatManager {
amount = amount.replace(TIMES, String.valueOf(item.getAmount()));
replacer = replacer.replace(AMOUNT, amount);
}
if (dname) {
String trp = item.getItemMeta().getDisplayName();
ChatItem.debug("trp: " + trp);
if (c.COLOR_IF_ALREADY_COLORED) {
replacer = replacer.replace(NAME, ChatColor.stripColor(trp));
} else {
replacer = replacer.replace(NAME, trp);
}
} else {
replacer = replacer.replace(NAME, NamerManager.getName(p, item, c));
}
return replacer;
return replacer.replace(NAME, NamerManager.getName(viewer, item, c));
}
/**
* Get the name of item according to player & config
*
* @param p the player
* @param p the player that is owner of item
* @param item the item
* @param c the config
* @param c the config
* @return the name of item or hand
*/
public static String getNameOfItem(Player p, ItemStack item, Storage c) {
if(ItemUtils.isEmpty(item)) {
if(c.HAND_DISABLED)
return c.PLACEHOLDERS.get(0);
else
return c.HAND_NAME;
public static String getNameOfItem(Player p, ItemStack item, Player viewer, Storage c) {
if (ItemUtils.isEmpty(item)) {
if (c.handDisabled)
return ItemSlot.HAND.getPlaceholders().get(0);
return getHandName(p);
}
String replacer = c.NAME_FORMAT;
String amount = c.AMOUNT_FORMAT;
boolean dname = item.hasItemMeta() && item.getItemMeta().hasDisplayName();
if (item.getAmount() == 1) {
if (c.FORCE_ADD_AMOUNT) {
amount = amount.replace(TIMES, "1");
replacer = replacer.replace(AMOUNT, amount);
} else {
replacer = replacer.replace(AMOUNT, "");
return ChatItem.replace(p, styleItem(viewer, item, c));
}
public static String getNameForChatAction(Player viewer, Chat chat, Storage c) {
ChatAction action = chat.getAction();
if (action.isItem()) {
ItemStack item = action.getItem();
if (ItemUtils.isEmpty(item)) {
if (c.handDisabled)
return chat.getSlot().getPlaceholders().get(0);
return getHandName(chat);
}
} else {
amount = amount.replace(TIMES, String.valueOf(item.getAmount()));
replacer = replacer.replace(AMOUNT, amount);
return ChatItem.replace(chat.getPlayer(), styleItem(viewer, item, c));
}
if (dname) {
String trp = item.getItemMeta().getDisplayName();
if (c.COLOR_IF_ALREADY_COLORED) {
replacer = replacer.replace(NAME, ChatColor.stripColor(trp));
} else {
replacer = replacer.replace(NAME, trp);
return ChatItem.replace(chat.getPlayer(), Messages.getMessage(action.getSlot().name().toLowerCase() + ".chat", "%cible%", action.getOrigin().getName()));
}
public static String getNameForChatAction(Player viewer, ChatAction action, Storage c) {
if (action.isItem()) {
ItemStack item = action.getItem();
if (ItemUtils.isEmpty(item)) {
if (c.handDisabled)
return action.getSlot().getPlaceholders().get(0);
else
return getHandName(action.getOrigin());
}
} else {
replacer = replacer.replace(NAME, NamerManager.getName(p, item, c));
return ChatItem.replace(action.getOrigin(), styleItem(viewer, item, c));
}
return replacer;
return ChatItem.replace(action.getOrigin(), Messages.getMessage(action.getSlot().name().toLowerCase() + ".chat", "%cible%", action.getOrigin().getName()));
}
@Deprecated
public static String getHandName(Player p) {
return ChatItem.replace(p, ChatItem.getInstance().getStorage().handName.replace("{name}", p.getName()).replace("{display-name}", p.getDisplayName()));
}
public static String getHandName(Chat c) {
Player p = c.getPlayer();
return ChatItem.replace(p, ChatItem.getInstance().getStorage().handName.replace("{name}", p.getName()).replace("{display-name}", p.getDisplayName()));
}
public static String calculateTime(long seconds) {
@@ -223,7 +260,7 @@ public abstract class ChatManager {
if (seconds < 3600) {
StringBuilder builder = new StringBuilder();
int minutes = (int) seconds / 60;
builder.append(minutes).append(c.MINUTES);
builder.append(minutes).append(c.minutes);
int secs = (int) seconds - minutes * 60;
if (secs != 0) {
builder.append(" ").append(secs).append(c.SECONDS);
@@ -232,10 +269,10 @@ public abstract class ChatManager {
}
StringBuilder builder = new StringBuilder();
int hours = (int) seconds / 3600;
builder.append(hours).append(c.HOURS);
builder.append(hours).append(c.hours);
int minutes = (int) (seconds / 60) - (hours * 60);
if (minutes != 0) {
builder.append(" ").append(minutes).append(c.MINUTES);
builder.append(" ").append(minutes).append(c.minutes);
}
int secs = (int) (seconds - ((seconds / 60) * 60));
if (secs != 0) {
@@ -244,72 +281,110 @@ public abstract class ChatManager {
return builder.toString();
}
public static boolean canShowItem(Player p, ItemStack item, @Nullable Cancellable e) {
public static boolean canUsePlaceholder(Player p, ChatAction action, ItemSlot slot, @Nullable Cancellable e) {
Storage c = ChatItem.getInstance().getStorage();
if (c.PERMISSION_ENABLED && !p.hasPermission(c.PERMISSION_NAME)) {
if (!c.LET_MESSAGE_THROUGH) {
if(e != null)
if (c.permissionEnabled && !p.hasPermission(c.permissionName)) {
if (!c.letMessageThrough) {
if (e != null)
e.setCancelled(true);
}
if (!c.NO_PERMISSION_MESSAGE.isEmpty() && c.SHOW_NO_PERM_NORMAL) {
sendIfNeed(p, c.NO_PERMISSION_MESSAGE);
if (!c.messageNoPermission.isEmpty() && c.showNoPermissionMessage) {
sendIfNeed(p, c.messageNoPermission);
}
return false;
}
if (item.getType().equals(Material.AIR)) {
if (c.DENY_IF_NO_ITEM) {
if(e != null)
if (action.isItem() && action.getItem().getType().equals(Material.AIR) && slot.isBasic()) {
if (slot.isDenyIfNoItem()) {
if (e != null)
e.setCancelled(true);
if (!c.DENY_MESSAGE.isEmpty())
sendIfNeed(p, c.DENY_MESSAGE);
if (!c.messageDeny.isEmpty())
sendIfNeed(p, c.messageDeny);
return false;
}
if (c.HAND_DISABLED) {
if (c.handDisabled) {
return false;
}
}
if (c.COOLDOWN > 0 && !p.hasPermission("chatitem.ignore-cooldown")) {
if (c.cooldown > 0 && !p.hasPermission("chatitem.ignore-cooldown")) {
if (COOLDOWNS.containsKey(p.getUniqueId())) {
long start = COOLDOWNS.get(p.getUniqueId());
long current = System.currentTimeMillis() / 1000;
long elapsed = current - start;
if (elapsed >= c.COOLDOWN) {
if (elapsed >= c.cooldown) {
COOLDOWNS.remove(p.getUniqueId());
} else {
if (!c.LET_MESSAGE_THROUGH) {
if(e != null)
if (!c.letMessageThrough) {
if (e != null)
e.setCancelled(true);
}
if (!c.COOLDOWN_MESSAGE.isEmpty()) {
long left = (start + c.COOLDOWN) - current;
sendIfNeed(p, c.COOLDOWN_MESSAGE.replace(LEFT, ChatManager.calculateTime(left)));
if (!c.messageCooldown.isEmpty()) {
long left = (start + c.cooldown) - current;
sendIfNeed(p, c.messageCooldown.replace(LEFT, ChatManager.calculateTime(left)));
}
ChatItem.debug("Cooldown");
return false;
}
}
}
if (action.isItem()) {
for (String ignored : c.ignoredItems) {
if (action.getItem().getType().name().toLowerCase().contains(ignored.toLowerCase())) {
return false;
}
}
}
LAST_INFO_MESSAGE.put(p.getUniqueId(), System.currentTimeMillis()); // prevent showing item then send cooldown error message
return true;
}
private static void sendIfNeed(Player p, String msg) {
Long time = LAST_INFO_MESSAGE.remove(p.getUniqueId());
if(time != null) {
if (time != null) {
long diff = System.currentTimeMillis() - time;
if(diff < 100)
if (diff < 100)
return; // don't show message
}
p.sendMessage(msg);
LAST_INFO_MESSAGE.put(p.getUniqueId(), System.currentTimeMillis());
}
public static void clear(Player p) {
COOLDOWNS.remove(p.getUniqueId());
LAST_INFO_MESSAGE.remove(p.getUniqueId());
}
public static void applyCooldown(Player p) {
COOLDOWNS.put(p.getUniqueId(), System.currentTimeMillis() / 1000);
}
public static boolean isTestingEnabled() {
return inTest != null;
}
public static boolean isTesting(String actual) {
return inTest != null && (inTest == "both" || inTest == "all" || inTest.equalsIgnoreCase(actual));
}
public static void setTesting(String actual) {
inTest = actual;
}
public static boolean isSelected(String actual) {
if(isTestingEnabled())
return true;
String selected = ChatItem.getInstance().getStorage().manager;
if (selected.equalsIgnoreCase("both") || selected.equalsIgnoreCase("all"))
return true;
if (selected == "auto") {
if (Utils.IS_PAPER && actual == "paper")
return true;
else if (actual == "packet" && ChatItem.getPluginThatRequirePacket().stream().map(Bukkit.getPluginManager()::getPlugin).anyMatch(Objects::nonNull)
&& Version.getVersion().isNewerThan(Version.V1_7))
return true;
else if (actual == "chat")
return true;
}
return selected.equalsIgnoreCase(actual);
}
}
@@ -3,20 +3,36 @@ package me.dadus33.chatitem.chatmanager;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import me.dadus33.chatitem.ItemSlot;
import me.dadus33.chatitem.utils.ItemUtils;
import me.dadus33.chatitem.utils.Version;
public class HandItem {
@SuppressWarnings("deprecation")
public static ItemStack getBetterItem(Player p) {
if(Version.getVersion().isNewerOrEquals(Version.V1_9)) {
ItemStack main = p.getInventory().getItemInMainHand();
if(!ItemUtils.isEmpty(main))
return main;
ItemStack off = p.getInventory().getItemInOffHand();
return ItemUtils.isEmpty(off) ? main : off;
public static ItemStack getBetterItem(Player p, ItemSlot slot) {
switch (slot) {
case HAND:
if(Version.getVersion().isNewerOrEquals(Version.V1_9)) {
ItemStack main = p.getInventory().getItemInMainHand();
if(!ItemUtils.isEmpty(main))
return main;
return p.getInventory().getItemInOffHand();
}
return p.getItemInHand();
case HELMET:
return p.getInventory().getHelmet();
case CHESTPLATE:
return p.getInventory().getChestplate();
case LEGGINGS:
return p.getInventory().getLeggings();
case BOOTS:
return p.getInventory().getBoots();
case ENDERCHEST:
break;
case INVENTORY:
break;
}
return p.getItemInHand();
return null; // should never happen
}
}
@@ -1,32 +1,29 @@
package me.dadus33.chatitem.chatmanager.v1;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import org.bukkit.Bukkit;
import org.bukkit.event.HandlerList;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.chatmanager.v1.json.JSONManipulatorCurrent;
import me.dadus33.chatitem.chatmanager.v1.listeners.ChatEventListener;
import me.dadus33.chatitem.chatmanager.v1.listeners.ChatPacketManager;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacketManager;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketContent;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketManager;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.Storage;
import me.dadus33.chatitem.utils.ReflectionUtils;
import me.dadus33.chatitem.utils.Utils;
public class PacketEditingChatManager extends ChatManager {
private final JSONManipulatorCurrent jsonManipulator;
private boolean baseComponentAvailable = true;
private final ChatItemPacketManager packetManager;
private final ChatEventListener chatEventListener;
private final ChatPacketManager chatPacketManager;
public PacketEditingChatManager(ChatItem pl) {
jsonManipulator = new JSONManipulatorCurrent();
packetManager = new ChatItemPacketManager(pl);
chatEventListener = new ChatEventListener(this);
chatPacketManager = new ChatPacketManager(this);
// Check for existence of BaseComponent class (only on spigot)
@@ -51,7 +48,6 @@ public class PacketEditingChatManager extends ChatManager {
public void load(ChatItem pl, Storage s) {
super.load(pl, s);
Bukkit.getPluginManager().registerEvents(chatEventListener, pl);
PacketManager pm = packetManager.getPacketManager();
pm.addHandler(chatPacketManager);
Bukkit.getOnlinePlayers().forEach(pm::addPlayer); // add actual online players
@@ -59,38 +55,116 @@ public class PacketEditingChatManager extends ChatManager {
@Override
public void unload(ChatItem pl) {
HandlerList.unregisterAll(chatEventListener);
PacketManager pm = packetManager.getPacketManager();
pm.removeHandler(chatPacketManager);
pm.stop();
}
public JSONManipulatorCurrent getManipulator() {
return jsonManipulator;
}
public boolean supportsChatComponentApi() {
return baseComponentAvailable;
}
private static String checkPacketSize(String packet, int maxSize) {
int size = packet.getBytes().length;
while(size > maxSize) {
packet = packet.replaceFirst(" ", " ");
if(size == packet.getBytes().length)
break; // could not fix myself
size = packet.getBytes().length;
}
return packet;
}
public static Object createSystemChatPacket(String json) throws Exception {
Class<?> packetClass = PacketUtils.getNmsClass("ClientboundSystemChatPacket", "network.protocol.game.");
public static Object createSystemChatPacket(String json, Object old) throws Exception {
json = checkPacketSize(json, 150000);
Object packet = internalCreateSystemChatPacket(json, old);
if(packet != null)
return packet;
Object icb = ChatItem.getPlatform().jsonToBaseComponent(json);
if(icb != null)
packet = internalCreateSystemChatPacket(icb, old);
if(packet != null)
return packet;
ChatItem.getInstance().getLogger().warning("Can't create a new packet for json " + json);
return null;
}
private static Object internalCreateSystemChatPacket(Object obj, Object old) throws Exception {
Class<?> packetClass = PacketUtils.getNmsClass("ClientboundSystemChatPacket", "network.protocol.game.", "ClientboundPlayerChatPacket", "PacketPlayOutChat");
Class<?> chatMessageTypeClass = Utils.isClassExist("net.minecraft.network.chat.ChatMessageType") ? PacketUtils.getNmsClass("ChatMessageType", "network.chat.") : null;
Constructor<?> betterOne = null;
Object[] betterParam = null;
for (Constructor<?> cons : packetClass.getDeclaredConstructors()) {
if (!cons.isAccessible())
cons.setAccessible(true);
if (cons.getParameterCount() == 2 && cons.getParameterTypes()[0].equals(String.class)
&& cons.getParameterTypes()[1].equals(int.class)) { // "string, int"
return cons.newInstance(json, 1);
} else if (cons.getParameterCount() == 3 && cons.getParameterTypes()[1].equals(String.class)) { // "component", "string", <something not checked>
Class<?> secondParam = cons.getParameterTypes()[2];
if(secondParam.equals(int.class)) // "component", "string", "int"
return cons.newInstance(null, json, 1);
else if(secondParam.equals(boolean.class)) // "component", "string", "boolean"
return cons.newInstance(null, json, false);
// check for basic method
if(obj instanceof String) {
if (cons.getParameterCount() == 2 && cons.getParameterTypes()[0].equals(String.class) && cons.getParameterTypes()[1].equals(int.class)) { // "string, int"
return cons.newInstance(obj, 1);
} else if (cons.getParameterCount() == 2 && cons.getParameterTypes()[0].equals(String.class) && cons.getParameterTypes()[1].equals(boolean.class)) { // "string, boolean"
return cons.newInstance(obj, false); // false for no overlay
} else if (cons.getParameterCount() == 3 && cons.getParameterTypes()[1].equals(String.class)) { // "component", "string", <something not checked>
Class<?> secondParam = cons.getParameterTypes()[2];
if (secondParam.equals(int.class)) // "component", "string", "int"
return cons.newInstance(null, obj, 1);
else if (secondParam.equals(boolean.class)) // "component", "string", "boolean"
return cons.newInstance(null, obj, false);
}
} else if(obj.getClass().isAssignableFrom(PacketUtils.COMPONENT_CLASS)) {
if (cons.getParameterCount() == 2 && cons.getParameterTypes()[0].isAssignableFrom(PacketUtils.COMPONENT_CLASS) && cons.getParameterTypes()[1].equals(boolean.class)) // "string, boolean"
return cons.newInstance(obj, false);
}
int nbPut = 0;
Object[] params = new Object[cons.getParameterCount()];
for(int i = 0; i < params.length; i++) {
Class<?> type = cons.getParameterTypes()[i];
if(type.isAssignableFrom(obj.getClass())) {
params[i] = obj;
nbPut++;
} else if(chatMessageTypeClass != null && type.isAssignableFrom(chatMessageTypeClass)) {
params[i] = getChatMessageType();
} else if(type.isAssignableFrom(boolean.class)) // need to set primitives
params[i] = false;
else if(type.isAssignableFrom(int.class)) // need to set primitives
params[i] = 0;
else {
boolean found = false;
for(Class<?> prim : Arrays.asList(float.class, long.class)) { // if not primitive
if(type.isAssignableFrom(prim)) {
found = true;
}
}
if(!found) {
params[i] = new PacketContent(old).getSpecificModifier(type).readSafely(0);
}
}
}
if(nbPut == 1) {
if((betterOne == null && betterParam == null) || betterParam.length > params.length) {
betterOne = cons;
betterParam = params;
if(params.length == 1) // only what we need
break;
continue; // check for something better?
}
} else if(nbPut > 1)
ChatItem.getInstance().getLogger().warning("Some constructor seems to have too many " + obj.getClass().getSimpleName() + ". Class: " + packetClass.getSimpleName());
}
if(betterOne != null && betterParam != null) {
try {
return betterOne.newInstance(betterParam);
} catch (IllegalArgumentException e) {
ChatItem.getInstance().getLogger().warning("Failed to create a new packet to send. " + betterOne.getParameterCount() + " (" + Utils.arrayToString(betterOne.getParameterTypes()) + "). Params: " + Utils.arrayToString(betterParam));
return null;
}
}
ChatItem.getInstance().getLogger()
.warning("Can't create a new packet for json " + json + ": no constructor found.");
return null;
}
private static Object getChatMessageType() throws Exception {
Class<?> c = PacketUtils.getNmsClass("ChatMessageType", "network.chat.");
return ReflectionUtils.getMethod(c, c, byte.class).invoke(null, (byte) 0);
}
}
@@ -1,61 +0,0 @@
package me.dadus33.chatitem.chatmanager.v1.basecomp;
import javax.annotation.Nullable;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.utils.Storage;
public interface IBaseComponentGetter {
default boolean hasConditions() {
return true;
}
String getBaseComponentAsJSON(ChatItemPacket packet);
void writeJson(ChatItemPacket packet, String json);
/**
* Use actual base component getter to check if the given json has placeholders
*
* @param c the storage config
* @param json the json
* @return the founded placeholder or null
*/
default @Nullable String hasPlaceholders(Storage c, String json) {
if(json == null || json.isEmpty())
return null;
for (String rep : c.PLACEHOLDERS) {
if (json.contains(rep)) {
return rep;
}
}
return null;
}
default @Nullable String getNameFromMessage(String json, String toReplace) {
for (Player p : Bukkit.getOnlinePlayers()) {
String name = toReplace + p.getName();
if (json.contains(name))
return p.getName();
}
return null;
}
/**
* Use actual base component getter to remove the player and the name.<br>
* This is for special component which split message into sub string
*
* @param json the global json
* @param toReplace the string which contains the placeholder
* @param foundedPlayer the player which has the name in message
* @return the replaced json
*/
default String removePlaceholdersAndName(String json, String toReplace, Player foundedPlayer) {
return json.replace(toReplace + foundedPlayer.getName(), Character.toString(ChatManager.SEPARATOR));
}
}
@@ -0,0 +1,138 @@
package me.dadus33.chatitem.chatmanager.v1.basecomp;
import java.util.ArrayList;
import javax.annotation.Nullable;
import org.bukkit.entity.Player;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.chatmanager.Chat;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.chatmanager.v1.json.JSONManipulator;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.utils.Utils;
public interface IComponentManager {
default boolean hasConditions() {
return true;
}
String getBaseComponentAsJSON(ChatItemPacket packet);
void writeJson(ChatItemPacket packet, String json);
default @Nullable Chat getChat(String json) {
json = ChatManager.fixSeparator(json);
try {
Chat possibleChat = Chat.getFrom(json);
if (possibleChat != null) // found something with basic search
return possibleChat;
Chat chat = new Searching(json).search();
if (chat == null)
ChatItem.debug("Failed to find chat for JSON " + json);
return chat;
} catch (Exception e) {
e.printStackTrace();
} // not JSON
return null;
}
default Object manageContent(Player viewer, Chat chat, ChatItemPacket packet, String json, Storage c) throws Exception {
String message;
if (Utils.isBeforeChatJson(viewer))
message = JSONManipulator.getInstance().parseEmpty(chat, json, chat.getAction().isItem() ? ChatManager.getMaxLinesFromItem(viewer, chat.getAction().getItem()) : new ArrayList<>(), chat.getPlayer());
else
message = JSONManipulator.getInstance().parse(chat, json, chat.getAction(), ChatManager.getNameForChatAction(viewer, chat, c));
if (message != null) {
ChatItem.debug("(v1) Writing message: " + message);
writeJson(packet, message);
}
return packet.getPacket();
}
default Object manageEmpty(Player p, Chat chat, ChatItemPacket packet, String json, Storage c) {
String message = JSONManipulator.getInstance().parseEmpty(chat, json, c.tooltipHand, chat.getPlayer());
if (message != null) {
ChatItem.debug("(v1) Writing empty message: " + message);
writeJson(packet, message);
}
return packet.getPacket();
}
public static class Searching {
private boolean found = false;
private String id = "", json;
public Searching(String json) {
this.json = json;
}
private Chat search() {
JsonObject jsonObj;
try {
jsonObj = JsonParser.parseString(json).getAsJsonObject();
} catch (Exception e) {
if(searchInString(json))
return getWithId();
return null;
}
if (jsonObj.has("extra")) {
if (searchInExtra(jsonObj.getAsJsonArray("extra"))) {
return getWithId();
}
}
if (jsonObj.has("text")) {
JsonElement text = jsonObj.get("text");
if (text.isJsonObject() && searchInObject(text.getAsJsonObject()))
return getWithId();
else if (text.isJsonArray() && searchInExtra(text.getAsJsonArray()))
return getWithId();
else if (text.isJsonPrimitive() && searchInString(text.getAsString()))
return getWithId();
}
return null;
}
private Chat getWithId() {
return id != "" && Utils.isInteger(id) ? Chat.getChat(Integer.parseInt(id)).orElse(null) : null;
}
private boolean searchInExtra(JsonArray json) {
for (JsonElement element : json) {
if (element.isJsonObject()) {
JsonObject withObj = element.getAsJsonObject();
if (withObj.has("extra") && searchInExtra(withObj.getAsJsonArray("extra")))
return true;
else if (withObj.has("text") && searchInObject(withObj))
return true;
}
}
return false;
}
private boolean searchInObject(JsonObject json) {
return json.has("text") && json.get("text").isJsonPrimitive() && searchInString(json.get("text").getAsString());
}
private boolean searchInString(String s) {
for (char c : ChatManager.fixSeparator(s).toCharArray()) {
if (c == ChatManager.SEPARATOR)
found = true;
else if (c == ChatManager.SEPARATOR_END)
return true;
else if (found)
id += c;
}
return id != "" && Utils.isInteger(id) && Chat.getChat(Integer.parseInt(id)).isPresent();
}
}
}
@@ -1,283 +0,0 @@
package me.dadus33.chatitem.chatmanager.v1.basecomp.hook;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.bukkit.entity.Player;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.chatmanager.v1.PacketEditingChatManager;
import me.dadus33.chatitem.chatmanager.v1.basecomp.IBaseComponentGetter;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.utils.ReflectionUtils;
import me.dadus33.chatitem.utils.Storage;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.md_5.bungee.chat.ComponentSerializer;
public class AdventureComponentGetter implements IBaseComponentGetter {
private boolean useExtra = false;
@Override
public boolean hasConditions() {
try {
for (String cl : Arrays.asList("net.kyori.adventure.text.Component", "net.kyori.adventure.builder.AbstractBuilder",
"net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer"))
Class.forName(cl);
} catch (Exception e) { // can't support this, adventure comp not found
return false;
}
return true;
}
@Override
public String getBaseComponentAsJSON(ChatItemPacket packet) {
Component comp = packet.getContent().getSpecificModifier(Component.class).readSafely(0);
if(comp == null) {
ChatItem.debug("The component is null.");
return null;
}
String json = ComponentSerializer.toString(BungeeComponentSerializer.get().serialize(comp).clone());
ChatItem.debug("AdventureJSON : " + json);
JsonObject jsonObj = JsonParser.parseString(json).getAsJsonObject();
if(jsonObj.has("with")) {
JsonObject next = new JsonObject();
next.add("extra", jsonObj.get("with"));
return next.toString();
}
useExtra = true;
return json;
}
@Override
public String hasPlaceholders(Storage c, String json) {
if(useExtra)
return IBaseComponentGetter.super.hasPlaceholders(c, json);
JsonObject jsonObj = JsonParser.parseString(json).getAsJsonObject();
if(!jsonObj.has("extra"))
return null;
for(JsonElement element : jsonObj.get("extra").getAsJsonArray()) {
if(element.isJsonObject()) {
JsonObject withObj = element.getAsJsonObject();
if(withObj.has("extra")) {
String text = "";
for(JsonElement extra : withObj.get("extra").getAsJsonArray()) {
if(extra.isJsonObject()) {
JsonObject extraObj = extra.getAsJsonObject();
if(extraObj.has("text") && extraObj.get("text").isJsonPrimitive())
text += extraObj.get("text").getAsString();
}
}
String placeholder = IBaseComponentGetter.super.hasPlaceholders(c, text);
if(placeholder != null)
return placeholder;
} else if(withObj.has("text")) {
String placeholder = IBaseComponentGetter.super.hasPlaceholders(c, withObj.get("text").getAsString());
if(placeholder != null)
return placeholder;
}
} // ignoring all others because it should not appear
}
return null;
}
@Override
public String getNameFromMessage(String json, String toReplace) {
if(useExtra)
return IBaseComponentGetter.super.getNameFromMessage(json, toReplace);
String tmpName = IBaseComponentGetter.super.getNameFromMessage(json, toReplace);
if(tmpName != null)
return tmpName; // don't need to check for json if basically found
JsonObject jsonObj = JsonParser.parseString(json).getAsJsonObject();
if(!jsonObj.has("extra"))
return null;
for(JsonElement element : jsonObj.get("extra").getAsJsonArray()) {
if(element.isJsonObject()) {
JsonObject withObj = element.getAsJsonObject();
if(withObj.has("extra")) {
String text = "";
for(JsonElement extra : withObj.get("extra").getAsJsonArray()) {
if(extra.isJsonObject()) {
JsonObject extraObj = extra.getAsJsonObject();
if(extraObj.has("text") && extraObj.get("text").isJsonPrimitive())
text += extraObj.get("text").getAsString();
}
}
String possibleName = IBaseComponentGetter.super.getNameFromMessage(text, toReplace);
if(possibleName != null)
return possibleName;
} else if(withObj.has("text")) {
String possibleName = IBaseComponentGetter.super.getNameFromMessage(withObj.get("text").getAsString(), toReplace);
if(possibleName != null)
return possibleName;
}
} // ignoring all others because it should not appear
}
return null;
}
@Override
public String removePlaceholdersAndName(String json, String toReplace, Player foundedPlayer) {
if(useExtra)
return IBaseComponentGetter.super.removePlaceholdersAndName(json, toReplace, foundedPlayer);
String tmpName = IBaseComponentGetter.super.removePlaceholdersAndName(json, toReplace, foundedPlayer);
if(!tmpName.equals(json)) // if not the same -> name found and removed
return tmpName;
JsonObject jsonObj = JsonParser.parseString(json).getAsJsonObject();
if(!jsonObj.has("extra"))
return json;
String searched = toReplace + foundedPlayer.getName();
for(JsonElement element : jsonObj.get("extra").getAsJsonArray()) {
if(element.isJsonObject()) {
JsonObject withObj = element.getAsJsonObject();
if(withObj.has("extra")) {
String text = "";
int possibleId = -1;
JsonArray extraArray = withObj.get("extra").getAsJsonArray();
for(int i = 0; i < extraArray.size(); i++) {
JsonElement extra = extraArray.get(i);
if(!extra.isJsonObject())
continue; // prevent error but should not appear
JsonObject extraObj = extra.getAsJsonObject();
if(extraObj.has("text") && extraObj.get("text").isJsonPrimitive()) {
String extraTxt = extraObj.get("text").getAsString();
if(possibleId == -1) { // don't found the begin yet
if(searched.startsWith(extraTxt)) { // begin of replaced
possibleId = i;
text = extraTxt;
}
} else {
if(searched.startsWith(extraTxt, text.length()) || ChatManager.equalsSeparator(extraTxt)) {
text += extraTxt;
if(searched.equals(text)) { // found everything
// change actual, then remove all old
extraArray.set(i, JsonParser.parseString("{\"text\":\"" + Character.toString(ChatManager.SEPARATOR) + "\"}"));
for(int x = possibleId; x < i; x++)
extraArray.remove(possibleId); // remove elements
ChatItem.debug("Cleaned: " + jsonObj.toString());
return jsonObj.toString();
}
} else {
possibleId = -1; // was not good things
text = "";
}
}
}
}
ChatItem.debug("Failed to find: " + text + ", id: " + possibleId + " for " + withObj);
}
} // ignoring all others because it should not appear
}
ChatItem.debug("Nothing founded while trying to remove placeholders");
return IBaseComponentGetter.super.removePlaceholdersAndName(json, toReplace, foundedPlayer);
}
@Override
public void writeJson(ChatItemPacket packet, String json) {
JsonElement globalElement = JsonParser.parseString(json);
JsonArray extraArray = fixParsedArray(globalElement.getAsJsonObject().getAsJsonArray("extra"));
String localJson;
if(useExtra) {
globalElement.getAsJsonObject().add("extra", extraArray);
localJson = globalElement.toString();
} else {
JsonObject next = new JsonObject();
next.addProperty("translate", "chat.type.text");
next.add("with", extraArray);
localJson = next.toString();
}
ChatItem.debug("Adventure Json: " + json);
try {
Class<?> packetClass = packet.getPacket().getClass();
if(packetClass.getSimpleName().equalsIgnoreCase("PacketPlayOutChat")) {
Field componentField = ReflectionUtils.getFirstFieldWith(packetClass, Component.class);
if(componentField != null) {
componentField.setAccessible(true);
componentField.set(packet.getPacket(), BungeeComponentSerializer.legacy().deserialize(ComponentSerializer.parse(localJson)));
} else {
throw new UnsupportedOperationException("The packet PacketPlayOutChat doesn't have Kyori's field. It has: " + Arrays.asList(packetClass.getDeclaredFields()).stream().map(f -> f.getName() + ": " + f.getType().getName()).collect(Collectors.toList()));
}
} else if(packetClass.getSimpleName().equalsIgnoreCase("ClientboundSystemChatPacket")) {
packet.setPacket(PacketEditingChatManager.createSystemChatPacket(localJson));
} else {
throw new UnsupportedOperationException("The packet " + packetClass.getSimpleName() + " isn't supported by the AdventureGetter. Please report this.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public JsonArray fixParsedArray(JsonArray arr) {
JsonArray next = new JsonArray();
for(JsonElement e : arr) {
if(e.isJsonArray()) {
JsonObject obj = null;
JsonArray extra = new JsonArray();
for(JsonElement element : e.getAsJsonArray()) {
JsonElement fixed = checkElement(element);
if(obj == null && fixed.isJsonObject()) {
obj = fixed.getAsJsonObject();
} else {
extra.add(fixed);
}
}
if(obj != null && extra.size() > 0) {
obj.add("extra", extra);
}
next.add(obj);
} else
next.add(checkElement(e));
}
return next;
}
private JsonElement checkElement(JsonElement e) {
if(e.isJsonObject()) {
JsonObject o = e.getAsJsonObject();
if(o.has("hoverEvent")) {// only hover event
JsonObject hoverObject = o.getAsJsonObject("hoverEvent");
if(hoverObject.get("action").getAsString().equalsIgnoreCase("show_item") && hoverObject.has("value")) {// if it's item to fix
String val = hoverObject.get("value").getAsString();
// now, we should fix the value
val = val.replaceAll("\\\"", "\"");
ChatItem.debug("Fixed json: " + ("{" + val.substring(1, val.length() - 1) + "}"));
hoverObject.remove("value");
JsonElement tagElement = JsonParser.parseString("{" + val.substring(1, val.length() - 1) + "}");
tagElement.getAsJsonObject().remove("tag");
/*if(tagElement.getAsJsonObject().has("tag")) {
JsonElement tag = tagElement.getAsJsonObject().get("tag");
if(tag.isJsonObject()) {
JsonObject tagObj = tag.getAsJsonObject();
tagObj.entrySet().forEach(entry -> {
ChatItem.debug("Tag json: " + entry.getKey() + " > " + entry.getValue());
JsonElement value = entry.getValue();
String sval = value.getAsString();
if(Utils.isInteger(sval)) {
if(Utils.isByte(sval))
tagObj.addProperty(entry.getKey(), sval + "b");
else if(Utils.isShort(sval))
tagObj.addProperty(entry.getKey(), sval + "s");
else if(Utils.isLong(sval))
tagObj.addProperty(entry.getKey(), sval + "l");
else
tagObj.addProperty(entry.getKey(), value + "i");
}
});
}
}*/
hoverObject.add("contents", tagElement);
o.add("hoverEvent", hoverObject);
}
}
}
return e;
}
}
@@ -0,0 +1,132 @@
package me.dadus33.chatitem.chatmanager.v1.basecomp.hook;
import java.util.Arrays;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.chatmanager.Chat;
import me.dadus33.chatitem.chatmanager.ChatAction;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.chatmanager.v1.basecomp.IComponentManager;
import me.dadus33.chatitem.chatmanager.v1.json.JSONManipulator;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.hook.DiscordSrvSupport;
import me.dadus33.chatitem.utils.Messages;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.ReflectionUtils;
import me.dadus33.chatitem.utils.Utils;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.nbt.api.BinaryTagHolder;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
public class AdventureComponentManager implements IComponentManager {
@Override
public boolean hasConditions() {
try {
for (String cl : Arrays.asList("net.kyori.adventure.text.Component", "net.kyori.adventure.text.serializer.gson.GsonComponentSerializer"))
Class.forName(cl);
} catch (Throwable e) { // can't support this, adventure comp not found
ChatItem.debug("Can't load AdventureComponentManager : " + e.getMessage());
return false;
}
return true;
}
@Override
public void writeJson(ChatItemPacket packet, String json) {
}
public void writeComponentToPacket(ChatItemPacket packet, Component next) {
if(packet.getContent().getSpecificModifier(Component.class).readSafely(0) == null && ReflectionUtils.hasObject(packet.getPacket(), "unsignedContent")) { // hard way
ReflectionUtils.setField(ReflectionUtils.getObject(packet.getPacket(), "unsignedContent"), "adventure", next);
} else { // easy way
packet.getContent().getSpecificModifier(Component.class).write(0, next);
}
}
public Component getComponentFromPacket(ChatItemPacket packet) {
Component comp = packet.getContent().getSpecificModifier(Component.class).readSafely(0);
if (comp == null && packet.getPacketName().equalsIgnoreCase("ClientboundPlayerChatPacket") && ReflectionUtils.hasObject(packet.getPacket(), "unsignedContent")) { // if can get one more
comp = (Component) ReflectionUtils.getObject(ReflectionUtils.getObject(packet.getPacket(), "unsignedContent"), "adventure");
}
return comp;
}
@Override
public String getBaseComponentAsJSON(ChatItemPacket packet) {
Component comp = getComponentFromPacket(packet);
if(comp == null) // if comp stay null
return null;
try {
String json = GsonComponentSerializer.gson().serialize(comp);
ChatItem.debug("AdventureJSON : " + json);
JsonObject jsonObj = JSONManipulator.parseOrGet(json);
if (jsonObj.has("with")) {
JsonObject next = new JsonObject();
next.add("extra", jsonObj.get("with"));
return next.toString();
}
return json;
} catch (JsonParseException e) { // ignore this and just let skip this
e.printStackTrace();
return null;
}
}
@SuppressWarnings("deprecation")
@Override
public Object manageContent(Player viewer, Chat chat, ChatItemPacket packet, String json, Storage c) throws Exception {
ChatAction action = chat.getAction();
if (action.isItem()) {
ItemStack item = action.getItem();
String itemName = ChatManager.getNameForChatAction(viewer, chat, c);
ChatItem.debug("NBT tag: " + PacketUtils.getNbtTag(item));
HoverEvent<?> hover;
if(Utils.IS_PAPER)
hover = item.asHoverEvent();
else
hover = HoverEvent.showItem(Key.key(item.getType().getKey().getKey()), item.getAmount(), BinaryTagHolder.of(PacketUtils.getNbtTag(item)));
return manage(viewer, chat, packet, itemName, hover, null);
}
return manage(viewer, chat, packet, Messages.getMessage(action.getSlot().name().toLowerCase() + ".chat", "%cible%", chat.getPlayer().getName()),
HoverEvent.showText(Component.text(Messages.getMessage(action.getSlot().name().toLowerCase() + ".hover", "%cible%", chat.getPlayer().getName()))),
ClickEvent.runCommand(action.getCommand()));
}
@Override
public Object manageEmpty(Player viewer, Chat chat, ChatItemPacket packet, String json, Storage c) {
Component builder = Component.text("");
c.tooltipHand.forEach(s -> builder.append(Component.text(s)));
ChatAction action = chat.getAction();
if (action.isItem()) {
return manage(viewer, chat, packet, ChatManager.getNameForChatAction(viewer, chat, c), HoverEvent.showText(builder), null);
}
return manage(viewer, chat, packet, Messages.getMessage(action.getSlot().name().toLowerCase() + ".chat", "%cible%", chat.getPlayer().getName()),
HoverEvent.showText(Component.text(Messages.getMessage(action.getSlot().name().toLowerCase() + ".hover", "%cible%", chat.getPlayer().getName()))),
ClickEvent.runCommand(action.getCommand()));
}
private Object manage(Player viewer, Chat chat, ChatItemPacket packet, String replacement, HoverEvent<?> hover, ClickEvent click) {
Component comp = getComponentFromPacket(packet);
if (comp == null) {
ChatItem.debug("The component is null.");
return null;
}
comp = comp.replaceText(TextReplacementConfig.builder().matchLiteral(ChatManager.SEPARATOR + "" + chat.getId() + ChatManager.SEPARATOR_END).replacement(Component.text(replacement).hoverEvent(hover).clickEvent(click)).build());
if(ChatItem.discordSrvSupport && DiscordSrvSupport.isSendingMessage() && viewer == chat.getPlayer())
DiscordSrvSupport.sendChatMessage(chat.getPlayer(), comp, null);
viewer.sendMessage(comp);
return null;
}
}
@@ -1,26 +0,0 @@
package me.dadus33.chatitem.chatmanager.v1.basecomp.hook;
import me.dadus33.chatitem.chatmanager.v1.basecomp.IBaseComponentGetter;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.utils.Version;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.chat.ComponentSerializer;
public class BaseComponentGetter implements IBaseComponentGetter {
@Override
public boolean hasConditions() {
return Version.getVersion().isNewerOrEquals(Version.V1_8);
}
@Override
public String getBaseComponentAsJSON(ChatItemPacket packet) {
BaseComponent[] comps = packet.getContent().getSpecificModifier(BaseComponent[].class).readSafely(0);
return comps == null ? null : ComponentSerializer.toString(comps);
}
@Override
public void writeJson(ChatItemPacket packet, String json) {
packet.getContent().getSpecificModifier(BaseComponent[].class).write(0, ComponentSerializer.parse(json));
}
}
@@ -1,36 +0,0 @@
package me.dadus33.chatitem.chatmanager.v1.basecomp.hook;
import me.dadus33.chatitem.chatmanager.v1.basecomp.IBaseComponentGetter;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.utils.PacketUtils;
public class ComponentGetter implements IBaseComponentGetter {
@Override
public boolean hasConditions() {
return PacketUtils.COMPONENT_CLASS != null;
}
@Override
public String getBaseComponentAsJSON(ChatItemPacket packet) {
Object chatBaseComp = packet.getContent().getSpecificModifier(PacketUtils.COMPONENT_CLASS).readSafely(0);
if (chatBaseComp != null) {
try {
return PacketUtils.CHAT_SERIALIZER.getMethod("a", PacketUtils.COMPONENT_CLASS)
.invoke(null, packet.getPacket()).toString();
} catch (Exception exc) {
exc.printStackTrace();
}
}
return null;
}
@Override
public void writeJson(ChatItemPacket packet, String json) {
try {
packet.getContent().getChatComponents().write(0, PacketUtils.CHAT_SERIALIZER.getMethod("a", String.class).invoke(null, json));
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,46 @@
package me.dadus33.chatitem.chatmanager.v1.basecomp.hook;
import com.google.gson.JsonParser;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.v1.PacketEditingChatManager;
import me.dadus33.chatitem.chatmanager.v1.basecomp.IComponentManager;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.hook.DiscordSrvSupport;
public class ComponentNMSManager implements IComponentManager {
@Override
public boolean hasConditions() {
return ChatItem.getPlatform().hasBaseComponentSerializer();
}
@Override
public String getBaseComponentAsJSON(ChatItemPacket packet) {
Object chatBaseComp = packet.getContent().getChatComponents().readSafely(0);
if (chatBaseComp != null) {
try {
Object o = ChatItem.getPlatform().baseComponentToJson(chatBaseComp);
if(o != null && o instanceof String && JsonParser.parseString((String) o).isJsonObject()) {
return (String) o;
}
} catch (Exception exc) {
exc.printStackTrace();
}
}
return null;
}
@Override
public void writeJson(ChatItemPacket packet, String json) {
// Not compatible with that for now
if(ChatItem.discordSrvSupport && DiscordSrvSupport.isSendingMessage())
ChatItem.debug("(v1 ComponentNMS) Can't send message to discord");
// DiscordSrvSupport.sendChatMessage(p, comp, null);
try {
packet.setPacket(PacketEditingChatManager.createSystemChatPacket(json, packet.getPacket()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -1,95 +0,0 @@
package me.dadus33.chatitem.chatmanager.v1.basecomp.hook;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.time.Instant;
import java.util.Optional;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.v1.basecomp.IBaseComponentGetter;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketContent;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.ReflectionUtils;
public class IChatBaseComponentGetter implements IBaseComponentGetter {
private Method serializerGetJson;
private boolean canEditVariable = true;
public IChatBaseComponentGetter() {
try {
for (Method m : PacketUtils.CHAT_SERIALIZER.getDeclaredMethods()) {
if (m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(PacketUtils.COMPONENT_CLASS)
&& m.getReturnType().equals(String.class)) {
serializerGetJson = m;
break;
}
}
if (serializerGetJson == null)
ChatItem.getInstance().getLogger().warning(
"Failed to find JSON serializer in class: " + PacketUtils.CHAT_SERIALIZER.getCanonicalName());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public boolean hasConditions() {
return serializerGetJson != null;
}
@Override
public String getBaseComponentAsJSON(ChatItemPacket packet) {
try {
Object obj = packet.getContent().getChatComponents().readSafely(0);
return obj == null ? null : (String) serializerGetJson.invoke(null, obj);
} catch (Exception exc) {
exc.printStackTrace();
}
return null;
}
@Override
public void writeJson(ChatItemPacket packet, String json) {
try {
PacketContent content = packet.getContent();
Object chatComponent = PacketUtils.CHAT_SERIALIZER.getMethod("a", String.class).invoke(null, json);
if (canEditVariable)
content.getChatComponents().write(0, chatComponent);
else {
try {
Class<?> packetClass = packet.getPacket().getClass();
if (packetClass.getSimpleName().equalsIgnoreCase("ClientboundSystemChatPacket")) {
for (Constructor<?> cons : packetClass.getConstructors()) {
if (cons.getParameterCount() == 6) {
Object newPacket = cons.newInstance(chatComponent, Optional.empty(),
content.getIntegers().readSafely(0, 0),
content.getSpecificModifier(
PacketUtils.getNmsClass("ChatSender", "network.chat.")).read(0),
content.getSpecificModifier(Instant.class).read(0),
ReflectionUtils.getObject(packet.getPacket(), "f"));
packet.setPacket(newPacket);
}
}
throw new UnsupportedOperationException("Failed to find valid constructor for packet "
+ packetClass.getSimpleName() + ". Please report this.");
} else {
throw new UnsupportedOperationException("The packet " + packetClass.getSimpleName()
+ " isn't supported by the AdventureGetter. Please report this.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (IllegalAccessException e) {
if (canEditVariable) {
canEditVariable = false;
writeJson(packet, json); // try again with good config
} else
e.printStackTrace(); // something else
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,34 @@
package me.dadus33.chatitem.chatmanager.v1.basecomp.hook;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.v1.PacketEditingChatManager;
import me.dadus33.chatitem.chatmanager.v1.basecomp.IComponentManager;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
public class IChatBaseComponentManager implements IComponentManager {
@Override
public boolean hasConditions() {
return ChatItem.getPlatform().hasBaseComponentSerializer();
}
@Override
public String getBaseComponentAsJSON(ChatItemPacket packet) {
try {
Object obj = packet.getContent().getChatComponents().readSafely(0);
return obj == null ? null : (String) ChatItem.getPlatform().baseComponentToJson(obj);
} catch (Exception exc) {
exc.printStackTrace();
}
return null;
}
@Override
public void writeJson(ChatItemPacket packet, String json) {
try {
packet.setPacket(PacketEditingChatManager.createSystemChatPacket(json, packet.getPacket()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,68 @@
package me.dadus33.chatitem.chatmanager.v1.basecomp.hook;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.v1.basecomp.IComponentManager;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketContent.ContentModifier;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.ReflectionUtils;
public class PCMComponentManager implements IComponentManager {
@Override
public boolean hasConditions() {
try {
for (String cl : Arrays.asList("net.minecraft.network.chat.PlayerChatMessage"))
Class.forName(cl);
} catch (Exception e) { // can't support this
ChatItem.debug("Can't load PCMComponentManager : " + e.getMessage());
return false;
}
return true;
}
@Override
public String getBaseComponentAsJSON(ChatItemPacket packet) {
Class<?> pcmClass = PacketUtils.getNmsClass("PlayerChatMessage", "network.chat.");
Object pcm = packet.getContent().getSpecificModifier(pcmClass).readSafely(0);
if (pcm != null) {
try {
Object chatBaseComp = ReflectionUtils.getMethod(pcmClass, PacketUtils.COMPONENT_CLASS).invoke(pcm);
if(chatBaseComp != null)
ChatItem.debug("[PCMManager] Founded " + chatBaseComp.getClass().getSimpleName());
return chatBaseComp == null ? null : ChatItem.getPlatform().baseComponentToJson(chatBaseComp);
} catch (Exception exc) {
exc.printStackTrace();
}
}
return null;
}
@Override
public void writeJson(ChatItemPacket packet, String json) {
try {
Object chatComp = ChatItem.getPlatform().jsonToBaseComponent(json);
Class<?> pcmClass = PacketUtils.getNmsClass("PlayerChatMessage", "network.chat.");
ContentModifier<Object> pcmModifier = packet.getContent().getSpecificModifier((Class<Object>) pcmClass);
Object pcm = ReflectionUtils.getMethod(pcmClass, pcmClass, PacketUtils.COMPONENT_CLASS).invoke(pcmModifier.readSafely(0), chatComp);
for(Constructor<?> cons : packet.getPacket().getClass().getConstructors()) {
if(cons.getParameterCount() <= 1)
continue;
Object[] params = new Object[cons.getParameterCount()];
for(int i = 0; i < params.length; i++) {
Class<?> cls = cons.getParameterTypes()[i];
if(cls.equals(pcmClass)) {
params[i] = pcm;
} else
params[i] = packet.getContent().getSpecificModifier(cls).readSafely(0);
}
packet.setPacket(cons.newInstance(params));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -1,44 +0,0 @@
package me.dadus33.chatitem.chatmanager.v1.basecomp.hook;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.v1.PacketEditingChatManager;
import me.dadus33.chatitem.chatmanager.v1.basecomp.IBaseComponentGetter;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
public class StringComponentGetter implements IBaseComponentGetter{
@Override
public String getBaseComponentAsJSON(ChatItemPacket packet) {
String json = packet.getContent().getStrings().readSafely(0);
if(json != null && json.startsWith("[") && json.endsWith("]")) { // if used as array instead of json obj
JsonArray extra = new JsonArray();
for(JsonElement element : JsonParser.parseString(json).getAsJsonArray()) {
if(element.isJsonObject()) { // ignore this
extra.add(element);
} else {
ChatItem.debug("Ignoring element " + element);
}
}
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("text", "");
jsonObject.add("extra", extra);
json = jsonObject.toString();
}
return json;
}
@Override
public void writeJson(ChatItemPacket packet, String json) {
try {
packet.setPacket(PacketEditingChatManager.createSystemChatPacket(json));
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,154 @@
package me.dadus33.chatitem.chatmanager.v1.basecomp.hook;
import java.util.Arrays;
import org.bukkit.entity.Player;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.chatmanager.Chat;
import me.dadus33.chatitem.chatmanager.ChatAction;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.chatmanager.v1.PacketEditingChatManager;
import me.dadus33.chatitem.chatmanager.v1.basecomp.IComponentManager;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.hook.DiscordSrvSupport;
import me.dadus33.chatitem.utils.Messages;
import me.dadus33.chatitem.utils.Utils;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;
public class StringComponentManager implements IComponentManager {
@Override
public String getBaseComponentAsJSON(ChatItemPacket packet) {
String json = packet.getContent().getStrings().readSafely(0);
if (json != null && json.startsWith("[") && json.endsWith("]")) { // if used as array instead of json obj
JsonArray extra = new JsonArray();
for (JsonElement element : JsonParser.parseString(json).getAsJsonArray()) {
if (element.isJsonObject()) { // ignore this
extra.add(element);
} else {
ChatItem.debug("Ignoring element " + element);
}
}
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("text", "");
jsonObject.add("extra", extra);
json = jsonObject.toString();
} else if (json == null) {
BaseComponent[] comp = packet.getContent().getSpecificModifier(BaseComponent[].class).readSafely(0);
if (comp != null)
return ComponentSerializer.toString(comp);
}
return json;
}
@Override
public void writeJson(ChatItemPacket packet, String json) {
try {
packet.setPacket(PacketEditingChatManager.createSystemChatPacket(json, packet.getPacket()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public Object manageContent(Player viewer, Chat chat, ChatItemPacket packet, String json, Storage c) throws Exception {
ChatAction action = chat.getAction();
if (action.isItem())
return manage(viewer, chat, packet, ChatManager.getNameForChatAction(viewer, chat, c), Utils.createItemHover(action.getItem(), viewer), null);
else
return manage(viewer, chat, packet, ChatManager.getNameForChatAction(viewer, chat, c),
Utils.createTextHover(Messages.getMessage(action.getSlot().name().toLowerCase() + ".hover", "%cible%", chat.getPlayer().getName())), Utils.createRunCommand(action.getCommand()));
}
@Override
public Object manageEmpty(Player viewer, Chat chat, ChatItemPacket packet, String json, Storage c) {
ComponentBuilder builder = new ComponentBuilder("");
c.tooltipHand.forEach(s -> builder.append(s));
HoverEvent hover;
ClickEvent click;
String rep;
ChatAction action = chat.getAction();
if (action.isItem()) {
hover = Utils.createTextHover(builder.create());
rep = ChatManager.getHandName(chat);
click = null;
} else {
hover = Utils.createTextHover(Messages.getMessage(action.getSlot().name().toLowerCase() + ".hover", "%cible%", chat.getPlayer().getName()));
rep = Messages.getMessage(action.getSlot().name().toLowerCase() + ".chat", "%cible%", chat.getPlayer().getName());
click = Utils.createRunCommand(action.getCommand());
}
return manage(viewer, chat, packet, rep, hover, click);
}
private Object manage(Player viewer, Chat chat, ChatItemPacket packet, String replacement, HoverEvent hover, ClickEvent click) {
BaseComponent[] components = packet.getContent().getSpecificModifier(BaseComponent[].class).readSafely(0);
if (components == null) {
String json = packet.getContent().getStrings().readSafely(0);
if (json != null && json.startsWith("[") && json.endsWith("]")) { // if used as array instead of json obj
JsonArray extra = new JsonArray();
for (JsonElement element : JsonParser.parseString(json).getAsJsonArray()) {
if (element.isJsonObject()) { // ignore this
extra.add(element);
} else {
ChatItem.debug("Ignoring element " + element);
}
}
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("text", "");
jsonObject.add("extra", extra);
json = jsonObject.toString();
}
ChatItem.debug("[StringComponentManager] Using JSON " + json);
try {
components = ComponentSerializer.parse(json);
} catch (Exception e) {
ChatItem.getInstance().getLogger().severe("Failed to parse JSON: " + json + ". Error:");
e.printStackTrace();
return packet.getPacket();
}
}
ChatItem.debug("Checking for " + components.length + " components");
Arrays.asList(components).forEach(comp -> checkComponent(comp, hover, click, replacement, chat));
if (ChatItem.discordSrvSupport && DiscordSrvSupport.isSendingMessage() && viewer == chat.getPlayer())
DiscordSrvSupport.sendChatMessage(viewer, TextComponent.toLegacyText(components), null);
try {
packet.setPacket(PacketEditingChatManager.createSystemChatPacket(ComponentSerializer.toString(components), packet.getPacket()));
} catch (Exception e) {
e.printStackTrace();
}
return packet.getPacket();
}
private void checkComponent(BaseComponent comp, HoverEvent hover, ClickEvent click, String itemName, Chat chat) {
if (comp instanceof TextComponent) {
TextComponent tc = (TextComponent) comp;
if (ChatManager.containsSeparator(tc.getText())) {
String oldText = tc.getText();
ChatItem.debug("Changing text " + oldText + " to " + itemName + ", extra: " + (tc.getExtra() == null ? "-" : tc.getExtra().size()));
tc.setText(ChatManager.replaceSeparator(chat, oldText, itemName));
tc.setHoverEvent(hover);
if (click != null)
tc.setClickEvent(click);
} else
ChatItem.debug("No insert of text without separator: " + tc.getText() + " (legacy: " + tc.toLegacyText() + ")");
}
if (comp.getExtra() != null) {
for (BaseComponent extra : comp.getExtra()) {
checkComponent(extra, hover, click, itemName, chat);
}
}
}
}
@@ -0,0 +1,258 @@
package me.dadus33.chatitem.chatmanager.v1.json;
import static me.dadus33.chatitem.utils.PacketUtils.getNmsClass;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.Chat;
import me.dadus33.chatitem.chatmanager.ChatAction;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.utils.Messages;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.ReflectionUtils;
public class JSONManipulator {
private static JSONManipulator instance = new JSONManipulator();
public static JSONManipulator getInstance() {
return instance;
}
public static final Class<?> CRAFT_ITEM_STACK_CLASS = PacketUtils.getObcClass("inventory.CraftItemStack");
public static final Class<?> NMS_ITEM_STACK_CLASS = getNmsClass("ItemStack", "world.item.");
public static final Method AS_NMS_COPY = ReflectionUtils.getMethod(CRAFT_ITEM_STACK_CLASS, "asNMSCopy", ItemStack.class);
public static final Class<?> NBT_TAG_COMPOUND = getNmsClass("NBTTagCompound", "nbt.", "CompoundTag");
public static final Method SAVE_NMS_ITEM_STACK_METHOD = ReflectionUtils.getMethod(NMS_ITEM_STACK_CLASS, NBT_TAG_COMPOUND, NBT_TAG_COMPOUND);
public static final Field MAP = ReflectionUtils.getField(NBT_TAG_COMPOUND, "map", "x");
private JsonArray classicTooltip;
public static JsonObject parseOrGet(String json) {
if(json.startsWith("\"") && json.endsWith("\"")) {// seems to be simple line
return JsonParser.parseString("{\"text\":" + json + "}").getAsJsonObject();
}
try {
return JsonParser.parseString(json).getAsJsonObject();
} catch (Exception e) {
JsonObject obj = new JsonObject();
obj.addProperty("text", json);
return obj;
}
}
public String parse(Chat chat, String json, ChatAction action, String replacement) throws Exception {
JsonObject obj = parseOrGet(json);
JsonObject wrapper = new JsonObject(); // Create a wrapper object for the whole array
JsonArray use = Translator.toJson(replacement); // We get the json representation of the old color
// formatting method
ChatItem.debug("Remplacement: " + replacement + " use: " + use.toString());
// There's no public clone method for JSONObjects so we need to parse them every
// time
JsonObject hover = new JsonObject();
if (action.isItem()) {
hover.addProperty("action", "show_item");
// Get the JSON representation of the item (well, not really JSON, but rather a
// string representation of NBT data)
hover.addProperty("value", ChatItem.getPlatform().stringifyItem(action.getItem()));
} else {
hover.addProperty("action", "show_text");
// Get the JSON representation of the item (well, not really JSON, but rather a
// string representation of NBT data)
JsonArray hoverArray = new JsonArray();
hoverArray.add(Messages.getMessage(action.getSlot().name().toLowerCase() + ".hover", "%cible%", chat.getItemPlayer().getPlayer().getName()));
hover.add("value", hoverArray);
JsonObject click = new JsonObject();
click.addProperty("action", "run_command");
click.addProperty("value", action.getCommand());
wrapper.add("clickEvent", click);
}
if (use.size() == 1) {
JsonElement extraElement = use.get(0);
if (extraElement.isJsonPrimitive())
wrapper.addProperty("text", extraElement.getAsString());
else if (extraElement.isJsonObject())
wrapper.addProperty("text", extraElement.getAsJsonObject().get("text").getAsString());
else
wrapper.add("extra", use); // add it only if
} else if (!use.isEmpty())
wrapper.add("extra", use); // add it only if
if (!wrapper.has("text"))
wrapper.addProperty("text", ""); // The text field is compulsory, even if it's empty
ChatItem.debug("Wrapper " + wrapper + " > " + use);
wrapper.add("hoverEvent", hover);
if (obj.size() == 1 && obj.has("text")) {
wrapper.add("text", obj.get("text"));
ChatItem.debug("[JsonManipulator] Parsed quick: " + obj.toString() + ", wrapper: " + wrapper);
return ChatManager.replaceSeparator(chat, wrapper.toString(), replacement);
}
obj.add("extra", parseArray(obj.has("extra") ? obj.getAsJsonArray("extra") : new JsonArray(), wrapper));
if (!obj.has("text")) {
obj.addProperty("text", "");
}
return obj.toString();
}
@SuppressWarnings("deprecation")
public String parseEmpty(Chat chat, String json, List<String> tooltip, Player sender) {
JsonObject obj = parseOrGet(json);
JsonArray array = obj.has("extra") ? obj.getAsJsonArray("extra") : new JsonArray();
JsonArray use = Translator.toJson(ChatManager.getNameForChatAction(chat.getPlayer(), chat, ChatItem.getInstance().getStorage()).replace("{name}", sender.getName()).replace("{display-name}", sender.getDisplayName()));
JsonObject hover = JsonParser.parseString("{\"action\":\"show_text\", \"value\": \"\"}").getAsJsonObject();
StringBuilder oneLineTooltip = new StringBuilder("");
int index = 0;
for (String m : tooltip) {
oneLineTooltip.append(m.replace("{name}", sender.getName()).replace("{display-name}", sender.getDisplayName()));
++index;
if (index != tooltip.size()) {
oneLineTooltip.append('\n');
}
}
hover.add("value", new JsonPrimitive(oneLineTooltip.toString()));
if (!tooltip.isEmpty()) {
for (JsonElement ob : use)
ob.getAsJsonObject().add("hoverEvent", hover);
classicTooltip = use;
}
obj.add("extra", parseArray(array, classicTooltip));
if (!obj.has("text")) {
obj.addProperty("text", "");
}
return obj.toString();
}
private JsonArray parseArray(JsonArray arr, JsonElement tooltip) {
JsonArray replacer = new JsonArray();
boolean separator = false;
for (int i = 0; i < arr.size(); ++i) {
JsonElement element = arr.get(i);
if(element.isJsonNull())
continue;
if(separator) {
if(ChatManager.containsSeparatorEnd(element.toString()))
separator = false;
continue;
}
if (element.isJsonObject()) {
JsonElement text = element.getAsJsonObject().get("text");
if(text != null && ChatManager.containsSeparator(text.getAsString())) {
if(!ChatManager.containsSeparatorEnd(text.getAsString())) // if the separator doesn't end in the same string as it's begin
separator = true;
}
ChatItem.debug("Parsing object " + element.toString());
addParsedJsonObjectToArray(element.getAsJsonObject(), replacer, tooltip);
} else if (element.isJsonArray()) {
JsonArray jar = element.getAsJsonArray();
if (jar.size() != 0) {
jar = parseArray(element.getAsJsonArray(), tooltip);
replacer.set(i, jar);
}
} else if(element.isJsonPrimitive()) {
if(ChatManager.containsSeparator(element.getAsString())) {
if(!ChatManager.containsSeparatorEnd(element.getAsString())) // if the separator doesn't end in the same string as it's begin
separator = true;
addParsedStringToArray(element.getAsString(), replacer, element, tooltip);
}
}
}
return replacer;
}
private void addParsedJsonObjectToArray(JsonObject o, JsonArray rep, JsonElement tooltip) {
JsonElement text = o.get("text");
if (text == null) {
JsonElement el = o.get("extra");
if (el != null) {
JsonArray jar = el.getAsJsonArray();
if (jar.size() != 0) {
JsonArray tmpArray = parseArray(jar, tooltip);
if (!tmpArray.isEmpty())
o.add("extra", tmpArray);
else
o.remove("extra");
} else {
o.remove("extra");
}
}
return;
} else {
if (text.getAsString().isEmpty()) {
JsonElement el = o.get("extra");
if (el != null) {
JsonArray jar = el.getAsJsonArray();
if (!jar.isEmpty()) {
JsonArray tmpArray = parseArray(jar, tooltip);
if (!tmpArray.isEmpty())
o.add("extra", tmpArray);
else
o.remove("extra");
} else {
o.remove("extra");
}
}
}
}
addParsedStringToArray(text.getAsString(), rep, o, tooltip);
}
private void addParsedStringToArray(String msg, JsonArray rep, JsonElement o, JsonElement tooltip) {
if (!ChatManager.containsSeparator(msg)) {
rep.add(o);
return;
}
ChatItem.debug("[JSONManipulator] Parsed string " + msg + ", rep: " + rep);
String current = "";
boolean wasSep = false;
for (String parts : msg.split("")) {
if (ChatManager.equalsSeparator(parts)) {
if (!current.isEmpty()) {
if(o.isJsonObject()) {
JsonObject jsonObj = o.getAsJsonObject().deepCopy();
jsonObj.addProperty("text", current); // edit text
rep.add(jsonObj); // add with all basic coloring things
} else {
rep.add(current);
}
current = "";
}
rep.add(tooltip);
wasSep = true;
} else if (wasSep) {
if (ChatManager.equalsSeparatorEnd(parts)) // sep finished
wasSep = false;
} else {
current += parts;
}
}
if (!current.isEmpty()) {
if(o.isJsonObject()) {
JsonObject jsonObj = o.getAsJsonObject().deepCopy();
jsonObj.addProperty("text", current); // edit text
rep.add(jsonObj); // add with all basic coloring things
} else {
rep.add(current);
}
}
}
}
@@ -1,254 +0,0 @@
package me.dadus33.chatitem.chatmanager.v1.json;
import static me.dadus33.chatitem.utils.PacketUtils.getNmsClass;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.Reflect;
import me.dadus33.chatitem.utils.Version;
@SuppressWarnings({ "unchecked" })
public class JSONManipulatorCurrent {
private static final Class<?> CRAFT_ITEM_STACK_CLASS = PacketUtils.getObcClass("inventory.CraftItemStack");
private static final Class<?> NMS_ITEM_STACK_CLASS = getNmsClass("ItemStack", "world.item.");
private static final Method AS_NMS_COPY = Reflect.getMethod(CRAFT_ITEM_STACK_CLASS, "asNMSCopy", ItemStack.class);
private static final Class<?> NBT_TAG_COMPOUND = getNmsClass("NBTTagCompound", "nbt.");
private static final Method SAVE_NMS_ITEM_STACK_METHOD = Reflect.getMethod(NMS_ITEM_STACK_CLASS, NBT_TAG_COMPOUND,
NBT_TAG_COMPOUND);
private static final Field MAP = Reflect.getField(NBT_TAG_COMPOUND, "map", "x");
private static final ConcurrentHashMap<Map.Entry<Version, ItemStack>, JsonObject> STACKS = new ConcurrentHashMap<>();
private Version protocolVersion;
private JsonObject itemTooltip;
private JsonArray classicTooltip;
public String parse(String json, ItemStack item, String replacement, int protocol)
throws Exception {
JsonObject obj = JsonParser.parseString(json).getAsJsonObject();
JsonArray array = obj.has("extra") ? obj.getAsJsonArray("extra") : new JsonArray();
final AbstractMap.SimpleEntry<Version, ItemStack> p = new AbstractMap.SimpleEntry<>(
protocolVersion = Version.getVersion(protocol), item);
if ((itemTooltip = STACKS.get(p)) == null) {
JsonArray use = Translator.toJson(replacement); // We get the json representation of the old color
// formatting method
ChatItem.debug("Remplacement: " + replacement + " use: " + use.toString());
// There's no public clone method for JSONObjects so we need to parse them every time
JsonObject hover = new JsonObject();
hover.addProperty("action", "show_item");
// Get the JSON representation of the item (well, not really JSON, but rather a string representation of NBT data)
hover.addProperty("value", stringifyItem(this, item, protocolVersion));
JsonObject wrapper = new JsonObject(); // Create a wrapper object for the whole array
wrapper.addProperty("text", ""); // The text field is compulsory, even if it's empty
wrapper.add("extra", use);
wrapper.add("hoverEvent", hover);
itemTooltip = wrapper; // Save the tooltip for later use when we encounter a placeholder
STACKS.put(p, itemTooltip); // Save it in the cache too so when parsing other packets with the same item
// (and client version) we no longer have to create it again
// We remove it later when no longer needed to save memory
Bukkit.getScheduler().runTaskLaterAsynchronously(ChatItem.getInstance(), () -> STACKS.remove(p), 100L);
}
obj.add("extra", parseArray(array, itemTooltip));
if (!obj.has("text")) {
obj.addProperty("text", "");
}
ChatItem.debug("Parsed array for item: " + obj.toString());
return obj.toString();
}
public String parseEmpty(String json, String repl, List<String> tooltip, Player sender) {
JsonObject obj = JsonParser.parseString(json).getAsJsonObject();
JsonArray array = obj.has("extra") ? obj.getAsJsonArray("extra") : new JsonArray();
JsonArray use = Translator
.toJson(repl.replace("{name}", sender.getName()).replace("{display-name}", sender.getDisplayName()));
JsonObject hover = JsonParser.parseString("{\"action\":\"show_text\", \"value\": \"\"}").getAsJsonObject();
StringBuilder oneLineTooltip = new StringBuilder("");
int index = 0;
for (String m : tooltip) {
oneLineTooltip
.append(m.replace("{name}", sender.getName()).replace("{display-name}", sender.getDisplayName()));
++index;
if (index != tooltip.size()) {
oneLineTooltip.append('\n');
}
}
hover.add("value", new JsonPrimitive(oneLineTooltip.toString()));
if (!tooltip.isEmpty()) {
for (JsonElement ob : use)
ob.getAsJsonObject().add("hoverEvent", hover);
classicTooltip = use;
}
obj.add("extra", parseArray(array, classicTooltip));
if (!obj.has("text")) {
obj.addProperty("text", "");
}
return obj.toString();
}
private JsonArray parseArray(JsonArray arr, JsonElement tooltip) {
JsonArray replacer = new JsonArray();
for (int i = 0; i < arr.size(); ++i) {
if (arr.get(i).isJsonNull()) {
continue;
} else if (arr.get(i).isJsonObject()) {
addParsedJsonObjectToArray(arr.get(i).getAsJsonObject(), replacer, tooltip);
} else if (arr.get(i).isJsonArray()) {
JsonArray jar = arr.get(i).getAsJsonArray();
if (jar.size() != 0) {
jar = parseArray(arr.get(i).getAsJsonArray(), tooltip);
replacer.set(i, jar);
}
} else {
addParsedStringToArray(arr.get(i).getAsString(), replacer, arr.get(i), tooltip);
}
}
return replacer;
}
private void addParsedJsonObjectToArray(JsonObject o, JsonArray rep, JsonElement tooltip) {
JsonElement text = o.get("text");
if (text == null) {
JsonElement el = o.get("extra");
if (el != null) {
JsonArray jar = el.getAsJsonArray();
if (jar.size() != 0) {
o.add("extra", parseArray(jar, tooltip));
} else {
o.remove("extra");
}
}
return;
} else {
if (text.getAsString().isEmpty()) {
JsonElement el = o.get("extra");
if (el != null) {
JsonArray jar = el.getAsJsonArray();
if (jar.size() != 0) {
o.add("extra", parseArray(jar, tooltip));
} else {
o.remove("extra");
}
}
}
}
addParsedStringToArray(text.getAsString(), rep, o, tooltip);
}
private void addParsedStringToArray(String msg, JsonArray rep, JsonElement o, JsonElement tooltip) {
ChatItem.debug("Checking " + msg + " > " + rep + ", o: " + o);
if(!ChatManager.containsSeparator(msg)) {
rep.add(o);
return;
}
String current = "";
for(String parts : msg.split("")) {
if(ChatManager.equalsSeparator(parts)) {
if(!current.isEmpty()) {
rep.add(current);
current = "";
}
rep.add(tooltip);
} else {
current += parts;
}
}
if(!current.isEmpty())
rep.add(current);
}
@SuppressWarnings({ "deprecation" })
public static String stringifyItem(JSONManipulatorCurrent j, ItemStack is, Version protocolVersion)
throws Exception {
Object nmsStack = JSONManipulatorCurrent.AS_NMS_COPY.invoke(null, is);
Object nmsTag = JSONManipulatorCurrent.NBT_TAG_COMPOUND.newInstance();
JSONManipulatorCurrent.SAVE_NMS_ITEM_STACK_METHOD.invoke(nmsStack, nmsTag);
HashMap<String, String> tagMap = new HashMap<>();
Map<String, Object> nmsMap = (Map<String, Object>) JSONManipulatorCurrent.MAP.get(nmsTag);
String id = nmsMap.get("id").toString().replace("\"", "");
Object realTag = nmsMap.get("tag");
if (JSONManipulatorCurrent.NBT_TAG_COMPOUND.isInstance(realTag)) { // We need to make sure this is indeed an
// NBTTagCompound
Map<String, Object> realMap = (Map<String, Object>) JSONManipulatorCurrent.MAP.get(realTag);
Set<Map.Entry<String, Object>> entrySet = realMap.entrySet();
for (Map.Entry<String, Object> entry : entrySet) {
tagMap.put(entry.getKey(), entry.getValue().toString());
}
}
// TODO check for ID remapping
// ItemRewriter.remapIds(Version.getVersion().MAX_VER, protocolVersion.MAX_VER,
// is);
StringBuilder sb = new StringBuilder("{id:");
if (protocolVersion.equals(Version.V1_7))
sb.append(id).append(","); // Append the id
else
sb.append("\"").append(id).append("\"").append(","); // Append the id
sb.append("Count:").append(is.getAmount()).append("b"); // Append the amount
if (!tagMap.containsKey("Damage")) { // for new versions
sb.append(",Damage:").append(is.getDurability()).append("s"); // Append the durability data
}
if (tagMap.isEmpty()) {
sb.append("}");
return sb.toString();
}
Set<Map.Entry<String, String>> entrySet = tagMap.entrySet();
boolean first = true;
sb.append(",tag:{"); // Start of the tag
for (Map.Entry<String, String> entry : entrySet) {
if (!first)
sb.append(",");
first = false;
if (!entry.getKey().isEmpty()) {
if(entry.getKey().contains(";"))
sb.append("\"" + entry.getKey() + "\"");
else
sb.append(entry.getKey());
sb.append(":");
}
if(entry.getKey().equalsIgnoreCase("display") && Version.getVersion().isNewerOrEquals(Version.V1_16)) {
String replaced = entry.getValue().replace("','", ",").replace("\"}',", "\"},");
ChatItem.debug("Cleaning display (custom): " + entry.getValue() + " > " + replaced);
sb.append(replaced);
} else {
ChatItem.debug("Cleaning " + entry.getKey() + ": " + entry.getValue() + " > " + cleanStr(entry.getValue()));
sb.append(cleanStr(entry.getValue()));
}
}
sb.append("}}"); // End of tag and end of item
return sb.toString();
}
private static String cleanStr(String s) {
return s.startsWith("'") && s.endsWith("'") ? s.substring(1, s.length() - 1) : s;
}
}
@@ -46,10 +46,12 @@ public class Translator {
if(!text.isEmpty()) // ignore this if no text before
text += ColorManager.getColorString(colorCode);
colorCode = "x";
} else if(!colorCode.isEmpty() && !colorCode.startsWith("x")) { // already color and not hex
text += ColorManager.COLOR_CHAR + colorCode; // add the color to text
colorCode = args + "";
} else
colorCode += args; // a color by itself
} else {
waiting = false;
if(!colorCode.isEmpty()) { // manage color
if(colorCode.startsWith("x") && colorCode.length() == 7) { // hex color code
next.addProperty("color", ColorManager.getColor(colorCode).getName());
@@ -58,20 +60,21 @@ public class Translator {
text += ColorManager.getColor(colorCode);
else
next.addProperty("color", ColorManager.getColor(colorCode).getName());
} else if(!text.isEmpty())// no text before -> color will be used as "color"
} else if(!text.isEmpty()) // no text before -> color will be used as "color"
text += ColorManager.getColorString(colorCode);
ChatItem.debug("Add " + colorCode + " to " + text + ", msg: " + message);
ChatItem.debug("[Translator] Add color code " + colorCode + " to " + text + args + ", msg: " + message);
colorCode = "";
}
// basic text, not waiting for code after '§'
text += args;
}
}
if(!text.isEmpty() || message.isEmpty()) {
if(!next.has("color") || colorCode.length() == 1) // if no color or a color that can override it
next.addProperty("color", (colorCode.length() == 1 ? ColorManager.getColor(colorCode).getName() : "white"));
if(!text.isEmpty() || message.isEmpty() || next.size() > 0) {
next.addProperty("text", text);
if(!next.has("color"))
next.addProperty("color", "white");
ChatItem.debug("[Translator] Added content " + next + " to message" + message);
message.add(next);
}
return message;
@@ -1,156 +0,0 @@
package me.dadus33.chatitem.chatmanager.v1.listeners;
import static me.dadus33.chatitem.chatmanager.ChatManager.SEPARATOR;
import java.util.StringJoiner;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
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.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.inventory.ItemStack;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.chatmanager.v1.PacketEditingChatManager;
import me.dadus33.chatitem.utils.Storage;
import me.dadus33.chatitem.utils.Utils;
public class ChatEventListener implements Listener {
private final PacketEditingChatManager manage;
public ChatEventListener(PacketEditingChatManager manage) {
this.manage = manage;
}
public Storage getStorage() {
return this.manage.getStorage();
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) // We need to have lowest priority in order
// to get to the event before DeluxeChat or
// other plugins do
public void onChat(AsyncPlayerChatEvent e) {
if (e.getMessage().indexOf(SEPARATOR) != -1) { // If the BELL character is found, we have to remove it
String msg = e.getMessage().replace(Character.toString(SEPARATOR), "");
ChatItem.debug("Already bell in message: " + e.getMessage());
e.setMessage(msg);
}
boolean found = false;
final String oldMsg = e.getMessage();
for (String rep : getStorage().PLACEHOLDERS)
if (oldMsg.contains(rep)) {
found = true;
break;
}
if (!found) {
ChatItem.debug("(v1) not found placeholders in: " + e.getMessage());
return;
}
Player p = e.getPlayer();
ItemStack item = ChatManager.getUsableItem(p);
if(!ChatManager.canShowItem(p, item, e))
return;
String s = e.getMessage(), firstPlaceholder = getStorage().PLACEHOLDERS.get(0);
for (String placeholder : getStorage().PLACEHOLDERS) {
s = s.replace(placeholder, firstPlaceholder);
}
if (Utils.countMatches(s, firstPlaceholder) > getStorage().LIMIT) {
e.setCancelled(true);
if (getStorage().LIMIT_MESSAGE.isEmpty()) {
return;
}
p.sendMessage(getStorage().LIMIT_MESSAGE);
return;
}
ChatItem.debug("(v1) Set placeholder: " + e.getMessage());
try {
StringJoiner msg = new StringJoiner(" ");
for(String part : s.split(" ")) {
if(part.equalsIgnoreCase(firstPlaceholder)) {
msg.add(firstPlaceholder + SEPARATOR + p.getName());
} else {
msg.add(part);
}
}
e.setMessage(msg.toString());
e.setFormat(e.getFormat().replace(oldMsg, e.getMessage())); // set own message for plugin that already put the message into the format
ChatItem.debug("Message: " + e.getMessage() + ", format: " + e.getFormat());
} catch (Exception exc) {
exc.printStackTrace();
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void onCommand(final PlayerCommandPreprocessEvent e) {
if (e.getMessage().indexOf(SEPARATOR) != -1) { // If the BELL character is found, we have to remove it
String msg = e.getMessage().replace(Character.toString(SEPARATOR), "");
e.setMessage(msg);
}
String commandString = e.getMessage().split(" ")[0].replaceAll("^/+", ""); // First part of the command, without
// leading slashes and without
// arguments
Command cmd = Bukkit.getPluginCommand(commandString);
if (cmd == null) { // not a plugin command
if (!getStorage().ALLOWED_DEFAULT_COMMANDS.contains(commandString)) {
return;
}
} else {
if (!getStorage().ALLOWED_PLUGIN_COMMANDS.contains(cmd)) {
return;
}
}
Player p = e.getPlayer();
boolean found = false;
for (String rep : getStorage().PLACEHOLDERS) {
if (e.getMessage().contains(rep)) {
found = true;
break;
}
}
if (!found) {
return;
}
ItemStack item = ChatManager.getUsableItem(p);
if(!ChatManager.canShowItem(p, item, e))
return;
String s = e.getMessage(), firstPlaceholder = getStorage().PLACEHOLDERS.get(0);
for (String placeholder : getStorage().PLACEHOLDERS) {
s = s.replace(placeholder, firstPlaceholder);
}
if (Utils.countMatches(s, firstPlaceholder) > getStorage().LIMIT) {
e.setCancelled(true);
if (getStorage().LIMIT_MESSAGE.isEmpty()) {
return;
}
p.sendMessage(getStorage().LIMIT_MESSAGE);
return;
}
ChatItem.debug("(v1) Set placeholder: " + e.getMessage());
try {
StringJoiner msg = new StringJoiner(" ");
for(String part : s.split(" ")) {
if(part.equalsIgnoreCase(firstPlaceholder)) {
msg.add(firstPlaceholder + Character.toString(SEPARATOR) + p.getName());
} else {
msg.add(part);
}
}
e.setMessage(msg.toString());
} catch (Exception exc) {
exc.printStackTrace();
}
}
}
@@ -1,17 +1,12 @@
package me.dadus33.chatitem.chatmanager.v1.listeners;
import static me.dadus33.chatitem.chatmanager.ChatManager.SEPARATOR;
import static me.dadus33.chatitem.chatmanager.ChatManager.SEPARATOR_STR;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.ShulkerBox;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@@ -21,233 +16,174 @@ import org.bukkit.inventory.meta.ItemMeta;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.ItemPlayer;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.chatmanager.Chat;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.chatmanager.v1.PacketEditingChatManager;
import me.dadus33.chatitem.chatmanager.v1.basecomp.IBaseComponentGetter;
import me.dadus33.chatitem.chatmanager.v1.basecomp.hook.AdventureComponentGetter;
import me.dadus33.chatitem.chatmanager.v1.basecomp.hook.BaseComponentGetter;
import me.dadus33.chatitem.chatmanager.v1.basecomp.hook.ComponentGetter;
import me.dadus33.chatitem.chatmanager.v1.basecomp.hook.IChatBaseComponentGetter;
import me.dadus33.chatitem.chatmanager.v1.basecomp.hook.StringComponentGetter;
import me.dadus33.chatitem.chatmanager.v1.basecomp.IComponentManager;
import me.dadus33.chatitem.chatmanager.v1.basecomp.hook.AdventureComponentManager;
import me.dadus33.chatitem.chatmanager.v1.basecomp.hook.ComponentNMSManager;
import me.dadus33.chatitem.chatmanager.v1.basecomp.hook.PCMComponentManager;
import me.dadus33.chatitem.chatmanager.v1.basecomp.hook.StringComponentManager;
import me.dadus33.chatitem.chatmanager.v1.json.JSONManipulator;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketContent;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketHandler;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketType;
import me.dadus33.chatitem.utils.ItemUtils;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.Storage;
import me.dadus33.chatitem.utils.Version;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.chat.ComponentSerializer;
public class ChatPacketManager extends PacketHandler {
private Object lastSentPacket = null;
private Method serializerGetJson;
private PacketEditingChatManager manager;
private final List<IBaseComponentGetter> baseComponentGetter = new ArrayList<>();
private final List<IComponentManager> componentManager = new ArrayList<>();
public ChatPacketManager(PacketEditingChatManager manager) {
this.manager = manager;
for (IComponentManager getter : Arrays.asList(new StringComponentManager(), new ComponentNMSManager(), new PCMComponentManager())) {
tryRegister(getter);
}
try {
for (Method m : PacketUtils.CHAT_SERIALIZER.getDeclaredMethods()) {
if (m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(PacketUtils.COMPONENT_CLASS)
&& m.getReturnType().equals(String.class)) {
serializerGetJson = m;
break;
}
}
if (serializerGetJson == null)
ChatItem.getInstance().getLogger().warning(
"Failed to find JSON serializer in class: " + PacketUtils.CHAT_SERIALIZER.getCanonicalName());
Class.forName("net.kyori.adventure.text.Component");
tryRegister(new AdventureComponentManager());
} catch (Exception e) {
e.printStackTrace();
}
for(IBaseComponentGetter getter : Arrays.asList(new IChatBaseComponentGetter(), new BaseComponentGetter(), new ComponentGetter(), new StringComponentGetter(), new AdventureComponentGetter())) {
if(getter.hasConditions())
baseComponentGetter.add(getter);
}
ChatItem.getInstance().getLogger().info("Loaded " + baseComponentGetter.size() + " getter for base components.");
ChatItem.debug("BaseComponentGetters: " + String.join(", ", baseComponentGetter.stream().map(IBaseComponentGetter::getClass).map(Class::getSimpleName).collect(Collectors.toList())));
ChatItem.debug("ComponentManager: " + String.join(", ", componentManager.stream().map(IComponentManager::getClass).map(Class::getSimpleName).collect(Collectors.toList())));
}
private void tryRegister(IComponentManager getter) {
if (getter.hasConditions())
componentManager.add(getter);
else
ChatItem.debug("Component " + getter.getClass().getSimpleName() + " doesn't answer conditions");
}
@SuppressWarnings("deprecation")
@Override
public void onSend(ChatItemPacket e) {
if (!e.hasPlayer() || !e.getPacketType().equals(PacketType.Server.CHAT))
return;
ChatItem.debug("Checking: " + e.getPacketType().getFullName() + " > " + e.getPacket().getClass().getSimpleName());
if (ChatManager.isTestingEnabled() && !ChatManager.isTesting("packet"))
return;
if(!ChatManager.isSelected("packet"))
return;
if (lastSentPacket != null && lastSentPacket == e.getPacket())
return; // prevent infinite loop
ChatItem.debug("Checking: " + e.getPacket().getClass().getSimpleName() + " to " + e.getPlayername());
PacketContent packet = e.getContent();
Version version = Version.getVersion();
String json = "{}";
IBaseComponentGetter choosedGetter = null;
IComponentManager choosedGetter = null;
if (version.isNewerOrEquals(Version.V1_19)) {
if(packet.getIntegers().readSafely(0, 0) > 1) { // not parsed chat message type
ChatItem.debug("Invalid int: " + packet.getIntegers().read(0));
return;
}
choosedGetter = new StringComponentGetter();
choosedGetter = new StringComponentManager();
json = choosedGetter.getBaseComponentAsJSON(e); // if null, will be re-checked so anyway
} else if (version.isNewerOrEquals(Version.V1_12)) {
// only if action bar messages are supported in this version of minecraft
try {
if (((Enum<?>) packet
.getSpecificModifier(PacketUtils.getNmsClass("ChatMessageType", "network.chat.")).read(0))
.name().equals("GAME_INFO")) {
return; // It means it's an actionbar message, and we ain't intercepting those
}
} catch (Exception exc) {
exc.printStackTrace();
}
} else if (version.isNewerOrEquals(Version.V1_8) && packet.getBytes().readSafely(0) == (byte) 2) {
return; // It means it's an actionbar message, and we ain't intercepting those
}
if(json == null || choosedGetter == null) {
for(IBaseComponentGetter getters : baseComponentGetter) {
// only if action bar messages are supported
if (((Enum<?>) packet.getSpecificModifier(PacketUtils.getNmsClass("ChatMessageType", "network.chat.")).read(0)).name().equals("GAME_INFO"))
return; // It's an actionbar message, ignoring
} else if (version.isNewerOrEquals(Version.V1_8) && packet.getBytes().readSafely(0) == (byte) 2)
return; // It's an actionbar message, ignoring
if (json == null || choosedGetter == null || !ChatManager.containsSeparator(json)) {
for (IComponentManager getters : componentManager) {
String tmpJson = getters.getBaseComponentAsJSON(e);
if(tmpJson != null) {
if (tmpJson != null) {
json = ChatManager.fixSeparator(tmpJson);
choosedGetter = getters;
break;
}
ChatItem.debug("Seems to have one nice manager with " + getters.getClass().getSimpleName() + " (json: " + json + ")");
if (ChatManager.containsSeparator(json))
break; // be sure it's valid one
} else
ChatItem.debug("Null JSON for manager " + getters.getClass().getSimpleName());
}
}
if(json == null || choosedGetter == null) {
if (json == null || choosedGetter == null) {
ChatItem.debug("Can't find valid json getter or json itself");
ChatItem.debug("String: " + packet.getStrings().getContent());
PacketUtils.printPacketToDebug(e.getPacket());
return; // can't find something
}
String placeholder = choosedGetter.hasPlaceholders(getStorage(), json);
if (placeholder == null) {
ChatItem.debug("No placeholders founded in " + json);
ChatItem.debug("String: " + packet.getStrings().getContent());
return; // then it's just a normal message without placeholders, so we leave it alone
}
ChatItem.debug("Found " + placeholder + " with " + choosedGetter.getClass().getName());
String toReplace = null;
if (json.lastIndexOf(SEPARATOR) != -1)
toReplace = ((Object) SEPARATOR).toString();
if (json.lastIndexOf(SEPARATOR_STR) != -1)
toReplace = SEPARATOR_STR;
if (toReplace == null) { // if the message doesn't contain the BELL separator
ChatItem.debug("Not containing bell " + json);
if (!ChatManager.containsSeparator(json)) // if the message doesn't contain the BELL separator
return;
}
toReplace = placeholder + toReplace; // add placeholder
String name = choosedGetter.getNameFromMessage(json, toReplace);
if (name == null) { // something went really bad, so we run away and hide (AKA the player left or is
ChatItem.debug("Found with " + choosedGetter.getClass().getName());
Chat chat = choosedGetter.getChat(json);
if (chat == null) { // something went really bad, so we run away and hide (AKA the player left or is
// on another server)
ChatItem.debug("Name null for " + json);
ChatItem.debug("Chat null for " + json);
return;
}
Player itemPlayer = Bukkit.getPlayer(name);
String localJson = choosedGetter.removePlaceholdersAndName(json, toReplace, itemPlayer);
ChatItem.debug("Local json: " + localJson);
IBaseComponentGetter fchoosedGetter = choosedGetter;
e.setCancelled(true); // We cancel the packet as we're going to resend it anyways (ignoring listeners
// this time)
Bukkit.getScheduler().runTaskAsynchronously(ChatItem.getInstance(), () -> {
Player itemPlayer = chat.getPlayer();
if (getStorage().cooldown > 0 && !itemPlayer.hasPermission("chatitem.ignore-cooldown"))
ChatManager.applyCooldown(itemPlayer);
IComponentManager getter = choosedGetter;
String fjson = json;
ChatItem.debug("Final json used: " + fjson);
e.setCancelled(true); // We cancel the packet as we're going to resends it anyways
CompletableFuture.runAsync(() -> {
Player p = e.getPlayer();
if (getStorage().COOLDOWN > 0 && !itemPlayer.hasPermission("chatitem.ignore-cooldown")) {
ChatManager.applyCooldown(itemPlayer);
}
String message = null;
try {
ItemStack item = ChatManager.getUsableItem(itemPlayer);
if (!ItemUtils.isEmpty(item)) {
ItemStack copy = item.clone();
if (ItemPlayer.getPlayer(p).isBuggedClient()) {
String act = getStorage().BUGGED_CLIENT_ACTION;
List<String> tooltip;// = act.equalsIgnoreCase("nothing") ? new ArrayList<>() : null;
if (act.equalsIgnoreCase("tooltip"))
tooltip = getStorage().BUGGED_CLIENTS_TOOLTIP;
else if (act.equalsIgnoreCase("item"))
tooltip = ChatManager.getMaxLinesFromItem(p, copy);
else if (act.equalsIgnoreCase("show_both")) {
tooltip = ChatManager.getMaxLinesFromItem(p, copy);
tooltip.addAll(getStorage().BUGGED_CLIENTS_TOOLTIP);
} else
tooltip = new ArrayList<>();
message = manager.getManipulator().parseEmpty(localJson,
ChatManager.styleItem(p, copy, getStorage()), tooltip, itemPlayer);
if (!manager.supportsChatComponentApi()) {
ChatItem.debug("Use basic for 1.7 lunar");
packet.getChatComponents().write(0, jsonToChatComponent(message));
} else {
ChatItem.debug("Use baseComponent for 1.7 lunar");
packet.getSpecificModifier(BaseComponent[].class).write(0,
ComponentSerializer.parse(message));
}
lastSentPacket = e.getPacket();
PacketUtils.sendPacket(p, lastSentPacket);
return;
}
if(copy.hasItemMeta()) {
ItemMeta meta = copy.getItemMeta();
if (meta instanceof BookMeta) { // filtering written books
BookMeta bm = (BookMeta) copy.getItemMeta();
bm.setPages(Collections.emptyList());
copy.setItemMeta(bm);
} else if (meta instanceof BlockStateMeta && Version.getVersion().isNewerOrEquals(Version.V1_9)) { // if it's a block
BlockStateMeta bsm = (BlockStateMeta) copy.getItemMeta();
if (bsm.hasBlockState() && bsm.getBlockState() instanceof ShulkerBox) {
ShulkerBox sb = (ShulkerBox) bsm.getBlockState();
for (ItemStack itemInv : sb.getInventory()) {
stripData(itemInv);
}
bsm.setBlockState(sb);
if(chat.getAction().isItem()) {
ItemStack item = ChatManager.getUsableItem(itemPlayer, chat.getSlot());
if (!ItemUtils.isEmpty(item)) {
ItemStack copy = item.clone();
if (ItemPlayer.getPlayer(p).isBuggedClient()) { // if the guy that will receive it is bugged
String act = getStorage().buggedClientAction;
List<String> tooltip;
if (act.equalsIgnoreCase("tooltip"))
tooltip = getStorage().tooltipBuggedClient;
else if (act.equalsIgnoreCase("item"))
tooltip = ChatManager.getMaxLinesFromItem(p, copy);
else if (act.equalsIgnoreCase("show_both")) {
tooltip = ChatManager.getMaxLinesFromItem(p, copy);
tooltip.addAll(getStorage().tooltipBuggedClient);
} else
tooltip = new ArrayList<>();
message = JSONManipulator.getInstance().parseEmpty(chat, fjson, tooltip, chat.getPlayer());
if (message != null) {
getter.writeJson(e, message);
}
copy.setItemMeta(bsm);
lastSentPacket = e.getPacket();
}
if (copy.hasItemMeta()) {
ItemMeta meta = copy.getItemMeta();
if (meta instanceof BookMeta) { // filtering written books
BookMeta bm = (BookMeta) copy.getItemMeta();
bm.setPages(Collections.emptyList());
copy.setItemMeta(bm);
} else if (meta instanceof BlockStateMeta && Version.getVersion().isNewerOrEquals(Version.V1_9)) { // if it's a block
BlockStateMeta bsm = (BlockStateMeta) copy.getItemMeta();
if (bsm.hasBlockState() && bsm.getBlockState() instanceof ShulkerBox) {
ShulkerBox sb = (ShulkerBox) bsm.getBlockState();
for (ItemStack itemInv : sb.getInventory()) {
ItemUtils.stripData(itemInv);
}
bsm.setBlockState(sb);
}
copy.setItemMeta(bsm);
}
}
lastSentPacket = getter.manageContent(p, chat, e, fjson, getStorage());
} else {
if (!getStorage().handDisabled) {
lastSentPacket = getter.manageEmpty(p, chat, e, fjson, getStorage());
}
}
message = manager.getManipulator().parse(localJson, copy,
ChatManager.styleItem(p, copy, getStorage()), ItemPlayer.getPlayer(itemPlayer).getProtocolVersion());
} else {
if (!getStorage().HAND_DISABLED) {
message = manager.getManipulator().parseEmpty(localJson, getStorage().HAND_NAME, getStorage().HAND_TOOLTIP, itemPlayer);
}
}
} else
lastSentPacket = getter.manageContent(p, chat, e, fjson, getStorage());
if (lastSentPacket == null) // maybe sent by the manager directly
ChatItem.debug("(v1) No packet to sent with manager " + getter.getClass().getName());
else
PacketUtils.sendPacket(p, lastSentPacket);
} catch (Exception e1) {
e1.printStackTrace();
}
if (message != null) {
ChatItem.debug("(v1) Writing message: " + message);
fchoosedGetter.writeJson(e, message);
}
lastSentPacket = e.getPacket();
PacketUtils.sendPacket(p, lastSentPacket);
});
}
private Object jsonToChatComponent(String json) {
try {
return PacketUtils.CHAT_SERIALIZER.getMethod("a", String.class).invoke(null, json);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private void stripData(ItemStack i) {
if (i == null) {
return;
}
if (i.getType().equals(Material.AIR)) {
return;
}
if (!i.hasItemMeta()) {
return;
}
ItemMeta im = Bukkit.getItemFactory().getItemMeta(i.getType());
ItemMeta original = i.getItemMeta();
if (original.hasDisplayName()) {
im.setDisplayName(original.getDisplayName());
}
i.setItemMeta(im);
}
public Storage getStorage() {
return manager.getStorage();
}
@@ -1,33 +0,0 @@
package me.dadus33.chatitem.chatmanager.v1.listeners;
import org.bukkit.Bukkit;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.playerversion.hooks.DefaultVersionHook;
import me.dadus33.chatitem.utils.Version;
public class HandshakeListener extends PacketAdapter {
public HandshakeListener(ChatItem pl) {
super(pl, ListenerPriority.MONITOR, PacketType.Handshake.Client.SET_PROTOCOL);
}
@Override
public void onPacketReceiving(final PacketEvent e){
if(e.isPlayerTemporary() || e.getPlayer() == null)
return;
PacketType.Protocol p = e.getPacket().getProtocols().read(0);
if(p == PacketType.Protocol.STATUS || p == PacketType.Protocol.LEGACY){
return;
}
final int version = e.getPacket().getIntegers().readSafely(0);
//Delay the mapping to make sure the true address of the player was received when using bungeecord or other types of proxies
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), () ->
DefaultVersionHook.PROTOCOL_PER_ADDRESS.put(Version.stringifyAdress(e.getPlayer().getAddress()), version), 10L);
}
}
@@ -67,7 +67,6 @@ public class PacketContent {
return new ContentModifier<byte[]>(obj, byte[].class);
}
@SuppressWarnings("unchecked")
public ContentModifier<Object> getChatComponents() {
return (ContentModifier<Object>) getSpecificModifier(PacketUtils.COMPONENT_CLASS);
}
@@ -77,7 +76,6 @@ public class PacketContent {
private Object obj;
private HashMap<Field, T> content = new HashMap<>();
@SuppressWarnings("unchecked")
public ContentModifier(Object obj, Class<?> clazz) {
this.obj = obj;
@@ -105,6 +103,10 @@ public class PacketContent {
}
}
public Object getObj() {
return obj;
}
/**
* Get the size of the Map of content
*
@@ -189,11 +191,6 @@ public class PacketContent {
content.put(key, value);
try {
key.setAccessible(true);
/*if(Modifier.isFinal(key.getModifiers())) {
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(key, key.getModifiers() & ~Modifier.FINAL);
}*/
key.set(obj, value);
} catch (Exception e) {
e.printStackTrace();
@@ -22,4 +22,13 @@ public abstract class PacketManager {
public void notifyHandlersSent(ChatItemPacket packet) {
handlers.forEach((handler) -> handler.onSend(packet));
}
public ChatItemPacket onPacketSent(PacketType type, Player sender, Object packet) {
if(type == null) {
return null;
}
ChatItemPacket customPacket = new ChatItemPacket(type, packet, sender);
notifyHandlersSent(customPacket);
return customPacket;
}
}
@@ -1,8 +1,8 @@
package me.dadus33.chatitem.chatmanager.v1.packets.custom;
import java.util.HashMap;
import java.util.concurrent.CompletableFuture;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -10,9 +10,7 @@ import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketManager;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketType;
import me.dadus33.chatitem.chatmanager.v1.packets.custom.channel.ChannelAbstract;
import me.dadus33.chatitem.chatmanager.v1.packets.custom.channel.INC2Channel;
import me.dadus33.chatitem.chatmanager.v1.packets.custom.channel.INCChannel;
@@ -39,11 +37,11 @@ public class CustomPacketManager extends PacketManager implements Listener {
pl.getServer().getPluginManager().registerEvents(this, pl);
// we wait the start server
Bukkit.getScheduler().runTaskLater(pl, () -> {
CompletableFuture.runAsync(() -> {
isStarted = true;
for(Player p : Utils.getOnlinePlayers())
addPlayer(p);
}, 20);
});
}
public Plugin getPlugin() {
@@ -80,13 +78,4 @@ public class CustomPacketManager extends PacketManager implements Listener {
if(channel.getRemoveChannelExecutor() != null)
channel.getRemoveChannelExecutor().shutdownNow();
}
public ChatItemPacket onPacketSent(PacketType type, Player sender, Object packet) {
if(type == null) {
return null;
}
ChatItemPacket customPacket = new ChatItemPacket(type, packet, sender);
notifyHandlersSent(customPacket);
return customPacket;
}
}
@@ -78,7 +78,7 @@ public class ChannelInboundHandler extends ChannelInboundHandlerAdapter {
int possibleProtocol = ints.readSafely(0, 0);
if(possibleProtocol == Bukkit.getPort())
possibleProtocol = ints.readSafely(1, 0);
if(possibleProtocol == -1 || possibleProtocol == 255)
if(possibleProtocol == -1 || possibleProtocol == 255 || possibleProtocol == Bukkit.getPort())
possibleProtocol = ints.readSafely(2, 0);
packetManager.protocolVersionPerChannel.put(channel, possibleProtocol);
}
@@ -26,7 +26,6 @@ public class INC2Channel extends ChannelAbstract {
private final ChannelInboundHandler boundHandler;
private ChannelPipeline pipeline;
@SuppressWarnings("unchecked")
public INC2Channel(CustomPacketManager customPacketManager) {
super(customPacketManager);
boundHandler = new ChannelInboundHandler(customPacketManager);
@@ -87,8 +86,9 @@ public class INC2Channel extends ChannelAbstract {
@Override
public Channel getChannel(Player p) throws Exception {
Object playerConnection = ReflectionUtils.getObject(getPlayerConnection(p), Version.getVersion().isNewerOrEquals(Version.V1_19) ? "b" : "a");
return ReflectionUtils.getFirstWith(playerConnection, playerConnection.getClass(), Channel.class);//(Channel) networkManager.getClass().getDeclaredField("channel").get(networkManager);
Object playerConnection = getPlayerConnection(p);
Object networkManager = ReflectionUtils.getFirstWith(playerConnection, PacketUtils.getNmsClass("NetworkManager", "network."));
return ReflectionUtils.getFirstWith(networkManager, Channel.class);
}
private class ChannelHandlerSent extends ChannelOutboundHandlerAdapter {
@@ -22,7 +22,6 @@ import me.dadus33.chatitem.chatmanager.v1.packets.custom.CustomPacketManager;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.ReflectionUtils;
@SuppressWarnings("unchecked")
public class INCChannel extends ChannelAbstract {
private final ChannelInboundHandler boundHandler;
@@ -36,7 +36,6 @@ public class NMUChannel extends ChannelAbstract {
Object dedicatedSrv = PacketUtils.getCraftServer();
Object mcServer = dedicatedSrv.getClass().getMethod("getServer").invoke(dedicatedSrv);
Object co = ReflectionUtils.getFirstWith(mcServer, PacketUtils.getNmsClass("MinecraftServer", "server."), PacketUtils.getNmsClass("ServerConnection", "network."));
@SuppressWarnings("unchecked")
List<ChannelFuture> g = (List<ChannelFuture>) ReflectionUtils.getObject(co, "g", "e");
g.forEach((channelFuture) -> {
pipeline = channelFuture.channel().pipeline();
@@ -13,7 +13,6 @@ import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.v1.listeners.HandshakeListener;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketManager;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketType;
@@ -46,19 +45,10 @@ public class ProtocollibPacketManager extends PacketManager {
e.setCancelled(packet.isCancelled());
}
});
protocolManager.addPacketListener(new HandshakeListener(pl));
}
@Override
public void stop() {
protocolManager.removePacketListeners(ChatItem.getInstance());
}
public ChatItemPacket onPacketSent(PacketType type, Player sender, Object packet) {
if(type == null)
return null;
ChatItemPacket customPacket = new ChatItemPacket(type, packet, sender);
notifyHandlersSent(customPacket);
return customPacket;
}
}
@@ -1,12 +1,7 @@
package me.dadus33.chatitem.chatmanager.v2;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@@ -14,61 +9,21 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.inventory.ItemStack;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.ItemPlayer;
import me.dadus33.chatitem.ItemSlot;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.chatmanager.Chat;
import me.dadus33.chatitem.chatmanager.ChatAction;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.hook.DiscordSrvSupport;
import me.dadus33.chatitem.playernamer.PlayerNamerManager;
import me.dadus33.chatitem.utils.ColorManager;
import me.dadus33.chatitem.utils.ItemUtils;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.ReflectionUtils;
import me.dadus33.chatitem.utils.Storage;
import me.dadus33.chatitem.utils.Utils;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.HoverEvent.Action;
import net.md_5.bungee.api.chat.TextComponent;
@SuppressWarnings("deprecation")
public class ChatListener implements Listener {
private static Method saveMethod;
private static boolean shouldUseAppendMethod = false;
static {
try {
Class<?> nbtTag = PacketUtils.getNmsClass("NBTTagCompound", "nbt.");
Class<?> itemClass = PacketUtils.getNmsClass("ItemStack", "world.item.");
for (Method m : itemClass.getDeclaredMethods()) {
if (m.getParameterTypes().length == 1) {
if (m.getParameterTypes()[0].equals(nbtTag) && m.getReturnType().equals(nbtTag)) {
saveMethod = m;
}
}
}
try {
ComponentBuilder.class.getDeclaredMethod("append", BaseComponent[].class);
shouldUseAppendMethod = true;
} catch (Exception e) {
shouldUseAppendMethod = false;
}
} catch (Exception e) {
}
Logger log = ChatItem.getInstance().getLogger();
String appendMethodMsg = shouldUseAppendMethod ? "Use ComponentBuilder's method."
: "Use own ComponentBuilder append method.";
if (saveMethod == null)
log.info("Failed to find save method. Using default system. " + appendMethodMsg);
else
log.info("Save method founded: " + saveMethod.getName() + ". " + appendMethodMsg);
}
private ChatListenerChatManager manage;
public ChatListener(ChatListenerChatManager manage) {
@@ -79,17 +34,22 @@ public class ChatListener implements Listener {
return manage.getStorage();
}
@EventHandler(priority = EventPriority.MONITOR)
@EventHandler(priority = EventPriority.HIGH)
public void onChat(AsyncPlayerChatEvent e) {
if(ChatManager.isTestingEnabled() && !ChatManager.isTesting("chat"))
return;
if(!ChatManager.isSelected("chat"))
return;
Storage c = getStorage();
if (e.isCancelled()) {
if (ChatItem.getInstance().getChatManager().size() == 1) { // only chat
String msg = e.getMessage().toLowerCase();
for (String rep : c.PLACEHOLDERS) {
if (msg.contains(rep)) {
ChatItem.debug(
"You choose 'chat' manager but it seems to don't be the good choice. More informations here: https://github.com/dadus33-plugins/ChatItem/wiki");
return;
for(ItemSlot slot : ItemSlot.values()) {
for (String rep : slot.getPlaceholders()) {
if (msg.contains(rep)) {
ChatItem.debug("You choose 'chat' manager but it seems to don't be the good choice. More informations here: https://github.com/dadus33-plugins/ChatItem/wiki");
return;
}
}
}
}
@@ -97,268 +57,46 @@ public class ChatListener implements Listener {
return;
}
Player p = e.getPlayer();
boolean hasv1 = false;
String placeholder = null;
for (String rep : c.PLACEHOLDERS) {
// v1 try to manage it, but the message have not been changed by another plugin
if (e.getMessage().contains(rep + ChatManager.SEPARATOR + p.getName())) {
hasv1 = true;
ChatItem.debug("Found v1 placeholders in v2");
placeholder = rep;
break;
}
if (e.getMessage().contains(rep)) {
placeholder = rep;
break;
String targetReplace = ChatManager.SEPARATOR + "";
if(ChatManager.containsSeparator(e.getMessage())) { // fix for v1
Chat chat = Chat.getFrom(e.getMessage());
if(chat != null) {
targetReplace = ChatManager.SEPARATOR + "" + chat.getId() + ChatManager.SEPARATOR_END;
e.setMessage(ChatManager.replaceSeparator(chat, e.getMessage(), chat.getSlot().getPlaceholders().get(0)));
}
}
if (placeholder == null) { // if not found
ItemSlot slot = ItemSlot.getItemSlotFromMessage(e.getMessage());
if (slot == null) { // if not found
ChatItem.debug("(v2) Can't found placeholder in: " + e.getMessage() + " > " + PlayerNamerManager.getPlayerNamer().getName(p));
return;
}
ItemStack item = ChatManager.getUsableItem(p);
if(!ChatManager.canShowItem(p, item, e))
ChatAction action = ChatManager.getChatAction(slot, p);
if(!ChatManager.canUsePlaceholder(p, action, slot, e))
return;
e.setCancelled(true);
String format = e.getFormat();
String msg, defMsg = e.getMessage();
for (String rep : c.PLACEHOLDERS) {
if (hasv1) // remove v1 char
defMsg = defMsg.replace(rep + ChatManager.SEPARATOR + p.getName(), String.valueOf(ChatManager.SEPARATOR));
else
defMsg = defMsg.replace(rep, String.valueOf(ChatManager.SEPARATOR));
}
if (Utils.countMatches(defMsg, String.valueOf(ChatManager.SEPARATOR)) > getStorage().LIMIT) {
e.setCancelled(true);
if (getStorage().LIMIT_MESSAGE.isEmpty()) {
return;
}
p.sendMessage(getStorage().LIMIT_MESSAGE);
String format = e.getFormat().replace(targetReplace, slot.getPlaceholders().get(0));
ChatItem.debug("(v2) Using format: " + format + " and message: " + e.getMessage());
String defMsg = slot.replacePlaceholdersToSeparator(e.getMessage());
if (Utils.countMatches(defMsg, Character.toString(ChatManager.SEPARATOR)) > c.limit) {
if (!c.messageLimit.isEmpty())
p.sendMessage(c.messageLimit);
return;
}
String msg;
if (format.contains("%1$s") || format.contains("%2$s")) {
msg = (format.contains("%2$s") ? String.format(format, p.getDisplayName(), defMsg)
: String.format(format, p.getDisplayName()));
msg = (format.contains("%2$s") ? String.format(format, p.getDisplayName(), defMsg) : String.format(format, p.getDisplayName()));
} else {
msg = format.replace(e.getMessage(), defMsg);
}
String itemName = ChatManager.getNameOfItem(p, item, c);
String loggedMessage = msg.replace(ChatManager.SEPARATOR + "", itemName).replace("{name}", p.getName())
.replace("{display-name}", p.getDisplayName());
String itemName = ChatManager.getNameForChatAction(p, action, c);
String loggedMessage = msg.replace(ChatManager.SEPARATOR + "", itemName);
Bukkit.getConsoleSender().sendMessage(loggedMessage); // show in log
if (ChatItem.discordSrvSupport)
DiscordSrvSupport.sendChatMessage(p, defMsg.replace(ChatManager.SEPARATOR + "", itemName).replace("{name}", p.getName())
.replace("{display-name}", p.getDisplayName()));
ChatItem.debug("Msg: " + msg.replace(ChatColor.COLOR_CHAR, '&') + ", format: " + format);
e.getRecipients().forEach((pl) -> showItem(pl, p, item, msg));
if (c.COOLDOWN > 0 && !p.hasPermission("chatitem.ignore-cooldown"))
DiscordSrvSupport.sendChatMessage(p, defMsg.replace(ChatManager.SEPARATOR + "", itemName), e);
Set<Player> recipients = e.getRecipients().isEmpty() ? new HashSet<>(Bukkit.getOnlinePlayers()) : e.getRecipients();
ChatItem.debug("(v2) Msg: " + ChatItem.replace(p, msg).replace(ChatColor.COLOR_CHAR, '&') + ", format: " + format + " to " + recipients.size() + " players");
recipients.forEach((pl) -> ChatItem.getPlatform().sendMessage(pl, p, action, ChatItem.replace(p, msg)));
if (c.cooldown > 0 && !p.hasPermission("chatitem.ignore-cooldown"))
ChatManager.applyCooldown(p);
}
public static void showItem(Player to, Player origin, ItemStack item, String msg) {
ComponentBuilder builder = new ComponentBuilder("");
ChatColor color = ChatColor.WHITE;
String colorCode = "", text = "";
boolean waiting = false;
for (char args : msg.toCharArray()) {
if (args == '§') { // begin of color
if (colorCode.isEmpty() && !text.isEmpty()) { // text before this char
ChatItem.debug("Append " + text);
appendToComponentBuilder(builder, new ComponentBuilder(text).color(color).create());
text = "";
}
waiting = true; // waiting for color code
} else if (waiting) { // if waiting for code and valid str
// if it's hexademical value and with enough space for full color
waiting = false;
if(args == 'r' && colorCode.isEmpty()) {
color = ChatColor.RESET;
continue;
}
if(args == 'x' && !colorCode.isEmpty()) {
text += ColorManager.getColorString(colorCode);
colorCode = "x";
} else
colorCode += args; // a color by itself
} else {
waiting = false;
if(!colorCode.isEmpty()) {
if(colorCode.startsWith("x") && colorCode.length() >= 7) {
if(colorCode.length() == 7)
color = ColorManager.getColor(colorCode);
else {
color = ColorManager.getColor(colorCode.substring(0, 7)); // only the hex code
ChatItem.debug("Adding color for " + colorCode.substring(7, colorCode.length()) + " (in " + colorCode + ")");
text += ColorManager.getColorString(colorCode.substring(7, colorCode.length()));
}
} else if(colorCode.length() == 1) // if only one color code
color = ColorManager.getColor(colorCode);
else
text += ColorManager.getColorString(colorCode);
colorCode = "";
}
if (args == ChatManager.SEPARATOR) {
// here put the item
appendToComponentBuilder(builder, fixColorComponent(text, color));
addItem(builder, to, origin, item);
text = "";
} else {
// basic text, not waiting for code after '§'
text += args;
}
}
}
if(!text.isEmpty())
appendToComponentBuilder(builder, new ComponentBuilder(text).color(color).create());
to.spigot().sendMessage(builder.create());
}
/**
* Converts an {@link org.bukkit.inventory.ItemStack} to a Json string for
* sending with {@link net.md_5.bungee.api.chat.BaseComponent}'s.
*
* @param itemStack the item to convert
* @return the Json string representation of the item
*/
public static String convertItemStackToJson(ItemStack itemStack) {
try {
Class<?> nbtTag = PacketUtils.getNmsClass("NBTTagCompound", "nbt.");
Class<?> craftItemClass = PacketUtils.getObcClass("inventory.CraftItemStack");
Object nmsNbtTagCompoundObj = nbtTag.getConstructor().newInstance();
if (saveMethod == null) {
Object nmsItemStackObj = craftItemClass.getMethod("asNMSCopy", ItemStack.class).invoke(null, itemStack);
return nmsItemStackObj.getClass().getMethod("save", nbtTag)
.invoke(nmsItemStackObj, nmsNbtTagCompoundObj).toString();
} else {
Object nmsItemStackObj = craftItemClass.getMethod("asNMSCopy", ItemStack.class).invoke(null, itemStack);
return saveMethod.invoke(nmsItemStackObj, nmsNbtTagCompoundObj).toString();
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void addItem(ComponentBuilder builder, Player to, Player origin, ItemStack item) {
Storage c = ChatItem.getInstance().getStorage();
if (!ItemUtils.isEmpty(item)) {
ComponentBuilder itemComponent = new ComponentBuilder("");
String itemJson = convertItemStackToJson(item);
BaseComponent[] itemBaseComponent = new ComponentBuilder(itemJson).create();
appendToComponentBuilder(itemComponent, fixColorComponent(ChatManager.getNameOfItem(to, item, c), ChatColor.WHITE, itemBaseComponent));
ChatItem.debug("Item for " + to.getName() + " (ver: " + ItemPlayer.getPlayer(to).getVersion().name() + ") : " + itemJson);
//itemComponent.event(new HoverEvent(Action.SHOW_ITEM, itemBaseComponent));
appendToComponentBuilder(builder, itemComponent.create());
} else {
String handName = c.HAND_NAME;
ComponentBuilder handComp = new ComponentBuilder("");
ComponentBuilder handTooltip = new ComponentBuilder("");
int stay = c.HAND_TOOLTIP.size();
for (String line : c.HAND_TOOLTIP) {
stay--;
handTooltip.append(ColorManager.fixColor(line.replace("{name}", origin.getName()).replace("{display-name}", origin.getDisplayName())));
if (stay > 0)
handTooltip.append("\n");
}
handComp.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, handTooltip.create()));
if (handName.contains("{display-name}")) {
String[] splitted = handName.split("\\{display-name\\}");
for (int i = 0; i < (splitted.length - 1); i++) {
handComp.append(splitted[i]);
appendToComponentBuilder(handComp, PlayerNamerManager.getPlayerNamer().getName(origin));
}
handComp.append(splitted[splitted.length - 1]);
} else
handComp.append(handName.replace("{name}", origin.getName()));
appendToComponentBuilder(builder, handComp.create());
}
}
@SuppressWarnings("unchecked")
public static void appendToComponentBuilder(ComponentBuilder builder, BaseComponent[] comps) {
if (shouldUseAppendMethod) {
try {
builder.append(comps);
} catch (Exception e) {
ChatItem.getInstance().getLogger().severe(
"This should NEVER append. The ComponentBuilder#append(BaseComponent[]) was found but it's NOT. Using own next time.");
shouldUseAppendMethod = false;
}
} else {
try {
Field currentField = ReflectionUtils.getField(builder, "current");
List<BaseComponent> parts = (List<BaseComponent>) ReflectionUtils.getObject(builder, "parts");
parts.add(new TextComponent((TextComponent) currentField.get(builder)));
parts.addAll(Arrays.asList(comps));
currentField.set(builder, new TextComponent(""));
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static BaseComponent[] fixColorComponent(String message, ChatColor color) {
return fixColorComponent(message, color, null);
}
public static BaseComponent[] fixColorComponent(String message, ChatColor color, @Nullable BaseComponent[] jsonItem) {
ComponentBuilder builder = new ComponentBuilder("");
String colorCode = "", text = "";
boolean waiting = false;
for (char args : message.toCharArray()) {
if (args == '§') { // begin of color
if (colorCode.isEmpty() && !text.isEmpty()) { // text before this char
ChatItem.debug("Append while fixing name " + (ColorManager.isHexColor(color) && builder.getParts().isEmpty() ? ColorManager.removeColorAtBegin(text) : text));
ComponentBuilder littleBuilder = new ComponentBuilder(ColorManager.isHexColor(color) ? ColorManager.removeColorAtBegin(text) : text).color(color);
if(jsonItem != null) { // add to all possible sub parts
littleBuilder.event(new HoverEvent(Action.SHOW_ITEM, jsonItem));
}
appendToComponentBuilder(builder, littleBuilder.create());
text = "";
}
waiting = true; // waiting for color code
} else if (waiting) { // if waiting for code and valid str
// if it's hexademical value and with enough space for full color
waiting = false;
if(args == 'r' && colorCode.isEmpty()) {
color = ChatColor.RESET;
continue;
}
if(args == 'x' && !colorCode.isEmpty()) {
text += ColorManager.getColorString(colorCode);
colorCode = "x";
} else
colorCode += args; // a color by itself
} else {
waiting = false;
if(!colorCode.isEmpty()) {
if(colorCode.startsWith("x") && colorCode.length() >= 7) {
if(colorCode.length() == 7)
color = ColorManager.getColor(colorCode);
else {
color = ColorManager.getColor(colorCode.substring(0, 7)); // only the hex code
ChatItem.debug("Adding color for " + colorCode.substring(7, colorCode.length()) + " (in " + colorCode + ")");
text += ColorManager.getColorString(colorCode.substring(7, colorCode.length()));
}
} else if(colorCode.length() == 1) // if only one color code
color = ColorManager.getColor(colorCode);
else
text += ColorManager.getColorString(colorCode);
ChatItem.debug("Color: " + color + ", text: " + text + ", code: " + colorCode);
colorCode = "";
}
// basic text, not waiting for code after '§'
text += args;
}
}
if(!text.isEmpty()) {
ComponentBuilder littleBuilder = new ComponentBuilder(text).color(color);
if(jsonItem != null) { // add to all possible sub parts
littleBuilder.event(new HoverEvent(Action.SHOW_ITEM, jsonItem));
}
appendToComponentBuilder(builder, littleBuilder.create());
}
return builder.create();
}
}
@@ -4,8 +4,8 @@ import org.bukkit.Bukkit;
import org.bukkit.event.HandlerList;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.utils.Storage;
public class ChatListenerChatManager extends ChatManager {
@@ -0,0 +1,40 @@
package me.dadus33.chatitem.chatmanager.v3;
import org.bukkit.Bukkit;
import org.bukkit.event.HandlerList;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.chatmanager.ChatManager;
public class PaperChatManager extends ChatManager {
private PaperListener paperListener;
public PaperChatManager(ChatItem pl) {
paperListener = new PaperListener(this);
}
@Override
public String getName() {
return "Paper";
}
@Override
public String getId() {
return "paper";
}
@Override
public void load(ChatItem pl, Storage s) {
super.load(pl, s);
Bukkit.getPluginManager().registerEvents(paperListener, pl);
}
@Override
public void unload(ChatItem pl) {
HandlerList.unregisterAll(paperListener);
}
}
@@ -0,0 +1,96 @@
package me.dadus33.chatitem.chatmanager.v3;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import io.papermc.paper.event.player.AsyncChatEvent;
import me.dadus33.chatitem.C;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.ItemSlot;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.chatmanager.Chat;
import me.dadus33.chatitem.chatmanager.ChatAction;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.utils.Messages;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.event.HoverEventSource;
public class PaperListener implements Listener {
private PaperChatManager manage;
public PaperListener(PaperChatManager manage) {
this.manage = manage;
}
public Storage getStorage() {
return manage.getStorage();
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onChat(AsyncChatEvent e) {
if (ChatManager.isTestingEnabled() && !ChatManager.isTesting("paper"))
return;
if (!ChatManager.isSelected("paper"))
return;
Player p = e.getPlayer();
Component message = e.message();
String rawMessage = C.string(message);
if (ChatManager.containsSeparator(rawMessage)) { // fix for v1
Chat chat = Chat.getFrom(rawMessage);
if (chat != null) {
message = message.replaceText(TextReplacementConfig.builder().matchLiteral(ChatManager.SEPARATOR + "" + chat.getId() + ChatManager.SEPARATOR_END)
.replacement(C.text(chat.getSlot().getPlaceholders().get(0))).build());
rawMessage = C.string(message);
}
}
ItemSlot slot = ItemSlot.getItemSlotFromMessage(rawMessage);
ChatItem.debug("(v3) Raw message: " + rawMessage + ", slot: " + slot);
if (slot == null) // if not found
return;
ChatAction action = ChatManager.getChatAction(slot, p);
if (!ChatManager.canUsePlaceholder(p, action, slot, e))
return;
HoverEventSource<?> hoverEvent = null;
if(action.isItem()) {
if(!action.getItem().getType().equals(Material.AIR))
hoverEvent = action.getItem().asHoverEvent();
else {
Component t = null;
for(String line : Messages.getMessageList("general.hand.tooltip", "%cible%", p.getName())) {
if(t == null) {
t = Component.text("");
} else
t.append(Component.newline());
t.append(C.text(line));
}
hoverEvent = HoverEvent.showText(t);
}
} else
hoverEvent = HoverEvent.showText(C.text(Messages.getMessage(action.getSlot().name().toLowerCase() + ".hover", "%cible%", p.getName())));
TextComponent like = C.text(ChatManager.getNameForChatAction(p, action, getStorage())).hoverEvent(hoverEvent);
if (action.hasCommand())
like.clickEvent(ClickEvent.runCommand(action.getCommand()));
for (String s : slot.getPlaceholders())
message = message.replaceText(TextReplacementConfig.builder().matchLiteral(s).replacement(like).build());
if (ChatItem.getInstance().getConfig().getBoolean("manager-config.paper.send-ourself", false)) {
for (Audience a : e.viewers().isEmpty() ? Bukkit.getOnlinePlayers() : e.viewers())
a.sendMessage(e.renderer().render(p, p.displayName(), message, a));
e.setCancelled(true);
} else
e.message(message);
ChatItem.debug("Changed message to " + C.string(message));
if (getStorage().cooldown > 0 && !p.hasPermission("chatitem.ignore-cooldown"))
ChatManager.applyCooldown(p);
}
}
@@ -0,0 +1,26 @@
package me.dadus33.chatitem.chatmanager.v4;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import io.papermc.paper.event.player.AsyncChatEvent;
import me.dadus33.chatitem.chatmanager.ChatManager;
public class OwnListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void onChat(AsyncChatEvent e) {
if (ChatManager.isTestingEnabled() && !ChatManager.isTesting("ownformatter"))
return;
if (!ChatManager.isSelected("ownformatter"))
return;
if (e.isCancelled())
return;
e.setCancelled(true);
/*Player p = e.getPlayer();
Component msg = e.message();*/
}
}
@@ -0,0 +1,22 @@
package me.dadus33.chatitem.chatmanager.v4;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.ChatManager;
public class OwnManager extends ChatManager {
@Override
public String getName() {
return "Own Formatter";
}
@Override
public String getId() {
return "ownformatter";
}
@Override
public void unload(ChatItem pl) {
}
}
@@ -15,19 +15,30 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.ItemSlot;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.chatmanager.ChatAction;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.chatmanager.v2.ChatListener;
import me.dadus33.chatitem.invsee.InvShower;
import me.dadus33.chatitem.listeners.InventoryListener;
import me.dadus33.chatitem.utils.Colors;
import me.dadus33.chatitem.utils.Messages;
import me.dadus33.chatitem.utils.Storage;
import me.dadus33.chatitem.utils.Utils;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.hover.content.Text;
@SuppressWarnings("deprecation")
public class ChatItemCommand implements CommandExecutor, TabExecutor {
private static final List<String> ORDERS;
static {
if(Utils.IS_PAPER)
ORDERS = Arrays.asList("chat", "paper", "packet", "all");
else
ORDERS = Arrays.asList("chat", "packet", "all");
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (!(sender instanceof Player)) {
@@ -37,29 +48,29 @@ public class ChatItemCommand implements CommandExecutor, TabExecutor {
Player p = (Player) sender;
if (args.length == 0) {
Messages.sendMessage(p, "chatitem-cmd.help");
} else if (args[0].equalsIgnoreCase("admin")) {
} else if (args[0].equalsIgnoreCase("admin") && p.hasPermission("chatitem.reload")) {
InventoryListener.open(p);
} else if (args[0].equalsIgnoreCase("reload")) {
} else if (args[0].equalsIgnoreCase("reload") && p.hasPermission("chatitem.reload")) {
ChatItem.reload(sender);
} else if (args[0].equalsIgnoreCase("show")) {
} else if (args[0].equalsIgnoreCase("show") && ChatItem.getInstance().getStorage().cmdShow) {
Player cible = args.length == 1 ? p : Bukkit.getPlayer(args[1]);
if(cible == null) {
Messages.sendMessage(p, "player-not-found", "%arg%", args[1]);
return false;
}
Storage c = ChatItem.getInstance().getStorage();
ItemStack item = ChatManager.getUsableItem(cible);
ChatListener.showItem(p, cible, item, c.COMMAND_FORMAT.replace("%name%", cible.getName()).replace("%item%", ChatManager.SEPARATOR + ""));
} else if (args[0].equalsIgnoreCase("broadcast")) {
ItemStack item = ChatManager.getUsableItem(cible, ItemSlot.HAND);
ChatItem.getPlatform().sendMessage(p, cible, new ChatAction(ItemSlot.HAND, cible, item), c.commandFormat.replace("%name%", cible.getName()).replace("%item%", ChatManager.SEPARATOR + ""));
} else if (args[0].equalsIgnoreCase("broadcast") && ChatItem.getInstance().getStorage().cmdBroadcast) {
Player cible = args.length == 1 ? p : Bukkit.getPlayer(args[1]);
if(cible == null) {
Messages.sendMessage(p, "player-not-found", "%arg%", args[1]);
return false;
}
Storage c = ChatItem.getInstance().getStorage();
ItemStack item = ChatManager.getUsableItem(cible);
ItemStack item = ChatManager.getUsableItem(cible, ItemSlot.HAND);
for(Player all : Bukkit.getOnlinePlayers())
ChatListener.showItem(all, cible, item, c.COMMAND_FORMAT.replace("%name%", cible.getName()).replace("%item%", ChatManager.SEPARATOR + ""));
ChatItem.getPlatform().sendMessage(all, cible, new ChatAction(ItemSlot.HAND, cible, item), c.commandFormat.replace("%name%", cible.getName()).replace("%item%", ChatManager.SEPARATOR + ""));
} else if (args[0].equalsIgnoreCase("link") || args[0].equalsIgnoreCase("links")) {
ConfigurationSection config = ChatItem.getInstance().getConfig()
.getConfigurationSection("messages.chatitem-cmd.links");
@@ -69,27 +80,100 @@ public class ChatItemCommand implements CommandExecutor, TabExecutor {
TextComponent linkComp = new TextComponent(Storage.color(linkConfig.getString("message")));
String hover = Storage.color(linkConfig.getString("hover"));
if (hover != null)
linkComp.setHoverEvent(
new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new ComponentBuilder(hover).create())));
linkComp.setHoverEvent(Utils.createTextHover(hover));
String link = linkConfig.getString("link");
if (link != null)
linkComp.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, link));
text.addExtra(linkComp);
}
p.spigot().sendMessage(text);
} else if (args[0].equalsIgnoreCase("select") && p.hasPermission("chatitem.reload")) {
if(args.length == 1) {
p.sendMessage(Colors.GRAY + "----------" + Colors.GOLD + " ChatItem - Setup " + Colors.GRAY + "----------");
p.sendMessage(Colors.AQUA + "Welcome in the help of setup." + Colors.YELLOW + " Please follow step by simply answer to test.");
sendCheckSelectMessage(p, ORDERS.get(0));
} else {
String tested = args[1];
if(!ORDERS.contains(tested)) {
p.sendMessage(Colors.RED + "Unknow test for " + tested + ".");
return false;
}
if(args.length == 2) {
p.sendMessage(Colors.RED + "Can't find if it works");
return false;
}
if(args[2].equalsIgnoreCase("yes")) {
ChatManager.setTesting(null);
InventoryListener.setInConfig("manager", tested);
p.sendMessage(Colors.GREEN + "Perfect ! Updating config ...");
ChatItem.reload(p);
} else if(args[2].equalsIgnoreCase("no")) {
int index = ORDERS.indexOf(tested);
if(ORDERS.size() == (index + 1)) {
p.sendMessage(Colors.RED + "Sad. Sorry but nothing is available. I suggest you to come on discord for more help. Do '/chatitem link' for all links.");
ChatManager.setTesting(null);
} else {
p.sendMessage(Colors.RED + "Sad. Checking for next manager ...");
sendCheckSelectMessage(p, ORDERS.get(index + 1));
}
} else {
p.sendMessage(Colors.RED + "Can't find if it works");
}
}
} else if (args[0].equalsIgnoreCase("seeinv")) {
if(args.length == 2 && Utils.isUUID(args[1])) {
InvShower inv = InvShower.get(args[1]);
if(inv == null) {
Messages.sendMessage(p, "seeinv_not_found");
} else {
inv.open(p);
}
} // else just ignore
} else {
Messages.sendMessage(p, "chatitem-cmd.help");
}
return false;
}
private void sendCheckSelectMessage(Player p, String testing) {
ChatManager.setTesting(testing);
p.chat("Checking for " + testing + ": [i]");
Bukkit.getScheduler().runTaskLater(ChatItem.getInstance(), () -> {
TextComponent text = new TextComponent(Colors.GOLD + "Did it worked fine? ");
TextComponent agree = new TextComponent(Colors.GREEN + "Yes");
agree.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/chatitem select " + testing + " yes"));
agree.setHoverEvent(Utils.createTextHover(Colors.GRAY + "Click to say it worked fine"));
text.addExtra(agree);
text.addExtra(" ");
TextComponent decline = new TextComponent(Colors.RED + "No");
decline.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/chatitem select " + testing + " no"));
decline.setHoverEvent(Utils.createTextHover(Colors.GRAY + "Click to say it's not working as expected"));
text.addExtra(decline);
if(testing.equalsIgnoreCase("packet"))
text.addExtra(" (This manager can have different result between 'chatitem select' and default chat for technical reasons. If nothing works, it's recommended to select it and try again)");
p.spigot().sendMessage(text);
}, 2);
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] arg) {
List<String> list = new ArrayList<>();
String prefix = arg[arg.length - 1].toLowerCase(Locale.ROOT);
for (String s : Arrays.asList("help", "admin", "reload", "link", "show", "broadcast"))
if (prefix.isEmpty() || s.startsWith(prefix))
list.add(s);
return list.isEmpty() ? null : list;
if(arg.length <= 2) {
if(sender.hasPermission("chatitem.reload")) {
for (String s : Arrays.asList("admin", "reload", "select"))
if (prefix.isEmpty() || s.startsWith(prefix))
list.add(s);
}
if (ChatItem.getInstance().getStorage().cmdShow && (prefix.isEmpty() || "show".startsWith(prefix)))
list.add("show");
if (ChatItem.getInstance().getStorage().cmdBroadcast && (prefix.isEmpty() || "broadcast".startsWith(prefix)))
list.add("broadcast");
for (String s : Arrays.asList("help", "link"))
if (prefix.isEmpty() || s.startsWith(prefix))
list.add(s);
}
return list;
}
}
@@ -1,81 +0,0 @@
package me.dadus33.chatitem.filters;
import static org.apache.logging.log4j.core.Filter.Result.NEUTRAL;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.message.Message;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.utils.Storage;
public class Log4jFilter implements Filter {
private Storage c;
public Log4jFilter(Storage st) {
c = st;
((Logger) LogManager.getRootLogger()).addFilter(this);
}
@Override
public Result getOnMismatch() {
return NEUTRAL;
}
@Override
public Result getOnMatch() {
return NEUTRAL;
}
@Override
public Result filter(Logger logger, Level level, Marker marker, String s, Object... objects) {
return checkMessage(s);
}
@Override
public Result filter(Logger logger, Level level, Marker marker, Object o, Throwable throwable) {
return checkMessage(((Message) o).getFormattedMessage());
}
@Override
public Result filter(Logger logger, Level level, Marker marker, Message message, Throwable throwable) {
return checkMessage(message.getFormattedMessage());
}
@Override
public Result filter(LogEvent logEvent) {
return checkMessage(logEvent.getMessage().getFormattedMessage());
}
public void stop() {
// seems to be required
}
private Result checkMessage(String msg) {
if (msg == null) {
return Result.NEUTRAL;
}
for (String placeholder : c.PLACEHOLDERS) {
if (msg.contains(placeholder)) {
for (Player p : Bukkit.getOnlinePlayers()) {
if (msg.contains(ChatManager.SEPARATOR + p.getName())) {
return Result.DENY;
}
}
}
}
return Result.NEUTRAL;
}
public void setStorage(Storage nst) {
this.c = nst;
}
}
@@ -0,0 +1,18 @@
package me.dadus33.chatitem.hook;
import me.dadus33.chatitem.ChatItem;
public class ChatControlSupport {
public static void init(ChatItem pl) {
try {
Class<?> clz = Class.forName("org.mineacademy.chatcontrol.settings.Settings$Chat$Grammar");
clz.getField("CAPITALIZE").setBoolean(null, false);
clz.getField("INSERT_DOT").setBoolean(null, false);
pl.getLogger().info("Loaded ChatControl support by disabling 2 options in 'Chat.Grammar' config.");
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,16 @@
package me.dadus33.chatitem.hook;
import java.util.List;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.h1dd3nxn1nja.chatmanager.Main;
public class ChatManagerSupport {
public static void init(ChatItem pl) {
List<String> whitelist = Main.settings.getConfig().getStringList("Anti_Unicode.Whitelist");
whitelist.add(ChatManager.SEPARATOR_STR);
whitelist.add(ChatManager.SEPARATOR_END_STR);
}
}
@@ -1,16 +1,26 @@
package me.dadus33.chatitem.hook;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import github.scarsz.discordsrv.DiscordSRV;
import me.dadus33.chatitem.ChatItem;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
public class DiscordSrvSupport {
public static boolean isSendingMessage() {
return ChatItem.getInstance().getStorage().discordSrvSendMsg;
}
public static void sendChatMessage(Player p, String message) {
public static void sendChatMessage(Player p, String message, Event e) {
DiscordSRV pl = DiscordSRV.getPlugin();
if (DiscordSRV.config().getBooleanElse("UseModernPaperChatEvent", false) && pl.isModernChatEventAvailable()) {
return;
}
pl.processChatMessage(p, message, pl.getOptionalChannel("global"), false);
pl.processChatMessage(p, message, pl.getOptionalChannel("global"), false, e);
}
public static void sendChatMessage(Player p, Component message, Event e) {
DiscordSRV pl = DiscordSRV.getPlugin();
pl.processChatMessage(p, github.scarsz.discordsrv.dependencies.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson().deserialize(GsonComponentSerializer.gson().serialize(message)), pl.getOptionalChannel("global"), false, e);
}
}
@@ -0,0 +1,57 @@
package me.dadus33.chatitem.hook.ecoenchants;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import me.dadus33.chatitem.ChatItem;
public class EcoEnchantsSupport {
private static int supportedVersion = 0;
public static boolean hasSupport() {
return supportedVersion > 0;
}
public static boolean load() {
String ver = ChatItem.getPlatform().getPluginVersion(Bukkit.getPluginManager().getPlugin("EcoEnchants"));
if(ver.startsWith("8."))
supportedVersion = 8;
else if(ver.startsWith("10."))
supportedVersion = 10;
else if(ver.startsWith("11."))
supportedVersion = 11;
else if(ver.startsWith("12."))
supportedVersion = 12;
else {
ChatItem.getInstance().getLogger().warning("Failed to find support version for EcoEnchants " + ver);
return false;
}
return true;
}
@SuppressWarnings("deprecation")
public static ItemStack manageItem(ItemStack item) {
if(supportedVersion == 8) {
List<String> addLore = EcoEnchantsV8Support.getLores(item);
if (!addLore.isEmpty()) {
ItemMeta meta = item.getItemMeta();
List<String> lores = meta.hasLore() ? meta.getLore() : new ArrayList<>();
for (int i = 0; i < addLore.size(); i++)
lores.add(i, addLore.get(i));
meta.setLore(lores);
item.setItemMeta(meta);
ChatItem.debug("Added " + addLore.size() + " lores from EcoEnchants");
} else
ChatItem.debug("No lore to add from EcoEnchants");
} else if(supportedVersion >= 10) {
EcoEnchantsV10Support.display(item);
}
return item;
}
}
@@ -0,0 +1,35 @@
package me.dadus33.chatitem.hook.ecoenchants;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.willfp.eco.core.display.DisplayProperties;
import com.willfp.ecoenchants.EcoEnchantsPlugin;
import com.willfp.ecoenchants.display.EnchantDisplay;
public class EcoEnchantsV10Support {
private static EnchantDisplay enchantDisplay;
public static EnchantDisplay getEnchantDisplay() {
if (enchantDisplay == null) {
try {
enchantDisplay = EnchantDisplay.class.getConstructor(EcoEnchantsPlugin.class).newInstance(Bukkit.getPluginManager().getPlugin("EcoEnchants"));
} catch (Exception e) {
e.printStackTrace();
}
}
return enchantDisplay;
}
public static void display(ItemStack item) {
try {
DisplayProperties display = DisplayProperties.class.getDeclaredConstructor(boolean.class, boolean.class, ItemStack.class).newInstance(false, false, item);
getEnchantDisplay().display(item, (Player) null, display, new Object[] { false });
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -1,4 +1,4 @@
package me.dadus33.chatitem.hook;
package me.dadus33.chatitem.hook.ecoenchants;
import java.util.ArrayList;
import java.util.List;
@@ -8,7 +8,7 @@ import org.bukkit.inventory.ItemStack;
import com.willfp.ecoenchants.display.EnchantmentCache;
import com.willfp.ecoenchants.enchantments.util.EnchantChecks;
public class EcoEnchantsSupport {
public class EcoEnchantsV8Support {
public static List<String> getLores(ItemStack item) {
List<String> lores = new ArrayList<>();
@@ -17,5 +17,5 @@ public class EcoEnchantsSupport {
});
return lores;
}
}
}
@@ -0,0 +1,40 @@
package me.dadus33.chatitem.hook.placeholders;
import java.util.Locale;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.Team;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.FormatUtil;
public class EssentialsPlaceholdersHook implements IPlaceholders {
private Essentials getEssentials() {
return ((Essentials) Bukkit.getPluginManager().getPlugin("Essentials"));
}
@SuppressWarnings("deprecation")
@Override
public String replace(Player p, String text) {
User user = getEssentials().getUser(p);
if (user == null) {
return null;
}
String world = user.getWorld().getName();
String username = user.getName();
String nickname = user.getFormattedNickname();
Player player = user.getBase();
Team team = player.getScoreboard().getPlayerTeam(player);
return text.replace("{GROUP}", user.getGroup()).replace("{WORLD}", getEssentials().getSettings().getWorldAlias(world)).replace("{WORLDNAME}", world)
.replace("{SHORTWORLDNAME}", world.substring(0, 1).toUpperCase(Locale.ENGLISH)).replace("{TEAMNAME}", team == null ? "" : team.getDisplayName())
.replace("{TEAMPREFIX}", team == null ? "" : team.getPrefix()).replace("{TEAMSUFFIX}", team == null ? "" : team.getSuffix())
.replace("{PREFIX}", FormatUtil.replaceFormat(getEssentials().getPermissionsHandler().getPrefix(player)))
.replace("{SUFFIX}", FormatUtil.replaceFormat(getEssentials().getPermissionsHandler().getSuffix(player))).replace("{USERNAME}", username)
.replace("{NICKNAME}", nickname == null ? username : nickname);
}
}
@@ -0,0 +1,9 @@
package me.dadus33.chatitem.hook.placeholders;
import org.bukkit.entity.Player;
public interface IPlaceholders {
String replace(Player p, String text);
}
@@ -0,0 +1,13 @@
package me.dadus33.chatitem.hook.placeholders;
import org.bukkit.entity.Player;
import be.maximvdw.placeholderapi.PlaceholderAPI;
public class MVdWPlaceholderAPIHook implements IPlaceholders {
@Override
public String replace(Player p, String text) {
return PlaceholderAPI.replacePlaceholders(p, text);
}
}
@@ -0,0 +1,12 @@
package me.dadus33.chatitem.hook.placeholders;
import org.bukkit.entity.Player;
public class OwnPlaceholder implements IPlaceholders {
@Override
public String replace(Player p, String text) {
return text.replace("{name}", p.getName()).replace("%name%", p.getName());
}
}
@@ -0,0 +1,14 @@
package me.dadus33.chatitem.hook.placeholders;
import org.bukkit.entity.Player;
import me.clip.placeholderapi.PlaceholderAPI;
public class PlaceholderAPIHook implements IPlaceholders {
@Override
public String replace(Player p, String text) {
return PlaceholderAPI.setPlaceholders(p, text);
}
}
@@ -0,0 +1,30 @@
package me.dadus33.chatitem.hook.placeholders;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.RegisteredServiceProvider;
import net.milkbowl.vault.chat.Chat;
public class VaultPlaceholderHook implements IPlaceholders {
private Chat chat = null;
public Chat getChat() {
if (chat == null) {
RegisteredServiceProvider<Chat> rs = Bukkit.getServicesManager().getRegistration(Chat.class);
if (rs != null) // chat well setup
chat = rs.getProvider();
}
return chat;
}
@Override
public String replace(Player p, String text) {
Chat chat = getChat();
if (chat == null)
return text;
return text.replace("{prefix}", chat.getPlayerPrefix(p)).replace("{suffix}", chat.getPlayerSuffix(p)).replace("%prefix%", chat.getPlayerPrefix(p)).replace("%suffix%", chat.getPlayerSuffix(p));
}
}
@@ -0,0 +1,57 @@
package me.dadus33.chatitem.invsee;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import me.dadus33.chatitem.ChatItem;
public abstract class InvShower {
private static final HashMap<String, InvShower> INV_SHOWER = new HashMap<>();
public static InvShower get(String s) {
return INV_SHOWER.get(s);
}
public static void add(String s, InvShower shower) {
INV_SHOWER.put(s, shower);
}
public static HashMap<String, InvShower> getInvShower() {
return INV_SHOWER;
}
static {
Bukkit.getScheduler().runTaskTimer(ChatItem.getInstance(), () -> {
for(Entry<String, InvShower> entries : new HashMap<>(INV_SHOWER).entrySet())
if(entries.getValue().hasExpired())
INV_SHOWER.remove(entries.getKey());
}, 200, 200);
}
protected final long time;
protected final UUID uuid;
protected final String name;
public InvShower(String id, Player cible) {
this.time = System.currentTimeMillis() + ChatItem.getInstance().getConfig().getInt("general.other-placeholders." + id + ".time-expire", 1800) * 1000;
this.uuid = cible.getUniqueId();
this.name = cible.getName();
}
public UUID getUuid() {
return uuid;
}
public long getTimeExpire() {
return time;
}
public boolean hasExpired() {
return System.currentTimeMillis() > time || Bukkit.getPlayer(uuid) == null || !Bukkit.getPlayer(uuid).isOnline();
}
public abstract void open(Player p);
}
@@ -0,0 +1,36 @@
package me.dadus33.chatitem.invsee.hook;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.invsee.InvShower;
import me.dadus33.chatitem.listeners.holder.CustomInventoryHolder;
import me.dadus33.chatitem.utils.ItemUtils;
import me.dadus33.chatitem.utils.Messages;
public class EnderChestShower extends InvShower {
private final ItemStack[] items;
public EnderChestShower(Player cible) {
super("enderchest", cible);
Inventory ec = cible.getEnderChest();
ItemStack[] tmp = ec.getContents();
items = new ItemStack[tmp.length];
for(int i = 0; i < ec.getSize(); i++)
items[i] = ItemUtils.copyIfExist(tmp[i]);
}
@Override
public void open(Player p) {
Inventory inv = ChatItem.getPlatform().createInventory(new CustomInventoryHolder(), items.length, Messages.getMessage("enderchest.name", "%cible%", name));
for(int i = 0; i < items.length; i++)
inv.setItem(i, items[i]);
p.openInventory(inv);
}
}
@@ -0,0 +1,49 @@
package me.dadus33.chatitem.invsee.hook;
import java.util.HashMap;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.invsee.InvShower;
import me.dadus33.chatitem.listeners.holder.CustomInventoryHolder;
import me.dadus33.chatitem.utils.ItemUtils;
import me.dadus33.chatitem.utils.Messages;
public class PlayerInventoryShower extends InvShower {
private final HashMap<Integer, ItemStack> items = new HashMap<>();
private final int level;
public PlayerInventoryShower(Player cible) {
super("inventory", cible);
this.level = cible.getLevel();
PlayerInventory pi = cible.getInventory();
items.put(4, ItemUtils.copyIfExist(pi.getHelmet()));
items.put(5, ItemUtils.copyIfExist(pi.getChestplate()));
items.put(6, ItemUtils.copyIfExist(pi.getLeggings()));
items.put(7, ItemUtils.copyIfExist(pi.getBoots()));
for(int i = 0; i < pi.getContents().length && i < (54 - 18); i++)
items.put(i + 18, ItemUtils.copyIfExist(pi.getContents()[i]));
}
@Override
public void open(Player p) {
Inventory inv = ChatItem.getPlatform().createInventory(new CustomInventoryHolder(), 54, Messages.getMessage("inventory.name", "%cible%", name));
for(int i = 0; i < 18; i++)
inv.setItem(i, ItemUtils.ITEM_EMPTY_BROWN);
inv.setItem(2, new ItemStack(ItemUtils.getMaterialWithCompatibility("EXPERIENCE_BOTTLE", "EXP_BOTTLE"), level == 0 ? 1 : (level >= 64 ? 64 : level)));
items.forEach(inv::setItem);
p.openInventory(inv);
}
}
@@ -7,7 +7,7 @@ import java.util.stream.Collectors;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import me.dadus33.chatitem.utils.Storage;
import me.dadus33.chatitem.Storage;
public interface INamer {
@@ -30,7 +30,7 @@ public interface INamer {
*/
String getName(Player p, ItemStack item, Storage storage);
enum Priority {
public enum Priority {
MAJOR(4),
IMPORTANT(3),
MEDIUM(2),
@@ -11,12 +11,12 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.PluginManager;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.itemnamer.INamer.Priority;
import me.dadus33.chatitem.itemnamer.hook.ChatItemTranslationNamer;
import me.dadus33.chatitem.itemnamer.hook.DefaultNamer;
import me.dadus33.chatitem.itemnamer.hook.ItemDisplayNamer;
import me.dadus33.chatitem.itemnamer.hook.LangUtilsNamer;
import me.dadus33.chatitem.utils.Storage;
public class NamerManager {
@@ -45,8 +45,7 @@ public class NamerManager {
* @param namer the namer to add
*/
public static void addNamer(INamer namer) {
List<INamer> namers = getOrCreate(namer.getPriority());
namers.add(namer);
getOrCreate(namer.getPriority()).add(namer);
}
private static List<INamer> getOrCreate(Priority p){
@@ -68,8 +67,10 @@ public class NamerManager {
continue;
for(INamer namer : allNamers) {
String tmpName = namer.getName(p, item, storage);
if(tmpName != null)
if(tmpName != null) {
ChatItem.debug("Using namer " + namer.getClass().getSimpleName() + ", value: " + tmpName);
return tmpName;
}
}
}
return null; // this should NEVER append
@@ -1,29 +1,22 @@
package me.dadus33.chatitem.itemnamer.hook;
import java.util.HashMap;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.Translation;
import me.dadus33.chatitem.itemnamer.INamer;
import me.dadus33.chatitem.utils.Storage;
public class ChatItemTranslationNamer implements INamer {
@Override
public Priority getPriority() {
return Priority.SMALL;
return Priority.MINOR;
}
@Override
public String getName(Player p, ItemStack item, Storage storage) {
HashMap<Short, String> translationSection = storage.TRANSLATIONS.get(item.getType().name());
if (translationSection != null) {
@SuppressWarnings("deprecation")
String translated = translationSection.get(item.getDurability());
return translated;
}
return null;
return Translation.getOr(item, null);
}
}
@@ -5,14 +5,14 @@ import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.itemnamer.INamer;
import me.dadus33.chatitem.utils.Storage;
public class DefaultNamer implements INamer {
@Override
public Priority getPriority() {
return Priority.MINOR;
return Priority.SMALL;
}
@Override
@@ -4,9 +4,11 @@ import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.itemnamer.INamer;
import me.dadus33.chatitem.utils.Storage;
@SuppressWarnings("deprecation")
public class ItemDisplayNamer implements INamer {
@Override
@@ -16,10 +18,9 @@ public class ItemDisplayNamer implements INamer {
@Override
public String getName(Player p, ItemStack item, Storage storage) {
if(item.hasItemMeta() && item.getItemMeta().hasDisplayName()) {
String name = item.getItemMeta().getDisplayName();
return storage.COLOR_IF_ALREADY_COLORED ? ChatColor.stripColor(name) : name;
}
String name = ChatItem.getPlatform().getItemDisplayName(item);
if(name != null && name != "")
return storage.colorIfColored ? ChatColor.stripColor(name) : name;
return null;
}
@@ -5,8 +5,8 @@ import org.bukkit.inventory.ItemStack;
import com.meowj.langutils.lang.LanguageHelper;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.itemnamer.INamer;
import me.dadus33.chatitem.utils.Storage;
public class LangUtilsNamer implements INamer {
@@ -1,17 +0,0 @@
package me.dadus33.chatitem.listeners;
import java.util.HashMap;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
public class ChatItemAdminHolder implements InventoryHolder {
public final HashMap<Integer, String> keyBySlot = new HashMap<>();
@Override
public Inventory getInventory() {
return null;
}
}
@@ -1,10 +1,7 @@
package me.dadus33.chatitem.listeners;
import static me.dadus33.chatitem.utils.ItemUtils.createItem;
import java.util.Arrays;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -12,110 +9,146 @@ import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.Translation;
import me.dadus33.chatitem.listeners.holder.AdminHolder;
import me.dadus33.chatitem.listeners.holder.ChatItemHolder;
import me.dadus33.chatitem.listeners.holder.CustomInventoryHolder;
import me.dadus33.chatitem.utils.ItemUtils;
import me.dadus33.chatitem.utils.Messages;
import me.dadus33.chatitem.utils.Storage;
import me.dadus33.chatitem.utils.Utils;
public class InventoryListener implements Listener {
@EventHandler
public void onClick(InventoryClickEvent e) {
if(e.getClickedInventory() == null || !(e.getWhoClicked() instanceof Player) || e.getCurrentItem() == null
|| !(e.getClickedInventory().getHolder() instanceof ChatItemAdminHolder))
if (!(e.getWhoClicked() instanceof Player))
return;
Player p = (Player) e.getWhoClicked();
InventoryHolder openInventoryHolder = null;
try {
openInventoryHolder = p.getOpenInventory().getTopInventory().getHolder();
} catch(java.lang.IncompatibleClassChangeError exc) {} // ignore this
if (openInventoryHolder != null && openInventoryHolder instanceof CustomInventoryHolder) {
e.setCancelled(true);
return;
}
if (e.getClickedInventory() == null)
return;
InventoryHolder holder = e.getClickedInventory().getHolder();
if (holder == null || !(holder instanceof ChatItemHolder)) {
if (e.getClick().equals(ClickType.DOUBLE_CLICK) && p.getOpenInventory() != null && p.getOpenInventory().getTopInventory() != null) {
Inventory top = p.getOpenInventory().getTopInventory();
if (top.getHolder() != null && top.getHolder() instanceof ChatItemHolder) {
e.setCancelled(true);
}
}
return;
}
if (holder instanceof CustomInventoryHolder) {
e.setCancelled(true);
return;
}
if (!(holder instanceof AdminHolder))
return;
e.setCancelled(true);
Player p = (Player) e.getWhoClicked();
if (e.getCurrentItem() == null)
return;
ItemStack item = e.getCurrentItem();
Material type = item.getType();
Storage c = ChatItem.getInstance().getStorage();
if(type.equals(ItemUtils.MATERIAL_CLOSE)) {
if (type.equals(ItemUtils.MATERIAL_CLOSE)) {
p.closeInventory();
} else if(type.equals(Material.PAPER)) {
ChatItemAdminHolder holder = (ChatItemAdminHolder) e.getClickedInventory().getHolder();
String key = holder.keyBySlot.get(e.getSlot());
if(key != null) {
} else if (type.equals(Material.BOOK)) {
TranslationInventoryListener.open(p, 0);
} else if (type.equals(Material.PAPER)) {
String key = ((AdminHolder) holder).keyBySlot.get(e.getSlot());
if (key != null) {
setInConfig("manager", key);
p.closeInventory();
ChatItem.reload(p);
}
} else if(type.equals(ItemUtils.INK_SAC)) {
setInConfig("general.color-if-already-colored", c.COLOR_IF_ALREADY_COLORED = !c.COLOR_IF_ALREADY_COLORED);
} else if (type.equals(ItemUtils.INK_SAC)) {
setInConfig("general.color-if-already-colored", c.colorIfColored = !c.colorIfColored);
open(p);
} else if(type.equals(Material.REDSTONE)) {
setInConfig("general.deny-if-no-item", c.DENY_IF_NO_ITEM = !c.DENY_IF_NO_ITEM);
} else if (type.equals(Material.STICK)) {
setInConfig("general.hand.disabled", c.handDisabled = !c.handDisabled);
open(p);
} else if(type.equals(Material.STICK)) {
setInConfig("general.hand.disabled", c.HAND_DISABLED = !c.HAND_DISABLED);
} else if (type.equals(Material.BLAZE_ROD)) {
setInConfig("general.check-update", c.checkUpdate = !c.checkUpdate);
open(p);
} else if(type.equals(Material.BOOK)) {
setInConfig("general.check-update", c.CHECK_UPDATE = !c.CHECK_UPDATE);
} else if (type.equals(ItemUtils.FIREWORK_CHARGE)) {
setInConfig("debug", c.debug = !c.debug);
open(p);
} else if(type.equals(ItemUtils.FIREWORK_CHARGE)) {
setInConfig("debug", c.DEBUG = !c.DEBUG);
} else if (type.equals(Material.IRON_DOOR)) {
if (e.getClick().equals(ClickType.RIGHT))
c.limit--;
else if (e.getClick().equals(ClickType.LEFT))
c.limit++;
setInConfig("general.limit-per-message", c.limit);
open(p);
} else if(type.equals(Material.IRON_DOOR)) {
if(e.getClick().equals(ClickType.RIGHT))
c.LIMIT--;
else if(e.getClick().equals(ClickType.LEFT))
c.LIMIT++;
setInConfig("general.limit-per-message", c.LIMIT);
open(p);
} else if(type.equals(Material.APPLE)) {
if(e.getClick().equals(ClickType.RIGHT))
c.COOLDOWN--;
else if(e.getClick().equals(ClickType.LEFT))
c.COOLDOWN++;
setInConfig("general.cooldown", c.COOLDOWN);
} else if (type.equals(Material.APPLE)) {
if (e.getClick().equals(ClickType.RIGHT))
c.cooldown--;
else if (e.getClick().equals(ClickType.LEFT))
c.cooldown++;
setInConfig("general.cooldown", c.cooldown);
open(p);
}
}
private void setInConfig(String key, Object val) {
public static void setInConfig(String key, Object val) {
ChatItem pl = ChatItem.getInstance();
pl.getConfig().set(key, val);
pl.saveConfig();
}
public static void open(Player p) {
ChatItemAdminHolder holder = new ChatItemAdminHolder();
AdminHolder holder = new AdminHolder();
Storage c = ChatItem.getInstance().getStorage();
Inventory inv = Bukkit.createInventory(holder, 27, Messages.getMessage("admin-inv.name"));
for(int i = 0; i < inv.getSize(); i ++)
inv.setItem(i, createItem(ItemUtils.WHITE_STAINED_GLASS, "-"));
Inventory inv = ChatItem.getPlatform().createInventory(holder, 27, Messages.getMessage("admin-inv.name"));
for (int i = 0; i < inv.getSize(); i++)
inv.setItem(i, ChatItem.getPlatform().createItemStack(ItemUtils.WHITE_STAINED_GLASS, "-"));
int slot = 0;
for(String manager : Arrays.asList("both", "auto", "packet", "chat")) {
for (String manager : Arrays.asList("all", "packet", "chat", "paper")) { //, "ownformatter")) {
if ((manager == "paper" || manager == "ownformatter") && !Utils.IS_PAPER)
continue;
holder.keyBySlot.put(slot, manager);
inv.setItem(slot++, getManagerItem(manager));
}
inv.setItem(slot + 1, getManagerItem("actual", "%manager%", Messages.getMessage("admin-inv.manager." + c.MANAGER + ".name")));
inv.setItem(8, getBoolChangeItem(ItemUtils.FIREWORK_CHARGE, "debug", c.DEBUG));
inv.setItem(slot + 1, getManagerItem("actual", "%manager%", Messages.getMessage("admin-inv.manager." + c.manager + ".name")));
inv.setItem(18, getBoolChangeItem(ItemUtils.INK_SAC, "color-if-already-colored", c.COLOR_IF_ALREADY_COLORED));
inv.setItem(19, getBoolChangeItem(Material.REDSTONE, "deny-no-item", c.DENY_IF_NO_ITEM));
inv.setItem(20, getBoolChangeItem(Material.STICK, "hand-disabled", c.HAND_DISABLED));
inv.setItem(21, getAmountChangeItem(Material.IRON_DOOR, "limit-per-message", c.LIMIT));
inv.setItem(22, getAmountChangeItem(Material.APPLE, "cooldown", c.COOLDOWN));
inv.setItem(23, getBoolChangeItem(Material.BOOK, "check-update", c.CHECK_UPDATE));
inv.setItem(26, createItem(ItemUtils.MATERIAL_CLOSE, Messages.getMessage("admin-inv.close")));
inv.setItem(8, getBoolChangeItem(ItemUtils.FIREWORK_CHARGE, "debug", c.debug));
inv.setItem(18, getBoolChangeItem(ItemUtils.INK_SAC, "color-if-already-colored", c.colorIfColored));
inv.setItem(20, getBoolChangeItem(Material.STICK, "hand-disabled", c.handDisabled));
inv.setItem(21, getAmountChangeItem(Material.IRON_DOOR, "limit-per-message", c.limit));
inv.setItem(22, getAmountChangeItem(Material.APPLE, "cooldown", c.cooldown));
inv.setItem(23, getBoolChangeItem(Material.BLAZE_ROD, "check-update", c.checkUpdate));
inv.setItem(24, ChatItem.getPlatform().createTranslatedItemStack(Material.BOOK, "admin-inv.language", "%name%", Translation.getMessage("language.name")));
inv.setItem(26, ChatItem.getPlatform().createItemStack(ItemUtils.MATERIAL_CLOSE, Messages.getMessage("admin-inv.close")));
p.openInventory(inv);
}
private static ItemStack getBoolChangeItem(Material type, String key, boolean b) {
return createItem(type, Messages.getMessage("admin-inv." + key, "%state%", Messages.getMessage(b ? "enabled" : "disabled")), Messages.getMessageList("admin-inv.bool-lore"));
return ChatItem.getPlatform().createItemStack(type, Messages.getMessage("admin-inv." + key, "%state%", Messages.getMessage(b ? "enabled" : "disabled")),
Messages.getMessageList("admin-inv.bool-lore"));
}
private static ItemStack getAmountChangeItem(Material type, String key, int amount) {
return createItem(type, Messages.getMessage("admin-inv." + key, "%state%", amount), Messages.getMessageList("admin-inv.amount-lore"));
return ChatItem.getPlatform().createItemStack(type, Messages.getMessage("admin-inv." + key, "%state%", amount), Messages.getMessageList("admin-inv.amount-lore"));
}
private static ItemStack getManagerItem(String manager, Object... placeholders) {
return createItem(Material.PAPER, Messages.getMessage("admin-inv.manager." + manager + ".name", placeholders),
Messages.getMessageList("admin-inv.manager." + manager + ".lore", placeholders));
return ChatItem.getPlatform().createTranslatedItemStack(Material.PAPER, "admin-inv.manager." + manager, placeholders);
}
}
@@ -8,14 +8,13 @@ import org.bukkit.event.player.PlayerQuitEvent;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.utils.Utils;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.hover.content.Text;
public class JoinListener implements Listener {
@SuppressWarnings("deprecation")
@EventHandler
public void onJoin(PlayerJoinEvent e) {
Player p = e.getPlayer();
@@ -23,8 +22,8 @@ public class JoinListener implements Listener {
return;
ChatItem pl = ChatItem.getInstance();
if(pl.isHasNewVersion()) {
TextComponent text = new TextComponent(pl.getStorage().JOIN_UPDATE_MESSAGE);
text.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new ComponentBuilder(pl.getStorage().JOIN_UPDATE_HOVER).create())));
TextComponent text = new TextComponent(pl.getStorage().updateMessage);
text.setHoverEvent(Utils.createTextHover(pl.getStorage().updateHover));
text.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.spigotmc.org/resources/19064/"));
p.spigot().sendMessage(text);
}
@@ -0,0 +1,91 @@
package me.dadus33.chatitem.listeners;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.Translation;
import me.dadus33.chatitem.listeners.holder.TranslationHolder;
import me.dadus33.chatitem.utils.Colors;
import me.dadus33.chatitem.utils.ItemUtils;
import me.dadus33.chatitem.utils.Messages;
public class TranslationInventoryListener implements Listener {
@EventHandler
public void onClick(InventoryClickEvent e) {
if(e.getClickedInventory() == null || !(e.getWhoClicked() instanceof Player) || e.getCurrentItem() == null
|| !(e.getClickedInventory().getHolder() instanceof TranslationHolder))
return;
e.setCancelled(true);
Player p = (Player) e.getWhoClicked();
ItemStack item = e.getCurrentItem();
Material type = item.getType();
TranslationHolder holder = (TranslationHolder) e.getClickedInventory().getHolder();
if(type.equals(Material.ARROW)) {
if(e.getSlot() == 0)
InventoryListener.open(p);
else if(e.getSlot() == 3)
open(p, holder.getPage() - 1);
else if(e.getSlot() == 5)
open(p, holder.getPage() + 1);
} else if(type.equals(ItemUtils.MATERIAL_CLOSE))
p.closeInventory();
else if(type.equals(Material.PAPER)) {
String lang = holder.langBySlot.get(e.getSlot());
if(lang == null)
return;
p.closeInventory();
ChatItem pl = ChatItem.getInstance();
pl.getStorage().language = lang;
pl.getConfig().set("general.language", lang);
pl.saveConfig();
Translation.loadLang(lang);
p.sendMessage(Colors.GREEN + "Language changed to " + Translation.getMessages().get("language.name").getAsString());
}
}
public static void open(Player p, int page) {
int perPage = 45;
List<String> langs = new ArrayList<>(Translation.getAllLangs().keySet());
TranslationHolder holder = new TranslationHolder(page);
Inventory inv = ChatItem.getPlatform().createInventory(holder, 54, "Change language - " + Colors.GOLD + " Page " + (page + 1) + " / " + ((langs.size() / perPage) + 1));
for(int i = 0; i < 9; i ++)
inv.setItem(i, new ItemStack(ItemUtils.GRAY_STAINED_GLASS_PANE));
inv.setItem(0, ChatItem.getPlatform().createItemStack(Material.ARROW, Colors.GRAY + "Back"));
if(page > 0)
inv.setItem(3, ChatItem.getPlatform().createItemStack(Material.ARROW, Colors.RED + "Previous page"));
if(langs.size() > (perPage * (page + 1)))
inv.setItem(5, ChatItem.getPlatform().createItemStack(Material.ARROW, Colors.GREEN + "Next page"));
inv.setItem(8, ChatItem.getPlatform().createItemStack(ItemUtils.MATERIAL_CLOSE, Messages.getMessage("admin-inv.close")));
int slot = 9;
for(int i = (page * perPage); i < langs.size() && (i < ((page + 1) * perPage)); i++) {
String lang = langs.get(i);
holder.langBySlot.put(slot, lang);
ItemStack item = ChatItem.getPlatform().createItemStack(Material.PAPER, Colors.GOLD + Translation.getAllLangs().get(lang), Colors.GRAY + "Clic to select this language");
if(lang.equalsIgnoreCase(ChatItem.getInstance().getStorage().language)) {
item.addUnsafeEnchantment(ItemUtils.getEnchant("DURABILITY", "UNBREAKING"), 1);
ItemMeta meta = item.getItemMeta();
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
item.setItemMeta(meta);
}
inv.setItem(slot++, item);
}
p.openInventory(inv);
}
}
@@ -0,0 +1,9 @@
package me.dadus33.chatitem.listeners.holder;
import java.util.HashMap;
public class AdminHolder extends ChatItemHolder {
public final HashMap<Integer, String> keyBySlot = new HashMap<>();
}
@@ -0,0 +1,12 @@
package me.dadus33.chatitem.listeners.holder;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
public abstract class ChatItemHolder implements InventoryHolder {
@Override
public Inventory getInventory() {
return null;
}
}
@@ -0,0 +1,5 @@
package me.dadus33.chatitem.listeners.holder;
public class CustomInventoryHolder extends ChatItemHolder {
}
@@ -0,0 +1,17 @@
package me.dadus33.chatitem.listeners.holder;
import java.util.HashMap;
public class TranslationHolder extends ChatItemHolder {
public final HashMap<Integer, String> langBySlot = new HashMap<>();
private final int page;
public TranslationHolder(int page) {
this.page = page;
}
public int getPage() {
return page;
}
}
@@ -0,0 +1,52 @@
package me.dadus33.chatitem.platform;
import java.util.Arrays;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import me.dadus33.chatitem.chatmanager.ChatAction;
import me.dadus33.chatitem.utils.Messages;
import me.dadus33.chatitem.utils.Version;
public interface IPlatform {
String getName();
Inventory createInventory(InventoryHolder holder, int slot, String name);
ItemStack createItemStack(Material type, String name);
default ItemStack createTranslatedItemStack(Material type, String key, Object... placeholders) {
return createItemStack(type, Messages.getMessage(key + ".name", placeholders), Messages.getMessageList(key + ".lore", placeholders));
}
default ItemStack createItemStack(Material type, String name, String... lore) {
return createItemStack(type, name, Arrays.asList(lore));
}
ItemStack createItemStack(Material type, String name, List<String> lore);
String getItemDisplayName(ItemStack item);
String getPluginVersion(Plugin plugin);
Version getMinecraftVersion();
String getNMSVersion();
boolean hasBaseComponentSerializer();
String baseComponentToJson(Object obj);
Object jsonToBaseComponent(String json);
void sendMessage(Player to, Player origin, ChatAction action, String msg);
String stringifyItem(ItemStack item);
}
@@ -0,0 +1,180 @@
package me.dadus33.chatitem.platform.hook;
import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.Plugin;
import me.dadus33.chatitem.C;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.ChatAction;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.platform.IPlatform;
import me.dadus33.chatitem.utils.Messages;
import me.dadus33.chatitem.utils.ReflectionUtils;
import me.dadus33.chatitem.utils.Version;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.event.HoverEvent.ShowItem;
import net.kyori.adventure.text.event.HoverEventSource;
import net.kyori.adventure.text.format.NamedTextColor;
public class PaperPlatform implements IPlatform {
@Override
public String getName() {
return "PaperMC";
}
@Override
public Inventory createInventory(InventoryHolder holder, int slot, String name) {
return Bukkit.createInventory(holder, slot, C.text(name));
}
@Override
public ItemStack createItemStack(Material type, String name) {
ItemStack item = new ItemStack(type);
ItemMeta meta = (ItemMeta) item.getItemMeta();
meta.displayName(C.text(name).color(NamedTextColor.WHITE));
item.setItemMeta(meta);
return item;
}
@Override
public ItemStack createItemStack(Material type, String name, List<String> lore) {
ItemStack item = new ItemStack(type);
ItemMeta meta = (ItemMeta) item.getItemMeta();
meta.displayName(C.text(name).color(NamedTextColor.WHITE));
meta.lore(lore.stream().map(C::text).collect(Collectors.toList()));
item.setItemMeta(meta);
return item;
}
@SuppressWarnings("deprecation")
@Override
public String getItemDisplayName(ItemStack item) {
// actually the get Displayname for better ... See:
// https://github.com/KyoriPowered/adventure-platform/issues/185
// return
// LegacyComponentSerializer.legacySection().serialize(item.displayName());
return item.hasItemMeta() && item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName() : null;
}
@Override
public String getPluginVersion(Plugin plugin) {
return plugin.getPluginMeta().getVersion();
}
@Override
public Version getMinecraftVersion() {
return Version.getVersionByName("v" + Bukkit.getMinecraftVersion().replace(".", "_"));
}
@Override
public String getNMSVersion() {
String[] parts = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",");
return parts.length <= 3 ? "" : parts[3];
}
@Override
public boolean hasBaseComponentSerializer() {
return SpigotPlatform.getBaseComponentToJsonMethod() != null;
}
private Object getRegistry() throws Exception {
Class<?> serverClass = Class.forName("net.minecraft.server.MinecraftServer");
return serverClass.getDeclaredMethod("registryAccess").invoke(serverClass.getDeclaredMethod("getServer").invoke(null));
}
@Override
public String baseComponentToJson(Object obj) {
Method m = SpigotPlatform.getBaseComponentToJsonMethod();
if (m == null)
return null;
try {
Object[] args = new Object[m.getParameterCount()];
args[0] = obj;
if (args.length > 1 && ReflectionUtils.isClassExist("net.minecraft.core.HolderLookup$Provider")) {
Class<?> c = Class.forName("net.minecraft.core.HolderLookup$Provider");
if (m.getParameterTypes()[1].isAssignableFrom(c)) {
args[1] = getRegistry();
}
}
return (String) m.invoke(null, args);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public Object jsonToBaseComponent(String json) {
Method m = SpigotPlatform.getJsonToBaseComponentMethod();
try {
Object[] args = new Object[m.getParameterCount()];
args[0] = json;
if (args.length > 1 && ReflectionUtils.isClassExist("net.minecraft.core.HolderLookup$Provider")) {
Class<?> c = Class.forName("net.minecraft.core.HolderLookup$Provider");
if (m.getParameterTypes()[1].isAssignableFrom(c)) {
args[1] = getRegistry();
}
}
return m.invoke(null, args);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public void sendMessage(Player to, Player origin, ChatAction action, String msg) {
HoverEventSource<?> hoverEvent = null;
if (action.isItem()) {
if (!action.getItem().getType().equals(Material.AIR))
hoverEvent = action.getItem().asHoverEvent();
else {
Component t = null;
for (String line : Messages.getMessageList("general.hand.tooltip", "%cible%", origin.getName())) {
if (t == null) {
t = Component.text("");
} else
t.append(Component.newline());
t.append(C.text(line));
}
hoverEvent = HoverEvent.showText(t);
}
} else
hoverEvent = HoverEvent.showText(C.text(Messages.getMessage(action.getSlot().name().toLowerCase() + ".hover", "%cible%", origin.getName())));
TextComponent like = Component.text(ChatManager.getNameForChatAction(origin, action, ChatItem.getInstance().getStorage())).hoverEvent(hoverEvent);
if (action.hasCommand())
like = like.clickEvent(ClickEvent.runCommand(action.getCommand()));
to.sendMessage(C.text(msg).replaceText(TextReplacementConfig.builder().matchLiteral(ChatManager.SEPARATOR + "").replacement(like).build()));
}
@SuppressWarnings("deprecation")
@Override
public String stringifyItem(ItemStack item) {
ShowItem si = item.asHoverEvent().value();
String json = "{id:\"" + si.item().asString() + "\",count:" + item.getAmount();
if(si.nbt() != null) {
json += ",tag:{" + si.nbt().string() + "}";
} else if(Version.getVersion().isNewerOrEquals(Version.V1_20_6)) { // since MC 1.20.5 in fact
json += ",components:" + (item.hasItemMeta() ? item.getItemMeta().getAsString() : "{}");
}
json += "}";
ChatItem.debug("Item stringified: " + json);
return json;
}
}
@@ -0,0 +1,450 @@
package me.dadus33.chatitem.platform.hook;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.Plugin;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.ItemPlayer;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.chatmanager.ChatAction;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.chatmanager.v1.json.JSONManipulator;
import me.dadus33.chatitem.platform.IPlatform;
import me.dadus33.chatitem.playernamer.PlayerNamerManager;
import me.dadus33.chatitem.utils.ColorManager;
import me.dadus33.chatitem.utils.Colors;
import me.dadus33.chatitem.utils.ItemUtils;
import me.dadus33.chatitem.utils.Messages;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.ReflectionUtils;
import me.dadus33.chatitem.utils.Utils;
import me.dadus33.chatitem.utils.Version;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.TextComponent;
@SuppressWarnings("deprecation")
public class SpigotPlatform implements IPlatform {
private static boolean shouldUseAppendMethod = false;
static {
try {
try {
ComponentBuilder.class.getDeclaredMethod("append", BaseComponent[].class);
shouldUseAppendMethod = true;
} catch (Exception e) {
shouldUseAppendMethod = false;
}
ChatItem.getInstance().getLogger().info(shouldUseAppendMethod ? "Use ComponentBuilder's method." : "Use own ComponentBuilder append method.");
} catch (Exception e) {
}
}
@Override
public String getName() {
return "Spigot";
}
@Override
public Inventory createInventory(InventoryHolder holder, int slot, String name) {
return Bukkit.createInventory(holder, slot, name);
}
@Override
public ItemStack createItemStack(Material type, String name) {
ItemStack item = new ItemStack(type);
ItemMeta meta = (ItemMeta) item.getItemMeta();
meta.setDisplayName(Colors.RESET + name);
item.setItemMeta(meta);
return item;
}
@Override
public ItemStack createItemStack(Material type, String name, List<String> lore) {
ItemStack item = new ItemStack(type);
ItemMeta meta = (ItemMeta) item.getItemMeta();
meta.setDisplayName(Colors.RESET + name);
meta.setLore(lore);
item.setItemMeta(meta);
return item;
}
@Override
public String getItemDisplayName(ItemStack item) {
return item.hasItemMeta() && item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName() : null;
}
@Override
public String getPluginVersion(Plugin plugin) {
return plugin.getDescription().getVersion();
}
@Override
public Version getMinecraftVersion() {
return Version.getVersionByName(getNMSVersion().replace("_R4", "_6"));
}
@Override
public String getNMSVersion() {
return Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
}
@Override
public boolean hasBaseComponentSerializer() {
return getBaseComponentToJsonMethod() != null;
}
@Override
public String baseComponentToJson(Object obj) {
Method m = getBaseComponentToJsonMethod();
try {
Object[] args = new Object[m.getParameterCount()];
args[0] = obj;
if (args.length > 1 && ReflectionUtils.isClassExist("net.minecraft.core.HolderLookup$a")) {
Class<?> c = Class.forName("net.minecraft.core.HolderLookup$a");
if (m.getParameterTypes()[1].isAssignableFrom(c)) {
args[1] = getRegistry();
}
}
return (String) m.invoke(null, args);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public Object jsonToBaseComponent(String json) {
Method m = getJsonToBaseComponentMethod();
try {
Object[] args = new Object[m.getParameterCount()];
args[0] = json;
if (args.length > 1 && ReflectionUtils.isClassExist("net.minecraft.core.HolderLookup$a")) {
Class<?> c = Class.forName("net.minecraft.core.HolderLookup$a");
if (m.getParameterTypes()[1].isAssignableFrom(c)) {
args[1] = getRegistry();
}
}
return m.invoke(null, args);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private Object getRegistry() throws Exception {
Class<?> serverClass = Class.forName("net.minecraft.server.MinecraftServer");
return serverClass.getDeclaredMethod("ba").invoke(serverClass.getDeclaredMethod("getServer").invoke(null));
}
public static Method getBaseComponentToJsonMethod() {
Class<?> chatSerializerClass = PacketUtils.getNmsClass("IChatBaseComponent$ChatSerializer", "network.chat.", "ChatSerializer", "Component$Serializer");
Class<?> chatBaseComponentClass = PacketUtils.getNmsClass("IChatBaseComponent", "network.chat.", "Component");
if (chatSerializerClass == null || chatBaseComponentClass == null)
return null;
try {
for (Method m : chatSerializerClass.getDeclaredMethods()) {
if (m.getParameterTypes()[0].equals(chatBaseComponentClass) && m.getReturnType().equals(String.class)) {
return m;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Method getJsonToBaseComponentMethod() {
Class<?> chatSerializerClass = PacketUtils.getNmsClass("IChatBaseComponent$ChatSerializer", "network.chat.", "ChatSerializer", "Component$Serializer");
Class<?> chatBaseComponentClass = PacketUtils.getNmsClass("IChatBaseComponent", "network.chat.", "Component");
Class<?> chatMutableComponentClass = PacketUtils.getNmsClass("IChatMutableComponent", "network.chat.");
if (chatSerializerClass == null || chatBaseComponentClass == null)
return null;
try {
for (Method m : chatSerializerClass.getDeclaredMethods()) {
if (m.getParameterCount() == 0)
continue;
if (m.getParameterTypes()[0].equals(String.class)
&& (m.getReturnType().isAssignableFrom(chatBaseComponentClass) || (chatMutableComponentClass != null && m.getReturnType().equals(chatMutableComponentClass)))) {
m.setAccessible(true);
return m;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public void sendMessage(Player to, Player origin, ChatAction action, String msg) {
ComponentBuilder builder = new ComponentBuilder("");
ChatColor color = ChatColor.WHITE;
String colorCode = "", text = "";
boolean waiting = false, removing = false;
for (char args : msg.toCharArray()) {
if (args == '§') { // begin of color
if (colorCode.isEmpty() && !text.isEmpty()) { // text before this char
if (text.length() > 2 && text.startsWith("§") && text.substring(2) == ChatColor.stripColor(text) && color != null && color != ChatColor.WHITE) {
text = text.substring(2); // remove some code which should not be here
}
appendToComponentBuilder(builder, createComponent(to, text, color, action));
text = "";
}
waiting = true; // waiting for color code
} else if (waiting) { // if waiting for code and valid str
// if it's hexademical value and with enough space for full color
waiting = false;
if (args == 'r' && colorCode.isEmpty()) {
color = ChatColor.RESET;
continue;
} else if (args == 'x') {
if (!colorCode.isEmpty()) {
color = ColorManager.getColor(colorCode);
colorCode = ""; // clean for previous things
}
}
colorCode += args;
} else {
waiting = false;
if (!colorCode.isEmpty()) {
if (colorCode.startsWith("x") && colorCode.length() >= 7) {
if (colorCode.length() == 7)
color = ColorManager.getColor(colorCode);
else {
color = ColorManager.getColor(colorCode.substring(0, 7)); // only the hex code
text += ColorManager.getColorString(colorCode.substring(7, colorCode.length()));
}
} else if (colorCode.length() == 1) // if only one color code
color = ColorManager.getColor(colorCode);
else
text += ColorManager.getColorString(colorCode);
colorCode = "";
}
if (args == ChatManager.SEPARATOR) {
// here put the item
appendToComponentBuilder(builder, fixColorComponent(to, text, color, action));
if (action.isItem())
addItem(builder, to, origin, action.getItem(), action);
else
addCommand(builder, to, origin, action.getCommand(), action);
text = "";
if (ChatManager.containsSeparatorEnd(msg))
removing = true;
} else if (args == ChatManager.SEPARATOR_END) {
removing = false;
} else if (!removing) { // not removing content
// basic text, not waiting for code after '§'
text += args;
}
}
}
if (!text.isEmpty())
appendToComponentBuilder(builder, createComponent(to, text, color, action));
to.spigot().sendMessage(builder.create());
}
public static void addItem(ComponentBuilder builder, Player to, Player origin, ItemStack item, ChatAction action) {
Storage c = ChatItem.getInstance().getStorage();
if (!ItemUtils.isEmpty(item)) {
ComponentBuilder itemComponent = new ComponentBuilder("");
appendToComponentBuilder(itemComponent, fixColorComponent(to, ChatManager.getNameOfItem(origin, item, to, c), ChatColor.WHITE, action));
ChatItem.debug("Item for " + to.getName() + " (ver: " + ItemPlayer.getPlayer(to).getVersion().name() + ") : " + PacketUtils.getNbtTag(item));
// itemComponent.event(new HoverEvent(Action.SHOW_ITEM, itemBaseComponent));
appendToComponentBuilder(builder, itemComponent.create());
} else {
String handName = c.handName;
ComponentBuilder handComp = new ComponentBuilder("");
ComponentBuilder handTooltip = new ComponentBuilder("");
int stay = c.tooltipHand.size();
for (String line : c.tooltipHand) {
stay--;
handTooltip.append(ColorManager.fixColor(line.replace("{name}", origin.getName()).replace("{display-name}", origin.getDisplayName())));
if (stay > 0)
handTooltip.append("\n");
}
handComp.event(Utils.createTextHover(handTooltip.create()));
if (handName.contains("{display-name}")) {
String[] splitted = handName.split("\\{display-name\\}");
for (int i = 0; i < (splitted.length - 1); i++) {
handComp.append(splitted[i]);
appendToComponentBuilder(handComp, PlayerNamerManager.getPlayerNamer().getName(origin));
}
handComp.append(splitted[splitted.length - 1]);
} else
handComp.append(handName.replace("{name}", origin.getName()));
appendToComponentBuilder(builder, handComp.create());
}
}
public static void addCommand(ComponentBuilder builder, Player to, Player origin, String command, ChatAction action) {
ComponentBuilder itemComponent = new ComponentBuilder("");
appendToComponentBuilder(itemComponent, fixColorComponent(to, Messages.getMessage(action.getSlot().name().toLowerCase() + ".chat", "%cible%", origin.getName()), ChatColor.WHITE, action));
appendToComponentBuilder(builder, itemComponent.create());
}
public static void appendToComponentBuilder(ComponentBuilder builder, BaseComponent[] comps) {
if (shouldUseAppendMethod) {
try {
builder.append(comps);
} catch (Exception e) {
ChatItem.getInstance().getLogger().severe("This should NEVER append. The ComponentBuilder#append(BaseComponent[]) was found but it's NOT. Using own next time.");
shouldUseAppendMethod = false;
}
} else {
try {
Field currentField = ReflectionUtils.getField(builder, "current");
List<BaseComponent> parts = (List<BaseComponent>) ReflectionUtils.getObject(builder, "parts");
parts.add(new TextComponent((TextComponent) currentField.get(builder)));
parts.addAll(Arrays.asList(comps));
currentField.set(builder, new TextComponent(""));
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static BaseComponent[] fixColorComponent(Player to, String message, ChatColor color, ChatAction action) {
ComponentBuilder builder = new ComponentBuilder("");
String colorCode = "", text = "";
boolean waiting = false;
for (char args : message.toCharArray()) {
if (args == '§') { // begin of color
if (colorCode.isEmpty() && !text.isEmpty()) { // text before this char
ChatItem.debug("Append while fixing name " + (ColorManager.isHexColor(color) && builder.getParts().isEmpty() ? ColorManager.removeColorAtBegin(text) : text));
appendToComponentBuilder(builder, createComponent(to, ColorManager.isHexColor(color) ? ColorManager.removeColorAtBegin(text) : text, color, action));
text = "";
}
waiting = true; // waiting for color code
} else if (waiting) { // if waiting for code and valid str
// if it's hexademical value and with enough space for full color
waiting = false;
if (args == 'r' && colorCode.isEmpty()) {
color = ChatColor.RESET;
continue;
}
if (args == 'x' && !colorCode.isEmpty()) {
text += ColorManager.getColorString(colorCode);
colorCode = "x";
} else
colorCode += args; // a color by itself
} else {
waiting = false;
if (!colorCode.isEmpty()) {
if (colorCode.startsWith("x") && colorCode.length() >= 7) {
if (colorCode.length() == 7)
color = ColorManager.getColor(colorCode);
else {
color = ColorManager.getColor(colorCode.substring(0, 7)); // only the hex code
text += ColorManager.getColorString(colorCode.substring(7, colorCode.length()));
}
} else if (colorCode.length() == 1) // if only one color code
color = ColorManager.getColor(colorCode);
else
text += ColorManager.getColorString(colorCode);
colorCode = "";
}
// basic text, not waiting for code after '§'
text += args;
}
}
if (!text.isEmpty()) {
appendToComponentBuilder(builder, createComponent(to, text, color, action));
}
return builder.create();
}
private static BaseComponent[] createComponent(Player to, String text, ChatColor color, ChatAction action) {
ComponentBuilder littleBuilder = new ComponentBuilder(ChatItem.replace(action.getOrigin(), text));
if (color != null && !Colors.isFormatting(color)) // don't add reset thing
littleBuilder.color(color);
if (action.isItem()) {
if (action.getItem().getType().equals(Material.AIR))
littleBuilder.event(Utils.createTextHover(String.join("\n", ChatItem.getInstance().getStorage().tooltipHand)));
else
littleBuilder.event(Utils.createItemHover(action.getItem(), to));
} else {
littleBuilder.event(Utils.createTextHover(Messages.getMessage(action.getSlot().name().toLowerCase() + ".hover")));
if (action.hasCommand())
littleBuilder.event(Utils.createRunCommand(action.getCommand()));
}
return littleBuilder.create();
}
private static final List<String> SKIPPED = Arrays.asList("HSTRY_ENCHANTS");
@Override
public String stringifyItem(ItemStack item) {
try {
ChatItem.debug("[JSONManipulator] stringifying item");
Object nmsStack = JSONManipulator.AS_NMS_COPY.invoke(null, item);
Object nmsTag = JSONManipulator.NBT_TAG_COMPOUND.newInstance();
JSONManipulator.SAVE_NMS_ITEM_STACK_METHOD.invoke(nmsStack, nmsTag);
HashMap<String, String> tagMap = new HashMap<>();
Map<String, Object> nmsMap = (Map<String, Object>) JSONManipulator.MAP.get(nmsTag);
String id = nmsMap.get("id").toString().replace("\"", "");
Object realTag = nmsMap.get("tag");
if (JSONManipulator.NBT_TAG_COMPOUND.isInstance(realTag)) { // We need to make sure this is indeed an
// NBTTagCompound
Map<String, Object> realMap = (Map<String, Object>) JSONManipulator.MAP.get(realTag);
Set<Map.Entry<String, Object>> entrySet = realMap.entrySet();
for (Map.Entry<String, Object> entry : entrySet) {
tagMap.put(entry.getKey(), entry.getValue().toString());
}
}
// TODO check for ID remapping
// ItemRewriter.remapIds(Version.getVersion().MAX_VER, protocolVersion.MAX_VER,
// is);
StringBuilder sb = new StringBuilder("{id:");
sb.append("\"").append(id).append("\"").append(","); // Append the id
sb.append("Count:").append(item.getAmount()).append("b"); // Append the amount
if (!tagMap.containsKey("Damage")) { // for new versions
sb.append(",Damage:").append(item.getDurability()).append("s"); // Append the durability data
}
if (tagMap.isEmpty()) {
sb.append("}");
return sb.toString();
}
Set<Map.Entry<String, String>> entrySet = tagMap.entrySet();
boolean first = true;
sb.append(",tag:{"); // Start of the tag
for (Map.Entry<String, String> entry : entrySet) {
if (SKIPPED.contains(entry.getKey()))
continue;
if (!first)
sb.append(",");
first = false;
if (!entry.getKey().isEmpty()) {
if (entry.getKey().contains(";"))
sb.append("\"" + entry.getKey() + "\"");
else
sb.append(entry.getKey());
sb.append(":");
}
sb.append(Utils.cleanStr(entry.getValue()));
}
sb.append("}}"); // End of tag and end of item
return sb.toString();
} catch (Exception e) {
return "{}";
}
}
}
@@ -1,10 +1,12 @@
package me.dadus33.chatitem.playernamer;
import me.dadus33.chatitem.playernamer.hook.HexNicksV3PlayerNamer;
import org.bukkit.Bukkit;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.playernamer.hook.DefaultPlayerNamer;
import me.dadus33.chatitem.playernamer.hook.HexNicksPlayerNamer;
import me.dadus33.chatitem.playernamer.hook.HexNicksV2PlayerNamer;
import org.bukkit.plugin.Plugin;
public class PlayerNamerManager {
@@ -17,11 +19,24 @@ public class PlayerNamerManager {
}
public static void load(ChatItem pl) {
if(Bukkit.getPluginManager().getPlugin("HexNicks") != null) {
setPlayerNamer(new HexNicksPlayerNamer());
pl.getLogger().info("Enable support for HexNicks plugin !");
} else {
setPlayerNamer(new DefaultPlayerNamer());
Plugin plugin = Bukkit.getPluginManager().getPlugin("HexNicks");
if (plugin != null) {
char majorVersion = ChatItem.getPlatform().getPluginVersion(plugin).charAt(0);
if (majorVersion == '3')
setPlayerNamer(new HexNicksV3PlayerNamer());
else
setPlayerNamer(new HexNicksV2PlayerNamer());
pl.getLogger().info("Enable support for HexNicks plugin v" + majorVersion);
return;
}
setPlayerNamer(new DefaultPlayerNamer());
}
}
@@ -0,0 +1,26 @@
package me.dadus33.chatitem.playernamer.hook;
import java.util.concurrent.CompletableFuture;
import org.bukkit.entity.Player;
import me.dadus33.chatitem.playernamer.IPlayerNamer;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.md_5.bungee.api.chat.BaseComponent;
public class HexNicksV2PlayerNamer implements IPlayerNamer {
@Override
public BaseComponent[] getName(Player p) {
try {
Object api = Class.forName("dev.majek.hexnicks.Nicks").getDeclaredMethod("api").invoke(null);
CompletableFuture<Component> storedNick = (CompletableFuture<Component>) api.getClass().getDeclaredMethod("getStoredNick", Player.class).invoke(api, p);
return BungeeComponentSerializer.get().serialize(storedNick.join());
} catch (Exception e) {
e.printStackTrace();
}
return new BaseComponent[0];
}
}
@@ -1,17 +1,17 @@
package me.dadus33.chatitem.playernamer.hook;
import dev.majek.hexnicks.HexNicks;
import org.bukkit.entity.Player;
import dev.majek.hexnicks.Nicks;
import me.dadus33.chatitem.playernamer.IPlayerNamer;
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.md_5.bungee.api.chat.BaseComponent;
public class HexNicksPlayerNamer implements IPlayerNamer {
public class HexNicksV3PlayerNamer implements IPlayerNamer {
@Override
public BaseComponent[] getName(Player p) {
return BungeeComponentSerializer.get().serialize(Nicks.api().getStoredNick(p).join());
}
@Override
public BaseComponent[] getName(Player p) {
return BungeeComponentSerializer.get().serialize(HexNicks.api().getStoredNick(p).join());
}
}
@@ -1,7 +1,5 @@
package me.dadus33.chatitem.playerversion.hooks;
import java.util.HashMap;
import org.bukkit.entity.Player;
import me.dadus33.chatitem.playerversion.IPlayerVersion;
@@ -9,10 +7,8 @@ import me.dadus33.chatitem.utils.Version;
public class DefaultVersionHook implements IPlayerVersion {
public static final HashMap<String, Integer> PROTOCOL_PER_ADDRESS = new HashMap<>();
@Override
public int getProtocolVersion(Player p) {
return PROTOCOL_PER_ADDRESS.getOrDefault(Version.stringifyAdress(p.getAddress()), Version.getVersion().MAX_VER);
return Version.getVersion().MAX_VER;
}
}
@@ -2,8 +2,9 @@ package me.dadus33.chatitem.playerversion.hooks;
import org.bukkit.entity.Player;
import com.viaversion.viaversion.api.Via;
import me.dadus33.chatitem.playerversion.IPlayerVersion;
import us.myles.ViaVersion.api.Via;
public class ViaVersionHook implements IPlayerVersion {
@@ -8,7 +8,8 @@ import net.md_5.bungee.api.ChatColor;
public class ColorManager {
public static final List<String> COLORS = Arrays.asList("4", "c", "6", "e", "2", "a", "b", "3", "1", "9", "d", "5", "f", "7", "8", "0");
public static final char COLOR_CHAR = '§';
public static final List<String> COLORS = Arrays.asList("4", "c", "6", "e", "2", "a", "b", "3", "1", "9", "d", "5", "f", "7", "8", "0", "k", "l", "m", "n", "o", "r");
public static boolean isHexColor(ChatColor c) {
return Version.getVersion().isNewerOrEquals(Version.V1_16) && c.getName().startsWith("#");
@@ -49,7 +50,6 @@ public class ColorManager {
return "";
StringBuilder str = new StringBuilder();
if (isHexColor(input)) { // x mean it's an hex
ChatItem.debug("Removing char x at begin: " + input.substring(1));
input = input.substring(1);
if (input.length() >= 6) { // at least hex
str.append(ChatColor.of("#" + input.substring(0, 6))); // get first hex color code
@@ -70,7 +70,6 @@ public class ColorManager {
if (input == null || input.isEmpty())
return ChatColor.RESET;
if (isHexColor(input)) { // x mean it's an hex
ChatItem.debug("Removing char x at begin: " + input.substring(1));
if (input.length() >= 7) { // at least hex, and 7 because we count the "x"
return ChatColor.of("#" + input.substring(1, 7)); // get first hex color code
} else
@@ -84,7 +83,7 @@ public class ColorManager {
String colorCode = "", text = "";
boolean waiting = false;
for (char args : message.toCharArray()) {
if (args == '§') { // begin of color
if (args == COLOR_CHAR) { // begin of color
waiting = true; // waiting for color code
} else if (waiting) { // if waiting for code and valid str
// if it's hexademical value and with enough space for full color
@@ -106,8 +105,6 @@ public class ColorManager {
text += ColorManager.getColor(colorCode);
else {
text += ColorManager.getColor(colorCode.substring(0, 7)); // only the hex code
ChatItem.debug("Adding color for " + colorCode.substring(7, colorCode.length()) + " (in "
+ colorCode + ")");
text += ColorManager.getColorString(colorCode.substring(7, colorCode.length()));
}
} else if (colorCode.length() == 1) // if only one color code
@@ -0,0 +1,42 @@
package me.dadus33.chatitem.utils;
import java.util.Arrays;
import org.jetbrains.annotations.NotNull;
import com.google.common.base.Preconditions;
import net.md_5.bungee.api.ChatColor;
public class Colors {
public static final String YELLOW = ColorManager.COLOR_CHAR + "e";
public static final String AQUA = ColorManager.COLOR_CHAR + "b";
public static final String GOLD = ColorManager.COLOR_CHAR + "6";
public static final String GRAY = ColorManager.COLOR_CHAR + "7";
public static final String RED = ColorManager.COLOR_CHAR + "c";
public static final String GREEN = ColorManager.COLOR_CHAR + "a";
public static final String RESET = ColorManager.COLOR_CHAR + "r";
public static String color(String s) {
return s == null || s.isEmpty() ? s : translateAlternateColorCodes('&', s);
}
public static String translateAlternateColorCodes(char altColorChar, @NotNull String textToTranslate) {
Preconditions.checkArgument(textToTranslate != null, "Cannot translate null text");
char[] b = textToTranslate.toCharArray();
for (int i = 0; i < b.length - 1; i++) {
if (b[i] == altColorChar && ColorManager.COLORS.contains(b[i + 1] + "")) {
b[i] = ColorManager.COLOR_CHAR;
b[i + 1] = Character.toLowerCase(b[i + 1]);
}
}
return new String(b);
}
public static boolean isFormatting(ChatColor c) {
return Arrays.asList(ChatColor.RESET, ChatColor.BOLD, ChatColor.MAGIC, ChatColor.UNDERLINE, ChatColor.ITALIC, ChatColor.STRIKETHROUGH).contains(c);
}
}
@@ -1,14 +1,14 @@
package me.dadus33.chatitem.utils;
import java.util.Arrays;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import me.dadus33.chatitem.ChatItem;
public class ItemUtils {
public static final Material MATERIAL_CLOSE = getMaterialWithCompatibility("BARRIER", "REDSTONE_BLOCK");
@@ -24,8 +24,11 @@ public class ItemUtils {
public static final Material BIRCH_WOOD_STAIRS = getMaterialWithCompatibility("BIRCH_WOOD_STAIRS", "BIRCH_STAIRS");
// colored items
public static final Material GRAY_STAINED_GLASS_PANE = getMaterialWithCompatibility("STAINED_GLASS_PANE", "GRAY_STAINED_GLASS_PANE");
public static final Material WHITE_STAINED_GLASS = getMaterialWithCompatibility("STAINED_GLASS_PANE", "WHITE_STAINED_GLASS_PANE");
public static final Material BROWN_STAINED_GLASS_PANE = getMaterialWithCompatibility("BROWN_STAINED_GLASS_PANE", "STAINED_GLASS_PANE");
public static final Material GRAY_STAINED_GLASS_PANE = getMaterialWithCompatibility("GRAY_STAINED_GLASS_PANE", "STAINED_GLASS_PANE");
public static final Material WHITE_STAINED_GLASS = getMaterialWithCompatibility("WHITE_STAINED_GLASS_PANE", "STAINED_GLASS_PANE");
public static final ItemStack ITEM_EMPTY_BROWN = ChatItem.getPlatform().createItemStack(BROWN_STAINED_GLASS_PANE, "");
public static Material getMaterialWithCompatibility(String... tempMat) {
for(String s : tempMat) {
@@ -39,42 +42,6 @@ public class ItemUtils {
}
return null;
}
public static ItemStack createItem(Material m, String name, String... lore) {
return createItem(m, name, 1, lore);
}
public static ItemStack createItem(Material m, String name, int quantite, String... lore) {
ItemStack item = new ItemStack(m, quantite);
ItemMeta meta = (ItemMeta) item.getItemMeta();
meta.setDisplayName(ChatColor.RESET + name);
meta.setLore(Arrays.asList(lore));
item.setItemMeta(meta);
return item;
}
public static ItemStack createItem(Material m, String name, List<String> lore) {
return createItem(m, name, 1, lore);
}
public static ItemStack createItem(Material m, String name, int quantite, List<String> lore) {
ItemStack item = new ItemStack(m, quantite);
ItemMeta meta = (ItemMeta) item.getItemMeta();
meta.setDisplayName(ChatColor.RESET + name);
meta.setLore(lore);
item.setItemMeta(meta);
return item;
}
@SuppressWarnings("deprecation")
public static ItemStack createItem(Material m, String name, int amount, byte b, String... lore) {
ItemStack item = new ItemStack(m, amount, b);
ItemMeta meta = (ItemMeta) item.getItemMeta();
meta.setDisplayName(ChatColor.RESET + name);
meta.setLore(Arrays.asList(lore));
item.setItemMeta(meta);
return item;
}
public static ItemStack hideAttributes(ItemStack stack) {
if (Version.getVersion().isNewerThan(Version.V1_7)) {
@@ -86,7 +53,40 @@ public class ItemUtils {
return stack;
}
public static ItemStack copyIfExist(ItemStack item) {
return isEmpty(item) ? null : item.clone();
}
public static boolean isEmpty(ItemStack item) {
return item == null || item.getType().equals(Material.AIR);
}
@SuppressWarnings("deprecation")
public static void stripData(ItemStack i) {
if (i == null) {
return;
}
if (i.getType().equals(Material.AIR)) {
return;
}
if (!i.hasItemMeta()) {
return;
}
ItemMeta im = Bukkit.getItemFactory().getItemMeta(i.getType());
ItemMeta original = i.getItemMeta();
if (original.hasDisplayName()) {
im.setDisplayName(original.getDisplayName());
}
i.setItemMeta(im);
}
@SuppressWarnings("deprecation")
public static Enchantment getEnchant(String... names) {
for(String name : names) {
Enchantment possible = Enchantment.getByName(name);
if(possible != null)
return possible;
}
return null;
}
}
@@ -7,6 +7,7 @@ import java.util.stream.Collectors;
import org.bukkit.command.CommandSender;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.Storage;
public class Messages {
@@ -18,7 +19,6 @@ public class Messages {
return colorAndPlaceholders(ChatItem.getInstance().getConfig().getString("messages." + key, key), placeholders);
}
@SuppressWarnings("unchecked")
public static List<String> getMessageList(String key, Object... placeholders) {
Object obj = ChatItem.getInstance().getConfig().get("messages." + key);
if(obj == null)
@@ -1,101 +1,99 @@
package me.dadus33.chatitem.utils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.v1.json.JSONManipulator;
public class PacketUtils {
public static final String VERSION = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",")
.split(",")[3];
public static final String NMS_PREFIX;
public static final String OBC_PREFIX;
public static final boolean IS_THERMOS;
public static final Class<?> CRAFT_PLAYER_CLASS, CRAFT_SERVER_CLASS, CHAT_SERIALIZER, COMPONENT_CLASS;
public static final boolean IS_THERMOS = Utils.isClassExist("thermos.Thermos");
public static final Class<?> COMPONENT_CLASS;
private static Method getNbtMethod, sendPacketMethod;
/**
* This Map is to reduce Reflection action which take more resources than just RAM action
* This Map is to reduce Reflection action which take more resources than just
* RAM action
*/
private static final Map<String, Class<?>> ALL_CLASS = Collections.synchronizedMap(new HashMap<String, Class<?>>());
static {
IS_THERMOS = isClassExist("thermos.Thermos");
NMS_PREFIX = Version.getVersion().isNewerOrEquals(Version.V1_17) || IS_THERMOS ? "net.minecraft." : "net.minecraft.server." + VERSION + ".";
OBC_PREFIX = "org.bukkit.craftbukkit." + VERSION + ".";
CRAFT_PLAYER_CLASS = getObcClass("entity.CraftPlayer");
CHAT_SERIALIZER = getNmsClass("IChatBaseComponent$ChatSerializer", "network.chat.", "ChatSerializer");
String version = ChatItem.getPlatform().getNMSVersion();
NMS_PREFIX = Version.getVersion().isNewerOrEquals(Version.V1_17) || IS_THERMOS ? "net.minecraft." : "net.minecraft.server." + (version == "" ? "" : version + ".");
OBC_PREFIX = "org.bukkit.craftbukkit." + (version == "" ? "" : version + ".");
COMPONENT_CLASS = getNmsClass("IChatBaseComponent", "network.chat.");
CRAFT_SERVER_CLASS = getObcClass("CraftServer");
}
/**
* Get the Class in NMS, with a processing reducer
*
* @param name of the NMS class (in net.minecraft.server package ONLY, because it's NMS)
* @return clazz the searched class
*/
public static Class<?> getNmsClass(String name, String packagePrefix, String... alias){
public static Class<?> getNmsClass(String name, String packagePrefix, String... alias) {
return ALL_CLASS.computeIfAbsent(name, (a) -> {
String fullPrefix = NMS_PREFIX + (Version.getVersion().isNewerOrEquals(Version.V1_17) || IS_THERMOS ? packagePrefix : "");
try {
Class<?> clazz = Class.forName(fullPrefix + name);
if(clazz != null)
if (clazz != null)
return clazz;
} catch (ClassNotFoundException e) {
if(alias.length == 0)
e.printStackTrace(); // no alias, print error
// else ignore and go check for alias
}
for(String className : alias) {
} catch (ClassNotFoundException e) {}
for (String className : alias) {
try {
Class<?> clazz = Class.forName(fullPrefix + className);
if(clazz != null)
if (clazz != null)
return clazz;
} catch (ClassNotFoundException e) {
if(className == alias[alias.length - 1]) // if it's last alias, print error
e.printStackTrace();
}
} catch (ClassNotFoundException e) {}
}
return null;
});
}
/**
* Get the Class in NMS, with a processing reducer
*
* @param name of the NMS class (in net.minecraft.server package ONLY, because it's NMS)
* @param name of the NMS class (in net.minecraft.server package ONLY, because
* it's NMS)
* @return clazz the searched class
*/
public static Class<?> getObcClass(String name, String... alias){
public static Class<?> getObcClass(String name, String... alias) {
return ALL_CLASS.computeIfAbsent(name, (a) -> {
try {
Class<?> clazz = Class.forName(OBC_PREFIX + name);
if(clazz != null)
if (clazz != null)
return clazz;
} catch (ClassNotFoundException e) {
if(alias.length == 0)
if (alias.length == 0)
e.printStackTrace(); // no alias, print error
// else ignore and go check for alias
}
for(String className : alias) {
for (String className : alias) {
try {
Class<?> clazz = Class.forName(OBC_PREFIX + className);
if(clazz != null)
if (clazz != null)
return clazz;
} catch (ClassNotFoundException e) {
if(className == alias[alias.length - 1]) // if it's last alias, print error
if (className == alias[alias.length - 1]) // if it's last alias, print error
e.printStackTrace();
}
}
return null;
});
}
/**
* Get NMS entity player of specified one
*
@@ -104,22 +102,12 @@ public class PacketUtils {
*/
public static Object getEntityPlayer(Player p) {
try {
Object craftPlayer = CRAFT_PLAYER_CLASS.cast(p);
return craftPlayer.getClass().getMethod("getHandle").invoke(craftPlayer);
return getObcClass("entity.CraftPlayer").getMethod("getHandle").invoke(p);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static boolean isClassExist(String name) {
try {
Class.forName(name);
return true;
} catch (Exception e) {
return false;
}
}
/**
* Get NMS player connection of specified player
@@ -130,16 +118,13 @@ public class PacketUtils {
public static Object getPlayerConnection(Player p) {
try {
Object entityPlayer = getEntityPlayer(p);
if(Version.getVersion().isNewerOrEquals(Version.V1_17))
return entityPlayer.getClass().getField("b").get(entityPlayer);
else
return entityPlayer.getClass().getField("playerConnection").get(entityPlayer);
return ReflectionUtils.getFirstWith(entityPlayer, entityPlayer.getClass(), getNmsClass("PlayerConnection", "server.network."));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* Get NMS entity player of specified one
*
@@ -148,8 +133,7 @@ public class PacketUtils {
*/
public static Object getCraftServer() {
try {
Object craftServer = CRAFT_SERVER_CLASS.cast(Bukkit.getServer());
return craftServer.getClass().getMethod("getHandle").invoke(craftServer);
return getObcClass("CraftServer").getMethod("getHandle").invoke(Bukkit.getServer());
} catch (Exception e) {
e.printStackTrace();
return null;
@@ -159,15 +143,76 @@ public class PacketUtils {
/**
* Send the packet to the specified player
*
* @param p which will receive the packet
* @param p which will receive the packet
* @param packet the packet to sent
*/
public static void sendPacket(Player p, Object packet) {
try {
Object playerConnection = getPlayerConnection(p);
playerConnection.getClass().getMethod(Version.getVersion().isNewerOrEquals(Version.V1_18) ? "a" : "sendPacket", getNmsClass("Packet", "network.protocol.")).invoke(playerConnection, packet);
if(sendPacketMethod == null) {
Version v = Version.getVersion();
if(v.isNewerOrEquals(Version.V1_20)) {
Class<?> packetSrvClass = getNmsClass("ServerCommonPacketListenerImpl", "server.network.");
if(packetSrvClass != null)
sendPacketMethod = packetSrvClass.getDeclaredMethod("b", getNmsClass("Packet", "network.protocol."));
}
if(sendPacketMethod == null)
sendPacketMethod = playerConnection.getClass().getMethod(Version.getVersion().isNewerOrEquals(Version.V1_18) ? "a" : "sendPacket", getNmsClass("Packet", "network.protocol."));
}
sendPacketMethod.invoke(playerConnection, packet);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Converts an {@link org.bukkit.inventory.ItemStack} to a Json string for
* sending with {@link net.md_5.bungee.api.chat.BaseComponent}'s.
*
* @param item the item to convert
* @return the Json string representation of the item
*/
public static String getNbtTag(ItemStack item) {
try {
if (getNbtMethod == null) {
Class<?> itemClass = getNmsClass("ItemStack", "world.item.");
Version v = Version.getVersion();
if(v.isNewerOrEquals(Version.V1_20_6))
getNbtMethod = itemClass.getDeclaredMethod("d"); // return DataComponentPatch's object
else if (v.equals(Version.V1_20))
getNbtMethod = itemClass.getDeclaredMethod("w");
else if (v.equals(Version.V1_19))
getNbtMethod = itemClass.getDeclaredMethod("u");
else if (v.equals(Version.V1_18))
getNbtMethod = itemClass.getDeclaredMethod("t");
else
getNbtMethod = itemClass.getDeclaredMethod("getTag");
getNbtMethod.setAccessible(true);
}
Object tag = getNbtMethod.invoke(JSONManipulator.AS_NMS_COPY.invoke(null, item));
return tag == null ? "{}" : tag.toString();
} catch (Exception e) {
e.printStackTrace();
}
return "{}";
}
public static void printPacketToDebug(Object packet) {
if(!ChatItem.hasDebug())
return;
if(packet == null) {
ChatItem.debug("Packet is null");
return;
}
ChatItem.debug("Packet with Class: " + packet.getClass().getSimpleName());
for (Field f : packet.getClass().getDeclaredFields()) {
f.setAccessible(true);
try {
ChatItem.debug(f.getName() + ": " + f.get(packet));
} catch (Exception exc) {
exc.printStackTrace();
}
}
}
}
@@ -1,56 +0,0 @@
package me.dadus33.chatitem.utils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import me.dadus33.chatitem.ChatItem;
public class Reflect {
public static Method getMethod(Class<?> clazz, String methodName, Class<?>... params) {
try {
return clazz.getMethod(methodName, params);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Method getMethod(Class<?> clazz, Class<?> returned, Class<?>... params) {
try {
for(Method m : clazz.getDeclaredMethods()) {
if(returned.equals(m.getReturnType()) && areParamsEquals(m.getParameterTypes(), params))
return m;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static boolean areParamsEquals(Class<?>[] p1, Class<?>[] p2) {
if(p1.length != p2.length)
return false;
for(int i = 0; i < p1.length; i++) {
if(!p1[i].equals(p2[i]))
return false;
}
return true;
}
public static Field getField(Class<?> clazz, String... fieldNames){
for(String field : fieldNames) {
try{
Field f = clazz.getDeclaredField(field);
f.setAccessible(true);
return f;
} catch (NoSuchFieldException e) {
// go to next
}
}
ChatItem.getInstance().getLogger().severe("Failed to find field: " + Arrays.asList(fieldNames) + " in class: " + clazz.getCanonicalName());
return null;
}
}
@@ -1,11 +1,70 @@
package me.dadus33.chatitem.utils;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import me.dadus33.chatitem.ChatItem;
public class ReflectionUtils {
public static Method getMethod(Class<?> clazz, String methodName, Class<?>... params) {
try {
return clazz.getMethod(methodName, params);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Method getMethodByName(Class<?> clazz, String methodName) {
try {
for(Method m : clazz.getDeclaredMethods())
if(m.getName().equals(methodName))
return m;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Method getMethod(Class<?> clazz, Class<?> returned, Class<?>... params) {
try {
for(Method m : clazz.getDeclaredMethods()) {
if(returned.equals(m.getReturnType()) && areParamsEquals(m.getParameterTypes(), params))
return m;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static boolean areParamsEquals(Class<?>[] p1, Class<?>[] p2) {
if(p1.length != p2.length)
return false;
for(int i = 0; i < p1.length; i++) {
if(!p1[i].equals(p2[i]))
return false;
}
return true;
}
public static Field getField(Class<?> clazz, String... fieldNames){
for(String field : fieldNames) {
try{
Field f = clazz.getDeclaredField(field);
f.setAccessible(true);
return f;
} catch (NoSuchFieldException e) {
// go to next
}
}
ChatItem.getInstance().getLogger().severe("Failed to find field: " + Arrays.asList(fieldNames) + " in class: " + clazz.getCanonicalName());
return null;
}
public static Object getPrivateField(Object object, String field)
throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
@@ -24,6 +83,20 @@ public class ReflectionUtils {
}
}
public static boolean hasObject(Object source, String... field) {
if(source == null)
return false;
for(String fieldName : field) {
try {
source.getClass().getDeclaredField(fieldName);
return true;
} catch (NoSuchFieldException e) {
// ignore because going to next item
}
}
return false;
}
/**
* Get the specified field name in the object source
*
@@ -32,6 +105,8 @@ public class ReflectionUtils {
* @return the requested object of the field
*/
public static Object getObject(Object source, String... field) {
if(source == null)
return null;
try {
for(String fieldName : field) {
try {
@@ -57,6 +132,8 @@ public class ReflectionUtils {
* @return the requested field
*/
public static Field getField(Object source, String field) {
if(source == null)
return null;
try {
Field f = source.getClass().getDeclaredField(field);
f.setAccessible(true);
@@ -92,7 +169,19 @@ public class ReflectionUtils {
* @return the field (or null if not found)
* @throws Exception if something gone wrong
*/
@SuppressWarnings("unchecked")
public static <T> T getFirstWith(Object from, Class<T> searchingFor) throws Exception {
return getFirstWith(from, from.getClass(), searchingFor);
}
/**
* Get the first object which have the searching for class type
*
* @param from the object where we will try to find the field
* @param clazz the class that have to define the field
* @param searchingFor the class of the required field
* @return the field (or null if not found)
* @throws Exception if something gone wrong
*/
public static <T> T getFirstWith(Object from, Class<?> clazz, Class<T> searchingFor) throws Exception {
for (Field f : clazz.getDeclaredFields()) {
if (f.getType().equals(searchingFor) && !Modifier.isStatic(f.getModifiers())) {
@@ -100,6 +189,8 @@ public class ReflectionUtils {
return (T) f.get(from);
}
}
if(!clazz.getSuperclass().equals(Object.class))
return getFirstWith(from, clazz.getSuperclass(), searchingFor);
return null;
}
@@ -121,4 +212,20 @@ public class ReflectionUtils {
}
return null;
}
public static boolean isClassExist(String name) {
try {
Class.forName(name);
return true;
} catch (Exception e) {
return false;
}
}
public static Constructor<?> getConstructor(Class<?> clazz, Class<?>... params) {
try {
return clazz.getConstructor(params);
} catch (Exception e) {}
return null;
}
}
@@ -1,123 +0,0 @@
package me.dadus33.chatitem.utils;
import com.google.common.collect.ImmutableList;
import me.dadus33.chatitem.ChatItem;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.configuration.file.FileConfiguration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class Storage {
public final HashMap<String, HashMap<Short, String>> TRANSLATIONS = new HashMap<>();
public final String HAND_NAME, NAME_FORMAT, AMOUNT_FORMAT, COMMAND_FORMAT, MANAGER, PERMISSION_NAME, BUGGED_CLIENT_ACTION;
public final String NO_PERMISSION_MESSAGE, DENY_MESSAGE, RELOAD_MESSAGE, COOLDOWN_MESSAGE, LIMIT_MESSAGE;
public final String SECONDS, MINUTES, HOURS;
public final String JOIN_UPDATE_MESSAGE, JOIN_UPDATE_HOVER;
public final List<Command> ALLOWED_PLUGIN_COMMANDS = new ArrayList<>();
public final List<String> ALLOWED_DEFAULT_COMMANDS = new ArrayList<>();
public final List<String> PLACEHOLDERS, HAND_TOOLTIP, BUGGED_CLIENTS_TOOLTIP;
public boolean COLOR_IF_ALREADY_COLORED, FORCE_ADD_AMOUNT, LET_MESSAGE_THROUGH, DENY_IF_NO_ITEM, DEBUG,
HAND_DISABLED, SHOW_NO_PERM_NORMAL, CHECK_UPDATE, SHOW_NO_PERM_COMMAND, PERMISSION_ENABLED;
public int CONFIG_VERSION, LIMIT, COOLDOWN;
private FileConfiguration conf;
public Storage(FileConfiguration cnf) {
this.conf = cnf;
CONFIG_VERSION = conf.getInt("config-version", 13);
checkConfigVersion();
this.MANAGER = conf.getString("manager", "auto");
Set<String> keys = conf.getConfigurationSection("translations").getKeys(false);
for (String key : keys) {
HashMap<Short, String> entry = new HashMap<>();
Set<String> subKeys = conf.getConfigurationSection("translations.".concat(key)).getKeys(false);
for (String subKey : subKeys) {
entry.put(Short.parseShort(subKey),
color(conf.getString("translations.".concat(key).concat(".").concat(subKey))));
}
TRANSLATIONS.put(key, entry);
}
DEBUG = conf.getBoolean("debug", false);
PLACEHOLDERS = ImmutableList.copyOf(conf.getStringList("general.placeholders"));
NAME_FORMAT = color(conf.getString("general.name-format", "&b&l&o{name} {amount}&r"));
AMOUNT_FORMAT = color(conf.getString("general.amount-format", "x{times}"));
COMMAND_FORMAT = color(conf.getString("general.command-format", "&6%name%'s item is %item%"));
COLOR_IF_ALREADY_COLORED = conf.getBoolean("general.color-if-already-colored", true);
LET_MESSAGE_THROUGH = conf.getBoolean("general.let-message-through", true);
FORCE_ADD_AMOUNT = conf.getBoolean("general.force-add-amount", true);
DENY_IF_NO_ITEM = conf.getBoolean("general.deny-if-no-item", false);
LIMIT = conf.getInt("general.limit", 8);
COOLDOWN = conf.getInt("general.cooldown", 60);
SHOW_NO_PERM_NORMAL = conf.getBoolean("general.show-no-permission-message.normal", true);
SHOW_NO_PERM_COMMAND = conf.getBoolean("general.show-no-permission-message.command", false);
PERMISSION_ENABLED = conf.getBoolean("general.permission.enabled", false);
PERMISSION_NAME = conf.getString("general.permission.name", "chatitem.use");
HAND_DISABLED = conf.getBoolean("general.hand.disabled", false);
HAND_NAME = color(conf.getString("general.hand.name", "&b&l&o{display-name}&b&l&o's hand"));
HAND_TOOLTIP = conf.getStringList("general.hand.tooltip").stream().map(Storage::color).collect(Collectors.toList());
BUGGED_CLIENT_ACTION = conf.getString("general.bugged_client.action", "show_both");
BUGGED_CLIENTS_TOOLTIP = conf.getStringList("general.bugged_client.tooltip").stream().map(Storage::color).collect(Collectors.toList());
CHECK_UPDATE = conf.getBoolean("general.check-update", true);
DENY_MESSAGE = color(conf.getString("messages.deny-message", "&c&lYou have no item in hand!"));
RELOAD_MESSAGE = color(conf.getString("messages.reload-success", "&b&lSuccessful reload!"));
NO_PERMISSION_MESSAGE = color(conf.getString("messages.no-permission",
"&c&lI'm sorry, but you are not allowed to use the placeholder in chat!"));
COOLDOWN_MESSAGE = color(conf.getString("messages.cooldown-message",
"&c&lYou can only use items in chat once a minute! You have {remaining} left!"));
JOIN_UPDATE_MESSAGE = color(conf.getString("messages.join-update.message",
"&cA new version of ChatItem is available. &aClick here to download."));
JOIN_UPDATE_HOVER = color(conf.getString("messages.join-update.hover", "&6Click to go to spigot page !"));
LIMIT_MESSAGE = color(conf.getString("messages.limit-message", "&c&lYou can only add 8 item placeholders per message!"));
SECONDS = color(conf.getString("messages.seconds", " seconds"));
MINUTES = color(conf.getString("messages.minutes", " minutes"));
HOURS = color(conf.getString("messages.hours", " hours"));
colorStringList(HAND_TOOLTIP);
final List<String> cmds = conf.getStringList("general.commands");
Bukkit.getScheduler().runTaskLaterAsynchronously(ChatItem.getInstance(), () -> {
for (String s : cmds) {
Command c = Bukkit.getPluginCommand(s);
if (c != null) {
ALLOWED_PLUGIN_COMMANDS.add(c);
} else {
ALLOWED_DEFAULT_COMMANDS.add(s);
}
}
}, 100L);
}
public static String color(String s) {
return s == null || s.isEmpty() ? s : ChatColor.translateAlternateColorCodes('&', s);
}
private static void colorStringList(List<String> input) {
for (int i = 0; i < input.size(); ++i) {
input.set(i, color(input.get(i)));
}
}
private void checkConfigVersion() {
int latestVersion = ChatItem.CFG_VER;
if (latestVersion != CONFIG_VERSION) {
ChatItem pl = ChatItem.getInstance();
pl.getLogger().warning(ChatColor.RED
+ "ChatItem detected an older or invalid configuration file. Replacing it with the default config...");
performOverwrite();
conf = pl.getConfig();
pl.getLogger().warning(ChatColor.RED + "Replacement complete!");
}
}
private void performOverwrite() {
ChatItem.getInstance().saveResource("config.yml", true);
}
}
@@ -1,23 +1,47 @@
package me.dadus33.chatitem.utils;
import me.dadus33.chatitem.ChatItem;
import org.bukkit.Bukkit;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.*;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.StringJoiner;
import java.util.TreeMap;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.chatmanager.ChatManager;
import me.dadus33.chatitem.playerversion.PlayerVersionManager;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.ItemTag;
import net.md_5.bungee.api.chat.hover.content.Item;
import net.md_5.bungee.api.chat.hover.content.Text;
public class Utils {
private final static TreeMap<Integer, String> ROMAN_KEYS = new TreeMap<>();
private final static HashMap<String, String> ENCHANTS_NAMES = new HashMap<>();
public static final boolean IS_PAPER = isClassExist("io.papermc.paper.event.player.AsyncChatEvent");
private static final Pattern UUID_PATTERN = Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$");
private static final TreeMap<Integer, String> ROMAN_KEYS = new TreeMap<>();
private static final HashMap<String, String> ENCHANTS_NAMES = new HashMap<>();
static {
ROMAN_KEYS.put(1000, "M");
@@ -96,7 +120,7 @@ public class Utils {
connection.setUseCaches(true);
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.setRequestProperty("User-Agent", "ChatItem " + pl.getDescription().getVersion());
connection.setRequestProperty("User-Agent", "ChatItem");
connection.setDoOutput(true);
connection.setRequestMethod("GET");
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
@@ -138,6 +162,42 @@ public class Utils {
return b;
}
public static boolean isBeforeChatJson(Player p) {
return !PlayerVersionManager.getPlayerVersionAdapter().getPlayerVersion(p).isNewerOrEquals(Version.V1_16) && Version.getVersion().isNewerOrEquals(Version.V1_16);
}
@SuppressWarnings("deprecation")
public static HoverEvent createItemHover(ItemStack item, Player to) {
if(isBeforeChatJson(to)) {
ComponentBuilder comp = new ComponentBuilder("");
for(String line : ChatManager.getMaxLinesFromItem(to, item))
comp.append(line + "\n");
return createTextHover(comp.create());
}
if(Version.getVersion().isNewerOrEquals(Version.V1_13)) {
return new HoverEvent(HoverEvent.Action.SHOW_ITEM, new Item(item.getType().getKey().getKey(), item.getAmount(), ItemTag.ofNbt(PacketUtils.getNbtTag(item))));
} else {
return new HoverEvent(HoverEvent.Action.SHOW_ITEM, new ComponentBuilder(ChatItem.getPlatform().stringifyItem(item)).create());
}
}
public static HoverEvent createTextHover(String text) {
return createTextHover(new ComponentBuilder(text).create());
}
@SuppressWarnings("deprecation")
public static HoverEvent createTextHover(BaseComponent[] comps) {
if(Version.getVersion().isNewerOrEquals(Version.V1_13)) {
return new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(comps));
} else {
return new HoverEvent(HoverEvent.Action.SHOW_TEXT, comps);
}
}
public static ClickEvent createRunCommand(String command) {
return new ClickEvent(ClickEvent.Action.RUN_COMMAND, command);
}
public static boolean isInteger(String s) {
try {
Integer.parseInt(s);
@@ -173,4 +233,43 @@ public class Utils {
return false;
}
}
public static boolean isUUID(String s) {
return s != null && UUID_PATTERN.matcher(s.toLowerCase()).matches();
}
public static YamlConfiguration copyLoadFile(File folder, String filename, String baseFile) {
File legacyConfig = new File(folder, filename);
if(!legacyConfig.exists())
copyFile(baseFile, legacyConfig);
return YamlConfiguration.loadConfiguration(legacyConfig);
}
public static void copyFile(String fileName, File dir) {
try (InputStream stream = ChatItem.getInstance().getResource(fileName)) {
Files.copy(stream, dir.toPath());
} catch(Exception e) {
e.printStackTrace();
}
}
public static String arrayToString(Object[] a) {
StringJoiner sj = new StringJoiner(", ");
for(Object o : a)
sj.add(o == null ? "null" : o.toString());
return sj.toString();
}
public static boolean isClassExist(String name) {
try {
Class.forName(name);
return true;
} catch (Exception e) {
return false;
}
}
public static String cleanStr(String s) {
return s.startsWith("'") && s.endsWith("'") ? s.substring(1, s.length() - 1) : s;
}
}
@@ -2,26 +2,27 @@ package me.dadus33.chatitem.utils;
import java.net.InetSocketAddress;
import org.bukkit.Bukkit;
import me.dadus33.chatitem.ChatItem;
public enum Version {
// http://wiki.vg/Protocol_version_numbers
V1_7(0, 5, 0),
V1_8(6, 47, 1),
V1_9(49, 110, 2), // 1.9.X - Starts with 49 as 48 was an april fools update
V1_10(201, 210, 3), // 1.10.X - Starts with 201 because why not.
V1_11(301, 316, 4),
V1_12(317, 340, 5),
V1_13(341, 440, 6),
V1_14(100, 441, 500),
V1_15(100, 550, 578),
V1_16(100, 700, 754),
V1_17(100, 755, 756),
V1_18(100, 757, 758),
V1_19(100, 761, 1000),
V1_7(0, 5, 7),
V1_8(6, 47, 8),
V1_9(49, 110, 9), // 1.9.X - Starts with 49 as 48 was an april fools update
V1_10(201, 210, 10), // 1.10.X - Starts with 201 because why not.
V1_11(301, 316, 11),
V1_12(317, 340, 12),
V1_13(341, 440, 13),
V1_14(441, 500, 14),
V1_15(550, 578, 15),
V1_16(700, 754, 16),
V1_17(755, 756, 17),
V1_18(757, 758, 18),
V1_19(759, 762, 19),
V1_20(763, 765, 20),
V1_20_6(766, 766, 20.6),
V1_21(767, 1000, 21),
HIGHER(Integer.MAX_VALUE, -1, Integer.MAX_VALUE);
// Latest version should always have the upper limit set to Integer.MAX_VALUE so
@@ -29,17 +30,11 @@ public enum Version {
public final int MIN_VER;
public final int MAX_VER;
public final int index; // Represents how new the version is (0 - extremely old)
public final double index; // Represents how new the version is (0 - extremely old)
private static final Version SERVER_VERSION;
public static final String BUKKIT_VERSION;
private static final Version SERVER_VERSION = ChatItem.getPlatform().getMinecraftVersion();
static {
BUKKIT_VERSION = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
SERVER_VERSION = getVersionByName(BUKKIT_VERSION);
}
Version(int min, int max, int index) {
Version(int min, int max, double index) {
this.MIN_VER = min;
this.MAX_VER = max;
this.index = index;
@@ -54,6 +49,9 @@ public enum Version {
}
public static Version getVersionByName(String name) {
try {
return Version.valueOf(name.toUpperCase());
} catch (Exception e) {}
for (Version v : Version.values())
if (name.toLowerCase().startsWith(v.name().toLowerCase()))
return v;
@@ -61,12 +59,7 @@ public enum Version {
}
public static Version getVersion(int protocolVersion) {
for (Version ver : Version.values()) {
if (protocolVersion >= ver.MIN_VER && protocolVersion <= ver.MAX_VER) {
return ver;
}
}
return HIGHER;
return getVersion(protocolVersion, HIGHER);
}
public static Version getVersion(int protocolVersion, Version def) {
@@ -84,6 +77,8 @@ public enum Version {
}
public static String stringifyAdress(InetSocketAddress address) {
if(address == null)
return "0.0.0.0:0";
String port = String.valueOf(address.getPort());
String ip = address.getAddress().getHostAddress();
return ip + ":" + port;
Loaded 100 of 227 files, more files were not shown because too many files have changed in this diff. Show more