Compare commits

..
501 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
Elikill58 2b0de9aa3c Upgrade to 2.4.4 2022-08-26 08:11:55 +02:00
Elikill58 3981992e37 Fix for new packet version 2022-08-24 09:56:51 +02:00
Elikill58 439710086e Fix color and hover 2022-08-12 08:43:51 +02:00
Elikill58 f5381b0430 Fix unknow color code 2022-08-12 08:28:06 +02:00
Elikill58 3cce52953a Make things more global 2022-08-12 08:16:58 +02:00
Elikill58 797de9c602 Fix issue with shulker check 2022-08-08 14:43:23 +02:00
Elikill58 c7f76d9f7b Fix #43 2022-08-08 14:37:28 +02:00
Elikill58 3947ea88d5 Add debug things 2022-07-26 15:56:02 +02:00
Elikill58 cc30049fdf Prevent error with books 2022-07-26 15:54:41 +02:00
Elikill58 7a964bb97c Upgrade to snapshot 2022-07-26 15:50:12 +02:00
Elikill58 13bbf3e5ca Fix first color thing 2022-07-22 12:44:11 +02:00
Elikill58 46de91b2ff Add some messages in config 2022-07-22 11:37:33 +02:00
Elikill58 cb5b3acab0 Add check update in admin inv 2022-07-22 11:36:52 +02:00
Elikill58 6f6d4dc263 Fix hex color 2022-07-22 11:33:29 +02:00
Elikill58 250b119391 Several fix 2022-07-21 23:00:51 +02:00
Elikill58 beee98d5d6 Upgrade to 2.4.3 2022-07-21 17:58:33 +02:00
Elikill58 4d270891be Fix when not using extra 2022-07-21 17:21:37 +02:00
Elikill58 7e9352661e Fix multiple color for same chat line 2022-07-21 17:17:31 +02:00
Elikill58 3f47d56bed Add chatitem broadcast command 2022-07-21 11:27:51 +02:00
Elikill58 1d0cac3a2b Fix chatitem show 2022-07-20 19:31:31 +02:00
Elikill58 64da26ea9f Use protocollib for all versions 2022-07-19 17:18:37 +02:00
Elikill58 4e53b6d5b0 Fix diff for spigot & paper 2022-07-16 09:50:01 +02:00
Elikill58 3b4ede3c22 Fix lib issue 2022-07-15 22:42:50 +02:00
Elikill58 59aade10a7 Prevent higher version 2022-07-15 10:53:05 +02:00
Elikill58 cd5bf7281b Change how color are managed 2022-07-15 10:48:59 +02:00
Elikill58 cd5bd87835 Fix wrong version detection 2022-07-12 21:36:49 +02:00
Elikill58 9384277901 Update few debugger 2022-07-12 19:42:57 +02:00
Elikill58 3b43e647a4 Update color management for v2 2022-07-12 19:34:23 +02:00
Elikill58 f28ad44e62 Fix color code 2022-07-12 18:53:21 +02:00
Elikill58 0baec19db1 Upgrade to snpashot 2022-07-12 18:13:02 +02:00
Elikill58 8ea83b3fab Prevent cooldown 2022-07-12 18:12:17 +02:00
Elikill58 7eaadd9ad6 Fix color 2022-07-08 11:27:05 +02:00
Elikill58 506985c9d1 Fix custom enchants 2022-07-08 10:04:55 +02:00
Elikill58 3fb0181ad7 Wrong char <.< 2022-07-08 09:29:14 +02:00
Elikill58 fc56bb6017 Add command to show item in chat 2022-07-05 23:10:14 +02:00
Elikill58 d9c60f45a4 Quick several fix 2022-07-02 14:32:25 +02:00
Elikill58 342060b86e Upgrade to 2.4.2 2022-06-30 16:10:38 +02:00
Elikill58 b5b30bd9d8 Fix hex color 2022-06-27 18:28:17 +02:00
Elikill58 55eaac0bd4 Update players 2022-06-25 18:27:29 +02:00
Elikill58 7583aeade7 Update constructor 2022-06-25 18:27:04 +02:00
Elikill58 4be3712082 Fix compatibility with old PL 2022-06-23 16:22:51 +02:00
Elikill58 c1e28709ac Fix array as string 2022-06-23 01:01:06 +02:00
Elikill58 f0965efe73 Fix wrong constructor used 2022-06-23 00:20:09 +02:00
Elikill58 529cdd1e04 Second wave to fix with other plugins 2022-06-22 17:35:23 +02:00
Elikill58 ce867d4065 Remove tag for adventure 2022-06-21 17:29:08 +02:00
Elikill58 1eefb78157 Fix adventure not found 2022-06-21 16:44:08 +02:00
Elikill58 ff0c8d2a8d Upgrade to snapshot 2022-06-21 15:29:22 +02:00
Elikill58 5a250d854d Upgrade to 2.4.1 2022-06-15 00:53:36 +02:00
Elikill58 caacf0d8ae Don't use deprecated things 2022-06-15 00:52:18 +02:00
Elikill58 0f7d4a0548 Remove strange char 2022-06-15 00:49:33 +02:00
Elikill58 4529f74f0a Update dependencies 2022-06-15 00:49:06 +02:00
Elikill58 1eaf32983a Fix purpur issue 2022-06-14 10:15:49 +02:00
Elikill58 24b0682e8b Go to snapshot 2022-06-14 09:25:28 +02:00
Elikill58 cbf3326de6 Fix, again 2022-06-13 19:12:40 +02:00
Elikill58 c4ae9198a4 Fix #41 (included in spigot release) 2022-06-13 15:28:15 +02:00
Elikill58 c01798f2e2 Upgrade to 2.4 2022-06-12 20:27:49 +02:00
Elikill58 5de8dbe98a Update item method 2022-06-10 18:01:41 +02:00
Elikill58 00eecd1841 Remove other useless debug 2022-06-10 16:37:00 +02:00
Elikill58 54783d657e Remove useless debug 2022-06-10 16:36:03 +02:00
Elikill58 e17b618b18 Fix v1 packets 2022-06-10 16:30:44 +02:00
Elikill58 3c8371fe28 Fix v2 chat manager for empty items 2022-06-10 14:42:29 +02:00
Elikill58 aafb677d01 Fix channel detection 2022-06-10 11:03:02 +02:00
Elikill58 3a945560a8 If it doesn't works, it's not because of me. Sorry for github msg 2022-06-06 20:57:01 +02:00
Elikill58 516156624e Upgrade maven compiler 2022-06-06 20:45:25 +02:00
Elikill58 b6e37edfa3 Update maven's plugin 2022-06-06 20:30:27 +02:00
Elikill58 6772d26747 Use java version 2022-06-06 20:26:17 +02:00
Elikill58 145ff70e3d Let maven manage own things 2022-06-06 20:24:12 +02:00
Elikill58 cd57c3d37f Change maven copmpiler option 2022-06-06 20:11:18 +02:00
Elikill58 80413bab3a Remove jitpack file and just use maven things 2022-06-06 20:00:59 +02:00
Elikill58 319e70696e Add target java versions 2022-06-06 19:46:20 +02:00
Elikill58 dfda46bcb7 Make jitpack use JDK 17 2022-06-06 19:29:32 +02:00
Elikill58 848a44c5da Finally fix with Kyori adventure messae 2022-06-01 19:01:06 +02:00
Elikill58 48a0666c79 Fix writing issue 2022-06-01 17:15:44 +02:00
Elikill58 d828a747db Possible fix for cmd 2022-06-01 17:02:12 +02:00
Elikill58 7ff7eb20b9 Change how base component is obtained 2022-06-01 16:57:15 +02:00
Elikill58 bae9d14ae5 Add discordSRV as soft dep 2022-05-31 22:44:04 +02:00
Elikill58 9b2fc7da65 Rename method 2022-05-30 13:33:32 +02:00
Elikill58 163686cf77 Fix discord srv message 2022-05-30 12:21:57 +02:00
Elikill58 895fbcf07e Fix ProtocolLib support 2022-05-23 22:14:46 +02:00
Elikill58 004131ddc3 Remove some useless color codes 2022-05-23 22:03:19 +02:00
Elikill58 e59d116918 Prevent some message to be sent multiple times 2022-05-23 17:10:07 +02:00
Elikill58 4ee9d4525a Fix cooldown 2022-05-15 11:11:12 +02:00
Elikill58 3d1672d4ef Upgrade to 2.3 2022-05-11 10:52:34 +02:00
Elikill58 91fc9ee913 Don't use removed class 2022-05-09 19:57:14 +02:00
Elikill58 15604b0ec4 Wtf wrong item 2022-05-08 17:38:37 +02:00
Elikill58 8108b949f7 Refactor of json manipulator 2022-05-06 11:55:36 +02:00
Elikill58 aabaa2a332 Remove wtf file 2022-05-03 22:03:08 +02:00
Elikill58 0896a7c63e Fix packet manager not well working 2022-05-03 22:02:52 +02:00
Elikill58 b4b6b19ec3 Fix limit message wrong triggering 2022-05-03 13:52:12 +02:00
Elikill58 93289f5b24 Fix possible NPE 2022-05-02 12:52:31 +02:00
Elikill58 5810652007 Add EcoEnchants support 2022-04-28 20:50:11 +02:00
Elikill58 1e92763497 Make method generic to fix for cmd in v1 2022-04-23 21:57:37 +02:00
Elikill58 a699c807fd Fix limit not working 2022-04-23 21:49:37 +02:00
Elikill58 7ef48f4202 Move some methods 2022-04-23 21:42:21 +02:00
Elikill58 7dc8042de7 Fix multiple items 2022-04-18 17:13:24 +02:00
Elikill58 9d13bd482c Fix loading managers 2022-04-18 16:50:10 +02:00
outsparkled 306ab41f08 Code cleanups (#39) 2022-04-15 18:17:44 +02:00
Elikill58 aea4950398 Fix error for PR without discord link 2022-04-15 11:24:45 +02:00
Elikill58 042c27c088 Fix building by using own ProtocolSupport build 2022-04-10 19:01:23 +02:00
Elikill58 b699d2ffad Fix object can't be founded 2022-04-10 17:12:11 +02:00
Elikill58 0400b0beaf Fix wrong name of item 2022-03-10 14:37:44 +01:00
Elikill58 88030f82b6 Fix wrong ID for 1.7 clients 2022-03-10 13:42:37 +01:00
Elikill58 e8f8bd5af4 Add way to show item with less informations for bugged clients 2022-03-10 13:39:48 +01:00
Elikill58 bfbcaf1598 Remove some debug messages 2022-03-10 13:07:39 +01:00
Elikill58 ffc57dd69a Clean code specially for json formatting 2022-03-10 13:03:29 +01:00
Elikill58 07fa5c256b Prevent some type of issues 2022-03-10 11:51:25 +01:00
Elikill58 c07357b89b Fix other placeholders 2022-03-10 01:01:40 +01:00
Elikill58 629d492fad Remove unused field 2022-03-10 00:58:00 +01:00
Elikill58 693ca51315 Fix NMU & content modifier 2022-03-10 00:56:36 +01:00
Elikill58 f65444cfe9 Put player as var 2022-03-10 00:30:09 +01:00
Elikill58 464b887ed5 Begin of prevent lunar issue 2022-03-10 00:26:24 +01:00
Elikill58 1bdf20feb0 Deprecated unused class to check in the future if they are useful 2022-03-06 02:00:57 +01:00
Elikill58 db89bfb5b5 Clean JSON use 2022-03-06 01:57:44 +01:00
Elikill58 efe2dd22e9 Use new json manager 2022-03-06 01:46:09 +01:00
Elikill58 144be87448 Upgrade to 2.2.1 2022-02-28 12:30:18 +01:00
Elikill58 217e7316b9 Add jitpack support 2022-02-26 14:10:11 +01:00
CatAndPaste 9bf2900bb5 Hot fix for hex-colored nicknames changed by Essentials-X. After the general hex-colored fix by Elikill58 that fixed 99% of the problem, first character formatting still was off (as you can see on screenshot: https://media.discordapp.net/attachments/171243756849201153/946441326205993010/unknown.png), this was caused by §r added to the begining of the name. I fixed an error by adding check for char 'r' in showItem function (ChatListener.java : 235). (#37) 2022-02-24 19:31:10 +01:00
Elikill58 23640b1772 Fix hex color ... again 2022-02-23 23:45:44 +01:00
Elikill58 fecf35b3a9 Add discord srv support and fix logged messages 2022-02-23 20:42:05 +01:00
Elikill58 8068fe6a7f Fix append for legacy versions 2022-02-23 19:31:23 +01:00
Elikill58 2f21538c76 Possible fix fox colors codes 2022-02-23 17:48:44 +01:00
Elikill58 340cad0b2f Fix item for old spigot version 2022-02-20 23:11:01 +01:00
Elikill58 0c51c73f31 Add option in inv to manage debug mode 2022-02-20 23:08:53 +01:00
Elikill58 717db94dc2 Prefer manage v1 rep if v2 is enabled 2022-02-20 23:02:11 +01:00
Elikill58 51e6708fcb Update which item is showed 2022-02-19 21:59:37 +01:00
Elikill58 a6f22d090a Fix some color for v1 2022-02-19 21:44:32 +01:00
Elikill58 979f39a171 If not comp, try to use chat base comp 2022-02-19 21:38:43 +01:00
Elikill58 0f057720b8 Prevent one method not found on some paper 2022-02-19 19:37:50 +01:00
Elikill58 a4eb8bd8fe Fix duplicated text 2022-02-19 19:21:11 +01:00
Elikill58 38a8f24c9c Add way to find ichatbase comp 2022-02-19 19:09:01 +01:00
Elikill58 82de0cf4dc Fix wrong parsing fields 2022-02-19 19:05:24 +01:00
Elikill58 13fcea5b57 Change how chat manager works 2022-02-19 15:52:35 +01:00
Elikill58 4292871294 Fix items messages (From XeonZ's config) 2022-02-18 11:06:22 +01:00
Elikill58 827c7f92ae Merge branch 'v2' of https://github.com/dadus33-plugins/ChatItem into v2 2022-02-16 16:16:58 +01:00
Elikill58 bcd28eddca Prevent instance error 2022-02-16 15:32:51 +01:00
outsparkled 4d873146dd Fix gson compatibility issues on 1.8 and clean up pom (#36)
* Fix gson compatibility issues on 1.8 and clean up pom

* re-add export_dir
2022-02-15 19:42:33 +01:00
Elikill58 95bcd6ceff Upgrade to v2.2 2022-02-14 21:20:24 +01:00
Elikill58 b596873300 Prevent too many char in color code 2022-02-08 18:37:47 +01:00
Elikill58 0425336f67 Prevent concurrent modifications 2022-02-02 12:17:56 +01:00
Elikill58 1a27bcbec2 Fix hex support with chat manager 2022-01-31 15:19:46 +01:00
Elikill58 17761fb649 Fix enchants issue with json 2022-01-31 14:37:58 +01:00
Elikill58 9b287c5f83 Add option to disable permission and change it 2022-01-31 13:54:36 +01:00
Elikill58 ce44cd7297 Fix for 1.12 only 2022-01-27 19:59:22 +01:00
Elikill58 4ee5a69a28 Edit auto manager 2022-01-26 23:43:09 +01:00
Elikill58 e7f19acc7f Prevent bell not found because of \ 2022-01-26 23:35:48 +01:00
Elikill58 9d557260ae Prevent bell not set 2022-01-26 23:20:53 +01:00
Elikill58 6bbf12182a Add some debugging message 2022-01-26 22:27:37 +01:00
Elikill58 54a582d3eb Prevent issue that show own item 2022-01-26 22:19:18 +01:00
Elikill58 0cbf4edbd1 Prevent ink sack not supported 2022-01-26 22:16:30 +01:00
Elikill58 0d4d8a7bf1 Merge branch 'v2' of https://github.com/dadus33-plugins/ChatItem into v2 2022-01-20 16:33:45 +01:00
Elikill58 332bed1bcb Fix for snapshot new ver message 2022-01-20 16:32:42 +01:00
Elikill58 ecbcbbab12 Go to snapshot 2022-01-20 15:49:23 +01:00
Elikill58 e143dd14bf Make link secret (and invalidate old one) 2022-01-20 15:42:45 +01:00
Elikill58 5234812a49 Change uploaded fild 2022-01-20 01:55:20 +01:00
Elikill58 ec770ddd15 Publish on discord 2022-01-20 01:50:23 +01:00
Elikill58 fbe0538a71 Make auto-run show artifact (#35 from averyanalex/v2)
Make auto-run show artifact
2022-01-11 21:59:02 +01:00
Alex Averyanov fb1027f4a8 Update build workflow 2022-01-11 18:37:58 +03:00
Elikill58 97e6ad4245 Add auto-upload of artifact 2022-01-11 16:11:11 +01:00
Elikill58 2ef74e9166 Upgrade to JDK 16 2022-01-11 12:54:58 +01:00
Elikill58 05ce1fb059 Upgrade to 2.1 2022-01-11 12:30:30 +01:00
Elikill58 3dcd31807f Fix #15 2022-01-11 12:15:31 +01:00
Elikill58 d026aeea41 Make v2 show tooltip for hand 2022-01-11 12:07:35 +01:00
Elikill58 5ab5ce9e95 Fix error for 1.18 2022-01-11 11:56:47 +01:00
Elikill58 cf5b5feb9c Edit action's config 2022-01-11 10:20:53 +01:00
Elikill58 d579eb8e4a Fix amount items 2022-01-11 10:12:12 +01:00
Elikill58 fec31fe4bb Fix possible reload issue 2022-01-11 10:09:13 +01:00
Elikill58 b6d25866c1 Add tab 2022-01-11 09:59:24 +01:00
Elikill58 58fe4a2aeb Add item in inventory 2022-01-11 09:56:33 +01:00
Elikill58 37e9359b1f Introduce message system 2022-01-10 16:52:53 +01:00
Elikill58 78adf1c9d0 Create inventory 2022-01-10 15:54:17 +01:00
Elikill58 19ad0c362c Introduce /chatitem command 2022-01-10 15:45:38 +01:00
Elikill58 3785534b0e Re-add warn message 2022-01-10 15:11:51 +01:00
Elikill58 8e8fa85ec3 Fix some plugin compatibility with 1.18 2022-01-10 14:52:16 +01:00
Elikill58 ad340f239e Make changes for 1.16+ 2022-01-09 23:17:21 +01:00
Elikill58 3e53c370ec Remove unused code 2022-01-09 21:56:36 +01:00
Elikill58 dff6d30e78 Fix 1.18 support 2022-01-09 21:03:15 +01:00
Elikill58 275a7bb773 Fix error while reloading with packets 2022-01-08 22:43:20 +01:00
Elikill58 26ec7ec819 Allow reload for manager and begin of 'both' manager 2022-01-08 22:28:02 +01:00
Elikill58 592981a678 Fix error with bungee serializer 2022-01-08 21:37:52 +01:00
Elikill58 fbe286ded5 Update chat v2 2022-01-08 19:12:46 +01:00
Elikill58 7780e8a406 Prevent translated item without space 2022-01-08 19:05:25 +01:00
Elikill58 b70bc7ee51 Remove unecessary mvn config 2022-01-08 18:53:37 +01:00
Elikill58 57baf6675a Use HexNicks for chat manager 2022-01-08 18:51:41 +01:00
Elikill58 8998498383 Make possible to change for API 2022-01-08 18:38:01 +01:00
Elikill58 94a7c549d7 add PlayerNamer 2022-01-08 18:37:25 +01:00
Elikill58 988b0e8080 Add HexNicks to dep 2022-01-08 18:06:53 +01:00
Elikill58 22e51bf668 Merge branch 'v2' of https://github.com/dadus33-plugins/ChatItem into v2 2021-12-31 13:10:06 +01:00
Elikill58 1f70b0048e Fix https repo 2021-12-30 11:13:49 +01:00
Elikill58 e18ef8a927 Fix chat spam 2021-12-30 08:31:08 +01:00
Elikill58 86078e7869 Add config for maven 2021-12-27 14:59:32 +01:00
Elikill58 212bf7174e Merge branch 'v2' of https://github.com/dadus33-plugins/ChatItem into v2 2021-12-27 14:39:16 +01:00
Elikill58 284396ea28 Use own repo 2021-12-27 14:39:07 +01:00
Elikill58 0bd697cbd4 Add workflow 2021-12-27 14:04:34 +01:00
Elikill58 72be8e243e Update starting messages 2021-12-27 14:00:45 +01:00
Elikill58 445fb84a40 Fix own packet system 2021-12-27 13:54:41 +01:00
Elikill58 1ebf5b4edb Add soft depend 2021-12-27 13:47:52 +01:00
Elikill58 8869bc88d1 Rename chat packet validator 2021-12-27 13:18:25 +01:00
Elikill58 aae9708647 Make protocol version general 2021-12-27 11:56:46 +01:00
Elikill58 e9736c4031 Rename packet listener 2021-12-26 23:56:17 +01:00
Elikill58 28199b5e0b Fix limit 2021-12-26 23:54:14 +01:00
Elikill58 fe743d8302 Add chat event for v1 2021-12-26 23:52:03 +01:00
Elikill58 2f08ea9509 Fix log 2021-12-26 23:30:44 +01:00
Elikill58 854dcca6ee Update config keys 2021-12-26 23:25:17 +01:00
Elikill58 9072db7c1b Add auto mode 2021-12-26 23:19:06 +01:00
Elikill58 2b0ca413b4 Add both manager 2021-12-26 23:11:50 +01:00
Elikill58 0f1ce81a31 Update dependencies 2021-12-26 20:31:12 +01:00
Elikill58 1b714f25b8 Upgrading to v13 for config 2021-12-26 20:20:29 +01:00
Elikill58 c03b8b4810 Remove some useless comments 2021-12-26 20:15:29 +01:00
Elikill58 5f0744dd0e Use recipients 2021-12-26 20:11:49 +01:00
Elikill58 fe1676620f Fix multiple message type 2021-11-25 17:06:39 +01:00
Elikill58 ec5b2fe509 Fix event not working 2021-11-25 16:12:49 +01:00
Elikill58 3efe63bb49 Add default values for config 2021-11-25 15:30:36 +01:00
Elikill58 48a1dfbc26 Fix messages not well parsed 2021-11-25 15:17:43 +01:00
Elikill58 0a604cf83d Upgrade to 2.0 2021-11-24 19:56:18 +01:00
Elikill58 4bc657ab63 Don't include LangUtils's code 2021-11-24 19:55:44 +01:00
Elikill58 165e8f4474 Clean dependencies 2021-11-24 19:54:23 +01:00
Elikill58 a4ca8611f4 Remove unused code 2021-11-24 19:46:58 +01:00
Elikill58 0f354e2dd9 Fix class not found for 1.17 2021-11-24 19:43:25 +01:00
Elikill58 c9bd62dc47 Add LanguageUtils support #27 2021-11-24 19:25:18 +01:00
Elikill58 f8304aeb28 Add namer feature 2021-11-24 18:48:37 +01:00
Elikill58 1fdf1312a0 Remove unused class event 2021-11-24 15:56:12 +01:00
Elikill58 295a7c406c Merge pull request #28 from dadus33-plugins/v2-without-packet
Removing all packet system and fix for thermos
2021-11-24 15:54:03 +01:00
Elikill58 78fbeed7d2 Fix for all versions 2021-11-24 15:52:14 +01:00
Elikill58 446127f7bb Fix for thermos 2021-11-23 18:59:41 +01:00
Elikill58 9dd172447c Clean code 2021-11-23 18:22:17 +01:00
Elikill58 38cb530993 Fix possible issue with 1.17 2021-11-20 23:11:14 +01:00
Elikill58 6bfd45727f Prevent cancellation when not using ChatItem 2021-11-09 18:03:29 +01:00
Elikill58 9f69f078fc Use hand disabled and amount management from config 2021-11-09 15:00:52 +01:00
Elikill58 2050c6c044 Make config reloadable 2021-11-09 00:16:04 +01:00
Elikill58 26d57460d5 Use new system 2021-11-08 22:33:33 +01:00
245 changed files with 8150 additions and 4148 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"
+30
View File
@@ -0,0 +1,30 @@
name: Build v2 for PR
on:
pull_request:
branches: [ v2 ]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
name: Checkout repo
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn install --file pom.xml
- uses: actions/upload-artifact@v3
name: Upload Artifact
with:
name: ChatItem.jar
path: target/ChatItem-*.jar
+36
View File
@@ -0,0 +1,36 @@
name: Build v2
on:
push:
branches: [ v2 ]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
name: Checkout repo
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn install --file pom.xml
- uses: actions/upload-artifact@v4
name: Upload Artifact
with:
name: ChatItem.jar
path: target/ChatItem-*.jar
- name: Send file README.md to discord channel
uses: sinshutu/upload-to-discord@master
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
with:
args: target/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.
+159 -59
View File
@@ -5,18 +5,14 @@
<modelVersion>4.0.0</modelVersion>
<groupId>me.dadus33</groupId>
<artifactId>chatitem</artifactId>
<version>1.4</version>
<artifactId>ChatItem</artifactId>
<version>2.6.2</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>dmulloy2-repo</id>
<url>http://repo.dmulloy2.net/nexus/repository/public/</url>
</repository>
<repository>
<id>Bungeecord</id>
<url>https://repo.md-5.net/content/groups/public/</url>
@@ -29,22 +25,54 @@
<id>sonatype</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<repository>
<id>lang-utils-repo</id>
<url>https://raw.github.com/MascusJeoraly/LanguageUtils/mvn-repo/</url>
</repository>
<repository>
<id>protocollib-repo</id>
<url>https://repo.dmulloy2.net/nexus/repository/public/</url>
</repository>
<repository>
<id>viaversion-repo</id>
<url>https://repo.viaversion.com</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
<id>elikill-repo</id>
<url>https://repo.eliapp.fr:8081/repository/internal/</url>
</repository>
<repository>
<id>dv8tion</id>
<url>https://m2.dv8tion.net/releases</url>
</repository>
<repository>
<id>Scarsz-Nexus</id>
<url>https://nexus.scarsz.me/content/groups/public/</url>
</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>
@@ -54,52 +82,119 @@
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>4.7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.7</version>
<version>2.9.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.meowj</groupId>
<artifactId>LangUtils</artifactId>
<version>1.9</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<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>
<groupId>com.github.ProtocolSupport</groupId>
<groupId>io.shevchik</groupId>
<artifactId>ProtocolSupport</artifactId>
<version>f34959c331</version>
<version>1.18.2-1-dev</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.GeyserMC</groupId>
<artifactId>opennbt</artifactId>
<version>1.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.53.Final</version>
<scope>compile</scope>
<version>4.1.58.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.GeyserMC</groupId>
<artifactId>opennbt</artifactId>
<version>1.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>dev.majek</groupId>
<artifactId>HexNicks</artifactId>
<version>3.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.17.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-bukkit</artifactId>
<version>4.3.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.discordsrv</groupId>
<artifactId>discordsrv</artifactId>
<version>1.28.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.willfp</groupId>
<artifactId>EcoEnchants</artifactId>
<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>
@@ -109,37 +204,24 @@
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>plugin.yml</include>
<include>config.yml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<version>3.10.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<outputDirectory>${dir}</outputDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
@@ -149,23 +231,41 @@
<configuration>
<minimizeJar>true</minimizeJar>
<relocations>
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>me.dadus33.libs.bstats</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.gson</pattern>
<shadedPattern>me.dadus33.libs.gson</shadedPattern>
</relocation>
<relocation>
<pattern>com.github.GeyserMC</pattern>
<pattern>com.github.steveice10.opennbt</pattern>
<shadedPattern>me.dadus33.libs.opennbt</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>*</artifact>
<excludes>
<exclude>net.kyori:examination-api:**</exclude>
<exclude>net.kyori:examination-string:**</exclude>
<exclude>net.kyori:adventure-platform-api:**</exclude>
<exclude>net.kyori:adventure-text-serializer-legacy:**</exclude>
<exclude>net.kyori:adventure-text-serializer-gson:**</exclude>
<exclude>net.kyori:adventure-platform-facet:**</exclude>
<exclude>net.kyori:adventure-nbt:**</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<outputDirectory>${export_dir}</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
+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);
}
}
+256 -132
View File
@@ -1,147 +1,271 @@
package me.dadus33.chatitem;
import org.bukkit.Bukkit;
import org.bukkit.Server;
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.plugin.ServicePriority;
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 me.dadus33.chatitem.api.APIImplementation;
import me.dadus33.chatitem.api.ChatItemAPI;
import me.dadus33.chatitem.commands.CIReload;
import me.dadus33.chatitem.filters.Log4jFilter;
import me.dadus33.chatitem.json.JSONManipulator;
import me.dadus33.chatitem.json.JSONManipulatorCurrent;
import me.dadus33.chatitem.listeners.ChatEventListener;
import me.dadus33.chatitem.listeners.ChatPacketListenerV2;
import me.dadus33.chatitem.listeners.ChatPacketValidatorV2;
import me.dadus33.chatitem.packets.ChatItemPacketManager;
import me.dadus33.chatitem.playerversion.IPlayerVersion;
import me.dadus33.chatitem.playerversion.hooks.DefaultVersionHook;
import me.dadus33.chatitem.playerversion.hooks.ProtocolSupportHook;
import me.dadus33.chatitem.playerversion.hooks.ViaVersionHook;
import me.dadus33.chatitem.utils.Storage;
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 = 12;
private static ChatItem instance;
private ChatEventListener chatEventListener;
private Log4jFilter filter;
private Storage storage;
private static boolean baseComponentAvailable = true;
private IPlayerVersion playerVersionAdapter;
private ChatItemPacketManager packetManager;
public static void reload(CommandSender sender) {
ChatItem obj = getInstance();
//obj.pm = ProtocolLibrary.getProtocolManager();
obj.saveDefaultConfig();
obj.reloadConfig();
obj.storage = new Storage(obj.getConfig());
//obj.packetListener.setStorage(obj.storage);
//obj.packetValidator.setStorage(obj.storage);
obj.chatEventListener.setStorage(obj.storage);
obj.filter.setStorage(obj.storage);
APIImplementation api = (APIImplementation) Bukkit.getServicesManager().getRegistration(ChatItemAPI.class).getProvider();
api.setStorage(obj.storage);
api.updateLogger();
if (!obj.storage.RELOAD_MESSAGE.isEmpty())
sender.sendMessage(obj.storage.RELOAD_MESSAGE);
}
public static ChatItem getInstance() {
return instance;
}
@Override
public void onEnable() {
//Save the instance (we're basically a singleton)
instance = this;
//Load ProtocolManager
//pm = ProtocolLibrary.getProtocolManager();
//Load config
saveDefaultConfig();
storage = new Storage(getConfig());
//Load API
APIImplementation api = new APIImplementation(storage);
Bukkit.getServicesManager().register(ChatItemAPI.class, api, this, ServicePriority.Highest);
//Packet listeners
packetManager = new ChatItemPacketManager(this);
packetManager.getPacketManager().addHandler(new ChatPacketValidatorV2(storage));
packetManager.getPacketManager().addHandler(new ChatPacketListenerV2(storage));
/*packetListener = new ChatPacketListener(this, ListenerPriority.LOW, storage, PacketType.Play.Server.CHAT);
packetValidator = new ChatPacketValidator(this, ListenerPriority.LOWEST, storage, PacketType.Play.Server.CHAT);
pm.addPacketListener(packetValidator);
pm.addPacketListener(packetListener);*/
if(Bukkit.getPluginManager().getPlugin("ViaVersion") != null){
playerVersionAdapter = new ViaVersionHook();
} else if(Bukkit.getPluginManager().getPlugin("ProtocolSupport") != null){
playerVersionAdapter = new ProtocolSupportHook();
} else {
playerVersionAdapter = new DefaultVersionHook();
}
//We halt the use of this system for now, until we can solve the infamous getProtocolVersion issue
//Till then, users of both ViaVersion and ProtocolSupport should do just fine
/*if(!protocolSupport && !viaVersion) {
//We only implement our own way of getting protocol versions if we have no other choice
pm.addPacketListener(new HandshakeListener(this, ListenerPriority.MONITOR, PacketType.Handshake.Client.SET_PROTOCOL));
}*/
//Commands
CIReload rld = new CIReload();
Bukkit.getPluginCommand("cireload").setExecutor(rld);
//Bukkit API listeners
chatEventListener = new ChatEventListener(storage);
Bukkit.getPluginManager().registerEvents(chatEventListener, this);
//Check for existence of BaseComponent class (only on spigot)
try {
Class.forName("net.md_5.bungee.api.chat.BaseComponent");
} catch (ClassNotFoundException e) {
baseComponentAvailable = false;
}
//Initialize Log4J filter (remove ugly console messages)
filter = new Log4jFilter(storage);
}
public IPlayerVersion getPlayerVersionAdapter() {
return playerVersionAdapter;
private static final List<IPlaceholders> PLACEHOLDERS = new ArrayList<>();
public static List<IPlaceholders> getPlaceholders() {
return PLACEHOLDERS;
}
public ChatItemPacketManager getPacketManager() {
return packetManager;
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();
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 String getVersion(Server server) {
final String packageName = server.getClass().getPackage().getName();
public static ChatItem getInstance() {
return instance;
}
return packageName.substring(packageName.lastIndexOf('.') + 1);
}
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;
}
public static boolean supportsChatComponentApi(){
return baseComponentAvailable;
}
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;
public static JSONManipulator getManipulator(){
/*
We used to have 2 kinds of JSONManipulators because of my bad understanding of the 1.7 way of parsing JSON chat
The interface should however stay as there might be great changes in future versions in JSON parsing (most likely 1.13)
*/
return new JSONManipulatorCurrent();
//We just return a new one whenever requested for the moment, should implement a cache of some sort some time though
}
public static void debug(String msg) {
if(getInstance().getConfig().getBoolean("debug", false))
getInstance().getLogger().info(msg);
}
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()));
NamerManager.load(this);
PlayerNamerManager.load(this);
}
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() + " (Platform: " + getPlatform().getName() + ")");
// 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());
// 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();
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());
}
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) -> ItemPlayer.getPlayer(p).setClientName(new String(msg).substring(1)));
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 Storage getStorage() {
return storage;
}
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 boolean isHasNewVersion() {
return hasNewVersion;
}
}
@@ -0,0 +1,83 @@
package me.dadus33.chatitem;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import me.dadus33.chatitem.playerversion.PlayerVersionManager;
import me.dadus33.chatitem.utils.Version;
public class ItemPlayer {
private static final ConcurrentHashMap<UUID, ItemPlayer> PLAYERS = new ConcurrentHashMap<>();
public static ItemPlayer getPlayer(Player p) {
return PLAYERS.computeIfAbsent(p.getUniqueId(), ItemPlayer::new);
}
public static ItemPlayer getPlayer(UUID uuid) {
return PLAYERS.computeIfAbsent(uuid, ItemPlayer::new);
}
private final UUID uuid;
private int protocolVersion = 0;
private Version version = null;
private String clientName = "unknow";
public ItemPlayer(UUID uuid) {
this.uuid = uuid;
Player p = Bukkit.getPlayer(uuid);
if(p != null)
setVersion(PlayerVersionManager.getPlayerVersionAdapter().getPlayerVersion(p));
}
public UUID getUUID() {
return uuid;
}
public Player getPlayer() {
return Bukkit.getPlayer(uuid);
}
public String getClientName() {
return clientName;
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
public int getProtocolVersion() {
if(protocolVersion == 0)
setProtocolVersion(PlayerVersionManager.getPlayerVersionAdapter().getProtocolVersion(getPlayer()));
return protocolVersion;
}
public void setProtocolVersion(int protocolVersion) {
this.protocolVersion = protocolVersion;
if(version == Version.getVersion()) {// if is default
version = Version.getVersion(protocolVersion);
ChatItem.debug("Detected version " + version.name() + " (protocol: " + protocolVersion + ")");
}
}
public Version getVersion() {
if(version == null)
setVersion(PlayerVersionManager.getPlayerVersionAdapter().getPlayerVersion(getPlayer()));
return version;
}
public void setVersion(Version version) {
this.version = version;
if(protocolVersion == 0)
this.protocolVersion = version.MAX_VER;
}
public boolean isBuggedClient() {
return (getVersion().equals(Version.V1_7) && getClientName().toLowerCase().contains("lunarclient")) || (!getVersion().isNewerOrEquals(Version.V1_15) && Version.getVersion().isNewerOrEquals(Version.V1_16));
}
@Override
public String toString() {
return "ItemPlayer[uuid=" + uuid + ",name=" + (getPlayer() != null ? getPlayer().getName() : "-") + ",version=" + version.name() + ",protocol=" + protocolVersion + ",client=" + clientName + "]";
}
}
@@ -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
}
}
}
}
@@ -1,184 +0,0 @@
package me.dadus33.chatitem.api;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.json.JSONManipulator;
import me.dadus33.chatitem.json.Translator;
import me.dadus33.chatitem.listeners.ChatPacketListenerV2;
import me.dadus33.chatitem.utils.ProtocolVersion;
import me.dadus33.chatitem.utils.Storage;
public class APIImplementation implements ChatItemAPI {
private final static String DEFAULT_JSON = "{\"extra\":[{\"text\":\"i\"}]}";
private final static String BASE_JSON = "{\"text\":\"\", \"extra\":[]}";
private final static List<String> DEFAULT_REPLACEMENT = Collections.singletonList("i");
private Storage c;
private Logger logger;
public APIImplementation(Storage st){
this.c = st;
this.logger = ChatItem.getInstance().getLogger();
}
public void updateLogger(){
this.logger = ChatItem.getInstance().getLogger();
}
public void setStorage(Storage newStorage){
this.c = newStorage;
}
@Override
public String getJSONFromItem(ItemStack item) {
JSONManipulator manipulator = ChatItem.getManipulator();
try {
return manipulator.parse(DEFAULT_JSON, DEFAULT_REPLACEMENT, item, ChatPacketListenerV2.styleItem(item, c), ProtocolVersion.getServerVersion().MAX_VER);
} catch (Exception e){
logger.log(Level.SEVERE, "An unexpected exception was caught while running an API method from ChatItem. Please contact the developer immediately, providing him with the following stack-trace:");
e.printStackTrace();
return null;
}
}
@Override
public String getJSONFromItem(ItemStack item, String customReplacement) {
JSONManipulator manipulator = ChatItem.getManipulator();
try {
return manipulator.parse(DEFAULT_JSON, DEFAULT_REPLACEMENT, item, customReplacement, ProtocolVersion.getServerVersion().MAX_VER);
} catch (Exception e){
logger.log(Level.SEVERE, "An unexpected exception was caught while running an API method from ChatItem. Please contact the developer immediately, providing him with the following stack-trace:");
e.printStackTrace();
return null;
}
}
@Override
public String getJSONFromItem(ItemStack item, Player client) {
JSONManipulator manipulator = ChatItem.getManipulator();
try {
return manipulator.parse(DEFAULT_JSON, DEFAULT_REPLACEMENT, item, ChatPacketListenerV2.styleItem(item, c), ProtocolVersion.getClientVersion(client));
} catch (Exception e){
logger.log(Level.SEVERE, "An unexpected exception was caught while running an API method from ChatItem. Please contact the developer immediately, providing him with the following stack-trace:");
e.printStackTrace();
return null;
}
}
@Override
public String getJSONFromItem(ItemStack item, String customReplacement, Player client) {
JSONManipulator manipulator = ChatItem.getManipulator();
try {
return manipulator.parse(DEFAULT_JSON, DEFAULT_REPLACEMENT, item, customReplacement, ProtocolVersion.getClientVersion(client));
} catch (Exception e){
logger.log(Level.SEVERE, "An unexpected exception was caught while running an API method from ChatItem. Please contact the developer immediately, providing him with the following stack-trace:");
e.printStackTrace();
return null;
}
}
@Override
public String getJSONFromInlineItem(String text, ItemStack... items) {
JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(BASE_JSON).getAsJsonObject();
obj.add("extra", Translator.toJson(text));
String main = obj.toString();
int version = ProtocolVersion.getServerVersion().MAX_VER;
for(int i = 0; i < items.length; ++i){
JSONManipulator manipulator = ChatItem.getManipulator();
ItemStack item = items[i];
String style = ChatPacketListenerV2.styleItem(item, c);
List<String> replacements = Collections.singletonList("%_"+i);
try {
main = manipulator.parse(main, replacements, item, style, version);
} catch (Exception e){
logger.log(Level.SEVERE, "An unexpected exception was caught while running an API method from ChatItem. Please contact the developer immediately, providing him with the following stack-trace:");
e.printStackTrace();
return null;
}
}
return main;
}
@Override
public String getJSONFromInlineItem(String text, String[] customReplacements, ItemStack... items) {
JsonObject wrapper = new JsonObject();
wrapper.add("extra", Translator.toJson(text));
String main = wrapper.toString();
int version = ProtocolVersion.getServerVersion().MAX_VER;
for(int i = 0; i < items.length; ++i){
JSONManipulator manipulator = ChatItem.getManipulator();
ItemStack item = items[i];
String style = Translator.toJson(customReplacements[i]).toString();
List<String> replacements = Collections.singletonList("%_"+i);
try {
main = manipulator.parse(main, replacements, item, style, version);
} catch (Exception e){
logger.log(Level.SEVERE, "An unexpected exception was caught while running an API method from ChatItem. Please contact the developer immediately, providing him with the following stack-trace:");
e.printStackTrace();
return null;
}
}
return main;
}
@Override
public String getJSONFromInlineItem(String text, Player client, ItemStack... items) {
JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(BASE_JSON).getAsJsonObject();
obj.add("extra", Translator.toJson(text));
String main = obj.toString();
int version = ProtocolVersion.getClientVersion(client);
for(int i = 0; i < items.length; ++i){
JSONManipulator manipulator = ChatItem.getManipulator();
ItemStack item = items[i];
String style = ChatPacketListenerV2.styleItem(item, c);
List<String> replacements = Collections.singletonList("%_"+i);
try {
main = manipulator.parse(main, replacements, item, style, version);
} catch (Exception e){
logger.log(Level.SEVERE, "An unexpected exception was caught while running an API method from ChatItem. Please contact the developer immediately, providing him with the following stack-trace:");
e.printStackTrace();
return null;
}
}
return main;
}
@Override
public String getJSONFromInlineItem(String text, Player client, String[] customReplacements, ItemStack... items) {
JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(BASE_JSON).getAsJsonObject();
obj.add("extra", Translator.toJson(text));
String main = obj.toString();
int version = ProtocolVersion.getClientVersion(client);
for(int i = 0; i < items.length; ++i){
JSONManipulator manipulator = ChatItem.getManipulator();
ItemStack item = items[i];
String style = Translator.toJson(customReplacements[i]).toString();
List<String> replacements = Collections.singletonList("%_"+i);
try {
main = manipulator.parse(main, replacements, item, style, version);
} catch (Exception e){
logger.log(Level.SEVERE, "An unexpected exception was caught while running an API method from ChatItem. Please contact the developer immediately, providing him with the following stack-trace:");
e.printStackTrace();
return null;
}
}
return main;
}
}
@@ -1,22 +0,0 @@
package me.dadus33.chatitem.api;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public interface ChatItemAPI {
String getJSONFromItem(ItemStack item);
String getJSONFromItem(ItemStack item, String customReplacement);
String getJSONFromItem(ItemStack item, Player client);
String getJSONFromItem(ItemStack item, String customReplacement, Player client);
String getJSONFromInlineItem(String text, ItemStack... items);
String getJSONFromInlineItem(String text, String[] customReplacements, ItemStack... items);
String getJSONFromInlineItem(String text, Player client, ItemStack... items);
String getJSONFromInlineItem(String text, Player client, String[] customReplacements, ItemStack... items);
}
@@ -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
}
}
@@ -0,0 +1,390 @@
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.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.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.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}";
private final static String AMOUNT = "{amount}";
private final static String TIMES = "{times}";
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 == null ? "" : s.replace(SEPARATOR_STR, Character.toString(SEPARATOR)).replace(SEPARATOR_END_STR, Character.toString(SEPARATOR_END));
}
public static boolean equalsSeparator(String s) {
return s != null && (s.equalsIgnoreCase(SEPARATOR_STR) || s.equalsIgnoreCase(Character.toString(SEPARATOR)));
}
public static boolean containsSeparator(String s) {
return s != null && (s.contains(SEPARATOR_STR) || s.contains(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 boolean containsSeparatorEnd(String s) {
return s != null && (s.contains(SEPARATOR_END_STR) || s.contains(Character.toString(SEPARATOR_END)));
}
protected Storage s;
public ChatManager() {
}
public abstract String getName();
public abstract String getId();
public Storage getStorage() {
return s;
}
public void load(ChatItem pl, Storage s) {
this.s = s;
}
public abstract void unload(ChatItem pl);
/**
* Get the item in hand as usable one.<br>
* Will include, in lore, all informations from other plugins.
*
* @param p the player
* @return the usable item
*/
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
*
* @param item the item to get lines from
* @return all lores
*/
public static List<String> getMaxLinesFromItem(Player viewer, ItemStack item) {
List<String> lines = new ArrayList<>();
if (item.hasItemMeta()) {
ItemMeta meta = item.getItemMeta();
lines.add(NamerManager.getName(viewer, item, ChatItem.getInstance().getStorage()));
if (meta.hasEnchants()) {
meta.getEnchants().forEach((enchant, lvl) -> {
lines.add(Colors.RESET + Utils.getEnchantName(enchant) + " " + Utils.toRoman(lvl));
});
}
if (meta.hasLore())
lines.addAll(meta.getLore());
} else {
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 viewer the player
* @param item the item
* @param c the config
* @return the name of item
*/
public static String styleItem(Player viewer, ItemStack item, Storage c) {
String replacer = c.nameFormat;
String amount = c.amountFormat;
if (item.getAmount() == 1) {
if (c.addAmountForced) {
amount = amount.replace(TIMES, "1");
replacer = replacer.replace(AMOUNT, amount);
} else {
replacer = replacer.replace(AMOUNT, "");
}
} else {
amount = amount.replace(TIMES, String.valueOf(item.getAmount()));
replacer = replacer.replace(AMOUNT, amount);
}
return replacer.replace(NAME, NamerManager.getName(viewer, item, c));
}
/**
* Get the name of item according to player & config
*
* @param p the player that is owner of item
* @param item the item
* @param c the config
* @return the name of item or hand
*/
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);
}
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);
}
return ChatItem.replace(chat.getPlayer(), styleItem(viewer, item, c));
}
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());
}
return ChatItem.replace(action.getOrigin(), styleItem(viewer, item, c));
}
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) {
Storage c = ChatItem.getInstance().getStorage();
if (seconds < 60) {
return seconds + c.SECONDS;
}
if (seconds < 3600) {
StringBuilder builder = new StringBuilder();
int minutes = (int) seconds / 60;
builder.append(minutes).append(c.minutes);
int secs = (int) seconds - minutes * 60;
if (secs != 0) {
builder.append(" ").append(secs).append(c.SECONDS);
}
return builder.toString();
}
StringBuilder builder = new StringBuilder();
int hours = (int) seconds / 3600;
builder.append(hours).append(c.hours);
int minutes = (int) (seconds / 60) - (hours * 60);
if (minutes != 0) {
builder.append(" ").append(minutes).append(c.minutes);
}
int secs = (int) (seconds - ((seconds / 60) * 60));
if (secs != 0) {
builder.append(" ").append(secs).append(c.SECONDS);
}
return builder.toString();
}
public static boolean canUsePlaceholder(Player p, ChatAction action, ItemSlot slot, @Nullable Cancellable e) {
Storage c = ChatItem.getInstance().getStorage();
if (c.permissionEnabled && !p.hasPermission(c.permissionName)) {
if (!c.letMessageThrough) {
if (e != null)
e.setCancelled(true);
}
if (!c.messageNoPermission.isEmpty() && c.showNoPermissionMessage) {
sendIfNeed(p, c.messageNoPermission);
}
return false;
}
if (action.isItem() && action.getItem().getType().equals(Material.AIR) && slot.isBasic()) {
if (slot.isDenyIfNoItem()) {
if (e != null)
e.setCancelled(true);
if (!c.messageDeny.isEmpty())
sendIfNeed(p, c.messageDeny);
return false;
}
if (c.handDisabled) {
return false;
}
}
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) {
COOLDOWNS.remove(p.getUniqueId());
} else {
if (!c.letMessageThrough) {
if (e != null)
e.setCancelled(true);
}
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) {
long diff = System.currentTimeMillis() - time;
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);
}
}
@@ -0,0 +1,38 @@
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, 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 null; // should never happen
}
}
@@ -0,0 +1,170 @@
package me.dadus33.chatitem.chatmanager.v1;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import org.bukkit.Bukkit;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.chatmanager.ChatManager;
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.ReflectionUtils;
import me.dadus33.chatitem.utils.Utils;
public class PacketEditingChatManager extends ChatManager {
private boolean baseComponentAvailable = true;
private final ChatItemPacketManager packetManager;
private final ChatPacketManager chatPacketManager;
public PacketEditingChatManager(ChatItem pl) {
packetManager = new ChatItemPacketManager(pl);
chatPacketManager = new ChatPacketManager(this);
// Check for existence of BaseComponent class (only on spigot)
try {
Class.forName("net.md_5.bungee.api.chat.BaseComponent");
} catch (ClassNotFoundException e) {
baseComponentAvailable = false;
}
}
@Override
public String getName() {
return "PacketEditing";
}
@Override
public String getId() {
return "packet";
}
@Override
public void load(ChatItem pl, Storage s) {
super.load(pl, s);
PacketManager pm = packetManager.getPacketManager();
pm.addHandler(chatPacketManager);
Bukkit.getOnlinePlayers().forEach(pm::addPlayer); // add actual online players
}
@Override
public void unload(ChatItem pl) {
PacketManager pm = packetManager.getPacketManager();
pm.removeHandler(chatPacketManager);
pm.stop();
}
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, 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);
// 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;
}
}
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);
}
}
@@ -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();
}
}
}
@@ -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;
}
}
@@ -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();
}
}
}
@@ -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();
}
}
}
@@ -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,17 +1,86 @@
package me.dadus33.chatitem.json;
package me.dadus33.chatitem.chatmanager.v1.json;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.bukkit.ChatColor;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.utils.ColorManager;
import net.md_5.bungee.api.ChatColor;
//Based on DarkSeraphim's system, but using Gson and supporting some more edge cases
public class Translator {
private static final String STYLES = "klmnor"; //All style codes
public static JsonArray toJson(String old){
if(old.lastIndexOf(ChatColor.COLOR_CHAR) == -1){
JsonArray arr = new JsonArray();
JsonObject obj = new JsonObject();
obj.addProperty("text", old);
arr.add(obj);
return arr;
}
JsonArray message = new JsonArray();
JsonObject next = new JsonObject();
String colorCode = "", text = "";
boolean waiting = false;
for (char args : old.toCharArray()) {
if (args == '§') { // begin of color
if(!text.isEmpty()) {
next.addProperty("text", text);
message.add(next);
next = new JsonObject();
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(isStyle(args)) { // is style and not making rich color code
next.addProperty(getStyleName(args), true);
continue;
}
if(args == 'x' && !colorCode.isEmpty()) {
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 {
if(!colorCode.isEmpty()) { // manage color
if(colorCode.startsWith("x") && colorCode.length() == 7) { // hex color code
next.addProperty("color", ColorManager.getColor(colorCode).getName());
} else if(colorCode.length() == 1) { // if only one color code
if(next.has("color"))
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"
text += ColorManager.getColorString(colorCode);
ChatItem.debug("[Translator] Add color code " + colorCode + " to " + text + args + ", msg: " + message);
colorCode = "";
}
// basic text, not waiting for code after '§'
text += args;
}
}
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);
ChatItem.debug("[Translator] Added content " + next + " to message" + message);
message.add(next);
}
return message;
}
public static JsonArray toJsonOld(String old){
if(old.lastIndexOf(ChatColor.COLOR_CHAR) == -1){
JsonArray arr = new JsonArray();
JsonObject obj = new JsonObject();
@@ -105,7 +174,7 @@ public class Translator {
}
private static String getColorName(char code){
return ChatColor.getByChar(code).name().toLowerCase();
return ChatColor.getByChar(code).getName().toLowerCase();
}
private static String getStyleName(char code){
@@ -116,7 +185,9 @@ public class Translator {
case 'n': return "underlined";
case 'o': return "italic";
case 'r': return "reset";
default: return null; //Should never happen. Made it return null to throw errors if a new format pops up and it really happens
default:
ChatItem.getInstance().getLogger().severe("Can't find code for style " + code);
return null; //Should never happen. Made it return null to throw errors if a new format pops up and it really happens
}
}
@@ -0,0 +1,190 @@
package me.dadus33.chatitem.chatmanager.v1.listeners;
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.block.ShulkerBox;
import org.bukkit.entity.Player;
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.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.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.Version;
public class ChatPacketManager extends PacketHandler {
private Object lastSentPacket = null;
private PacketEditingChatManager manager;
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 {
Class.forName("net.kyori.adventure.text.Component");
tryRegister(new AdventureComponentManager());
} catch (Exception e) {
}
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;
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 = "{}";
IComponentManager choosedGetter = null;
if (version.isNewerOrEquals(Version.V1_19)) {
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
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) {
json = ChatManager.fixSeparator(tmpJson);
choosedGetter = getters;
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) {
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
}
if (!ChatManager.containsSeparator(json)) // if the message doesn't contain the BELL separator
return;
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("Chat null for " + json);
return;
}
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();
String message = null;
try {
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);
}
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());
}
}
} 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();
}
});
}
public Storage getStorage() {
return manager.getStorage();
}
}
@@ -1,14 +1,13 @@
package me.dadus33.chatitem.packets;
package me.dadus33.chatitem.chatmanager.v1.packets;
import org.bukkit.entity.Player;
public class ChatItemPacket {
protected Player player;
protected final Player player;
protected Object packet;
protected PacketType type;
protected boolean cancel = false;
protected PacketMetadata metaData = new PacketMetadata();
public ChatItemPacket(PacketType type, Object packet, Player player) {
this.player = player;
@@ -31,6 +30,10 @@ public class ChatItemPacket {
public Object getPacket() {
return packet;
}
public void setPacket(Object packet) {
this.packet = packet;
}
public String getPacketName() {
return packet.getClass().getSimpleName();
@@ -51,8 +54,4 @@ public class ChatItemPacket {
public PacketContent getContent() {
return new PacketContent(this);
}
public PacketMetadata getMetaData() {
return metaData;
}
}
@@ -1,11 +1,13 @@
package me.dadus33.chatitem.packets;
package me.dadus33.chatitem.chatmanager.v1.packets;
import java.util.Arrays;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.packets.custom.CustomPacketManager;
import me.dadus33.chatitem.packets.protocollib.ProtocollibPacketManager;
import me.dadus33.chatitem.chatmanager.v1.packets.custom.CustomPacketManager;
import me.dadus33.chatitem.chatmanager.v1.packets.protocollib.ProtocollibPacketManager;
public class ChatItemPacketManager {
@@ -18,12 +20,14 @@ public class ChatItemPacketManager {
pl.getLogger().info("The plugin ProtocolLib has been detected. Loading Protocollib support ...");
packetManager = new ProtocollibPacketManager(pl);
} else {
pl.getLogger().warning("The plugin ProtocolLib has been detected but you have an OLD version, so we cannot use it.");
pl.getLogger().warning("The plugin ProtocolLib has been detected but you have an old or too new version, so we cannot use it.");
pl.getLogger().warning("Fallback to default Packet system ...");
packetManager = new CustomPacketManager(pl);
}
} else
} else {
pl.getLogger().info("Loading own packet system.");
packetManager = new CustomPacketManager(pl);
}
}
public PacketManager getPacketManager() {
@@ -31,11 +35,12 @@ public class ChatItemPacketManager {
}
private boolean checkProtocollibConditions() {
try {
Class.forName("com.comphenix.protocol.injector.server.TemporaryPlayer");
return true;
} catch (ClassNotFoundException e) {
return false;
for(String searchedClass : Arrays.asList("com.comphenix.protocol.injector.server.TemporaryPlayer", "com.comphenix.protocol.injector.temporary.TemporaryPlayer")) { // class since 4.4.0 until 4.8.0, then the new one
try {
Class.forName(searchedClass);
return true; // class found
} catch (ClassNotFoundException e) {}
}
return false;
}
}
@@ -1,9 +1,11 @@
package me.dadus33.chatitem.packets;
package me.dadus33.chatitem.chatmanager.v1.packets;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.stream.Collectors;
import me.dadus33.chatitem.utils.PacketUtils;
@@ -65,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);
}
@@ -75,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;
@@ -103,6 +103,10 @@ public class PacketContent {
}
}
public Object getObj() {
return obj;
}
/**
* Get the size of the Map of content
*
@@ -148,7 +152,7 @@ public class PacketContent {
* @throws NoSuchElementException if the value doesn't exist
*/
public T read(int i) {
return content.values().stream().filter(Objects::nonNull).findFirst().get();
return content.values().stream().filter(Objects::nonNull).collect(Collectors.toList()).get(i);
}
/**
@@ -169,7 +173,8 @@ public class PacketContent {
* @return the requested value.
*/
public T readSafely(int i, T defaultValue) {
return content.values().stream().filter(Objects::nonNull).findFirst().orElse(defaultValue);
List<T> vals = content.values().stream().filter(Objects::nonNull).collect(Collectors.toList());
return vals.size() <= i ? defaultValue : vals.get(i);
}
/**
@@ -185,6 +190,7 @@ public class PacketContent {
} else {
content.put(key, value);
try {
key.setAccessible(true);
key.set(obj, value);
} catch (Exception e) {
e.printStackTrace();
@@ -1,4 +1,4 @@
package me.dadus33.chatitem.packets;
package me.dadus33.chatitem.chatmanager.v1.packets;
public abstract class PacketHandler {
@@ -1,4 +1,4 @@
package me.dadus33.chatitem.packets;
package me.dadus33.chatitem.chatmanager.v1.packets;
import java.util.ArrayList;
@@ -6,9 +6,9 @@ import org.bukkit.entity.Player;
public abstract class PacketManager {
public abstract void addPlayer(Player p);
public abstract void removePlayer(Player p);
public abstract void clear();
public void addPlayer(Player p) {}
public void removePlayer(Player p) {}
public abstract void stop();
private final ArrayList<PacketHandler> handlers = new ArrayList<>();
public boolean addHandler(PacketHandler handler) {
@@ -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,6 +1,7 @@
package me.dadus33.chatitem.packets;
package me.dadus33.chatitem.chatmanager.v1.packets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public interface PacketType {
@@ -10,6 +11,13 @@ public interface PacketType {
String getFullName();
List<String> getAlias();
public static List<PacketType> values() {
List<PacketType> list = new ArrayList<>();
list.addAll(Arrays.asList(Server.values()));
list.addAll(Arrays.asList(Handshake.values()));
return list;
}
static final String SERVER_PREFIX = "PacketPlayOut", HANDSHAKE_PREFIX = "PacketHandshaking";
public static PacketType getType(String packetName) {
@@ -18,6 +26,10 @@ public interface PacketType {
} else if(packetName.startsWith(HANDSHAKE_PREFIX)) {
return getPacketTypeFor(packetName, Handshake.values(), Handshake.UNSET);
} else {
for(PacketType types : values()) {
if(types.getFullName().equalsIgnoreCase(packetName) || types.getAlias().contains(packetName))
return types;
}
return null;
}
}
@@ -31,7 +43,7 @@ public interface PacketType {
public static enum Server implements PacketType {
CHAT("Chat"),
CHAT("Chat", "ClientboundPlayerChatPacket", "ClientboundSystemChatPacket"),
UNSET("Unset");
private final String packetName, fullName;
@@ -41,7 +53,7 @@ public interface PacketType {
this.packetName = packetName;
this.fullName = SERVER_PREFIX + packetName;
for(String al : alias)
this.alias.add(SERVER_PREFIX + al);
this.alias.add(al);
}
@Override
@@ -1,8 +1,8 @@
package me.dadus33.chatitem.packets.custom;
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,15 +10,13 @@ import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;
import me.dadus33.chatitem.packets.ChatItemPacket;
import me.dadus33.chatitem.packets.PacketManager;
import me.dadus33.chatitem.packets.PacketType;
import me.dadus33.chatitem.packets.custom.channel.ChannelAbstract;
import me.dadus33.chatitem.packets.custom.channel.INC2Channel;
import me.dadus33.chatitem.packets.custom.channel.INCChannel;
import me.dadus33.chatitem.packets.custom.channel.NMUChannel;
import me.dadus33.chatitem.utils.ProtocolVersion;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketManager;
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;
import me.dadus33.chatitem.chatmanager.v1.packets.custom.channel.NMUChannel;
import me.dadus33.chatitem.utils.Utils;
import me.dadus33.chatitem.utils.Version;
public class CustomPacketManager extends PacketManager implements Listener {
@@ -29,24 +27,21 @@ public class CustomPacketManager extends PacketManager implements Listener {
public CustomPacketManager(Plugin pl) {
this.pl = pl;
ProtocolVersion version = ProtocolVersion.getServerVersion();
if (version.isNewerOrEquals(ProtocolVersion.V1_17))
Version version = Version.getVersion();
if (version.isNewerOrEquals(Version.V1_17))
channel = new INC2Channel(this);
else if (version.equals(ProtocolVersion.V1_7))
else if (version.equals(Version.V1_7))
channel = new NMUChannel(this);
else
channel = new INCChannel(this);
pl.getServer().getPluginManager().registerEvents(this, pl);
// we wait the start server
Bukkit.getScheduler().runTaskLater(pl, new Runnable() {
@Override
public void run() {
isStarted = true;
for(Player p : Utils.getOnlinePlayers())
addPlayer(p);
}
}, 40);
CompletableFuture.runAsync(() -> {
isStarted = true;
for(Player p : Utils.getOnlinePlayers())
addPlayer(p);
});
}
public Plugin getPlugin() {
@@ -75,7 +70,7 @@ public class CustomPacketManager extends PacketManager implements Listener {
}
@Override
public void clear() {
public void stop() {
for(Player player : Utils.getOnlinePlayers())
removePlayer(player);
if(channel.getAddChannelExecutor() != null)
@@ -83,12 +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;
}
}
@@ -1,19 +1,21 @@
package me.dadus33.chatitem.packets.custom.channel;
package me.dadus33.chatitem.chatmanager.v1.packets.custom.channel;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import me.dadus33.chatitem.packets.custom.CustomPacketManager;
import me.dadus33.chatitem.playerversion.hooks.DefaultVersionHook;
import me.dadus33.chatitem.ItemPlayer;
import me.dadus33.chatitem.chatmanager.v1.packets.custom.CustomPacketManager;
public abstract class ChannelAbstract {
private ExecutorService addChannelExecutor, removeChannelExecutor;
static final String KEY_HANDSHAKE = "packet_handshake_negativity", KEY_HANDLER_SERVER = "packet_handler", KEY_SERVER = "packet_server_negativity";
static final String KEY_HANDSHAKE = "packet_handshake_chatitem", KEY_HANDLER_SERVER = "packet_handler", KEY_SERVER = "packet_server_chatitem";
private CustomPacketManager customPacketManager;
private HashSet<UUID> players = new HashSet<>();
@@ -31,7 +33,7 @@ public abstract class ChannelAbstract {
}
public ExecutorService getOrCreateAddChannelExecutor() {
if(addChannelExecutor == null)
if(addChannelExecutor == null || addChannelExecutor.isTerminated())
addChannelExecutor = Executors.newSingleThreadExecutor();
return addChannelExecutor;
}
@@ -41,7 +43,7 @@ public abstract class ChannelAbstract {
}
public ExecutorService getOrCreateRemoveChannelExecutor() {
if(removeChannelExecutor == null)
if(removeChannelExecutor == null || removeChannelExecutor.isTerminated())
removeChannelExecutor = Executors.newSingleThreadExecutor();
return removeChannelExecutor;
}
@@ -52,7 +54,7 @@ public abstract class ChannelAbstract {
try {
Integer protocol = customPacketManager.protocolVersionPerChannel.remove(getChannel(p));
if(protocol != null)
DefaultVersionHook.PROTOCOL_PER_UUID.put(p.getUniqueId(), protocol);
ItemPlayer.getPlayer(p).setProtocolVersion(protocol);
} catch (Exception e) {
e.printStackTrace();
}
@@ -64,6 +66,17 @@ public abstract class ChannelAbstract {
removeChannel(p, p.getUniqueId().toString());
}
public void removeAllPlayers() {
new ArrayList<>(players).forEach((uuid) -> {
Player p = Bukkit.getPlayer(uuid);
if(p != null) // player don't left
removeChannel(Bukkit.getPlayer(uuid), uuid.toString());
});
players.clear();
}
protected abstract void stopPipelines();
public abstract void addChannel(Player player, String endChannelName);
public abstract void removeChannel(Player player, String endChannelName);
@@ -1,31 +1,42 @@
package me.dadus33.chatitem.packets.custom.channel;
package me.dadus33.chatitem.chatmanager.v1.packets.custom.channel;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import me.dadus33.chatitem.packets.ChatItemPacket;
import me.dadus33.chatitem.packets.PacketContent;
import me.dadus33.chatitem.packets.PacketType;
import me.dadus33.chatitem.packets.custom.CustomPacketManager;
import io.netty.channel.ChannelPipeline;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketContent;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketType;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketContent.ContentModifier;
import me.dadus33.chatitem.chatmanager.v1.packets.custom.CustomPacketManager;
public class ChannelInboundHandler extends ChannelInboundHandlerAdapter {
public static final HashMap<Channel, ChatItemPacket> TMP = new HashMap<>();
private CustomPacketManager packetManager;
private List<ChannelPipeline> pipelines = new ArrayList<>();
public ChannelInboundHandler(CustomPacketManager packetManager) {
this.packetManager = packetManager;
}
public void clean() {
pipelines.forEach(ChannelPipeline::removeFirst);
pipelines.clear();
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.fireChannelRead(msg);
((Channel) msg).pipeline().addFirst(new ChannelInitializer<Channel>() {
ChannelPipeline pipe = ((Channel) msg).pipeline();
pipelines.add(pipe);
pipe.addFirst(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel channel) {
try {
@@ -63,7 +74,13 @@ public class ChannelInboundHandler extends ChannelInboundHandlerAdapter {
try {
PacketType packetType = PacketType.getType(packet.getClass().getSimpleName());
if(packetType != null && packetType == PacketType.Handshake.IS_SET_PROTOCOL) {
packetManager.protocolVersionPerChannel.put(channel, new PacketContent(packet).getIntegers().readSafely(0, 0));
ContentModifier<Integer> ints = new PacketContent(packet).getIntegers();
int possibleProtocol = ints.readSafely(0, 0);
if(possibleProtocol == Bukkit.getPort())
possibleProtocol = ints.readSafely(1, 0);
if(possibleProtocol == -1 || possibleProtocol == 255 || possibleProtocol == Bukkit.getPort())
possibleProtocol = ints.readSafely(2, 0);
packetManager.protocolVersionPerChannel.put(channel, possibleProtocol);
}
super.channelRead(ctx, packet);
} catch (Exception e) {
@@ -1,4 +1,4 @@
package me.dadus33.chatitem.packets.custom.channel;
package me.dadus33.chatitem.chatmanager.v1.packets.custom.channel;
import static me.dadus33.chatitem.utils.PacketUtils.getPlayerConnection;
@@ -11,31 +11,41 @@ import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.ChannelPromise;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.packets.ChatItemPacket;
import me.dadus33.chatitem.packets.PacketType;
import me.dadus33.chatitem.packets.custom.CustomPacketManager;
import me.dadus33.chatitem.playerversion.hooks.DefaultVersionHook;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketType;
import me.dadus33.chatitem.chatmanager.v1.packets.custom.CustomPacketManager;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.ProtocolVersion;
import me.dadus33.chatitem.utils.ReflectionUtils;
import me.dadus33.chatitem.utils.Version;
public class INC2Channel extends ChannelAbstract {
@SuppressWarnings("unchecked")
private final ChannelInboundHandler boundHandler;
private ChannelPipeline pipeline;
public INC2Channel(CustomPacketManager customPacketManager) {
super(customPacketManager);
boundHandler = new ChannelInboundHandler(customPacketManager);
try {
Object mcServer = ReflectionUtils.callMethod(PacketUtils.getCraftServer(), "getServer");
Object mcServer = ReflectionUtils.callMethod(PacketUtils.getCraftServer(), Version.getVersion().equals(Version.V1_17) ? "getServer" : "b");
Object co = ReflectionUtils.getFirstWith(mcServer, PacketUtils.getNmsClass("MinecraftServer", "server."), PacketUtils.getNmsClass("ServerConnection", "server.network."));
((List<ChannelFuture>) ReflectionUtils.getField(co, "f")).forEach((channelFuture) -> {
channelFuture.channel().pipeline().addFirst(new ChannelInboundHandler(customPacketManager));
((List<ChannelFuture>) ReflectionUtils.getObject(co, "f")).forEach((channelFuture) -> {
pipeline = channelFuture.channel().pipeline();
pipeline.addFirst(boundHandler);
});
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void stopPipelines() {
pipeline.remove(boundHandler);
boundHandler.clean();
}
@Override
public void addChannel(final Player player, String endChannelName) {
@@ -46,10 +56,6 @@ public class INC2Channel extends ChannelAbstract {
Channel channel = getChannel(player);
// Managing outgoing packet (to the player)
channel.pipeline().addAfter(KEY_HANDLER_SERVER, KEY_SERVER + endChannelName, new ChannelHandlerSent(player));
ChatItemPacket pa = ChannelInboundHandler.TMP.remove(channel);
if(pa != null)
DefaultVersionHook.PROTOCOL_PER_UUID.put(player.getUniqueId(), pa.getContent().getIntegers().readSafely(0, ProtocolVersion.getServerVersion().MAX_VER));
} catch (NoSuchElementException e) {
// appear when the player's channel isn't accessible because of reload.
getPacketManager().getPlugin().getLogger().warning("Please, don't use reload, this can produce some problem. Currently, " + player.getName() + " isn't fully checked because of that. More details: " + e.getMessage() + " (NoSuchElementException)");
@@ -81,8 +87,8 @@ public class INC2Channel extends ChannelAbstract {
@Override
public Channel getChannel(Player p) throws Exception {
Object playerConnection = getPlayerConnection(p);
Object networkManager = playerConnection.getClass().getField("a").get(playerConnection);
return (Channel) networkManager.getClass().getDeclaredField("k").get(networkManager);//(Channel) networkManager.getClass().getDeclaredField("channel").get(networkManager);
Object networkManager = ReflectionUtils.getFirstWith(playerConnection, PacketUtils.getNmsClass("NetworkManager", "network."));
return ReflectionUtils.getFirstWith(networkManager, Channel.class);
}
private class ChannelHandlerSent extends ChannelOutboundHandlerAdapter {
@@ -98,7 +104,7 @@ public class INC2Channel extends ChannelAbstract {
ChatItemPacket nextPacket = getPacketManager().onPacketSent(PacketType.getType(packet.getClass().getSimpleName()), owner, packet);
if(nextPacket != null && nextPacket.isCancelled())
return;
super.write(ctx, packet, promise);
super.write(ctx, nextPacket == null ? packet : nextPacket.getPacket(), promise);
}
}
}
@@ -1,4 +1,4 @@
package me.dadus33.chatitem.packets.custom.channel;
package me.dadus33.chatitem.chatmanager.v1.packets.custom.channel;
import static me.dadus33.chatitem.utils.PacketUtils.getPlayerConnection;
@@ -12,24 +12,27 @@ import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.ChannelPromise;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.packets.ChatItemPacket;
import me.dadus33.chatitem.packets.PacketContent;
import me.dadus33.chatitem.packets.PacketType;
import me.dadus33.chatitem.packets.custom.CustomPacketManager;
import me.dadus33.chatitem.playerversion.hooks.DefaultVersionHook;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketContent;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketType;
import me.dadus33.chatitem.chatmanager.v1.packets.custom.CustomPacketManager;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.ProtocolVersion;
import me.dadus33.chatitem.utils.ReflectionUtils;
@SuppressWarnings("unchecked")
public class INCChannel extends ChannelAbstract {
private final ChannelInboundHandler boundHandler;
private ChannelPipeline pipeline;
public INCChannel(CustomPacketManager customPacketManager) {
super(customPacketManager);
boundHandler = new ChannelInboundHandler(customPacketManager);
getFuturChannel().forEach((channelFuture) -> {
channelFuture.channel().pipeline().addFirst(new ChannelInboundHandler(customPacketManager));
pipeline = channelFuture.channel().pipeline();
pipeline.addFirst(boundHandler);
});
}
@@ -48,6 +51,12 @@ public class INCChannel extends ChannelAbstract {
return new ArrayList<>();
}
}
@Override
protected void stopPipelines() {
pipeline.remove(boundHandler);
boundHandler.clean();
}
@Override
public void addChannel(final Player player, String endChannelName) {
@@ -58,10 +67,6 @@ public class INCChannel extends ChannelAbstract {
Channel channel = getChannel(player);
// Managing outgoing packet (to the player)
channel.pipeline().addAfter(KEY_HANDLER_SERVER, KEY_SERVER + endChannelName, new ChannelHandlerSent(player));
ChatItemPacket pa = ChannelInboundHandler.TMP.remove(channel);
if(pa != null)
DefaultVersionHook.PROTOCOL_PER_UUID.put(player.getUniqueId(), pa.getContent().getIntegers().readSafely(0, ProtocolVersion.getServerVersion().MAX_VER));
} catch (NoSuchElementException e) {
// appear when the player's channel isn't accessible because of reload.
getPacketManager().getPlugin().getLogger().warning("Please, don't use reload, this can produce some problem. Currently, " + player.getName() + " isn't fully checked because of that. More details: " + e.getMessage() + " (NoSuchElementException)");
@@ -108,15 +113,10 @@ public class INCChannel extends ChannelAbstract {
@Override
public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception {
try {
ChatItemPacket nextPacket = getPacketManager().onPacketSent(PacketType.getType(packet.getClass().getSimpleName()), owner, packet);
if(nextPacket != null && nextPacket.isCancelled())
return;
super.write(ctx, packet, promise);
} catch (Exception e) {
e.printStackTrace();
super.write(ctx, packet, promise);
}
ChatItemPacket nextPacket = getPacketManager().onPacketSent(PacketType.getType(packet.getClass().getSimpleName()), owner, packet);
if(nextPacket != null && nextPacket.isCancelled())
return;
super.write(ctx, nextPacket == null ? packet : nextPacket.getPacket(), promise);
}
}
}
@@ -1,4 +1,4 @@
package me.dadus33.chatitem.packets.custom.channel;
package me.dadus33.chatitem.chatmanager.v1.packets.custom.channel;
import static me.dadus33.chatitem.utils.PacketUtils.getPlayerConnection;
@@ -9,10 +9,10 @@ import java.util.logging.Level;
import org.bukkit.entity.Player;
import me.dadus33.chatitem.packets.ChatItemPacket;
import me.dadus33.chatitem.packets.PacketContent;
import me.dadus33.chatitem.packets.PacketType;
import me.dadus33.chatitem.packets.custom.CustomPacketManager;
import me.dadus33.chatitem.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketContent;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketType;
import me.dadus33.chatitem.chatmanager.v1.packets.custom.CustomPacketManager;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.ReflectionUtils;
import net.minecraft.util.io.netty.channel.Channel;
@@ -22,20 +22,24 @@ import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
import net.minecraft.util.io.netty.channel.ChannelInboundHandlerAdapter;
import net.minecraft.util.io.netty.channel.ChannelInitializer;
import net.minecraft.util.io.netty.channel.ChannelOutboundHandlerAdapter;
import net.minecraft.util.io.netty.channel.ChannelPipeline;
import net.minecraft.util.io.netty.channel.ChannelPromise;
public class NMUChannel extends ChannelAbstract {
private ChannelInboundHandlerAdapter boundHandler;
private ChannelPipeline pipeline;
public NMUChannel(CustomPacketManager customPacketManager) {
super(customPacketManager);
try {
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.getField(co, "g");
List<ChannelFuture> g = (List<ChannelFuture>) ReflectionUtils.getObject(co, "g", "e");
g.forEach((channelFuture) -> {
channelFuture.channel().pipeline().addFirst(new ChannelInboundHandlerAdapter() {
pipeline = channelFuture.channel().pipeline();
pipeline.addFirst(boundHandler = new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
((Channel) msg).pipeline().addFirst(new ChannelInitializer<Channel>() {
@@ -69,6 +73,11 @@ public class NMUChannel extends ChannelAbstract {
e.printStackTrace();
}
}
@Override
protected void stopPipelines() {
pipeline.remove(boundHandler);
}
@Override
public void addChannel(final Player player, String endChannelName) {
@@ -129,7 +138,7 @@ public class NMUChannel extends ChannelAbstract {
ChatItemPacket nextPacket = getPacketManager().onPacketSent(PacketType.getType(packet.getClass().getSimpleName()), owner, packet);
if(nextPacket != null && nextPacket.isCancelled())
return;
super.write(ctx, packet, promise);
super.write(ctx, nextPacket == null ? packet : nextPacket.getPacket(), promise);
}
}
@@ -146,7 +155,7 @@ public class NMUChannel extends ChannelAbstract {
try {
PacketType packetType = PacketType.getType(packet.getClass().getSimpleName());
if(packetType != null && packetType == PacketType.Handshake.IS_SET_PROTOCOL) {
getPacketManager().protocolVersionPerChannel.put(channel, new PacketContent(packet).getIntegers().readSafely(0, 0));
getPacketManager().protocolVersionPerChannel.put(channel, new PacketContent(packet).getIntegers().readSafely(1, 0));
}
super.channelRead(ctx, packet);
} catch (Exception e) {
@@ -0,0 +1,54 @@
package me.dadus33.chatitem.chatmanager.v1.packets.protocollib;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.entity.Player;
import com.comphenix.protocol.PacketType.Play;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
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.chatmanager.v1.packets.ChatItemPacket;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketManager;
import me.dadus33.chatitem.chatmanager.v1.packets.PacketType;
public class ProtocollibPacketManager extends PacketManager {
private final ProtocolManager protocolManager;
public ProtocollibPacketManager(ChatItem pl) {
protocolManager = ProtocolLibrary.getProtocolManager();
List<com.comphenix.protocol.PacketType> list = new ArrayList<>();
list.add(Play.Server.CHAT);
try {
list.add((com.comphenix.protocol.PacketType) Play.Server.class.getDeclaredField("SYSTEM_CHAT").get(null));
} catch (Exception e) {
// ignore because using old version
}
protocolManager.addPacketListener(new PacketAdapter(pl, ListenerPriority.LOWEST, list) {
@Override
public void onPacketSending(PacketEvent e) {
Player p = e.getPlayer();
if (p == null || e.isPlayerTemporary())
return;
ChatItemPacket packet = onPacketSent(PacketType.getType(e.getPacket().getHandle().getClass().getSimpleName()), p, e.getPacket().getHandle());
if(packet == null) {
ChatItem.debug("Can't find packet: " + e.getPacket().getHandle().getClass().getName());
return;
}
if(!e.isCancelled())
e.setCancelled(packet.isCancelled());
}
});
}
@Override
public void stop() {
protocolManager.removePacketListeners(ChatItem.getInstance());
}
}
@@ -1,8 +1,9 @@
package me.dadus33.chatitem.utils;
package me.dadus33.chatitem.chatmanager.v1.utils;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
@Deprecated
public class Item {
private String id;
private byte amount;
@@ -0,0 +1,50 @@
package me.dadus33.chatitem.chatmanager.v1.utils;
import static me.dadus33.chatitem.utils.Version.V1_10;
import static me.dadus33.chatitem.utils.Version.V1_11;
import static me.dadus33.chatitem.utils.Version.V1_8;
import static me.dadus33.chatitem.utils.Version.V1_9;
import org.bukkit.inventory.ItemStack;
@Deprecated
public class ItemRewriter {
public static String remapIds(int server, int player, ItemStack is) {
Item item = new Item();
item.setAmount((byte)is.getAmount());
//item.setData(is.getDurability());
//item.setId(id);
//item.setTag(tag);
if (areIdsCompatible(server, player)) {
return item.getId();
}
if ((server >= V1_9.MIN_VER && player <= V1_8.MAX_VER) || (player >= V1_9.MIN_VER && server <= V1_8.MAX_VER)) {
if ((server >= V1_9.MIN_VER && player <= V1_8.MAX_VER)) {
ItemRewriter_1_9_TO_1_8.reversedToClient(item);
} else
ItemRewriter_1_9_TO_1_8.toClient(item);
}
if ((server <= V1_10.MAX_VER && player >= V1_11.MIN_VER)
|| (player <= V1_10.MAX_VER && server >= V1_11.MIN_VER)) {
if (server <= V1_10.MAX_VER && player >= V1_11.MIN_VER) {
ItemRewriter_1_11_TO_1_10.toClient(item);
} else {
ItemRewriter_1_11_TO_1_10.reverseToClient(item);
}
}
return item.getId();
}
public static boolean areIdsCompatible(int version1, int version2) {
if ((version1 >= V1_9.MIN_VER && version2 <= V1_8.MAX_VER)
|| (version2 >= V1_9.MIN_VER && version1 <= V1_8.MAX_VER)) {
return false;
}
if ((version1 <= V1_10.MAX_VER && version2 >= V1_11.MIN_VER)
|| (version1 <= V1_10.MAX_VER && version2 >= V1_11.MIN_VER)) {
return false;
}
return true;
}
}
@@ -1,4 +1,4 @@
package me.dadus33.chatitem.utils;
package me.dadus33.chatitem.chatmanager.v1.utils;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
@@ -10,6 +10,7 @@ import com.google.common.collect.HashBiMap;
/**
* Thanks to the developers of ViaVersion for this!
*/
@Deprecated
public class ItemRewriter_1_11_TO_1_10 {
private static BiMap<String, String> oldToNewNames = HashBiMap.create();
@@ -1,4 +1,4 @@
package me.dadus33.chatitem.utils;
package me.dadus33.chatitem.chatmanager.v1.utils;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
@@ -9,6 +9,7 @@ import java.util.Map;
/**
* Thanks to the developers of ViaVersion for this!
*/
@Deprecated
public class ItemRewriter_1_9_TO_1_8 {
private static final Map<String, Integer> ENTTIY_NAME_TO_ID = new HashMap<>();
@@ -0,0 +1,102 @@
package me.dadus33.chatitem.chatmanager.v2;
import java.util.HashSet;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
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.hook.DiscordSrvSupport;
import me.dadus33.chatitem.playernamer.PlayerNamerManager;
import me.dadus33.chatitem.utils.Utils;
import net.md_5.bungee.api.ChatColor;
@SuppressWarnings("deprecation")
public class ChatListener implements Listener {
private ChatListenerChatManager manage;
public ChatListener(ChatListenerChatManager manage) {
this.manage = manage;
}
public Storage getStorage() {
return manage.getStorage();
}
@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(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;
}
}
}
}
ChatItem.debug("Chat cancelled for " + e.getPlayer().getName());
return;
}
Player p = e.getPlayer();
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)));
}
}
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;
}
ChatAction action = ChatManager.getChatAction(slot, p);
if(!ChatManager.canUsePlaceholder(p, action, slot, e))
return;
e.setCancelled(true);
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()));
} else {
msg = format.replace(e.getMessage(), defMsg);
}
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), 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);
}
}
@@ -0,0 +1,51 @@
package me.dadus33.chatitem.chatmanager.v2;
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 ChatListenerChatManager extends ChatManager {
private final ChatListener chatListener;
private boolean baseComponentAvailable = true;
public ChatListenerChatManager(ChatItem pl) {
chatListener = new ChatListener(this);
//Check for existence of BaseComponent class (only on spigot)
try {
Class.forName("net.md_5.bungee.api.chat.BaseComponent");
} catch (ClassNotFoundException e) {
baseComponentAvailable = false;
}
}
@Override
public String getName() {
return "ChatListener";
}
@Override
public String getId() {
return "chat";
}
@Override
public void load(ChatItem pl, Storage s) {
super.load(pl, s);
Bukkit.getPluginManager().registerEvents(chatListener, pl);
}
@Override
public void unload(ChatItem pl) {
HandlerList.unregisterAll(chatListener);
}
public boolean supportsChatComponentApi(){
return baseComponentAvailable;
}
}
@@ -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) {
}
}
@@ -1,16 +1,16 @@
package me.dadus33.chatitem.commands;
import me.dadus33.chatitem.ChatItem;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import me.dadus33.chatitem.ChatItem;
public class CIReload implements CommandExecutor {
public class CIReloadCommand implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
ChatItem.reload(sender);
ChatItem.reload(sender);
return false;
}
}
@@ -0,0 +1,179 @@
package me.dadus33.chatitem.commands;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.configuration.ConfigurationSection;
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.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.Utils;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.TextComponent;
@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)) {
Messages.sendMessage(sender, "only-players");
return false;
}
Player p = (Player) sender;
if (args.length == 0) {
Messages.sendMessage(p, "chatitem-cmd.help");
} else if (args[0].equalsIgnoreCase("admin") && p.hasPermission("chatitem.reload")) {
InventoryListener.open(p);
} else if (args[0].equalsIgnoreCase("reload") && p.hasPermission("chatitem.reload")) {
ChatItem.reload(sender);
} 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, 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, ItemSlot.HAND);
for(Player all : Bukkit.getOnlinePlayers())
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");
TextComponent text = new TextComponent(Storage.color(config.getString("begin")));
for (String key : config.getConfigurationSection("list").getKeys(false)) {
ConfigurationSection linkConfig = config.getConfigurationSection("list." + key);
TextComponent linkComp = new TextComponent(Storage.color(linkConfig.getString("message")));
String hover = Storage.color(linkConfig.getString("hover"));
if (hover != null)
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);
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,78 +0,0 @@
package me.dadus33.chatitem.filters;
import me.dadus33.chatitem.listeners.ChatEventListener;
import me.dadus33.chatitem.utils.Storage;
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 static org.apache.logging.log4j.core.Filter.Result.NEUTRAL;
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());
}
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(ChatEventListener.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);
}
}
@@ -0,0 +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, Event e) {
DiscordSRV pl = DiscordSRV.getPlugin();
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();
}
}
}
@@ -0,0 +1,21 @@
package me.dadus33.chatitem.hook.ecoenchants;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.inventory.ItemStack;
import com.willfp.ecoenchants.display.EnchantmentCache;
import com.willfp.ecoenchants.enchantments.util.EnchantChecks;
public class EcoEnchantsV8Support {
public static List<String> getLores(ItemStack item) {
List<String> lores = new ArrayList<>();
EnchantChecks.getEnchantsOnItem(item).forEach((en, lvl) -> {
lores.add(EnchantmentCache.getEntry(en).getNameWithLevel(lvl));
});
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);
}
}
@@ -0,0 +1,54 @@
package me.dadus33.chatitem.itemnamer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import me.dadus33.chatitem.Storage;
public interface INamer {
/**
* Get priority of this namer.<br>
* Get first name that is not null, with this order:
* - MAJOR
*
*
* @return priority
*/
Priority getPriority();
/**
* Get the name of the item thanks to this namer.
*
* @param item the item to get the name
* @param storage the actual config
* @return the name or null if can't find a name
*/
String getName(Player p, ItemStack item, Storage storage);
public enum Priority {
MAJOR(4),
IMPORTANT(3),
MEDIUM(2),
SMALL(1),
MINOR(0);
private final int priority;
Priority(int priority) {
this.priority = priority;
}
public int getPriority() {
return priority;
}
public static List<Priority> getOrderedPriorities() {
return Arrays.stream(values()).sorted((p1, p2) -> p2.getPriority() - p1.getPriority()).collect(Collectors.toList());
}
}
}
@@ -0,0 +1,78 @@
package me.dadus33.chatitem.itemnamer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.StringJoiner;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
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;
public class NamerManager {
private static final HashMap<Priority, List<INamer>> NAMER_PER_PRIORITY = new HashMap<>();
public static void load(ChatItem pl) {
NAMER_PER_PRIORITY.clear();
StringJoiner sj = new StringJoiner(", ");
PluginManager pm = Bukkit.getPluginManager();
if(pm.getPlugin("LangUtils") != null) {
addNamer(new LangUtilsNamer());
sj.add("LangUtils");
}
if(sj.length() > 0)
pl.getLogger().info("Loaded namer for plugin " + sj.toString() + ".");
addNamer(new ChatItemTranslationNamer());
addNamer(new ItemDisplayNamer());
addNamer(new DefaultNamer());
}
/**
* Add namer according to his {@link INamer#getPriority()}'s value
*
* @param namer the namer to add
*/
public static void addNamer(INamer namer) {
getOrCreate(namer.getPriority()).add(namer);
}
private static List<INamer> getOrCreate(Priority p){
return NAMER_PER_PRIORITY.computeIfAbsent(p, (a) -> new ArrayList<>());
}
/**
* Get the name of this item, according to this storage.
*
* @param p the player that will see the name
* @param item the item to show
* @param storage the storage
* @return the name (should NOT return null)
*/
public static String getName(Player p, ItemStack item, Storage storage) {
for(Priority pr : Priority.getOrderedPriorities()) {
List<INamer> allNamers = NAMER_PER_PRIORITY.get(pr);
if(allNamers == null || allNamers.isEmpty())
continue;
for(INamer namer : allNamers) {
String tmpName = namer.getName(p, item, storage);
if(tmpName != null) {
ChatItem.debug("Using namer " + namer.getClass().getSimpleName() + ", value: " + tmpName);
return tmpName;
}
}
}
return null; // this should NEVER append
}
}
@@ -0,0 +1,22 @@
package me.dadus33.chatitem.itemnamer.hook;
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;
public class ChatItemTranslationNamer implements INamer {
@Override
public Priority getPriority() {
return Priority.MINOR;
}
@Override
public String getName(Player p, ItemStack item, Storage storage) {
return Translation.getOr(item, null);
}
}
@@ -0,0 +1,23 @@
package me.dadus33.chatitem.itemnamer.hook;
import org.apache.commons.lang.WordUtils;
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;
public class DefaultNamer implements INamer {
@Override
public Priority getPriority() {
return Priority.SMALL;
}
@Override
public String getName(Player p, ItemStack item, Storage storage) {
Material m = item.getType();
return m.equals(Material.TNT) ? "TNT" : WordUtils.capitalize(m.name().replaceAll("_", " ").toLowerCase());
}
}
@@ -0,0 +1,27 @@
package me.dadus33.chatitem.itemnamer.hook;
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;
@SuppressWarnings("deprecation")
public class ItemDisplayNamer implements INamer {
@Override
public Priority getPriority() {
return Priority.MEDIUM;
}
@Override
public String getName(Player p, ItemStack item, Storage storage) {
String name = ChatItem.getPlatform().getItemDisplayName(item);
if(name != null && name != "")
return storage.colorIfColored ? ChatColor.stripColor(name) : name;
return null;
}
}
@@ -0,0 +1,23 @@
package me.dadus33.chatitem.itemnamer.hook;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.meowj.langutils.lang.LanguageHelper;
import me.dadus33.chatitem.Storage;
import me.dadus33.chatitem.itemnamer.INamer;
public class LangUtilsNamer implements INamer {
@Override
public Priority getPriority() {
return Priority.IMPORTANT;
}
@Override
public String getName(Player p, ItemStack item, Storage storage) {
return LanguageHelper.getItemName(item, p);
}
}
@@ -1,13 +0,0 @@
package me.dadus33.chatitem.json;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
public interface JSONManipulator {
String parse(String json, List<String> replacements, ItemStack item, String repl, int protocol) throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException;
String parseEmpty(String json, List<String> replacements, String repl, List<String> tooltip, Player sender);
}
@@ -1,903 +0,0 @@
package me.dadus33.chatitem.json;
import com.github.steveice10.opennbt.tag.builtin.*;
import com.google.gson.*;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.utils.Item;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.ProtocolVersion;
import me.dadus33.chatitem.utils.Reflect;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@SuppressWarnings("unchecked")
public class JSONManipulatorCurrent implements JSONManipulator{
private static final Class<?> CRAFT_ITEM_STACK_CLASS = PacketUtils.getObcClass("inventory.CraftItemStack");
private static final Class<?> NBT_STRING = PacketUtils.getNmsClass("NBTTagString", "nbt.");
private static final Class<?> NBT_LIST = PacketUtils.getNmsClass("NBTTagList", "nbt.");
private static final Map<Type, Tag> TYPES_TO_OPEN_NBT_TAGS = new HashMap<>();
private static final List<Class<?>> NBT_BASE_CLASSES = new ArrayList<>();
private static final List<Field> NBT_BASE_DATA_FIELD = new ArrayList<>();
private static final Class<?> NMS_ITEM_STACK_CLASS = PacketUtils.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 = PacketUtils.getNmsClass("NBTTagCompound", "nbt.");
private static final Method SAVE_NMS_ITEM_STACK_METHOD = Reflect.getMethod(NMS_ITEM_STACK_CLASS, "save", NBT_TAG_COMPOUND);
private static final Field MAP = Reflect.getField(NBT_TAG_COMPOUND, "map", "x");
private static final Field LIST_FIELD = Reflect.getField(NBT_LIST, "list", "c");
//Tags to be ignored. Currently it only contains tags from PortableHorses, but feel free to submit a pull request to add tags from your plugins
private static final List<String> IGNORED = Arrays.asList("horsetag", "phorse", "iscnameviz", "cname");
private static final ConcurrentHashMap<Map.Entry<ProtocolVersion, ItemStack>, JsonObject> STACKS = new ConcurrentHashMap<>();
static{
NBT_BASE_CLASSES.add(PacketUtils.getNmsClass("NBTTagByte", "nbt."));
NBT_BASE_CLASSES.add(PacketUtils.getNmsClass("NBTTagByteArray", "nbt."));
NBT_BASE_CLASSES.add(PacketUtils.getNmsClass("NBTTagDouble", "nbt."));
NBT_BASE_CLASSES.add(PacketUtils.getNmsClass("NBTTagFloat", "nbt."));
NBT_BASE_CLASSES.add(PacketUtils.getNmsClass("NBTTagInt", "nbt."));
NBT_BASE_CLASSES.add(PacketUtils.getNmsClass("NBTTagIntArray", "nbt."));
NBT_BASE_CLASSES.add(PacketUtils.getNmsClass("NBTTagLong", "nbt."));
NBT_BASE_CLASSES.add(PacketUtils.getNmsClass("NBTTagShort", "nbt."));
for (Class<?> NBT_BASE_CLASS : NBT_BASE_CLASSES) {
NBT_BASE_DATA_FIELD.add(Reflect.getField(NBT_BASE_CLASS, "data", "c", "x"));
}
TYPES_TO_OPEN_NBT_TAGS.put(Byte.class, new ByteTag(""));
TYPES_TO_OPEN_NBT_TAGS.put(Byte[].class, new ByteArrayTag(""));
TYPES_TO_OPEN_NBT_TAGS.put(Double.class, new DoubleTag(""));
TYPES_TO_OPEN_NBT_TAGS.put(Float.class, new FloatTag(""));
TYPES_TO_OPEN_NBT_TAGS.put(Integer.class, new IntTag(""));
TYPES_TO_OPEN_NBT_TAGS.put(Integer[].class, new IntArrayTag(""));
TYPES_TO_OPEN_NBT_TAGS.put(Long.class, new LongTag(""));
TYPES_TO_OPEN_NBT_TAGS.put(Short.class, new ShortTag(""));
//Add the primitive types too, just in case
TYPES_TO_OPEN_NBT_TAGS.put(byte.class, new ByteTag(""));
TYPES_TO_OPEN_NBT_TAGS.put(byte[].class, new ByteArrayTag(""));
TYPES_TO_OPEN_NBT_TAGS.put(double.class, new DoubleTag(""));
TYPES_TO_OPEN_NBT_TAGS.put(float.class, new FloatTag(""));
TYPES_TO_OPEN_NBT_TAGS.put(int.class, new IntTag(""));
TYPES_TO_OPEN_NBT_TAGS.put(int[].class, new IntArrayTag(""));
TYPES_TO_OPEN_NBT_TAGS.put(long.class, new LongTag(""));
TYPES_TO_OPEN_NBT_TAGS.put(short.class, new ShortTag(""));
}
private List<String> replaces;
private String rgx;
private ProtocolVersion protocolVersion;
private JsonObject itemTooltip;
private JsonArray classicTooltip;
private final JsonParser PARSER = new JsonParser();
public String parse(String json, List<String> replacements, ItemStack item, String replacement, int protocol) throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException {
JsonObject obj = PARSER.parse(json).getAsJsonObject();
JsonArray array = obj.getAsJsonArray("extra");
replaces = replacements;
String regex = "";
for (int i = 0; i < replacements.size(); ++i) {
if (replacements.size() == 1) {
regex = Pattern.quote(replacements.get(0));
break;
}
if (i == 0 || i + 1 == replacements.size()) {
if (i == 0) {
regex = "(" + Pattern.quote(replacements.get(i));
} else {
regex = regex.concat("|").concat(Pattern.quote(replacements.get(i))).concat(")");
}
continue;
}
regex = regex.concat("|").concat(Pattern.quote(replacements.get(i)));
}
rgx = regex;
JsonArray rep = new JsonArray();
final AbstractMap.SimpleEntry<ProtocolVersion, ItemStack> p = new AbstractMap.SimpleEntry<>(protocolVersion = ProtocolVersion.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
JsonObject hover = PARSER.parse("{\"action\":\"show_item\", \"value\": \"\"}").getAsJsonObject(); //There's no public clone method for JSONObjects so we need to parse them every time
String jsonRep = stringifyItem(item); //Get the JSON representation of the item (well, not really JSON, but rather a string representation of NBT data)
hover.addProperty("value", jsonRep);
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
Bukkit.getScheduler().runTaskLaterAsynchronously(ChatItem.getInstance(), () ->
STACKS.remove(p)
, 100L); //We remove it later when no longer needed to save memory
}
for (int i = 0; i < array.size(); ++i) {
if (array.get(i).isJsonObject()){
JsonObject o = array.get(i).getAsJsonObject();
boolean inside = false;
for (String replace : replacements)
if (o.toString().contains(replace)) {
if (inside) {
break;
}
inside = true;
}
JsonElement text = o.get("text");
if (text == null) {
JsonElement el = o.get("extra");
if (el != null) {
JsonArray jar = el.getAsJsonArray();
if(jar.size()!=0) {
jar = parseArray(jar);
o.add("extra", jar);
}else{
o.remove("extra");
}
}
continue;
} else {
if (text.getAsString().isEmpty()) {
JsonElement el = o.get("extra");
if (el != null) {
JsonArray jar = el.getAsJsonArray();
if(jar.size()!=0) {
jar = parseArray(jar);
o.add("extra", jar);
}else{
o.remove("extra");
}
}
}
}
String msg = text.getAsString();
boolean isLast = false;
boolean done = false;
boolean fnd;
String[] splits;
for (String repls : replacements) {
if (done) {
break;
}
isLast = msg.endsWith(repls);
if (isLast) {
done = true;
msg = msg.concat(".");
}
}
splits = msg.split(regex);
fnd = splits.length != 1;
if (fnd)
for (int j = 0; j < splits.length; ++j) {
boolean endDot = (j == splits.length - 1) && isLast;
if (!splits[j].isEmpty() && !endDot) {
String st = o.toString();
JsonObject fix = PARSER.parse(st).getAsJsonObject();
fix.addProperty("text", splits[j]);
rep.add(fix);
}
if (j != splits.length - 1) {
rep.add(itemTooltip);
}
}
if (!fnd) {
rep.add(o);
}
}else{
if(array.get(i).isJsonNull()){
continue;
}else{
if(array.get(i).isJsonArray()){
JsonArray jar = array.get(i).getAsJsonArray();
if(jar.size()!=0) {
jar = parseArray(array.get(i).getAsJsonArray());
rep.set(i, jar);
}
}else{
String msg = array.get(i).getAsString();
boolean isLast = false;
boolean done = false;
boolean fnd;
String[] splits;
for (String repls : replacements) {
if (done) {
break;
}
isLast = msg.endsWith(repls);
if (isLast) {
done = true;
msg = msg.concat(".");
}
}
splits = msg.split(regex);
fnd = splits.length != 1;
if (fnd)
for (int j = 0; j < splits.length; ++j) {
boolean endDot = (j == splits.length - 1) && isLast;
if (!splits[j].isEmpty() && !endDot) {
JsonElement fix = new JsonPrimitive(splits[j]);
rep.add(fix);
}
if (j != splits.length - 1) {
rep.add(itemTooltip);
}
}
if (!fnd) {
rep.add(array.get(i));
}
}
}
}
}
obj.add("extra", rep);
if(!obj.has("text")){
obj.addProperty("text", "");
}
return obj.toString();
}
@Override
public String parseEmpty(String json, List<String> replacements, String repl, List<String> tooltip, Player sender) {
JsonObject obj = PARSER.parse(json).getAsJsonObject();
JsonArray array = obj.getAsJsonArray("extra");
replaces = replacements;
String regex = "";
for (int i = 0; i < replacements.size(); ++i) {
if (replacements.size() == 1) {
regex = Pattern.quote(replacements.get(0));
break;
}
if (i == 0 || i + 1 == replacements.size()) {
if (i == 0) {
regex = "(" + Pattern.quote(replacements.get(i));
} else {
regex = regex.concat("|").concat(Pattern.quote(replacements.get(i))).concat(")");
}
continue;
}
regex = regex.concat("|").concat(Pattern.quote(replacements.get(i)));
}
rgx = regex;
JsonArray rep = new JsonArray();
JsonArray use = Translator.toJson(repl.replace("{name}", sender.getName()).replace("{display-name}", sender.getDisplayName()));
JsonObject hover = PARSER.parse("{\"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()));
for (JsonElement ob : use)
ob.getAsJsonObject().add("hoverEvent", hover);
classicTooltip = use;
for (int i = 0; i < array.size(); ++i) {
if (array.get(i).isJsonObject()){
JsonObject o = array.get(i).getAsJsonObject();
boolean inside = false;
for (String replace : replacements)
if (o.toString().contains(replace)) {
if (inside) {
break;
}
inside = true;
}
JsonElement text = o.get("text");
if (text == null) {
JsonElement el = o.get("extra");
if (el != null) {
JsonArray jar = el.getAsJsonArray();
if(jar.size()!=0) {
jar = parseNoItemArray(jar);
o.add("extra", jar);
}else{
o.remove("extra");
}
}
continue;
} else {
if (text.getAsString().isEmpty()) {
JsonElement el = o.get("extra");
if (el != null) {
JsonArray jar = el.getAsJsonArray();
if(jar.size()!=0) {
jar = parseNoItemArray(jar);
o.add("extra", jar);
}else{
o.remove("extra");
}
}
}
}
String msg = text.getAsString();
boolean isLast = false;
boolean done = false;
boolean fnd;
String[] splits;
for (String repls : replacements) {
if (done) {
break;
}
isLast = msg.endsWith(repls);
if (isLast) {
done = true;
msg = msg.concat(".");
}
}
splits = msg.split(regex);
fnd = splits.length != 1;
if (fnd)
for (int j = 0; j < splits.length; ++j) {
boolean endDot = (j == splits.length - 1) && isLast;
if (!splits[j].isEmpty() && !endDot) {
String st = o.toString();
JsonObject fix = PARSER.parse(st).getAsJsonObject();
fix.addProperty("text", splits[j]);
rep.add(fix);
}
if (j != splits.length - 1) {
rep.addAll(use);
}
}
if (!fnd) {
rep.add(o);
}
}else{
if(array.get(i).isJsonNull()){
continue;
}else{
if(array.get(i).isJsonArray()){
JsonArray jar = array.get(i).getAsJsonArray();
if(jar.size()!=0) {
jar = parseNoItemArray(array.get(i).getAsJsonArray());
rep.set(i, jar);
}
}else{
String msg = array.get(i).getAsString();
boolean isLast = false;
boolean done = false;
boolean fnd;
String[] splits;
for (String repls : replacements) {
if (done) {
break;
}
isLast = msg.endsWith(repls);
if (isLast) {
done = true;
msg = msg.concat(".");
}
}
splits = msg.split(regex);
fnd = splits.length != 1;
if (fnd)
for (int j = 0; j < splits.length; ++j) {
boolean endDot = (j == splits.length - 1) && isLast;
if (!splits[j].isEmpty() && !endDot) {
JsonElement fix = new JsonPrimitive(splits[j]);
rep.add(fix);
}
if (j != splits.length - 1) {
rep.addAll(use);
}
}
if (!fnd) {
rep.add(array.get(i));
}
}
}
}
}
obj.add("extra", rep);
return obj.toString();
}
private JsonArray parseNoItemArray(JsonArray arr) {
JsonArray replacer = new JsonArray();
for (int i = 0; i < arr.size(); ++i) {
if (arr.get(i).isJsonObject()){
JsonObject o = arr.get(i).getAsJsonObject();
boolean inside = false;
for (String replacement : replaces)
if (o.toString().contains(replacement)) {
if (inside) {
break;
}
inside = true;
}
if (!inside) { //the placeholder we're looking for is not inside this element, so we continue searching
replacer.add(o);
continue;
}
JsonElement text = o.get("text");
if (text == null) {
continue;
}
if (text.getAsString().isEmpty()) {
JsonElement el = o.get("extra");
if (el == null) {
continue;
}
JsonArray jar = el.getAsJsonArray();
if(jar.size()!=0) {
jar = parseNoItemArray(jar);
o.add("extra", jar);
}else{
o.remove("extra");
}
}
String msg = text.getAsString();
boolean isLast = false;
boolean done = false;
boolean fnd;
String[] splits;
for (String repls : replaces) {
if (done) {
break;
}
isLast = msg.endsWith(repls);
if (isLast) {
done = true;
msg = msg.concat(".");
}
}
splits = msg.split(rgx);
fnd = splits.length != 1;
if (fnd)
for (int j = 0; j < splits.length; ++j) {
boolean endDot = (j == splits.length - 1) && isLast;
if (!splits[j].isEmpty() && !endDot) {
String st = o.toString();
JsonObject fix = PARSER.parse(st).getAsJsonObject();
fix.addProperty("text", splits[j]);
replacer.add(fix);
}
if (j != splits.length - 1) {
replacer.addAll(classicTooltip);
}
}
if (!fnd) {
replacer.add(o);
}
}else{
if(arr.get(i).isJsonNull()){
continue;
}else{
if(arr.get(i).isJsonArray()){
JsonArray jar = arr.get(i).getAsJsonArray();
if(jar.size()!=0) {
jar = parseNoItemArray(arr.get(i).getAsJsonArray());
replacer.set(i, jar);
}
}else{
String msg = arr.get(i).getAsString();
boolean isLast = false;
boolean done = false;
boolean fnd;
String[] splits;
for (String repls : replaces) {
if (done) {
break;
}
isLast = msg.endsWith(repls);
if (isLast) {
done = true;
msg = msg.concat(".");
}
}
splits = msg.split(rgx);
fnd = splits.length != 1;
if (fnd)
for (int j = 0; j < splits.length; ++j) {
boolean endDot = (j == splits.length - 1) && isLast;
if (!splits[j].isEmpty() && !endDot) {
JsonElement fix = new JsonPrimitive(splits[j]);
replacer.add(fix);
}
if (j != splits.length - 1) {
replacer.addAll(classicTooltip);
}
}
if (!fnd) {
replacer.add(arr.get(i));
}
}
}
}
}
return replacer;
}
private JsonArray parseArray(JsonArray arr) {
JsonArray replacer = new JsonArray();
for (int i = 0; i < arr.size(); ++i) {
if (arr.get(i).isJsonObject()){
JsonObject o = arr.get(i).getAsJsonObject();
boolean inside = false;
for (String replacement : replaces)
if (o.toString().contains(replacement)) {
if (inside) {
break;
}
inside = true;
}
if (!inside) { //the placeholder we're looking for is not inside this element, so we continue searching
replacer.add(o);
continue;
}
JsonElement text = o.get("text");
if (text == null) {
continue;
}
if (text.getAsString().isEmpty()) {
JsonElement el = o.get("extra");
if (el == null) {
continue;
}
JsonArray jar = el.getAsJsonArray();
if(jar.size()!=0) {
jar = parseArray(jar);
o.add("extra", jar);
}else{
o.remove("extra");
}
}
String msg = text.getAsString();
boolean isLast = false;
boolean done = false;
boolean fnd;
String[] splits;
for (String repls : replaces) {
if (done) {
break;
}
isLast = msg.endsWith(repls);
if (isLast) {
done = true;
msg = msg.concat(".");
}
}
splits = msg.split(rgx);
fnd = splits.length != 1;
if (fnd)
for (int j = 0; j < splits.length; ++j) {
boolean endDot = (j == splits.length - 1) && isLast;
if (!splits[j].isEmpty() && !endDot) {
String st = o.toString();
JsonObject fix = PARSER.parse(st).getAsJsonObject();
fix.addProperty("text", splits[j]);
replacer.add(fix);
}
if (j != splits.length - 1) {
replacer.add(itemTooltip);
}
}
if (!fnd) {
replacer.add(o);
}
}else{
if(arr.get(i).isJsonNull()){
continue;
}else{
if(arr.get(i).isJsonArray()){
JsonArray jar = arr.get(i).getAsJsonArray();
if(jar.size()!=0) {
jar = parseArray(arr.get(i).getAsJsonArray());
replacer.set(i, jar);
}
}else{
String msg = arr.get(i).getAsString();
boolean isLast = false;
boolean done = false;
boolean fnd;
String[] splits;
for (String repls : replaces) {
if (done) {
break;
}
isLast = msg.endsWith(repls);
if (isLast) {
done = true;
msg = msg.concat(".");
}
}
splits = msg.split(rgx);
fnd = splits.length != 1;
if (fnd)
for (int j = 0; j < splits.length; ++j) {
boolean endDot = (j == splits.length - 1) && isLast;
if (!splits[j].isEmpty() && !endDot) {
JsonElement fix = new JsonPrimitive(splits[j]);
replacer.add(fix);
}
if (j != splits.length - 1) {
replacer.add(itemTooltip);
}
}
if (!fnd) {
replacer.add(arr.get(i));
}
}
}
}
}
return replacer;
}
@SuppressWarnings("deprecation")
private Item toItem(ItemStack is) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
CompoundTag tag = new CompoundTag("tag");
Object nmsStack = AS_NMS_COPY.invoke(null, is);
Object nmsTag = NBT_TAG_COMPOUND.newInstance();
SAVE_NMS_ITEM_STACK_METHOD.invoke(nmsStack, nmsTag);
Map<String, Object> nmsMap = (Map<String, Object>) MAP.get(nmsTag);
String id = nmsMap.get("id").toString().replace("\"", "");
Object realTag = nmsMap.get("tag");
if(NBT_TAG_COMPOUND.isInstance(realTag)) { //We need to make sure this is indeed an NBTTagCompound
Map<String, Object> realMap = (Map<String, Object>) MAP.get(realTag);
Set<Map.Entry<String, Object>> entrySet = realMap.entrySet();
Map<String, Tag> map = tag.getValue();
for (Map.Entry<String, Object> entry : entrySet) {
map.put(entry.getKey(), toOpenTag(entry.getValue(), entry.getKey()));
}
tag.setValue(map);
}
Item item = new Item();
item.setAmount((byte)is.getAmount());
item.setData(is.getDurability());
item.setId(id);
item.setTag(tag);
return item;
}
private Tag toOpenTag(Object nmsTag, String name) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException {
if(NBT_TAG_COMPOUND.isInstance(nmsTag)) {
CompoundTag tag = new CompoundTag(name);
Map<String, Tag> tagMap = tag.getValue();
Map<String, Object> nmsMap = (Map<String, Object>) MAP.get(nmsTag);
Set<Map.Entry<String, Object>> entrySet = nmsMap.entrySet();
for (Map.Entry<String, Object> entry : entrySet) {
Tag value = toOpenTag(entry.getValue(), entry.getKey());
tagMap.put(entry.getKey(), value);
}
tag.setValue(tagMap);
return tag;
} else {
//Strings are a special case as they need proper escaping
if(NBT_STRING.isInstance(nmsTag)) {
String toString = nmsTag.toString();
if (toString.startsWith("\"") && toString.endsWith("\"")) {
toString = toString.substring(1, toString.length() - 1);
//toString = escapeSpecials(toString);
return new StringTag(name, toString);
}
}
//NBTTag Lists are also special, as they are a sort of compound themselves and need to be parsed recursively
if(NBT_LIST.isInstance(nmsTag)){
List<Object> nmsNBTBaseList = (List<Object>) LIST_FIELD.get(nmsTag);
List<Tag> list = new ArrayList<>();
int i = 0;
for(Object baseTag : nmsNBTBaseList){
list.add(toOpenTag(baseTag, String.valueOf(i)));
++i;
}
return new ListTag(name, list);
}
for(int i = 0; i < NBT_BASE_CLASSES.size(); ++i){
Class<?> c = NBT_BASE_CLASSES.get(i);
if(c.isInstance(nmsTag)){
Object value = NBT_BASE_DATA_FIELD.get(i).get(nmsTag);
Tag t = TYPES_TO_OPEN_NBT_TAGS.get(value.getClass()).getClass().getConstructor(String.class).newInstance(name);
if(t instanceof ByteTag){
((ByteTag)t).setValue((byte)value);
((ByteTag)t).setValue((byte)value);
return t;
}
if(t instanceof ByteArrayTag){
((ByteArrayTag)t).setValue((byte[])value);
return t;
}
if(t instanceof DoubleTag){
((DoubleTag)t).setValue((double)value);
return t;
}
if(t instanceof FloatTag){
((FloatTag)t).setValue((float)value);
return t;
}
if(t instanceof IntTag){
((IntTag)t).setValue((int)value);
return t;
}
if(t instanceof IntArrayTag){
((IntArrayTag)t).setValue((int[])value);
return t;
}
if(t instanceof LongTag){
((LongTag)t).setValue((long)value);
return t;
}
if(t instanceof ShortTag){
((ShortTag)t).setValue((short)value);
return t;
}
return null; //Should never happen
}
}
return null; //Should never happen
}
}
private String stringifyItem(ItemStack stack) throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException {
Item item = toItem(stack);
ProtocolVersion.remapIds(ProtocolVersion.getServerVersion().MAX_VER, protocolVersion.MAX_VER, item);
StringBuilder sb = new StringBuilder("{id:");
sb.append("\"").append(item.getId()).append("\"").append(","); //Append the id
sb.append("Count:").append(item.getAmount()).append("b,"); //Append the amount
sb.append("Damage:").append(item.getData()).append("s"); //Append the durability data
Map<String, Tag> tagMap = item.getTag().getValue();
if(tagMap.isEmpty()){
sb.append("}");
return sb.toString();
}
Set<Map.Entry<String, Tag>> entrySet = tagMap.entrySet();
boolean first = true;
sb.append(",tag:{"); //Start of the tag
for(Map.Entry<String, Tag> entry : entrySet){
String key = entry.getKey();
if(IGNORED.contains(key)){
continue;
}
Pattern pattern = Pattern.compile("[{}\\[\\],\":\\\\/]");
Matcher matcher = pattern.matcher(key);
if(matcher.find()){
continue; //Skip invalid keys, as they can cause exceptions client-side
}
String value = stringifyTag(entry.getValue());
if(!first){
sb.append(",");
}
sb.append(key).append(":").append(value);
first = false;
}
sb.append("}}"); //End of tag and end of item
return sb.toString();
}
private String stringifyTag(Tag normalTag){
if(normalTag instanceof CompoundTag) {
StringBuilder sb = new StringBuilder("{");
CompoundTag tagCompound = (CompoundTag) normalTag;
Map<String, Tag> tagMap = tagCompound.getValue();
Set<Map.Entry<String, Tag>> entrySet = tagMap.entrySet();
for(Map.Entry<String, Tag> entry : entrySet){
String value = stringifyTag(entry.getValue());
if(value == null){
continue;
}
if(sb.length()>1){
sb.append(",");
}
sb.append(entry.getKey()).append(":").append(value);
}
sb.append("}");
return sb.toString();
} else {
if(normalTag instanceof StringTag) {
return "\""+((StringTag)normalTag).getValue()+"\""; //Should be already escaped
}
if(normalTag instanceof ListTag){
List<Tag> list = ((ListTag)normalTag).getValue();
StringBuilder sb = new StringBuilder("[");
boolean first = true;
for(Tag tag : list){
String index = tag.getName();
String value = stringifyTag(tag);
if(value == null){
continue;
}
if(!first){
sb.append(",");
}
if(protocolVersion.MAX_VER <= ProtocolVersion.V1_11.MAX_VER){ //it's before 1.12
sb.append(index).append(":").append(value);
}else{
sb.append(value);
}
first = false;
}
sb.append("]");
return sb.toString();
}
if(normalTag instanceof ByteTag){
return normalTag.getValue()+"b";
}
if(normalTag instanceof ByteArrayTag){
return "["+((byte[])normalTag.getValue()).length+" bytes]";
}
if(normalTag instanceof DoubleTag){
return (double)normalTag.getValue()+"d";
}
if(normalTag instanceof FloatTag){
return (float)normalTag.getValue()+"f";
}
if(normalTag instanceof IntTag){
return String.valueOf((int)normalTag.getValue());
}
if(normalTag instanceof IntArrayTag){
int[] array = (int[])normalTag.getValue();
if(array.length == 0){
return null;
}
StringBuilder sb = new StringBuilder("[");
boolean first = true;
for(int i : array){
if(!first){
sb.append(",");
}
sb.append(i);
first = false;
}
sb.append("]");
return sb.toString();
}
if(normalTag instanceof LongTag){
return (long)normalTag.getValue()+"L";
}
if(normalTag instanceof ShortTag){
return (short)normalTag.getValue()+"s";
}
return null; //Should never happen
}
}
}
@@ -1,256 +0,0 @@
package me.dadus33.chatitem.listeners;
import me.dadus33.chatitem.utils.Storage;
import org.bukkit.Bukkit;
import org.bukkit.Material;
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 java.util.HashMap;
public class ChatEventListener implements Listener {
private Storage c;
public final static char SEPARATOR = ((char)0x0007);
private final static String LEFT = "{remaining}";
private final HashMap<String, Long> COOLDOWNS = new HashMap<>();
public ChatEventListener(Storage storage) {
c = storage;
}
private String calculateTime(long seconds){
if(seconds < 60){
return seconds+c.SECONDS;
}
if(seconds < 3600){
StringBuilder builder = new StringBuilder();
int minutes = (int) seconds / 60;
builder.append(minutes).append(c.MINUTES);
int secs = (int) seconds - minutes*60;
if(secs != 0){
builder.append(" ").append(secs).append(c.SECONDS);
}
return builder.toString();
}
StringBuilder builder = new StringBuilder();
int hours = (int) seconds / 3600;
builder.append(hours).append(c.HOURS);
int minutes = (int) (seconds/60) - (hours*60);
if(minutes != 0){
builder.append(" ").append(minutes).append(c.MINUTES);
}
int secs = (int) (seconds - ((seconds/60)*60));
if(secs != 0){
builder.append(" ").append(secs).append(c.SECONDS);
}
return builder.toString();
}
private int countOccurrences(String findStr, String str){
int lastIndex = 0;
int count = 0;
while(lastIndex != -1){
lastIndex = str.indexOf(findStr,lastIndex);
if(lastIndex != -1){
count++;
lastIndex += findStr.length();
}
}
return count;
}
@SuppressWarnings("deprecation")
@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(final 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), "");
e.setMessage(msg);
}
boolean found = false;
for (String rep : c.PLACEHOLDERS)
if (e.getMessage().contains(rep)) {
found = true;
break;
}
if (!found) {
return;
}
Player p = e.getPlayer();
if (!p.hasPermission("chatitem.use")) {
if(!c.LET_MESSAGE_THROUGH) {
e.setCancelled(true);
}
if(!c.NO_PERMISSION_MESSAGE.isEmpty() && c.SHOW_NO_PERM_NORMAL){
p.sendMessage(c.NO_PERMISSION_MESSAGE);
}
return;
}
if (p.getItemInHand().getType().equals(Material.AIR)) {
if (c.DENY_IF_NO_ITEM) {
e.setCancelled(true);
if (!c.DENY_MESSAGE.isEmpty())
e.getPlayer().sendMessage(c.DENY_MESSAGE);
return;
}
if(c.HAND_DISABLED) {
return;
}
}
if(c.COOLDOWN > 0 && !p.hasPermission("chatitem.ignore-cooldown")){
if(COOLDOWNS.containsKey(p.getName())){
long start = COOLDOWNS.get(p.getName());
long current = System.currentTimeMillis()/1000;
long elapsed = current - start;
if(elapsed >= c.COOLDOWN){
COOLDOWNS.remove(p.getName());
}else{
if(!c.LET_MESSAGE_THROUGH) {
e.setCancelled(true);
}
if(!c.COOLDOWN_MESSAGE.isEmpty()){
long left = (start + c.COOLDOWN) - current;
p.sendMessage(c.COOLDOWN_MESSAGE.replace(LEFT, calculateTime(left)));
}
return;
}
}
}
String s = e.getMessage();
for(String placeholder : c.PLACEHOLDERS){
s = s.replace(placeholder, c.PLACEHOLDERS.get(0));
}
int occurrences = countOccurrences(c.PLACEHOLDERS.get(0), s);
if(occurrences>c.LIMIT){
e.setCancelled(true);
if(c.LIMIT_MESSAGE.isEmpty()){
return;
}
e.getPlayer().sendMessage(c.LIMIT_MESSAGE);
return;
}
String oldmsg = e.getMessage();
StringBuilder sb = new StringBuilder(oldmsg);
sb.append(SEPARATOR).append(e.getPlayer().getName());
e.setMessage(sb.toString());
Bukkit.getConsoleSender().sendMessage(String.format(e.getFormat(), e.getPlayer().getDisplayName(), oldmsg));
if(!p.hasPermission("chatitem.ignore-cooldown")) {
COOLDOWNS.put(p.getName(), System.currentTimeMillis() / 1000);
}
}
@SuppressWarnings("deprecation")
@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(!c.ALLOWED_DEFAULT_COMMANDS.contains(commandString)){
return;
}
}else{
if(!c.ALLOWED_PLUGIN_COMMANDS.contains(cmd)){
return;
}
}
Player p = e.getPlayer();
boolean found = false;
for (String rep : c.PLACEHOLDERS) {
if (e.getMessage().contains(rep)) {
found = true;
break;
}
}
if (!found) {
return;
}
if (!p.hasPermission("chatitem.use")) {
if(!c.NO_PERMISSION_MESSAGE.isEmpty() && c.SHOW_NO_PERM_COMMAND){
p.sendMessage(c.NO_PERMISSION_MESSAGE);
}
e.setCancelled(true);
return;
}
if (e.getPlayer().getItemInHand().getType().equals(Material.AIR)) {
if (c.DENY_IF_NO_ITEM) {
e.setCancelled(true);
if (!c.DENY_MESSAGE.isEmpty()) {
e.getPlayer().sendMessage(c.DENY_MESSAGE);
}
}
if(c.HAND_DISABLED) {
return;
}
}
if(c.COOLDOWN > 0 && !p.hasPermission("chatitem.ignore-cooldown")){
if(COOLDOWNS.containsKey(p.getName())){
long start = COOLDOWNS.get(p.getName());
long current = System.currentTimeMillis()/1000;
long elapsed = current - start;
if(elapsed >= c.COOLDOWN){
COOLDOWNS.remove(p.getName());
}else{
if(!c.LET_MESSAGE_THROUGH) {
e.setCancelled(true);
}
if(!c.COOLDOWN_MESSAGE.isEmpty()){
long left = (start + c.COOLDOWN) - current;
p.sendMessage(c.COOLDOWN_MESSAGE.replace(LEFT, calculateTime(left)));
}
return;
}
}
}
String s = e.getMessage();
for(String placeholder : c.PLACEHOLDERS){
s = s.replace(placeholder, c.PLACEHOLDERS.get(0));
}
int occurrences = countOccurrences(c.PLACEHOLDERS.get(0), s);
if(occurrences>c.LIMIT){
e.setCancelled(true);
if(c.LIMIT_MESSAGE.isEmpty()){
return;
}
e.getPlayer().sendMessage(c.LIMIT_MESSAGE);
return;
}
StringBuilder sb = new StringBuilder(e.getMessage());
sb.append(SEPARATOR).append(e.getPlayer().getName());
e.setMessage(sb.toString());
if(!p.hasPermission("chatitem.ignore-cooldown")) {
COOLDOWNS.put(p.getName(), System.currentTimeMillis() / 1000);
}
}
public void setStorage(Storage st) {
c = st;
}
}
@@ -1,233 +0,0 @@
package me.dadus33.chatitem.listeners;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.ShulkerBox;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.utils.ProtocolVersion;
import me.dadus33.chatitem.utils.Storage;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.chat.ComponentSerializer;
@Deprecated
public class ChatPacketListener extends PacketAdapter {
private final static String NAME = "{name}";
private final static String AMOUNT = "{amount}";
private final static String TIMES = "{times}";
private final static List<Material> SHULKER_BOXES = new ArrayList<>();
private Storage c;
public ChatPacketListener(Plugin plugin, ListenerPriority listenerPriority, Storage s, PacketType... types) {
super(plugin, listenerPriority, types);
if(ProtocolVersion.getServerVersion().isNewerOrEquals(ProtocolVersion.V1_11)){
SHULKER_BOXES.addAll(Arrays.asList(Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX,
Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX,
Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX,
Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX,
Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX));
}
c = s;
}
private static String materialToName(Material m) {
if (m.equals(Material.TNT)) {
return "TNT";
}
String orig = m.toString().toLowerCase();
String[] splits = orig.split("_");
StringBuilder sb = new StringBuilder(orig.length());
int pos = 0;
for (String split : splits) {
sb.append(split);
int loc = sb.lastIndexOf(split);
char charLoc = sb.charAt(loc);
if (!(split.equalsIgnoreCase("of") || split.equalsIgnoreCase("and") ||
split.equalsIgnoreCase("with") || split.equalsIgnoreCase("on")))
sb.setCharAt(loc, Character.toUpperCase(charLoc));
if (pos != splits.length - 1)
sb.append(' ');
++pos;
}
return sb.toString();
}
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);
}
@Override
public void onPacketSending(final PacketEvent e) {
if(e.isPlayerTemporary())
return;
final PacketContainer packet = e.getPacket();
if(!packet.getMeta("parse").isPresent()){ //First we check if the packet validator has validated this packet to be parsed by us
return;
}
final boolean usesBaseComponents = (boolean)packet.getMeta("base-component").orElse(false); //The packet validator should also tell if this packet uses base components
e.setCancelled(true); //We cancel the packet as we're going to resend it anyways (ignoring listeners this time)
Bukkit.getScheduler().runTaskAsynchronously(ChatItem.getInstance(), () -> {
String json = (String)packet.getMeta("json").orElse(""); //The packet validator got the json for us, so no need to get it again
int topIndex = -1;
String name = null;
for(Player p : Bukkit.getOnlinePlayers()){
String pname = "\\u0007"+p.getName();
if(!json.contains(pname)){
continue;
}
int index = json.lastIndexOf(pname)+pname.length();
if(index>topIndex){
topIndex = index;
name = pname.replace("\\u0007", "");
}
}
if(name==null){ //something went really bad, so we run away and hide (AKA the player left or is on another server)
return;
}
Player p = Bukkit.getPlayer(name);
StringBuilder builder = new StringBuilder(json);
builder.replace(topIndex-(name.length()+6), topIndex, ""); //we remove both the name and the separator from the json string
json = builder.toString();
String message = null;
try {
if(!p.getItemInHand().getType().equals(Material.AIR)) {
ItemStack copy = p.getItemInHand().clone();
if(copy.getType().name().contains("_BOOK")){ //filtering written books
BookMeta bm = (BookMeta)copy.getItemMeta();
bm.setPages(Collections.emptyList());
copy.setItemMeta(bm);
} else {
if (ProtocolVersion.getServerVersion().isNewerOrEquals(ProtocolVersion.V1_11)) { //filtering shulker boxes
if (SHULKER_BOXES.contains(copy.getType())) {
if (copy.hasItemMeta()) {
BlockStateMeta bsm = (BlockStateMeta) copy.getItemMeta();
if (bsm.hasBlockState()) {
ShulkerBox sb = (ShulkerBox) bsm.getBlockState();
for (ItemStack item : sb.getInventory()) {
stripData(item);
}
bsm.setBlockState(sb);
}
copy.setItemMeta(bsm);
}
}
}
}
message = ChatItem.getManipulator().parse(json, c.PLACEHOLDERS, copy, styleItem(copy, c), ProtocolVersion.getClientVersion(e.getPlayer()));
} else {
if(!c.HAND_DISABLED){
message = ChatItem.getManipulator().parseEmpty(json, c.PLACEHOLDERS, c.HAND_NAME, c.HAND_TOOLTIP, p);
}
}
} catch (InvocationTargetException | IllegalAccessException | InstantiationException | NoSuchFieldException | NoSuchMethodException e1) {
e1.printStackTrace();
}
if(message!=null) {
if(!usesBaseComponents) {
packet.getChatComponents().writeSafely(0, WrappedChatComponent.fromJson(message));
}else{
packet.getSpecificModifier(BaseComponent[].class).writeSafely(0, ComponentSerializer.parse(message));
}
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(e.getPlayer(), packet, false);
} catch (InvocationTargetException e1) {
e1.printStackTrace();
}
} else {
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(e.getPlayer(), packet, false);
} catch (InvocationTargetException e1) {
e1.printStackTrace();
}
}
});
}
public void setStorage(Storage st) {
c = st;
}
public static String styleItem(ItemStack item, Storage c){
String replacer = c.NAME_FORMAT;
String amount = c.AMOUNT_FORMAT;
boolean dname = item.hasItemMeta() ? item.getItemMeta().hasDisplayName() : false;
if (item.getAmount() == 1) {
if (c.FORCE_ADD_AMOUNT) {
amount = amount.replace(TIMES, "1");
replacer = replacer.replace(AMOUNT, amount);
} else {
replacer = replacer.replace(AMOUNT, "");
}
} else {
amount = amount.replace(TIMES, String.valueOf(item.getAmount()));
replacer = replacer.replace(AMOUNT, amount);
}
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);
}
} else {
HashMap<Short, String> translationSection = c.TRANSLATIONS.get(item.getType().name());
if(translationSection==null){
String trp = materialToName(item.getType());
replacer = replacer.replace(NAME, trp);
}else {
String translated = translationSection.get(item.getDurability());
if (translated != null) {
replacer = replacer.replace(NAME, translated);
} else {
replacer = replacer.replace(NAME, materialToName(item.getType()));
}
}
}
return replacer;
}
}
@@ -1,229 +0,0 @@
package me.dadus33.chatitem.listeners;
import java.util.Collections;
import java.util.HashMap;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.ShulkerBox;
import org.bukkit.entity.Player;
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.packets.ChatItemPacket;
import me.dadus33.chatitem.packets.PacketContent;
import me.dadus33.chatitem.packets.PacketHandler;
import me.dadus33.chatitem.packets.PacketMetadata;
import me.dadus33.chatitem.packets.PacketType;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.ProtocolVersion;
import me.dadus33.chatitem.utils.Storage;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.chat.ComponentSerializer;
public class ChatPacketListenerV2 extends PacketHandler {
private final static String NAME = "{name}";
private final static String AMOUNT = "{amount}";
private final static String TIMES = "{times}";
private Storage c;
public ChatPacketListenerV2(Storage s) {
c = s;
}
private static String materialToName(Material m) {
if (m.equals(Material.TNT)) {
return "TNT";
}
String orig = m.toString().toLowerCase();
String[] splits = orig.split("_");
StringBuilder sb = new StringBuilder(orig.length());
int pos = 0;
for (String split : splits) {
sb.append(split);
int loc = sb.lastIndexOf(split);
char charLoc = sb.charAt(loc);
if (!(split.equalsIgnoreCase("of") || split.equalsIgnoreCase("and") || split.equalsIgnoreCase("with")
|| split.equalsIgnoreCase("on")))
sb.setCharAt(loc, Character.toUpperCase(charLoc));
if (pos != splits.length - 1)
sb.append(' ');
++pos;
}
return sb.toString();
}
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);
}
@SuppressWarnings("deprecation")
@Override
public void onSend(ChatItemPacket e) {
if(!e.hasPlayer() || !e.getPacketType().equals(PacketType.Server.CHAT)) {
return;
}
final PacketContent packet = e.getContent();
final PacketMetadata meta = e.getMetaData();
if (!meta.hasMeta("parse")) { // First we check if the packet validator has validated this packet to be parsed
// by us
ChatItem.debug("Can't parse : " + e.getPacket());
meta.getMetas().forEach((s, o) -> ChatItem.debug("metaData: " + s + " > " + o));
return;
}
meta.removeMeta("parse");
boolean usesBaseComponents = meta.getMeta("base-component", false); // The packet validator should also tell if this
// packet uses base
// components
e.setCancelled(true); // We cancel the packet as we're going to resend it anyways (ignoring listeners
// this time)
Bukkit.getScheduler().runTaskAsynchronously(ChatItem.getInstance(), () -> {
String json = (String) meta.getMeta("json", ""); // The packet validator got the json for us, so no need to
// get it again
int topIndex = -1;
String name = null;
for (Player p : Bukkit.getOnlinePlayers()) {
String pname = "\\u0007" + p.getName();
if (!json.contains(pname)) {
continue;
}
int index = json.lastIndexOf(pname) + pname.length();
if (index > topIndex) {
topIndex = index;
name = pname.replace("\\u0007", "");
}
}
if (name == 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);
return;
}
Player p = Bukkit.getPlayer(name);
StringBuilder builder = new StringBuilder(json);
builder.replace(topIndex - (name.length() + 6), topIndex, ""); // we remove both the name and the separator
// from the json string
json = builder.toString();
String message = null;
try {
if (!p.getItemInHand().getType().equals(Material.AIR)) {
ItemStack copy = p.getItemInHand().clone();
if (copy.getType().name().contains("_BOOK")) { // filtering written books
BookMeta bm = (BookMeta) copy.getItemMeta();
bm.setPages(Collections.emptyList());
copy.setItemMeta(bm);
} else {
if (copy.getType().name().contains("SHULKER_BOX")) { // if it's shulker
if (copy.hasItemMeta()) {
BlockStateMeta bsm = (BlockStateMeta) copy.getItemMeta();
if (bsm.hasBlockState()) {
ShulkerBox sb = (ShulkerBox) bsm.getBlockState();
for (ItemStack item : sb.getInventory()) {
stripData(item);
}
bsm.setBlockState(sb);
}
copy.setItemMeta(bsm);
}
}
}
message = ChatItem.getManipulator().parse(json, c.PLACEHOLDERS, copy, styleItem(copy, c),
ProtocolVersion.getClientVersion(e.getPlayer()));
} else {
if (!c.HAND_DISABLED) {
message = ChatItem.getManipulator().parseEmpty(json, c.PLACEHOLDERS, c.HAND_NAME,
c.HAND_TOOLTIP, p);
}
}
} catch (Exception e1) {
e1.printStackTrace();
}
if (message != null) {
if (!usesBaseComponents) {
packet.getChatComponents().write(0, jsonToChatComponent(message));
} else {
packet.getSpecificModifier(BaseComponent[].class).write(0, ComponentSerializer.parse(message));
}
}
PacketUtils.sendPacket(p, e.getPacket());
});
}
private Object jsonToChatComponent(String json) {
try {
return PacketUtils.CHAT_SERIALIZER.getMethod("a", String.class).invoke(null, json);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void setStorage(Storage st) {
c = st;
}
public static String styleItem(ItemStack item, Storage c) {
String replacer = c.NAME_FORMAT;
String amount = c.AMOUNT_FORMAT;
boolean dname = item.hasItemMeta() ? item.getItemMeta().hasDisplayName() : false;
if (item.getAmount() == 1) {
if (c.FORCE_ADD_AMOUNT) {
amount = amount.replace(TIMES, "1");
replacer = replacer.replace(AMOUNT, amount);
} else {
replacer = replacer.replace(AMOUNT, "");
}
} else {
amount = amount.replace(TIMES, String.valueOf(item.getAmount()));
replacer = replacer.replace(AMOUNT, amount);
}
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);
}
} else {
HashMap<Short, String> translationSection = c.TRANSLATIONS.get(item.getType().name());
if (translationSection == null) {
String trp = materialToName(item.getType());
replacer = replacer.replace(NAME, trp);
} else {
@SuppressWarnings("deprecation")
String translated = translationSection.get(item.getDurability());
if (translated != null) {
replacer = replacer.replace(NAME, translated);
} else {
replacer = replacer.replace(NAME, materialToName(item.getType()));
}
}
}
return replacer;
}
}
@@ -1,84 +0,0 @@
package me.dadus33.chatitem.listeners;
import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.utils.ProtocolVersion;
import me.dadus33.chatitem.utils.Storage;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.chat.ComponentSerializer;
@Deprecated
public class ChatPacketValidator extends PacketAdapter {
private Storage c;
public ChatPacketValidator(Plugin plugin, ListenerPriority listenerPriority, Storage s, PacketType... types) {
super(plugin, listenerPriority, types);
c = s;
}
@Override
public void onPacketSending(PacketEvent e){
if(e.isPlayerTemporary())
return;
ProtocolVersion version = ProtocolVersion.getServerVersion();
if(version.isNewerOrEquals(ProtocolVersion.V1_8)) { //only if action bar messages are supported in this version of minecraft
if(version.isNewerOrEquals(ProtocolVersion.V1_12)){
try {
if(((Enum<?>)e.getPacket().getSpecificModifier(Class.forName("net.minecraft.server." + ProtocolVersion.BUKKIT_VERSION + ".ChatMessageType")).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 (e.getPacket().getBytes().readSafely(0) == (byte) 2) {
return; //It means it's an actionbar message, and we ain't intercepting those
}
}
boolean usesBaseComponents = false;
PacketContainer packet = e.getPacket();
String json;
if(packet.getChatComponents().readSafely(0)==null){ //null check for some cases of messages sent using spigot's Chat Component API or other means
if(ChatItem.supportsChatComponentApi()){ //only if the API is supported in this server distribution
BaseComponent[] components = packet.getSpecificModifier(BaseComponent[].class).readSafely(0);
if(components == null){
return;
}
json = ComponentSerializer.toString(components);
usesBaseComponents = true;
}else{
return; //We don't know how to deal with anything else. Most probably some mod message we shouldn't mess with anyways
}
}else{
json = packet.getChatComponents().readSafely(0).getJson();
}
boolean found = false;
for (String rep : c.PLACEHOLDERS)
if (json.contains(rep)) {
found = true;
break;
}
if (!found) {
return; //then it's just a normal message without placeholders, so we leave it alone
}
if(json.lastIndexOf("\\u0007")==-1){ //if the message doesn't contain the BELL separator, then it's certainly NOT a message we want to parse
return;
}
packet.setMeta("parse", true); //We mark this packet to be parsed by the packet listener
packet.setMeta("base-component", usesBaseComponents); //We also tell it whether this packet uses the base component API
packet.setMeta("json", json); //And we finally provide it with the json we already got from the packet
}
public void setStorage(Storage st){
c = st;
}
}
@@ -1,101 +0,0 @@
package me.dadus33.chatitem.listeners;
import java.lang.reflect.Method;
import me.dadus33.chatitem.ChatItem;
import me.dadus33.chatitem.packets.ChatItemPacket;
import me.dadus33.chatitem.packets.PacketContent;
import me.dadus33.chatitem.packets.PacketHandler;
import me.dadus33.chatitem.packets.PacketMetadata;
import me.dadus33.chatitem.packets.PacketType;
import me.dadus33.chatitem.utils.PacketUtils;
import me.dadus33.chatitem.utils.ProtocolVersion;
import me.dadus33.chatitem.utils.Storage;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.chat.ComponentSerializer;
public class ChatPacketValidatorV2 extends PacketHandler {
private Storage c;
private Method serializerGetJson;
public ChatPacketValidatorV2(Storage s) {
c = s;
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 void onSend(ChatItemPacket e) {
if(!e.hasPlayer() || !e.getPacketType().equals(PacketType.Server.CHAT))
return;
ProtocolVersion version = ProtocolVersion.getServerVersion();
if(version.isNewerOrEquals(ProtocolVersion.V1_8)) { //only if action bar messages are supported in this version of minecraft
if(version.isNewerOrEquals(ProtocolVersion.V1_12)){
try {
if(((Enum<?>)e.getContent().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 (e.getContent().getBytes().readSafely(0) == (byte) 2) {
return; //It means it's an actionbar message, and we ain't intercepting those
}
}
boolean usesBaseComponents = false;
PacketContent packet = e.getContent();
String json;
if(packet.getChatComponents().readSafely(0) == null){ //null check for some cases of messages sent using spigot's Chat Component API or other means
if(!ChatItem.supportsChatComponentApi()) //only if the API is supported in this server distribution
return;//We don't know how to deal with anything else. Most probably some mod message we shouldn't mess with anyways
BaseComponent[] components = packet.getSpecificModifier(BaseComponent[].class).readSafely(0);
if(components == null){
return;
}
json = ComponentSerializer.toString(components);
usesBaseComponents = true;
} else {
try {
json = (String) serializerGetJson.invoke(null, packet.getChatComponents().readSafely(0));// (String) ReflectionUtils.callMethod(packet.getChatComponents().readSafely(0), "getJson");
} catch (Exception exc) {
exc.printStackTrace();
json = "{}";
}
}
boolean found = false;
for (String rep : c.PLACEHOLDERS) {
if (json.contains(rep)) {
found = true;
break;
}
}
if (!found) {
return; //then it's just a normal message without placeholders, so we leave it alone
}
if(json.lastIndexOf("\\u0007") == -1){ //if the message doesn't contain the BELL separator, then it's certainly NOT a message we want to parse
ChatItem.debug("Not containb bell " + json);
return;
}
PacketMetadata meta = e.getMetaData();
meta.setMeta("parse", true); //We mark this packet to be parsed by the packet listener
meta.setMeta("base-component", usesBaseComponents); //We also tell it whether this packet uses the base component API
meta.setMeta("json", json); //And we finally provide it with the json we already got from the packet
}
public void setStorage(Storage st){
c = st;
}
}
@@ -1,32 +0,0 @@
package me.dadus33.chatitem.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.ProtocolVersion;
public class HandshakeListener extends PacketAdapter{
public HandshakeListener() {
super(ChatItem.getInstance(), ListenerPriority.MONITOR, PacketType.Handshake.Client.SET_PROTOCOL);
}
@Override
public void onPacketReceiving(final PacketEvent e){
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(ProtocolVersion.stringifyAdress(e.getPlayer().getAddress()), version), 10L);
}
}
@@ -0,0 +1,154 @@
package me.dadus33.chatitem.listeners;
import java.util.Arrays;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
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.Utils;
public class InventoryListener implements Listener {
@EventHandler
public void onClick(InventoryClickEvent e) {
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);
if (e.getCurrentItem() == null)
return;
ItemStack item = e.getCurrentItem();
Material type = item.getType();
Storage c = ChatItem.getInstance().getStorage();
if (type.equals(ItemUtils.MATERIAL_CLOSE)) {
p.closeInventory();
} 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.colorIfColored = !c.colorIfColored);
open(p);
} else if (type.equals(Material.STICK)) {
setInConfig("general.hand.disabled", c.handDisabled = !c.handDisabled);
open(p);
} else if (type.equals(Material.BLAZE_ROD)) {
setInConfig("general.check-update", c.checkUpdate = !c.checkUpdate);
open(p);
} else if (type.equals(ItemUtils.FIREWORK_CHARGE)) {
setInConfig("debug", c.debug = !c.debug);
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);
open(p);
}
}
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) {
AdminHolder holder = new AdminHolder();
Storage c = ChatItem.getInstance().getStorage();
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("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(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 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 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 ChatItem.getPlatform().createTranslatedItemStack(Material.PAPER, "admin-inv.manager." + manager, placeholders);
}
}
@@ -0,0 +1,36 @@
package me.dadus33.chatitem.listeners;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
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.TextComponent;
public class JoinListener implements Listener {
@SuppressWarnings("deprecation")
@EventHandler
public void onJoin(PlayerJoinEvent e) {
Player p = e.getPlayer();
if(!p.isOp())
return;
ChatItem pl = ChatItem.getInstance();
if(pl.isHasNewVersion()) {
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);
}
}
@EventHandler
public void onLeft(PlayerQuitEvent e) {
ChatManager.clear(e.getPlayer());
}
}
@@ -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;
}
}
@@ -1,29 +0,0 @@
package me.dadus33.chatitem.packets;
import java.util.HashMap;
public class PacketMetadata {
private final HashMap<String, Object> metas = new HashMap<>();
public void setMeta(String key, Object obj) {
this.metas.put(key, obj);
}
public boolean hasMeta(String key) {
return metas.containsKey(key);
}
public void removeMeta(String key) {
metas.remove(key);
}
@SuppressWarnings("unchecked")
public <T> T getMeta(String key, T def) {
return (T) metas.getOrDefault(key, def);
}
public HashMap<String, Object> getMetas() {
return metas;
}
}
@@ -1,59 +0,0 @@
package me.dadus33.chatitem.packets.protocollib;
import java.util.Arrays;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.PacketType.Play;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent;
import me.dadus33.chatitem.listeners.HandshakeListener;
import me.dadus33.chatitem.packets.ChatItemPacket;
import me.dadus33.chatitem.packets.PacketManager;
import me.dadus33.chatitem.packets.PacketType;
public class ProtocollibPacketManager extends PacketManager {
private final ProtocolManager protocolManager;
public ProtocollibPacketManager(Plugin pl) {
protocolManager = ProtocolLibrary.getProtocolManager();
protocolManager.addPacketListener(new PacketAdapter(pl, ListenerPriority.LOWEST, Arrays.asList(Play.Server.CHAT)) {
@Override
public void onPacketSending(PacketEvent e) {
Player p = e.getPlayer();
if (p == null || e.isPlayerTemporary())
return;
ChatItemPacket packet = onPacketSent(PacketType.getType(e.getPacket().getHandle().getClass().getSimpleName()),
p, e.getPacket().getHandle());
if(packet == null)
return;
if(!e.isCancelled())
e.setCancelled(packet.isCancelled());
}
});
protocolManager.addPacketListener(new HandshakeListener());
}
@Override
public void addPlayer(Player p) {}
@Override
public void removePlayer(Player p) {}
@Override
public void clear() {}
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;
}
}
@@ -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 "{}";
}
}
}
@@ -0,0 +1,11 @@
package me.dadus33.chatitem.playernamer;
import org.bukkit.entity.Player;
import net.md_5.bungee.api.chat.BaseComponent;
public interface IPlayerNamer {
public BaseComponent[] getName(Player p);
}
@@ -0,0 +1,42 @@
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.HexNicksV2PlayerNamer;
import org.bukkit.plugin.Plugin;
public class PlayerNamerManager {
private static IPlayerNamer playerNamer;
public static IPlayerNamer getPlayerNamer() {
return playerNamer;
}
public static void setPlayerNamer(IPlayerNamer playerNamer) {
PlayerNamerManager.playerNamer = playerNamer;
}
public static void load(ChatItem pl) {
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,15 @@
package me.dadus33.chatitem.playernamer.hook;
import org.bukkit.entity.Player;
import me.dadus33.chatitem.playernamer.IPlayerNamer;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ComponentBuilder;
public class DefaultPlayerNamer implements IPlayerNamer {
@Override
public BaseComponent[] getName(Player p) {
return new ComponentBuilder(p.getName()).create();
}
}
Loaded 100 of 245 files, more files were not shown because too many files have changed in this diff. Show more