Compare commits

...

438 Commits

Author SHA1 Message Date
Will FP
f01e18950c Merge pull request #365 from Exanthiax/develop 2024-07-24 10:44:03 +01:00
Exanthiax
d4a6bf105b Update ParticleFactoryRGB.kt 2024-07-24 01:55:20 +01:00
Auxilor
a9a961ff2b Added FancyHolograms integration 2024-07-20 12:49:07 +01:00
Auxilor
25d572c0db Added AutocrafterPatch 2024-07-20 09:59:58 +01:00
Auxilor
8a4243e434 Fixed XP price 2024-07-19 20:01:20 +01:00
Auxilor
6c40670f5e Updated to 6.72.0 2024-07-19 19:46:26 +01:00
Auxilor
6e94f3cee8 Added support for multiple display modules per plugin 2024-07-19 19:46:26 +01:00
Auxilor
4968d3ff22 Updated to 6.71.6 2024-07-14 16:04:21 +01:00
Auxilor
eecd80be1c Fixed display name 2024-07-14 16:04:14 +01:00
Auxilor
52c1b52f6d Fixed tab completion bug 2024-07-12 18:18:40 +01:00
Auxilor
f321296227 Updated to 6.71.5 2024-07-12 18:08:35 +01:00
Auxilor
ddd12db420 Fixed ExtendedPersistentDataContainerFactory 2024-07-12 18:07:53 +01:00
Auxilor
bd09791b5b Improved command tab-completion 2024-07-08 18:49:29 +01:00
Auxilor
ce9549f03d Updated to 6.71.4 2024-07-08 15:14:24 +01:00
Auxilor
52367dbb95 Fixed Java 17 compatibility 2024-07-08 15:14:18 +01:00
Auxilor
0080c32c23 Updated to 6.71.3 2024-06-25 02:30:45 +01:00
Auxilor
581094a930 Fixed DurabilityUtils 2024-06-25 02:30:37 +01:00
Auxilor
5d9c8775e8 Updated to 6.71.2 2024-06-24 18:44:16 +01:00
Auxilor
9ab51d2c87 Added fix for TopInventory on pre-1.21 2024-06-24 18:42:32 +01:00
Auxilor
b0de341d7f Updated to 6.71.1 2024-06-23 16:45:17 +01:00
Auxilor
1bada835ea Added 1.21 item arg parsers 2024-06-23 14:20:49 +01:00
Auxilor
de04833f0c Updated custom name and lore on 1.21 2024-06-22 23:44:29 +01:00
Auxilor
75dd6be539 Fixed custom name on 1.21 2024-06-22 22:52:01 +01:00
Auxilor
9b47e4777a Dropped 1.20.6 support and made modern commons module for 1.21+ 2024-06-22 22:23:51 +01:00
Will FP
e2a6d6d9ac Merge pull request #359 from MCCasper/master
fix empty nbt
2024-06-22 22:11:36 +01:00
Nikolai Connolly
4c1bc76ee2 fix empty nbt 2024-06-22 17:09:23 -04:00
Auxilor
61c90d85ac Fixed 1.20.6+ getEnchants 2024-06-20 23:14:09 +01:00
Auxilor
6faaac2257 Fixed 1.20.6+ getEnchants 2024-06-20 23:13:52 +01:00
Auxilor
9ad489b9d9 Updated to 6.71.0 2024-06-20 18:48:19 +01:00
Auxilor
3a0e1eaf4d Added 1.21 support and fixed paperweight issues for Java 17 versions 2024-06-18 20:53:04 +01:00
Jason Penilla
80afa9127f Explicitly declare toolchains/make compile work consistently
Signed-off-by: WillFP <william.favierparsons1@gmail.com>
2024-06-18 20:53:04 +01:00
Auxilor
ad44891f5f 1.21 groundwork 2024-06-18 20:53:04 +01:00
Will FP
303f5eedac Updated paperweight 2024-05-13 19:18:55 +01:00
Will FP
830199d8ca Updated to 6.70.1 2024-05-13 19:14:15 +01:00
Will FP
aa86426895 Moved ShopGUIPlus into loadbefore 2024-05-13 19:14:02 +01:00
Will FP
edf20d8ab8 Removed Ssomar plugins from plugin.yml 2024-05-12 23:00:25 +01:00
Will FP
d99121ad47 Added onRegister and onRemove master functions to registries 2024-05-11 17:42:56 +01:00
Will FP
f71fa64ccd Merge remote-tracking branch 'origin/master' 2024-05-11 16:26:37 +01:00
Will FP
697e0b7c9c Fixed FastItemStack on 1.20.6 2024-05-11 16:26:29 +01:00
Will FP
08f6715305 Merge pull request #354
Fix IllegalArgumentException
2024-05-11 16:24:09 +01:00
Will FP
bff502c281 Fixed item SNBT conversions 2024-05-07 13:01:13 +01:00
Will FP
2500258166 1.20.6 Improvements 2024-05-06 17:30:32 +01:00
Will FP
a8d6aaad30 Fixed several things, updated version 2024-05-04 16:22:25 +01:00
Will FP
160635a2a7 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	eco-core/core-nms/build.gradle.kts
#	eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/integrations/antigrief/AntigriefIridiumSkyblock.kt
#	gradle/wrapper/gradle-wrapper.jar
2024-05-04 15:05:02 +01:00
Will FP
6fd4eb7e4c Added preliminary 1.20.6 support 2024-05-04 15:04:36 +01:00
24Cr
5941060479 Fix IllegalArgumentException 2024-05-03 21:49:32 +03:00
Auxilor
a9ba317e7d Updated to 6.69.2 2024-04-10 16:36:10 +01:00
Auxilor
1adbcc105e Minor code reformatting from PR 2024-04-10 16:30:26 +01:00
Auxilor
c4c0f38969 Improved modern NMS version tooling 2024-04-10 16:30:10 +01:00
Will FP
9059ddf856 Merge pull request #351 from bridgelol/master
Fixed MongoDB data handler
2024-04-08 13:04:07 +01:00
Will FP
4209161046 Merge pull request #348 from Auxilor/develop
Added ability to modify items on DropQueuePushEvent
2024-04-08 12:47:01 +01:00
bridge
79ac0838d0 refactor(mongo): use non-deprecated mongodb driver and migrate to kotlinx serialization for mongodb codecs 2024-04-05 03:40:39 +02:00
bridge
cf0a96426c fix: MongoDataHandler 2024-04-05 02:52:48 +02:00
bridge
5ccb9ca30a chore: add toolchain for both java & kotlin (paperweight support) 2024-04-05 02:37:58 +02:00
bridge
033cc44200 chore: update paperweight 2024-04-05 02:35:55 +02:00
bridge
67ae0ec8cd chore: update gradle wrapper 2024-04-05 02:31:37 +02:00
bridge
c8329d050c feat(mongodb): add configurable database name 2024-04-05 02:19:51 +02:00
Auxilor
ab73c2202a Updated to 6.69.1 2024-03-29 16:50:04 +00:00
Auxilor
af640881b0 Fixed IridiumSkyblock 2024-03-29 16:49:57 +00:00
Auxilor
9bd5cb5046 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	gradle.properties
2024-03-29 16:39:42 +00:00
Will FP
2829baf5b0 Preliminary support for new NMS versioning 2024-03-22 19:00:57 +00:00
often
7ef928c360 Fixed additional player placeholders 2024-03-16 20:21:14 +03:00
often
17db6dbf7f Merge branch 'master' into develop 2024-03-16 20:20:21 +03:00
Will FP
446e7a9534 Fixed ExtendedPersistentDataContainerFactory on 1.20.4 2024-03-10 17:03:51 +00:00
often
dbbab8518e Added ability to modify items on DropQueuePushEvent 2024-02-24 21:13:01 +03:00
Will FP
1908d9a5c2 Added workflow dispatch 2024-02-08 19:37:26 +00:00
Will FP
4ab7e888ef Updated to 6.69.0 2024-02-08 14:22:59 +00:00
Will FP
47c8617d3d Added onCreateTasks 2024-02-08 14:22:47 +00:00
Will FP
c977cb2602 Fixed PR 2024-02-08 14:21:34 +00:00
Will FP
2402fd6736 Merge pull request #344 from Auxilor/develop
Additions and fixes
2024-02-08 14:20:20 +00:00
often
db41e11dab Added HuskClaims antigrief support
Added HuskTowns antigrief support
Added ItemBridge lookup support (`itembridge:key__id)
2024-01-27 14:33:36 +03:00
often
6b46ea7e67 Added random function for math taking min and max arguments 2024-01-27 14:30:59 +03:00
often
7defdcc1ff Merge branch 'master' into develop 2024-01-26 17:21:58 +03:00
Will FP
35496c60fc Updated to 6.68.6 2024-01-23 14:48:40 +00:00
Will FP
9b4af3eeab Fixed SCore 2024-01-23 14:48:19 +00:00
often
b6b4d7e2f8 Fixed console commands in config slots 2024-01-22 16:55:57 +03:00
often
74a8dcea90 Added ability to configure literal cache ttl 2024-01-22 16:55:22 +03:00
often
e0f631b3b4 Merge remote-tracking branch 'origin/master' into develop 2024-01-22 16:24:00 +03:00
Will FP
67981b4f9a Updated to 6.68.5 2024-01-15 23:17:27 +00:00
Will FP
03eb2f5d0a Fixed DeluxeCombat 2024-01-15 23:17:17 +00:00
Will FP
2df60bffee Updated to 6.68.4 2024-01-14 16:44:31 +00:00
Will FP
b97506ae70 Fixed bugs on spigot and old paper versions 2024-01-14 16:44:09 +00:00
often
747e702d54 Bring develop up to date 2024-01-08 04:31:28 +03:00
often
9e583f18de Merge branch 'master' into develop 2024-01-08 04:04:01 +03:00
Will FP
75afe1f2b0 Moved CMI to loadbefore 2024-01-07 14:31:22 +00:00
Will FP
4464d3bf75 Updated to 6.68.3 2024-01-07 12:41:16 +00:00
Will FP
75f217b141 Added math expression parsing to placeholders, {{expr}} and {^{expr}} (to format values nicely) 2024-01-07 12:41:06 +00:00
Will FP
2387849adb Updated to 6.68.2 2024-01-06 13:36:33 +00:00
Will FP
e7a5d8d155 Reimplemented lost commits 2024-01-06 13:36:19 +00:00
Will FP
d6e50e34e1 Updated to 6.68.1 2024-01-06 13:28:23 +00:00
Will FP
89e58be1a3 Added %value_commas% to ConfiguredPrice 2024-01-06 13:28:04 +00:00
Auxilor
8a8606bea4 Suppressed paper deprecations 2024-01-04 17:09:23 +00:00
Auxilor
3f751e8865 Updated to 6.68.1 2024-01-04 17:08:15 +00:00
Auxilor
6a035426b4 Fixed namespacedkey creation 2024-01-04 17:05:47 +00:00
Auxilor
f9bf97c90c Improved DropQueue telekinesis for paper users 2024-01-04 17:05:36 +00:00
Will FP
476faeec61 Fixed issues with CustomCrafting 2023-12-26 13:38:39 +01:00
Will FP
64647e3dad Merge remote-tracking branch 'origin/master'
# Conflicts:
#	gradle.properties
2023-12-26 13:34:19 +01:00
Will FP
dba640f8ee Updated to 6.68.0 2023-12-26 13:33:56 +01:00
Will FP
f52a760bbe Added yaml autosaving 2023-12-26 13:33:46 +01:00
Auxilor
c80cdf7b60 Oops 2023-12-20 12:59:59 +00:00
Auxilor
749f6229ac Updated to 6.67.3 2023-12-20 12:56:22 +00:00
Auxilor
e6318c0727 Updated DecentHOlos 2023-12-20 12:56:14 +00:00
Auxilor
989118a653 Updated IridiumSkyblock integration 2023-12-20 12:52:57 +00:00
Auxilor
6134e8de04 Fixed ESGUI circular load 2023-12-20 12:28:07 +00:00
Auxilor
5a8c2828f7 Fixed loadbefore 2023-12-20 12:23:52 +00:00
Will FP
0dba790bb2 Switched some plugins to loadbefore 2023-12-08 12:16:07 +00:00
Will FP
85991b6d7e Updated to 6.67.2 2023-12-08 12:12:44 +00:00
Will FP
ad272a2f6b Added clientside entity display name API for all versions 2023-12-08 12:12:04 +00:00
Will FP
9c4a65dc19 Updated to 6.67.1 2023-12-07 15:30:48 +00:00
Will FP
8d2d6153e5 Added 1.20.3 support 2023-12-07 15:30:37 +00:00
_OfTeN_
6248dafc70 Removed the custom biomes manager (moved to libreforge) 2023-12-04 01:29:06 +03:00
Will FP
9ad12c2578 Finally deprecated @ConfigUpdater for removal 2023-12-03 15:28:44 +00:00
Will FP
24d9052080 Updated dependencies, including Kotlin 2023-12-03 15:22:32 +00:00
Will FP
e2d2e955a4 Removed jitpack.yml 2023-12-03 14:47:41 +00:00
Will FP
c5cbdc2449 Fixed README 2023-12-03 14:47:29 +00:00
Will FP
1a4e8be1b2 Removed paper-plugin.yml 2023-12-03 14:14:23 +00:00
Will FP
1a75dd8e5b Improved local keys 2023-12-03 14:06:01 +00:00
Will FP
77de51b1fd Merge remote-tracking branch 'origin/develop' 2023-12-03 14:03:26 +00:00
Will FP
3495d2317d Merge remote-tracking branch 'origin/dependabot/gradle/org.spigotmc-spigot-api-1.20.2-R0.1-SNAPSHOT'
# Conflicts:
#	eco-core/core-backend/build.gradle.kts
2023-12-03 14:02:36 +00:00
Will FP
0284aec119 Merge remote-tracking branch 'origin/dependabot/gradle/org.litote.kmongo-kmongo-coroutine-4.10.0' 2023-12-03 14:01:54 +00:00
Will FP
0d4289b756 Merge remote-tracking branch 'origin/dependabot/gradle/me.clip-placeholderapi-2.11.4' 2023-12-03 14:01:48 +00:00
Will FP
6931ba0393 Merge remote-tracking branch 'origin/dependabot/gradle/com.github.TownyAdvanced-Towny-0.99.5.21' 2023-12-03 14:01:45 +00:00
Will FP
cb49fa2690 Packet listeners will no longer kick players if LinkageErrors are thrown 2023-12-03 13:56:49 +00:00
Will FP
4898ca4a25 Fixed 1.20.2 2023-12-03 13:51:34 +00:00
_OfTeN_
67d70098ef - Added CustomBiomesManager to add support for custom world generators and their biomes
- Added a Terra generator integration for Custom Biomes
- Added an entity arg parser to set entity type for spawners (`item: spawner entity:zombie`)
2023-12-03 05:34:00 +03:00
Auxilor
d072ac15a0 Changed to MIT license 2023-12-03 01:22:05 +03:00
Auxilor
fea3152660 Updated to 6.66.1 2023-12-03 01:22:05 +03:00
Auxilor
8fc9c718ce Fixed custom AI goals on 1.20 2023-12-03 01:22:05 +03:00
Auxilor
1fe6a3caeb Updated to 6.66.0 2023-12-03 01:22:05 +03:00
Auxilor
8668d36304 Fixed GUI lag exploit 2023-12-03 01:22:05 +03:00
Auxilor
72608c381e Updated to 6.65.7 2023-12-03 01:22:05 +03:00
Auxilor
80cdaf6ea0 Updated FabledSkyblock integration 2023-12-03 01:22:05 +03:00
Auxilor
de6a3e76fd Fixed IntegrationRegistry 2023-12-03 01:22:05 +03:00
Auxilor
80d24b8366 Updated to 6.65.6 2023-12-03 01:22:05 +03:00
Auxilor
4d6399dd6c Added 1.20.2 support 2023-12-03 01:22:04 +03:00
Auxilor
f1815aee4f Updated to 6.65.5 2023-12-03 01:22:04 +03:00
Auxilor
18e05da958 Patched GUI bug 2023-12-03 01:22:04 +03:00
Will FP
12d6ff180e Fixed ModelEngineBridge 2023-11-29 19:18:14 +00:00
Will FP
1c0f40880f Fixed repos 2023-11-29 19:05:41 +00:00
Will FP
6625385e1c Added support for ModelEngine 4 2023-11-29 18:58:13 +00:00
Will FP
75ca3dc9a6 Updated to 6.67.0 2023-11-28 14:28:23 +00:00
Will FP
1db2671bc5 Added client side display names (requires Paper 1.20+) 2023-11-28 14:27:48 +00:00
Auxilor
70dd3c0d64 Changed to MIT license 2023-11-23 09:17:23 +00:00
Auxilor
8665df51cc Updated to 6.66.1 2023-11-07 13:46:39 +00:00
Auxilor
e306190109 Fixed custom AI goals on 1.20 2023-11-07 13:46:32 +00:00
Auxilor
3e0a8b1838 Updated to 6.66.0 2023-10-26 18:30:01 +01:00
Auxilor
29d69d77b4 Fixed GUI lag exploit 2023-10-26 18:24:32 +01:00
Auxilor
9e625c004e Updated to 6.65.7 2023-10-16 22:24:24 +01:00
Will FP
59dfeeb012 Merge pull request #318
Fix RoyaleEconomy integration
2023-10-16 22:24:04 +01:00
Auxilor
6fdbb2d63f Updated FabledSkyblock integration 2023-10-16 22:23:32 +01:00
Auxilor
e77c8ab9aa Fixed IntegrationRegistry 2023-10-14 14:11:24 +01:00
dependabot[bot]
48e1618c84 Bump com.github.TownyAdvanced:Towny from 0.97.2.6 to 0.99.5.21
Bumps com.github.TownyAdvanced:Towny from 0.97.2.6 to 0.99.5.21.

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-02 22:06:27 +00:00
dependabot[bot]
19f60afaf9 Bump me.clip:placeholderapi from 2.10.10 to 2.11.4
Bumps me.clip:placeholderapi from 2.10.10 to 2.11.4.

---
updated-dependencies:
- dependency-name: me.clip:placeholderapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-25 22:06:15 +00:00
Auxilor
26e2282385 Updated to 6.65.6 2023-09-22 19:45:58 +01:00
Auxilor
2e9d5c36f2 Added 1.20.2 support 2023-09-22 19:45:23 +01:00
dependabot[bot]
b4fb66ffa0 Bump org.spigotmc:spigot-api
Bumps org.spigotmc:spigot-api from 1.17.1-R0.1-SNAPSHOT to 1.20.2-R0.1-SNAPSHOT.

---
updated-dependencies:
- dependency-name: org.spigotmc:spigot-api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-21 21:25:15 +00:00
Auxilor
ba0bf5ee8f Updated to 6.65.5 2023-09-12 16:51:33 +01:00
Auxilor
3bf9589cd2 Patched GUI bug 2023-09-12 16:51:20 +01:00
Sen2000
510034af0d Fix RoyaleEconomy integration 2023-09-03 18:03:19 +07:00
_OfTeN_
8052ffa706 Added ability to specify local storage usage individually for each persistent data key via a constructor parameter 2023-08-20 17:39:22 +03:00
Auxilor
ed41c1091c Suppression 2023-07-31 16:17:49 +02:00
Auxilor
4fcf8c0368 Updated to 6.65.4 2023-07-31 16:13:16 +02:00
Auxilor
4ae4af6f1d Fixed UltraEconomy 2023-07-31 16:10:32 +02:00
Auxilor
bba0900183 Fixed UltraEconomy build 2023-07-31 16:04:23 +02:00
Auxilor
641aee3965 Patched an exploit 2023-07-31 15:38:42 +02:00
Auxilor
18ea6cc568 Clarifications and fixes for other commits 2023-07-31 15:14:01 +02:00
Auxilor
8335f6bae5 Added quick patch for an exploit 2023-07-31 15:13:45 +02:00
Auxilor
514a8e76f9 Revert "Reworked EntityDamageByEntityEvent, finally"
This reverts commit 5cfb87e0
2023-07-31 15:12:48 +02:00
_OfTeN_
f34af36690 Added ArmorTrim arg parser (now without NMS) 2023-07-30 21:27:09 +03:00
_OfTeN_
143148d93e Made backend use 1.20 API 2023-07-30 21:26:21 +03:00
_OfTeN_
4f6c023217 Stupidity fix 2023-07-30 20:44:45 +03:00
_OfTeN_
620e1d3042 Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoSpigotPlugin.kt
#	eco-core/core-plugin/src/main/resources/config.yml
2023-07-30 20:39:00 +03:00
_OfTeN_
d3c831c19b Added a config option to enforce additional crafting recipe check (in case you're encountering issues with 3d party custom item plugins like ItemsAdder or Oraxen) 2023-07-30 20:38:09 +03:00
dependabot[bot]
47e87fa6ce Bump org.litote.kmongo:kmongo-coroutine from 4.6.0 to 4.10.0
Bumps [org.litote.kmongo:kmongo-coroutine](https://github.com/Litote/kmongo) from 4.6.0 to 4.10.0.
- [Release notes](https://github.com/Litote/kmongo/releases)
- [Commits](https://github.com/Litote/kmongo/compare/kmongo-4.6.0...kmongo-4.10.0)

---
updated-dependencies:
- dependency-name: org.litote.kmongo:kmongo-coroutine
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-24 21:38:07 +00:00
Auxilor
22d9dbdf66 Added display-without-meta option 2023-07-22 16:13:31 +01:00
Auxilor
238ea86e09 Merge branch 'master' into develop 2023-07-22 14:16:42 +01:00
Auxilor
5cfb87e03c Reworked EntityDamageByEntityEvent, finally 2023-07-22 14:16:34 +01:00
Auxilor
ff61527939 Updated to 6.65.3 2023-07-20 13:01:19 +01:00
Auxilor
7ff578f89b Fixed clearInjectedPlaceholders 2023-07-20 12:36:41 +01:00
Auxilor
27da03e8db Optimised config hashing 2023-07-20 12:19:10 +01:00
Auxilor
f1bef38046 Updated to 6.65.2 2023-07-16 13:03:50 +01:00
Auxilor
ee237f9c58 Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	eco-api/src/main/java/com/willfp/eco/core/config/interfaces/Config.java
2023-07-16 13:01:28 +01:00
Auxilor
0a80518755 Merge remote-tracking branch 'origin/develop' into develop 2023-07-13 15:17:13 +01:00
Auxilor
134859fea0 Extremely obvious optimisation to expression parsing 2023-07-13 15:16:23 +01:00
_OfTeN_
5c267d500a Fixed head arg parser breaking back serialization when used with texture 2023-07-12 23:42:52 +03:00
Auxilor
4c9735583c Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/math/ExpressionHandlers.kt
2023-07-10 15:07:15 +01:00
Auxilor
739d9cfffb Optimised Config#getDoubleFromExpression for constant values 2023-07-06 17:35:52 +01:00
Auxilor
4301d83e91 Removed ItemMetaProxy, can be reimplemented much better without NMS 2023-07-06 17:33:44 +01:00
Auxilor
84d5c5e665 Merge branch 'master' into develop 2023-07-05 15:33:07 +01:00
Auxilor
50f217eebe Switched to a standard map for LazyPlaceholderTranslationExpressionHandler 2023-07-05 15:30:06 +01:00
Auxilor
041fce69cc Updated gradle 2023-07-05 15:00:34 +01:00
Auxilor
238bd08502 Merge remote-tracking branch 'origin/dependabot/gradle/org.javassist-javassist-3.29.2-GA' 2023-07-05 14:51:57 +01:00
Auxilor
940e6e8b5b Merge remote-tracking branch 'origin/dependabot/gradle/io.lumine-Mythic-5.3.5' 2023-07-05 14:51:56 +01:00
Auxilor
eb07622496 Merge remote-tracking branch 'origin/dependabot/gradle/com.github.johnrengelman.shadow-8.1.1' 2023-07-05 14:51:54 +01:00
Auxilor
841ed52bdd Merge remote-tracking branch 'origin/dependabot/gradle/com.arcaniax-HeadDatabase-API-1.3.1' 2023-07-05 14:51:52 +01:00
Auxilor
342f6dbc7b Updated to 6.65.1 2023-07-05 14:44:31 +01:00
Auxilor
245b577adc Expressions that are just numbers will be immediately converted rather than being evaluated 2023-07-05 14:44:22 +01:00
dependabot[bot]
1258305755 Bump io.lumine:Mythic from 5.2.1 to 5.3.5
Bumps io.lumine:Mythic from 5.2.1 to 5.3.5.

---
updated-dependencies:
- dependency-name: io.lumine:Mythic
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-04 21:35:54 +00:00
_OfTeN_
cd8ed5a823 Implemented ItemMetaProxy with an ability to set/get trim from the 1.20 armor meta
Added an ArgParserTrim to add trims to armor via item lookup strings
2023-06-24 16:38:10 +03:00
_OfTeN_
795ead57bf Fixed MythicMobs mob test predicate 2023-06-23 11:24:03 +03:00
_OfTeN_
910cdaf992 Updated KingdomsX antigrief integration 2023-06-23 10:41:15 +03:00
_OfTeN_
85c02d3402 Merge remote-tracking branch 'origin/master' into develop 2023-06-23 09:42:26 +03:00
dependabot[bot]
b4ad2fd4d7 Bump com.github.johnrengelman.shadow from 7.1.2 to 8.1.1
Bumps com.github.johnrengelman.shadow from 7.1.2 to 8.1.1.

---
updated-dependencies:
- dependency-name: com.github.johnrengelman.shadow
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-19 22:00:27 +00:00
dependabot[bot]
3c5190da3a Bump com.arcaniax:HeadDatabase-API from 1.3.0 to 1.3.1
Bumps [com.arcaniax:HeadDatabase-API](https://github.com/Arcaniax-Development/HeadDatabase-API) from 1.3.0 to 1.3.1.
- [Release notes](https://github.com/Arcaniax-Development/HeadDatabase-API/releases)
- [Commits](https://github.com/Arcaniax-Development/HeadDatabase-API/compare/1.3.0...1.3.1)

---
updated-dependencies:
- dependency-name: com.arcaniax:HeadDatabase-API
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-19 21:59:50 +00:00
dependabot[bot]
0f0f003f23 Bump org.javassist:javassist from 3.28.0-GA to 3.29.2-GA
Bumps [org.javassist:javassist](https://github.com/jboss-javassist/javassist) from 3.28.0-GA to 3.29.2-GA.
- [Release notes](https://github.com/jboss-javassist/javassist/releases)
- [Changelog](https://github.com/jboss-javassist/javassist/blob/master/Changes.md)
- [Commits](https://github.com/jboss-javassist/javassist/commits)

---
updated-dependencies:
- dependency-name: org.javassist:javassist
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-19 21:59:28 +00:00
Auxilor
7e5e5162c3 LazyPlaceholderTranslationExpressionHandler now uses a regular map rather than a caffeine cache 2023-06-18 22:03:48 +02:00
Auxilor
09417d0834 Expressions that are just numbers will be immediately converted rather than being evaluated 2023-06-18 21:11:14 +02:00
Auxilor
c85b8c08c7 Merge remote-tracking branch 'origin/master' 2023-06-18 14:35:31 +02:00
Auxilor
a65ac0aa4f Updated to 6.65.0 2023-06-18 14:23:18 +02:00
Auxilor
9d03ba2bd2 Fixed deprecated use of placeholder methods 2023-06-18 14:14:52 +02:00
Auxilor
8eb62d65b4 Fixed PersistentDataKeyType.BIG_DECIMAL 2023-06-18 14:11:50 +02:00
Will FP
178f21b1f3 Create CODEOWNERS 2023-06-17 21:14:57 +02:00
Will FP
a3fe4f97ff Merge pull request #280 from Auxilor/develop
Fixed not player messages
2023-06-17 21:09:31 +02:00
Auxilor
ff356fcde5 Fixed not player messages 2023-06-17 20:57:36 +02:00
Will FP
59b57b17ba Create master-pr.yml 2023-06-17 20:35:49 +02:00
Auxilor
c8f710161d Merge remote-tracking branch 'origin/master'
# Conflicts:
#	gradle.properties
2023-06-13 15:29:12 +02:00
Auxilor
f840a55734 Fixed 1.20 bugs 2023-06-13 15:28:12 +02:00
Auxilor
36677fe503 Updated to 6.63.1 2023-06-08 21:30:26 +01:00
Auxilor
7e74223352 Added 1.20 support 2023-06-08 21:30:16 +01:00
Auxilor
b6f2b9d4ea Added global %player% placeholder 2023-06-05 14:09:17 +01:00
Auxilor
f320e77008 Updated to 6.64.0 2023-06-05 13:44:50 +01:00
Auxilor
c8b255b358 Added placeholder extension methods 2023-06-05 13:44:42 +01:00
Auxilor
5b5e161062 Added head arg parser 2023-06-05 13:22:21 +01:00
Auxilor
ffa511176f Improved packet event error logging 2023-06-03 15:39:38 +01:00
Auxilor
8515ff2b7b Updated to 6.63.0 2023-06-03 15:13:51 +01:00
Auxilor
74aeaec257 Added NumberUtils.evaluateExpressionOrNull 2023-06-03 15:13:42 +01:00
Auxilor
0ce3d294d1 Updated to 6.62.2 2023-06-03 14:23:33 +01:00
Auxilor
7c7052f5b9 Placeholders with identical patterns will now override previous registrations 2023-06-03 14:23:15 +01:00
Auxilor
a6b7dda82d Added check to prevent !!float in configs 2023-06-03 14:20:59 +01:00
Auxilor
04aaefb9ea Updated to 6.62.1 2023-06-03 14:03:23 +01:00
Auxilor
d2fdb4f8e0 Packet events will no longer kick players if exceptions are thrown 2023-06-03 14:03:14 +01:00
Auxilor
87f90d8b26 Updated to 6.62.0 2023-05-24 14:45:37 +01:00
Auxilor
899d5cc054 Added caching to literal pattern compilation 2023-05-24 14:41:15 +01:00
Auxilor
c1ed771eb3 Updated to 6.61.1 2023-05-22 13:22:03 +01:00
Auxilor
08a4d9d6b1 Changed playerflow to use local server ID 2023-05-22 01:35:23 +01:00
Auxilor
7ef8dcfd64 Merge branch 'develop' 2023-05-21 19:07:56 +01:00
Auxilor
5bedf88b4c Updated lang.yml 2023-05-21 19:03:47 +01:00
Auxilor
1d241651b5 Added config option for playerflow 2023-05-21 17:01:13 +01:00
Auxilor
3ff2bfa412 Updated playerflow URL 2023-05-21 16:58:21 +01:00
Auxilor
3a508c693b Updated to 6.61.0 2023-05-21 16:38:35 +01:00
Auxilor
a4c5ff921e Added playerflow 2023-05-21 16:38:17 +01:00
Auxilor
137e9dc7d6 Added global price display names 2023-05-20 18:01:45 +01:00
Auxilor
710cec4bc1 Merge branch 'develop' 2023-05-19 13:17:05 +01:00
Auxilor
fa0ec7d6b0 Updated to 6.60.4 2023-05-19 13:16:20 +01:00
Auxilor
5093799775 Merge remote-tracking branch 'origin/develop' into develop 2023-05-19 13:15:34 +01:00
Will FP
8535f23ede Merge pull request #274
Fix PvPManager integration
2023-05-19 13:15:24 +01:00
Will FP
8e09ae7f4c Merge pull request #275
Add RoyaleEconomy to prices system
2023-05-19 13:14:54 +01:00
Sen2000
bbc2513b40 Fix RoyaleEconomy integration 2023-05-19 16:54:05 +07:00
Sen2000
c7f8063a3a Add RoyaleEconomy to prices system 2023-05-19 09:11:17 +07:00
ChanceSD
14b0f1be0c Fix PvPManager integration 2023-05-18 22:42:49 +01:00
Auxilor
af20bb315b Updated to 6.60.3 2023-05-18 15:35:54 +01:00
Auxilor
6645e216d5 Fixed stupid profile saver bug 2023-05-18 15:35:47 +01:00
Auxilor
eddf240f0c Updated to 6.60.2 2023-05-18 14:33:21 +01:00
Auxilor
4f406353ba Fixed data bug 2023-05-18 14:33:14 +01:00
Auxilor
095494dd2e Fixed PersistentDataKeyType.BIG_DECIMAL and javadoc 2023-05-17 18:39:48 +01:00
Auxilor
fd92645500 Updated to 6.60.1 2023-05-17 17:27:00 +01:00
Auxilor
1a6ac29083 Fixed PersistentDataKeyType.BIG_DECIMAL 2023-05-17 17:26:48 +01:00
Auxilor
7edc00d459 Added createTasks 2023-05-16 14:50:02 +01:00
Auxilor
a51bad058f Updated to 6.60.0 2023-05-16 14:47:06 +01:00
Auxilor
89ebb8ba59 Updated to 6.59.1 2023-05-15 17:43:03 +01:00
Auxilor
f0ae8f4f84 Fixed DelegatedBukkitCommand (again) 2023-05-15 17:42:49 +01:00
Auxilor
7d6cf78442 Cleanup 2023-05-15 16:38:33 +01:00
Auxilor
780d8f3b86 Fixed DefaultMap 2023-05-15 16:33:58 +01:00
Auxilor
146a0130f9 Fixed DefaultMap 2023-05-15 16:33:32 +01:00
Auxilor
df8c3411cb Updated to 6.59.0 2023-05-15 12:06:56 +01:00
Auxilor
4fc3c22a7d Added PersistentDataKeyType#BIG_DECIMAL 2023-05-15 12:05:37 +01:00
Auxilor
cfc4808bb8 Updated to 6.58.1 2023-05-14 16:36:05 +01:00
Auxilor
4ac6325a41 Fixed T?.toSingletonList() 2023-05-14 16:35:56 +01:00
Auxilor
4aed33751d EcoPlugin#afterLoad now runs 2 ticks after, with a preliminary reload 1 tick after startup to fix load order bugs 2023-05-13 17:43:31 +01:00
Auxilor
3fe1c2c69f Added EcoPlugin#cancelsTasksOnReload 2023-05-13 12:10:08 +01:00
Auxilor
5feaa84b2c Revert "Probably janky solution to command aliases"
This reverts commit 862b588c8d.
2023-05-12 16:57:12 +01:00
Auxilor
d8793bc2bb Fixed command aliases 2023-05-12 16:54:03 +01:00
Auxilor
15c512f3ca Cleanup 2023-05-12 15:40:28 +01:00
Auxilor
15ff2fb1d6 Fixed registry locks 2023-05-12 15:39:51 +01:00
Auxilor
862b588c8d Probably janky solution to command aliases 2023-05-12 15:37:29 +01:00
Auxilor
3c2a99b5f4 Added MenuBuilder#defaultPage 2023-05-12 14:53:44 +01:00
Auxilor
2d23c05c47 Added kotlin extensions to NumberUtils methods 2023-05-12 14:26:00 +01:00
Auxilor
8fc55d3393 Merge remote-tracking branch 'origin/develop' into develop 2023-05-12 13:53:45 +01:00
Auxilor
5900a756e4 Added margin options to line wrapping 2023-05-12 13:53:38 +01:00
Auxilor
c18b85f223 AAAAAAA 2023-05-12 13:53:16 +01:00
Auxilor
85116108c2 Oops 2023-05-12 13:47:47 +01:00
Auxilor
044f141bd0 Added margin options to line wrapping 2023-05-12 13:45:21 +01:00
Auxilor
9ca7f99fdb Added StringUtils#lineWrap kotlin extensions 2023-05-12 13:28:21 +01:00
Auxilor
7aa7770a3e Added StringUtils#lineWrap for lists 2023-05-12 13:27:13 +01:00
Auxilor
10202917fa Added StringUtils#lineWrap to wrap strings while preserving formatting 2023-05-11 17:24:05 +01:00
Auxilor
43df79e3b1 Fixed captive slots not forcing a re-render on shift click 2023-05-10 16:03:29 +01:00
Auxilor
5ef244f0bc Added option to store plugin data locally, even if eco is set to use a database 2023-05-10 15:19:15 +01:00
Auxilor
861f076c11 Updated to 6.58.0 2023-05-10 14:52:52 +01:00
Auxilor
7bed43059f Added Slot#shouldRenderOnClick 2023-05-08 18:39:27 +01:00
Auxilor
37e271c96c More optimisations to EcoConfig 2023-05-04 14:32:52 +01:00
Auxilor
3dad48e24d Updated to 6.57.2 2023-05-03 23:45:01 +01:00
Auxilor
ae77e4810b Digsusting hacks to optimise eval pipeline 2023-05-03 23:44:53 +01:00
Auxilor
3d50e37c37 Merge branch 'master' into develop 2023-05-03 23:01:41 +01:00
Auxilor
421fd3bd04 Finally removed LegacyMySQLDataHandler 2023-05-03 16:03:36 +01:00
Auxilor
5ecae0a366 Updated to 6.57.1 2023-05-03 14:19:01 +01:00
Auxilor
5de4914fd7 Fixed expression loading, improved hash codes down evaluation pipeline 2023-05-03 14:18:50 +01:00
Auxilor
0f9bf094ae Ignore case 2023-05-02 18:47:54 +01:00
Auxilor
e67680f397 Improved PlaceholderAPI 2023-05-02 17:39:15 +01:00
Auxilor
73c0a5d655 Fixed more stupidity 2023-05-02 17:17:41 +01:00
Auxilor
220ed26f4a Fixed stupidity 2023-05-02 17:14:03 +01:00
Auxilor
edf2ea41c7 Cleaned up RECIPE ERROR message to be nicer 2023-05-02 16:13:33 +01:00
Auxilor
16859b8ce5 Revert "Temporarily disabled Wolfyscript"
This reverts commit f973281dd9.
2023-05-02 15:01:01 +01:00
Auxilor
10fe7d190a Clean 2023-05-02 14:58:25 +01:00
Auxilor
60a1f2429c Added plugin-version and plugin to extension.yml 2023-05-02 14:26:53 +01:00
Auxilor
cc6dc1e67c Improved PAPI expansion 2023-05-02 13:57:23 +01:00
Auxilor
f4f5941691 Fixed duplicate config placeholder bug 2023-05-02 13:56:10 +01:00
Auxilor
f973281dd9 Temporarily disabled Wolfyscript 2023-05-02 13:55:50 +01:00
Auxilor
8acd76f363 Updated to 6.57.0 2023-05-01 19:53:45 +01:00
Auxilor
4a165a86dc Added PluginLike#getFile 2023-05-01 19:53:37 +01:00
Auxilor
43b7c393b9 Cleaned up data desync PR 2023-04-29 15:52:13 +01:00
Auxilor
714952bc45 PR Cleanup 2023-04-29 15:47:42 +01:00
Will FP
322e179b81 Merge pull request #269
Add PlayerPoints to prices system
2023-04-29 15:43:54 +01:00
Auxilor
469be73ada Added option to translate placeholders without a context 2023-04-29 15:03:02 +01:00
Auxilor
7eac60146f Added placeholderContext#copy 2023-04-29 13:44:03 +01:00
Auxilor
ad0223e1bb Cleaned up PlaceholderContext 2023-04-29 13:22:18 +01:00
BuildTools
430117f342 Add PlayerPoints to prices system 2023-04-29 10:20:53 +07:00
Auxilor
fa87cae81e Clarified PlaceholderParser 2023-04-28 19:59:13 +01:00
Auxilor
5695750fc5 Optimised additional player placeholder parsing 2023-04-28 17:05:40 +01:00
Auxilor
45e8a57880 Fixed DynamicInjectablePlaceholder 2023-04-28 16:24:34 +01:00
Auxilor
17fcd2c1b5 Added DynamicPlaceholder and DynamicInjectablePlaceholder 2023-04-28 16:24:18 +01:00
Auxilor
0c1e17c351 Massively optimised placeholder parsing with ListViewOfCollection 2023-04-28 16:11:21 +01:00
Auxilor
9415515849 Simplified enable logs 2023-04-28 14:34:30 +01:00
Auxilor
d0e957ea37 Cleaned up imports 2023-04-28 14:23:44 +01:00
Will FP
69514e2f85 Merge pull request #268
Denizen Integration
2023-04-28 14:22:29 +01:00
FireML
259e35c978 Script Name Alternative 2023-04-28 00:47:01 +01:00
FireML
40aec26f15 Initial Denizen Support 2023-04-27 23:03:34 +01:00
Auxilor
67b2fdd594 Merge branch 'master' into develop
# Conflicts:
#	gradle.properties
2023-04-27 19:27:57 +01:00
Auxilor
83f86983f6 Updated to 6.55.4 2023-04-27 19:22:30 +01:00
Auxilor
3ba98a9a5e Fixed UltraEconomy 2023-04-27 19:22:20 +01:00
Auxilor
f19e565fbe Moved to native fastToDoubleOrNull function 2023-04-27 19:08:10 +01:00
Auxilor
ee3ecb643b Cleanup 2023-04-27 18:55:03 +01:00
Auxilor
3aefb0e481 Switched back to ConcurrentHashMap in EcoConfig 2023-04-27 18:04:02 +01:00
Auxilor
d9eb1e1c26 Merge branch 'fix-data-desync' into develop 2023-04-27 18:02:09 +01:00
Auxilor
70631e67c5 Config injections no longer use a ConcurrentHashMap 2023-04-27 15:51:16 +01:00
Auxilor
82797e7342 Rewrote placeholder parsing 2023-04-27 15:42:46 +01:00
Auxilor
d2917341b1 Removed use-lower-protocollib-priority 2023-04-26 20:31:53 +01:00
Auxilor
760f42be0c Refactor, made math cache TTL configurable 2023-04-26 20:31:44 +01:00
Auxilor
bb01af2ab2 Optimised StringUtils#replaceQuickly 2023-04-26 18:22:56 +01:00
Auxilor
517d890c05 More optimisations to evaluation pipeline 2023-04-26 17:37:31 +01:00
Auxilor
f02fc56778 Added alternate crunch evaluation option 2023-04-26 16:55:40 +01:00
Auxilor
4417b09c14 Various optimisations along the evaluation pipeline 2023-04-26 16:10:04 +01:00
Auxilor
6b37fafa90 Further simplified Config 2023-04-26 15:25:50 +01:00
Auxilor
f8c5c9f06d Revert "Added KPlaceholderContext"
This reverts commit 0fd6cbaa08.
2023-04-26 15:02:05 +01:00
Auxilor
0fd6cbaa08 Added KPlaceholderContext 2023-04-26 14:58:48 +01:00
Auxilor
81afa32eb0 Added placeholderContext kotlin builder 2023-04-26 14:47:40 +01:00
Auxilor
7387fe2332 Improved default config methods 2023-04-26 14:44:13 +01:00
Auxilor
80fa05da98 Added PlaceholderContext#copyWithItem 2023-04-26 14:07:22 +01:00
Auxilor
77754249ad Added SimplePlaceholder and SimpleInjectablePlaceholder 2023-04-26 13:23:29 +01:00
Auxilor
1843cf0f8a PlaceholderManager#translatePlaceholders now includes injections 2023-04-26 13:13:59 +01:00
Auxilor
05eb5ee993 Rewrote more placeholder backend, deprecated MathContext 2023-04-26 13:07:18 +01:00
Auxilor
7bc11ee716 Added new format options 2023-04-25 19:19:43 +01:00
Auxilor
f566aec00e PlaceholderContext now extends MathContext 2023-04-25 19:11:15 +01:00
Auxilor
36d47c55a1 Updated to 6.56.0 2023-04-25 18:57:22 +01:00
Auxilor
40463213ac Added PlaceholderContext as a unified way to parse placeholders 2023-04-25 18:57:06 +01:00
Auxilor
6ec80d30ad Updated to 6.55.3 2023-04-25 10:28:38 +01:00
Auxilor
7ccee60a0c Fixed IntegrationRegistry#executeSafely 2023-04-25 10:28:23 +01:00
Auxilor
0805b48763 Updated to 6.55.2 2023-04-24 22:12:47 +01:00
Auxilor
d737322aaa Merge remote-tracking branch 'origin/master'
# Conflicts:
#	gradle.properties
2023-04-24 22:12:19 +01:00
Auxilor
4ddc150e1c Updated to 6.54.1 2023-04-24 22:11:55 +01:00
Auxilor
0da119d89d Finally reimplemented BlockUtils#getVein 2023-04-24 22:10:42 +01:00
Auxilor
fc0a07d1c5 Config injections now use a ConcurrentHashMap 2023-04-24 22:05:37 +01:00
Cyramek
4ce2850138 fix data desync 2023-04-23 14:35:17 +02:00
Auxilor
58316c2a06 Fixed locale bug with Registry 2023-04-20 20:32:07 +01:00
Auxilor
d96ad10960 Added locker to registry 2023-04-20 19:27:52 +01:00
Auxilor
21283b0928 Added ExternalDataStoreObjectAdapter 2023-04-20 19:19:00 +01:00
Auxilor
2797687f01 Cleanup 2023-04-20 17:54:23 +01:00
Auxilor
9c68d1fbc3 Merge branch 'master' into develop
# Conflicts:
#	eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/integrations/customitems/CustomItemsOraxen.kt
2023-04-20 17:45:06 +01:00
Auxilor
9371d9b88d Upstream 2023-04-20 17:44:58 +01:00
Auxilor
14e2ead488 Fixed javadoc, updated Kingdoms 2023-04-20 17:42:46 +01:00
Auxilor
5473bb8ef8 Cleaned up IntegrationRegistry 2023-04-20 17:34:18 +01:00
Auxilor
90c55849ae Isolated integration registration 2023-04-20 17:24:56 +01:00
Auxilor
9809140cf9 Isolated remaining integrations 2023-04-20 17:23:24 +01:00
Auxilor
49a82dc005 Isolated ShopManager 2023-04-20 17:15:18 +01:00
Auxilor
92dec03b9a Added IntegrationRegistry 2023-04-20 17:09:46 +01:00
Auxilor
7453c70b87 Fixed imports 2023-04-20 16:52:49 +01:00
Auxilor
3038ea43d0 Updated to 6.55.0 2023-04-20 16:51:11 +01:00
Auxilor
3c6ddd8255 Added OutdatedEcoVersionError 2023-04-20 16:50:35 +01:00
Auxilor
925ee04cc1 Added Version as a cross-version compatible version of DefaultArtifactVersion 2023-04-20 16:48:20 +01:00
Auxilor
6f7de8716b Added KRegistrable 2023-04-20 16:41:35 +01:00
Auxilor
a17b951a8b Made registry lockable and iterable 2023-04-20 16:40:06 +01:00
Auxilor
f003ed06a8 Fixed imports 2023-04-19 18:00:19 +01:00
Auxilor
f864953da2 Updated to 6.54.1 2023-04-19 17:38:22 +01:00
Auxilor
6ef31444ac Removed Checkstyle CI, cleaned up Oraxen PR 2023-04-19 17:38:09 +01:00
Will FP
99258116de Merge pull request #264 from MCCasper/master
fix oraxen and SNBT
2023-04-19 12:33:14 -04:00
casper
a59c68102e fix SNBT matching the same tag for diff materials 2023-04-19 11:09:26 -05:00
casper
2482525fe2 load oraxen later 2023-04-18 22:23:49 -05:00
Auxilor
acb326c0c8 Updated to 6.54.0 2023-04-13 12:13:32 -04:00
Auxilor
11d947e24b Updated to 6.53.2 2023-04-13 12:09:14 -04:00
Auxilor
3cced3012c Added Prerequisite#HAS_1_19_4 2023-04-13 11:59:04 -04:00
Auxilor
520523e903 Isolated integration loading 2023-04-13 11:57:49 -04:00
Auxilor
ee36cc74f8 Improved lifecycle error logging 2023-04-13 11:50:32 -04:00
Auxilor
55344e0550 Improved lifecycle error handling, isolated tasks 2023-04-13 11:49:43 -04:00
Auxilor
75f6f05c7d Merge branch 'master' into develop 2023-03-30 14:05:09 +01:00
Auxilor
17fa519501 Revert "Fixed ContinuallyAppliedPersistentDataContainer"
This reverts commit 1852ff86ec.
2023-03-30 14:04:43 +01:00
Auxilor
1a72cf3ca9 Revert "Updated to 6.53.2"
This reverts commit d11f355c44.
2023-03-30 14:04:43 +01:00
Auxilor
d11f355c44 Updated to 6.53.2 2023-03-30 12:08:37 +01:00
Auxilor
1852ff86ec Fixed ContinuallyAppliedPersistentDataContainer 2023-03-30 12:08:26 +01:00
Auxilor
ffe9219f45 Changed README to show repo.auxilor.io 2023-03-29 13:33:24 +01:00
Auxilor
f67a5d3b3d Added repo.auxilor.io 2023-03-29 13:30:15 +01:00
Auxilor
bbd541abe0 Added repo.auxilor.io 2023-03-29 13:21:40 +01:00
Auxilor
3de8d0fed9 Updated to 6.53.1 2023-03-28 17:13:04 +01:00
Auxilor
df4abe39eb Fixed tab completion for dynamically registered commands 2023-03-28 17:12:54 +01:00
Auxilor
f5e289966f Fixed tab completion for dynamically registered commands 2023-03-28 17:12:35 +01:00
Auxilor
bcfa4bd82e Added json() extension 2023-03-25 17:48:27 +00:00
Auxilor
229c9e58c3 Merge branch 'develop'
# Conflicts:
#	eco-api/src/main/java/com/willfp/eco/core/config/TransientConfig.java
#	eco-core/core-nms/nms-common/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/common/packet/PacketInjectorListener.kt
#	gradle.properties
2023-03-25 15:34:47 +00:00
Auxilor
4f30a6e04e Removed all forRemoval classes / methods deprecated since before 6.43.0 2023-03-20 12:52:41 +00:00
Auxilor
9ea45ee0d0 Updated EcoPlugin#getID 2023-03-19 22:24:02 +00:00
Auxilor
192316214d Added Items.matchesAny 2023-03-19 22:08:47 +00:00
Auxilor
feb8898a87 Added default values to ExternalDataStore.get 2023-03-19 22:03:21 +00:00
Auxilor
1e64815e47 Added Registry.tryFitPattern 2023-03-19 22:00:42 +00:00
Auxilor
dc10648c25 Fixed DefaultMap and ListMap, adding tasks to lifecycle events, and packet injection 2023-03-19 17:39:20 +00:00
Auxilor
70131a6cae Added logging for invalid registry IDs 2023-03-18 15:22:20 +00:00
Auxilor
6d23cc7141 Fixed Registry#clear 2023-03-18 15:17:41 +00:00
Auxilor
473202527a Fixed EntityDeathByEntityEvent for WildStacker users 2023-03-17 21:23:54 +00:00
Auxilor
bc24aaeb3c Fixed 1.19.4 support
(cherry picked from commit ad47b7898e)
2023-03-15 21:10:33 +00:00
Auxilor
52072bd935 Added 1.19.4 support
(cherry picked from commit cb3ccbb39a)
2023-03-15 21:10:33 +00:00
Auxilor
ad47b7898e Fixed 1.19.4 support 2023-03-15 21:06:02 +00:00
Auxilor
19d6533db6 Updated to 6.52.3 2023-03-15 21:05:15 +00:00
Auxilor
3a37d40271 Fixed missing channel bug 2023-03-15 21:02:05 +00:00
Auxilor
cb3ccbb39a Added 1.19.4 support 2023-03-15 21:02:01 +00:00
Auxilor
5c3bb678b3 Updated backend paper version 2023-03-15 18:20:46 +00:00
Auxilor
4f4ee82e6b Converted remaining groovy buildscripts to kotlin 2023-03-14 19:46:12 +00:00
Auxilor
32d88f55f8 Fixed environment variables 2023-03-14 17:18:05 +00:00
Auxilor
bc8d615079 Added environment variables, moved eco.yml components around, added option to disable reflective reload, moved eco to be a paper plugin 2023-03-14 16:35:30 +00:00
Auxilor
55b7c3c16f Added ExternalDataStore 2023-03-14 12:45:35 +00:00
Auxilor
9535986f59 Fixed EcoPlugin#getID 2023-03-14 12:25:29 +00:00
Auxilor
fb17fc1383 Fixed annotation mismatch 2023-03-13 15:24:51 +00:00
Auxilor
4221368388 Made EcoPlugin registrable 2023-03-13 15:18:21 +00:00
Auxilor
d4432d0cb8 Updated to 6.53.0 2023-03-13 14:31:19 +00:00
Auxilor
f9093c2ed6 Added LifecyclePosition 2023-03-13 14:23:28 +00:00
Auxilor
15f4d5c098 Fixed missing channel bug 2023-03-13 13:35:51 +00:00
Auxilor
dc47bc7995 Updated Placeholder API, added ability to parse placeholders without PAPI installed 2023-03-11 17:08:50 +00:00
Auxilor
29ce0deb1b Merge remote-tracking branch 'origin/develop' into develop 2023-02-27 19:19:21 +00:00
Auxilor
fd78402bf5 Updated to 6.52.2 2023-02-27 19:19:18 +00:00
Will FP
5f65e3f520 Merge pull request #248
Yet another economyshopgui fix
2023-02-27 19:19:06 +00:00
0ft3n
ceaf4d34a5 Yet another economyshopgui fix 2023-02-27 22:13:02 +03:00
Auxilor
2d2e5f8150 Updated to 6.52.1 2023-02-27 17:00:24 +00:00
Auxilor
323a4aefef Fixed ListMap overload resolution ambiguity for kotlin 2023-02-27 17:00:15 +00:00
450 changed files with 11381 additions and 3574 deletions

1
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1 @@
* @WillFP

View File

@@ -1,15 +0,0 @@
name: Check PR Codestyle
on: [ pull_request ]
jobs:
checkstyle:
name: Checkstyle
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: dbelyaev/action-checkstyle@v0.5.1
with:
github_token: ${{ secrets.github_token }}
reporter: github-pr-review
level: warning
checkstyle_config: ../../config/checkstyle/checkstyle.xml

View File

@@ -1,6 +1,6 @@
name: Java CI name: Java CI
on: [ push, pull_request ] on: [ push, pull_request, workflow_dispatch ]
jobs: jobs:
build: build:
@@ -14,11 +14,11 @@ jobs:
id: vars id: vars
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- name: Set up JDK 17 - name: Set up JDK 21
uses: actions/setup-java@v2 uses: actions/setup-java@v2
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 17 java-version: 21
- name: Setup build cache - name: Setup build cache
uses: actions/cache@v2.1.6 uses: actions/cache@v2.1.6

21
.github/workflows/master-pr.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
name: PR Alert for Master Branch
on:
pull_request:
branches:
- master
jobs:
alert:
runs-on: ubuntu-latest
steps:
- name: Comment PR
uses: actions/github-script@v5
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '⚠️ PRs should not be opened against the `master` branch directly. Please use the `develop` branch as the base for your PRs. ⚠️'
})

View File

@@ -12,11 +12,11 @@ jobs:
- name: Checkout latest code - name: Checkout latest code
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Set up JDK 17 - name: Set up JDK 21
uses: actions/setup-java@v2 uses: actions/setup-java@v2
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 17 java-version: 21
- name: Setup build cache - name: Setup build cache
uses: actions/cache@v2.1.6 uses: actions/cache@v2.1.6
@@ -28,6 +28,8 @@ jobs:
- name: Publish artifact - name: Publish artifact
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
# The GITHUB_REF tag comes in the format 'refs/tags/xxx'. # The GITHUB_REF tag comes in the format 'refs/tags/xxx'.
# So if we split on '/' and take the 3rd value, we can get the release name. # So if we split on '/' and take the 3rd value, we can get the release name.

View File

@@ -14,11 +14,11 @@ jobs:
id: vars id: vars
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- name: Set up JDK 17 - name: Set up JDK 21
uses: actions/setup-java@v2 uses: actions/setup-java@v2
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 17 java-version: 21
- name: Setup build cache - name: Setup build cache
uses: actions/cache@v2.1.6 uses: actions/cache@v2.1.6

View File

@@ -1,674 +1,23 @@
GNU GENERAL PUBLIC LICENSE The MIT License (MIT)
Version 3, 29 June 2007 =====================
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> Permission is hereby granted, free of charge, to any person
Everyone is permitted to copy and distribute verbatim copies obtaining a copy of this software and associated documentation
of this license document, but changing it is not allowed. files (the “Software”), to deal in the Software without
restriction, including without limitation the rights to use,
Preamble copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
The GNU General Public License is a free, copyleft license for Software is furnished to do so, subject to the following
software and other kinds of works. conditions:
The licenses for most software and other practical works are designed The above copyright notice and this permission notice shall be
to take away your freedom to share and change the works. By contrast, included in all copies or substantial portions of the Software.
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
software for all its users. We, the Free Software Foundation, use the EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
GNU General Public License for most of our software; it applies also to OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
any other work released this way by its authors. You can apply it to NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
your programs, too. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
When we speak of free software, we are referring to freedom, not FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
price. Our General Public Licenses are designed to make sure that you OTHER DEALINGS IN THE SOFTWARE.
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View File

@@ -63,7 +63,7 @@ eco comes packed with all the tools you need in your plugins:
# For developers # For developers
## Javadoc ## Javadoc
The 6.49.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.49.0/javadoc/) The 6.53.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.53.0/javadoc/)
## Plugin Information ## Plugin Information
@@ -75,31 +75,31 @@ depend:
- eco - eco
``` ```
## Get from JitPack: ## Dependency Information:
Gradle: Gradle:
```groovy ```kts
repositories { repositories {
maven { url 'https://jitpack.io' } maven("https://repo.auxilor.io/repository/maven-public/")
} }
``` ```
```groovy ```groovy
dependencies { dependencies {
compileOnly 'com.willfp:eco:Tag' compileOnly("com.willfp:eco:Tag")
} }
``` ```
Replace `Tag` with a release tag for eco, eg `6.49.0`. Replace `Tag` with a release tag for eco, eg `6.53.0`.
Maven: Maven:
```xml ```xml
<repository> <repository>
<id>jitpack.io</id> <id>auxilor</id>
<url>https://jitpack.io</url> <url>https://repo.auxilor.io/repository/maven-public/</url>
</repository> </repository>
``` ```
@@ -112,7 +112,7 @@ Maven:
</dependency> </dependency>
``` ```
Replace `Tag` with a release tag for eco, eg `6.49.0`. Replace `Tag` with a release tag for eco, eg `6.53.0`.
## Build locally: ## Build locally:
@@ -127,7 +127,7 @@ cd eco
## License ## License
eco is licensed under GNU GPL3. *Click here to read [the entire license](https://github.com/Auxilor/eco/blob/master/LICENSE.md).* eco is licensed under the MIT license. *Click here to read [the entire license](https://github.com/Auxilor/eco/blob/master/LICENSE.md).*
<h1 align="center"> <h1 align="center">
Check out our partners! Check out our partners!

View File

@@ -4,16 +4,17 @@ buildscript {
} }
dependencies { dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.21")
} }
} }
plugins { plugins {
id("java-library") id("java-library")
id("com.github.johnrengelman.shadow") version "7.1.2" id("io.github.goooler.shadow") version "8.1.7"
id("maven-publish") id("maven-publish")
id("java") id("java")
kotlin("jvm") version "1.7.10" kotlin("jvm") version "1.9.21"
kotlin("plugin.serialization") version "1.9.21"
} }
dependencies { dependencies {
@@ -21,27 +22,33 @@ dependencies {
implementation(project(path = ":eco-core:core-plugin", configuration = "shadow")) implementation(project(path = ":eco-core:core-plugin", configuration = "shadow"))
implementation(project(":eco-core:core-proxy")) implementation(project(":eco-core:core-proxy"))
implementation(project(":eco-core:core-backend")) implementation(project(":eco-core:core-backend"))
implementation(project(":eco-core:core-backend-modern"))
implementation(project(path = ":eco-core:core-nms:v1_17_R1", configuration = "reobf")) implementation(project(path = ":eco-core:core-nms:v1_17_R1", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf")) implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_18_R2", configuration = "reobf")) implementation(project(path = ":eco-core:core-nms:v1_18_R2", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_19_R1", configuration = "reobf")) implementation(project(path = ":eco-core:core-nms:v1_19_R1", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_19_R2", configuration = "reobf")) implementation(project(path = ":eco-core:core-nms:v1_19_R2", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_19_R3", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_20_R1", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_20_R2", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_20_R3", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_21", configuration = "reobf"))
} }
allprojects { allprojects {
apply(plugin = "java") apply(plugin = "java")
apply(plugin = "java-library") apply(plugin = "java-library")
apply(plugin = "maven-publish") apply(plugin = "maven-publish")
apply(plugin = "com.github.johnrengelman.shadow") apply(plugin = "io.github.goooler.shadow")
apply(plugin = "kotlin") apply(plugin = "kotlin")
apply(plugin = "org.jetbrains.kotlin.plugin.serialization")
repositories { repositories {
mavenCentral() mavenCentral()
mavenLocal() maven("https://repo.auxilor.io/repository/maven-public/")
maven("https://jitpack.io") maven("https://jitpack.io") {
content { includeGroupByRegex("com\\.github\\..*") }
// CustomCrafting }
maven("https://maven.wolfyscript.com/repository/public/")
// SuperiorSkyblock2 // SuperiorSkyblock2
maven("https://repo.bg-software.com/repository/api/") maven("https://repo.bg-software.com/repository/api/")
@@ -56,7 +63,7 @@ allprojects {
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
// ProtocolLib // ProtocolLib
maven("https://repo.dmulloy2.net/nexus/repository/public/") //maven("https://repo.dmulloy2.net/nexus/repository/public/")
// WorldGuard // WorldGuard
maven("https://maven.enginehub.org/repo/") maven("https://maven.enginehub.org/repo/")
@@ -79,21 +86,34 @@ allprojects {
// LibsDisguises // LibsDisguises
maven("https://repo.md-5.net/content/groups/public/") maven("https://repo.md-5.net/content/groups/public/")
maven("https://repo.techscode.com/repository/maven-releases/") // PlayerPoints
maven("https://repo.rosewooddev.io/repository/public/")
// Denizen
maven("https://maven.citizensnpcs.co/repo")
// IridiumSkyblock
maven("https://nexus.iridiumdevelopment.net/repository/maven-releases/")
// HuskPlugins
maven("https://repo.william278.net/releases")
// FancyHolograms
maven("https://repo.fancyplugins.de/releases")
} }
dependencies { dependencies {
// Kotlin // Kotlin
implementation(kotlin("stdlib", version = "1.7.10")) implementation(kotlin("stdlib", version = "1.9.21"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.2") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
// Included in spigot jar, no need to move to implementation // Included in spigot jar, no need to move to implementation
compileOnly("org.jetbrains:annotations:23.0.0") compileOnly("org.jetbrains:annotations:23.0.0")
compileOnly("com.google.guava:guava:31.1-jre") compileOnly("com.google.guava:guava:31.1-jre")
// Test // Test
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2") testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.2")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2")
// Adventure // Adventure
implementation("net.kyori:adventure-api:4.10.1") implementation("net.kyori:adventure-api:4.10.1")
@@ -103,8 +123,8 @@ allprojects {
implementation("net.kyori:adventure-text-serializer-legacy:4.10.1") implementation("net.kyori:adventure-text-serializer-legacy:4.10.1")
// Other // Other
implementation("com.github.ben-manes.caffeine:caffeine:3.1.0") implementation("com.github.ben-manes.caffeine:caffeine:3.1.5")
implementation("org.apache.maven:maven-artifact:3.8.5") implementation("org.apache.maven:maven-artifact:3.9.0")
} }
tasks.withType<JavaCompile> { tasks.withType<JavaCompile> {
@@ -128,58 +148,21 @@ allprojects {
} }
tasks { tasks {
withType<Jar> {
duplicatesStrategy = DuplicatesStrategy.WARN
}
compileKotlin { compileKotlin {
kotlinOptions { kotlinOptions {
jvmTarget = "17" jvmTarget = "17"
} }
} }
shadowJar {
relocate("org.bstats", "com.willfp.eco.libs.bstats")
relocate("redempt.crunch", "com.willfp.eco.libs.crunch")
relocate("org.apache.commons.lang3", "com.willfp.eco.libs.lang3")
relocate("org.apache.maven", "com.willfp.eco.libs.maven")
relocate("org.checkerframework", "com.willfp.eco.libs.checkerframework")
relocate("org.intellij", "com.willfp.eco.libs.intellij")
relocate("org.jetbrains.annotations", "com.willfp.eco.libs.jetbrains.annotations")
//relocate("org.jetbrains.exposed", "com.willfp.eco.libs.exposed")
relocate("org.objenesis", "com.willfp.eco.libs.objenesis")
relocate("org.reflections", "com.willfp.eco.libs.reflections")
relocate("javassist", "com.willfp.eco.libs.javassist")
relocate("javax.annotation", "com.willfp.eco.libs.annotation")
relocate("com.google.errorprone", "com.willfp.eco.libs.errorprone")
relocate("com.google.j2objc", "com.willfp.eco.libs.j2objc")
relocate("com.google.thirdparty", "com.willfp.eco.libs.google.thirdparty")
relocate("com.google.protobuf", "com.willfp.eco.libs.google.protobuf") // No I don't know either
relocate("google.protobuf", "com.willfp.eco.libs.protobuf") // Still don't know
relocate("com.zaxxer.hikari", "com.willfp.eco.libs.hikari")
//relocate("com.mysql", "com.willfp.eco.libs.mysql")
relocate("de.undercouch.bson4jackson", "com.willfp.eco.libs.bson4jackson")
relocate("com.fasterxml.jackson", "com.willfp.eco.libs.jackson")
relocate("com.mongodb", "com.willfp.eco.libs.mongodb")
relocate("org.bson", "com.willfp.eco.libs.bson")
relocate("org.litote", "com.willfp.eco.libs.litote")
relocate("org.reactivestreams", "com.willfp.eco.libs.reactivestreams")
relocate("reactor.", "com.willfp.eco.libs.reactor.") // Dot in name to be safe
relocate("com.moandjiezana.toml", "com.willfp.eco.libs.toml")
/*
Kotlin and caffeine are not shaded so that they can be accessed directly by eco plugins.
Also, not relocating adventure, because it's a pain in the ass, and it doesn't *seem* to be causing loader constraint violations.
*/
}
compileJava { compileJava {
dependsOn(clean) dependsOn(clean)
options.encoding = "UTF-8" options.encoding = "UTF-8"
} }
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
withSourcesJar()
}
test { test {
useJUnitPlatform() useJUnitPlatform()
@@ -192,6 +175,53 @@ allprojects {
build { build {
dependsOn(shadowJar) dependsOn(shadowJar)
} }
withType<JavaCompile>().configureEach {
options.release = 17
}
}
java {
withSourcesJar()
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
}
tasks {
shadowJar {
relocate("org.bstats", "com.willfp.eco.libs.bstats")
relocate("redempt.crunch", "com.willfp.eco.libs.crunch")
relocate("org.apache.commons.lang3", "com.willfp.eco.libs.lang3")
relocate("org.apache.maven", "com.willfp.eco.libs.maven")
relocate("org.checkerframework", "com.willfp.eco.libs.checkerframework")
relocate("org.intellij", "com.willfp.eco.libs.intellij")
relocate("org.jetbrains.annotations", "com.willfp.eco.libs.jetbrains.annotations")
//relocate("org.jetbrains.exposed", "com.willfp.eco.libs.exposed")
relocate("org.objenesis", "com.willfp.eco.libs.objenesis")
relocate("org.reflections", "com.willfp.eco.libs.reflections")
relocate("javassist", "com.willfp.eco.libs.javassist")
relocate("javax.annotation", "com.willfp.eco.libs.annotation")
relocate("com.google.errorprone", "com.willfp.eco.libs.errorprone")
relocate("com.google.j2objc", "com.willfp.eco.libs.j2objc")
relocate("com.google.thirdparty", "com.willfp.eco.libs.google.thirdparty")
relocate("com.google.protobuf", "com.willfp.eco.libs.google.protobuf") // No I don't know either
relocate("google.protobuf", "com.willfp.eco.libs.protobuf") // Still don't know
relocate("com.zaxxer.hikari", "com.willfp.eco.libs.hikari")
//relocate("com.mysql", "com.willfp.eco.libs.mysql")
relocate("com.mongodb", "com.willfp.eco.libs.mongodb")
relocate("org.bson", "com.willfp.eco.libs.bson")
relocate("org.litote", "com.willfp.eco.libs.litote")
relocate("org.reactivestreams", "com.willfp.eco.libs.reactivestreams")
relocate("reactor.", "com.willfp.eco.libs.reactor.") // Dot in name to be safe
relocate("com.moandjiezana.toml", "com.willfp.eco.libs.toml")
relocate("com.willfp.modelenginebridge", "com.willfp.eco.libs.modelenginebridge")
/*
Kotlin and caffeine are not shaded so that they can be accessed directly by eco plugins.
Also, not relocating adventure, because it's a pain in the ass, and it doesn't *seem* to be causing loader constraint violations.
*/
} }
} }

View File

@@ -1,38 +0,0 @@
dependencies {
// Adventure
compileOnly 'net.kyori:adventure-platform-bukkit:4.1.0'
// Other
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.1-SNAPSHOT'
compileOnly 'com.google.code.gson:gson:2.8.8'
}
group 'com.willfp'
version rootProject.version
java {
withJavadocJar()
}
build.dependsOn publishToMavenLocal
publishing {
publications {
shadow(MavenPublication) {
from components.java
artifactId 'eco'
}
}
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/Auxilor/eco")
credentials {
username = System.getenv("GITHUB_ACTOR")
password = System.getenv("GITHUB_TOKEN")
}
}
}
}

56
eco-api/build.gradle.kts Normal file
View File

@@ -0,0 +1,56 @@
dependencies {
// Adventure
compileOnly("net.kyori:adventure-platform-bukkit:4.1.0")
// Other
compileOnly("org.spigotmc:spigot-api:1.20.2-R0.1-SNAPSHOT")
compileOnly("commons-lang:commons-lang:2.6")
compileOnly("com.comphenix.protocol:ProtocolLib:4.6.1-SNAPSHOT")
compileOnly("com.google.code.gson:gson:2.8.8")
}
group = "com.willfp"
version = rootProject.version
java {
withJavadocJar()
}
tasks {
build {
dependsOn(publishToMavenLocal)
}
}
publishing {
publications {
create<MavenPublication>("shadow") {
from(components["java"])
artifactId = "eco"
}
}
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/Auxilor/eco")
credentials {
username = System.getenv("GITHUB_ACTOR")
password = System.getenv("GITHUB_TOKEN")
}
}
}
publishing {
repositories {
maven {
name = "Auxilor"
url = uri("https://repo.auxilor.io/repository/maven-releases/")
credentials {
username = System.getenv("MAVEN_USERNAME")
password = System.getenv("MAVEN_PASSWORD")
}
}
}
}
}

View File

@@ -25,16 +25,18 @@ import com.willfp.eco.core.gui.menu.MenuType;
import com.willfp.eco.core.gui.slot.SlotBuilder; import com.willfp.eco.core.gui.slot.SlotBuilder;
import com.willfp.eco.core.gui.slot.functional.SlotProvider; import com.willfp.eco.core.gui.slot.functional.SlotProvider;
import com.willfp.eco.core.items.TestableItem; import com.willfp.eco.core.items.TestableItem;
import com.willfp.eco.core.math.MathContext;
import com.willfp.eco.core.packet.Packet; import com.willfp.eco.core.packet.Packet;
import com.willfp.eco.core.placeholder.context.PlaceholderContext;
import com.willfp.eco.core.proxy.ProxyFactory; import com.willfp.eco.core.proxy.ProxyFactory;
import com.willfp.eco.core.scheduling.Scheduler; import com.willfp.eco.core.scheduling.Scheduler;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Mob; import org.bukkit.entity.Mob;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@@ -135,6 +137,14 @@ public interface Eco {
@NotNull @NotNull
Logger createLogger(@NotNull EcoPlugin plugin); Logger createLogger(@NotNull EcoPlugin plugin);
/**
* Get NOOP logger.
*
* @return The logger.
*/
@NotNull
Logger getNOOPLogger();
/** /**
* Create a PAPI integration. * Create a PAPI integration.
* *
@@ -170,7 +180,7 @@ public interface Eco {
* @return The PluginCommandBase implementation * @return The PluginCommandBase implementation
*/ */
@NotNull @NotNull
PluginCommandBase createPluginCommand(@NotNull CommandBase parentDelegate, PluginCommandBase createPluginCommand(@NotNull PluginCommandBase parentDelegate,
@NotNull EcoPlugin plugin, @NotNull EcoPlugin plugin,
@NotNull String name, @NotNull String name,
@NotNull String permission, @NotNull String permission,
@@ -393,15 +403,6 @@ public interface Eco {
@NotNull @NotNull
ServerProfile getServerProfile(); ServerProfile getServerProfile();
/**
* Unload a player profile from memory.
* <p>
* This will not save the profile first.
*
* @param uuid The uuid.
*/
void unloadPlayerProfile(@NotNull UUID uuid);
/** /**
* Create dummy entity - never spawned, exists purely in code. * Create dummy entity - never spawned, exists purely in code.
* *
@@ -528,10 +529,11 @@ public interface Eco {
* *
* @param expression The expression. * @param expression The expression.
* @param context The context. * @param context The context.
* @return The value of the expression, or zero if invalid. * @return The value of the expression, or null if invalid.
*/ */
double evaluate(@NotNull String expression, @Nullable
@NotNull MathContext context); Double evaluate(@NotNull String expression,
@NotNull PlaceholderContext context);
/** /**
* Get the menu a player currently has open. * Get the menu a player currently has open.
@@ -563,6 +565,43 @@ public interface Eco {
void sendPacket(@NotNull Player player, void sendPacket(@NotNull Player player,
@NotNull Packet packet); @NotNull Packet packet);
/**
* Translate placeholders in a string.
*
* @param text The text.
* @param context The context.
* @return The translated text.
*/
@NotNull
String translatePlaceholders(@NotNull String text,
@NotNull PlaceholderContext context);
/**
* Get the value of a placeholder.
*
* @param plugin The plugin that owns the placeholder.
* @param args The placeholder arguments.
* @param context The context.
* @return The value, or null if invalid.
*/
@Nullable
String getPlaceholderValue(@Nullable EcoPlugin plugin,
@NotNull String args,
@NotNull PlaceholderContext context);
/**
* Set a client-side entity display name.
*
* @param entity The entity.
* @param player The player.
* @param name The display name.
* @param visible If the display name should be forcibly visible.
*/
void setClientsideDisplayName(@NotNull LivingEntity entity,
@NotNull Player player,
@NotNull Component name,
boolean visible);
/** /**
* Get the instance of eco; the bridge between the api frontend and the implementation backend. * Get the instance of eco; the bridge between the api frontend and the implementation backend.
* *

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core; package com.willfp.eco.core;
import com.google.common.collect.ImmutableList;
import com.willfp.eco.core.command.impl.PluginCommand; import com.willfp.eco.core.command.impl.PluginCommand;
import com.willfp.eco.core.config.base.ConfigYml; import com.willfp.eco.core.config.base.ConfigYml;
import com.willfp.eco.core.config.base.LangYml; import com.willfp.eco.core.config.base.LangYml;
@@ -13,12 +14,16 @@ import com.willfp.eco.core.factory.MetadataValueFactory;
import com.willfp.eco.core.factory.NamespacedKeyFactory; import com.willfp.eco.core.factory.NamespacedKeyFactory;
import com.willfp.eco.core.factory.RunnableFactory; import com.willfp.eco.core.factory.RunnableFactory;
import com.willfp.eco.core.integrations.IntegrationLoader; import com.willfp.eco.core.integrations.IntegrationLoader;
import com.willfp.eco.core.map.ListMap;
import com.willfp.eco.core.packet.PacketListener; import com.willfp.eco.core.packet.PacketListener;
import com.willfp.eco.core.proxy.ProxyFactory; import com.willfp.eco.core.proxy.ProxyFactory;
import com.willfp.eco.core.registry.Registrable;
import com.willfp.eco.core.registry.Registry;
import com.willfp.eco.core.scheduling.Scheduler; import com.willfp.eco.core.scheduling.Scheduler;
import com.willfp.eco.core.version.OutdatedEcoVersionError;
import com.willfp.eco.core.version.Version;
import com.willfp.eco.core.web.UpdateChecker; import com.willfp.eco.core.web.UpdateChecker;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
@@ -29,12 +34,16 @@ import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -53,27 +62,12 @@ import java.util.stream.Collectors;
* <b>IMPORTANT: When reloading a plugin, all runnables / tasks will * <b>IMPORTANT: When reloading a plugin, all runnables / tasks will
* be cancelled.</b> * be cancelled.</b>
*/ */
@SuppressWarnings({"unused", "DeprecatedIsStillUsed", "deprecation", "RedundantSuppression"}) @SuppressWarnings({"unused", "DeprecatedIsStillUsed", "deprecation", "RedundantSuppression", "MismatchedQueryAndUpdateOfCollection"})
public abstract class EcoPlugin extends JavaPlugin implements PluginLike { public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Registrable {
/** /**
* The polymart resource ID of the plugin. * The properties (eco.yml).
*/ */
private final int resourceId; private final PluginProps props;
/**
* The bStats resource ID of the plugin.
*/
private final int bStatsId;
/**
* The package where proxy implementations are.
*/
private final String proxyPackage;
/**
* The color of the plugin, used in messages.
*/
private final String color;
/** /**
* Loaded integrations. * Loaded integrations.
@@ -129,24 +123,27 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
/** /**
* The display module for the plugin. * The display module for the plugin.
*
* @deprecated Plugins can now have multiple display modules.
*/ */
@Deprecated(since = "6.72.0")
private DisplayModule displayModule; private DisplayModule displayModule;
/**
* The display modules for the plugin.
*/
private List<DisplayModule> displayModules = new ArrayList<>();
/** /**
* The logger for the plugin. * The logger for the plugin.
*/ */
private final Logger logger; private Logger logger;
/** /**
* If the server is running an outdated version of the plugin. * If the server is running an outdated version of the plugin.
*/ */
private boolean outdated = false; private boolean outdated = false;
/**
* If the plugin supports extensions.
*/
private final boolean supportingExtensions;
/** /**
* The proxy factory. * The proxy factory.
*/ */
@@ -156,27 +153,32 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
/** /**
* The tasks to run on enable. * The tasks to run on enable.
*/ */
private final List<Runnable> onEnable = new ArrayList<>(); private final ListMap<LifecyclePosition, Runnable> onEnable = new ListMap<>();
/** /**
* The tasks to run on disable. * The tasks to run on disable.
*/ */
private final List<Runnable> onDisable = new ArrayList<>(); private final ListMap<LifecyclePosition, Runnable> onDisable = new ListMap<>();
/** /**
* The tasks to run on reload. * The tasks to run on reload.
*/ */
private final List<Runnable> onReload = new ArrayList<>(); private final ListMap<LifecyclePosition, Runnable> onReload = new ListMap<>();
/** /**
* The tasks to run on load. * The tasks to run on load.
*/ */
private final List<Runnable> onLoad = new ArrayList<>(); private final ListMap<LifecyclePosition, Runnable> onLoad = new ListMap<>();
/** /**
* The tasks to run after load. * The tasks to run after load.
*/ */
private final List<Runnable> afterLoad = new ArrayList<>(); private final ListMap<LifecyclePosition, Runnable> afterLoad = new ListMap<>();
/**
* The tasks to run on task creation.
*/
private final ListMap<LifecyclePosition, Runnable> onCreateTasks = new ListMap<>();
/** /**
* Create a new plugin. * Create a new plugin.
@@ -193,7 +195,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* Create a new plugin without proxy support, polymart, or bStats. * Create a new plugin without proxy support, polymart, or bStats.
* *
* @param color The color. * @param color The color.
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(@NotNull final String color) { protected EcoPlugin(@NotNull final String color) {
this("", color); this("", color);
} }
@@ -204,7 +208,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* *
* @param proxyPackage The package where proxy implementations are stored. * @param proxyPackage The package where proxy implementations are stored.
* @param color The color of the plugin (used in messages, using standard formatting) * @param color The color of the plugin (used in messages, using standard formatting)
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(@NotNull final String proxyPackage, protected EcoPlugin(@NotNull final String proxyPackage,
@NotNull final String color) { @NotNull final String color) {
this(0, 0, proxyPackage, color); this(0, 0, proxyPackage, color);
@@ -216,7 +222,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param resourceId The polymart resource ID for the plugin. * @param resourceId The polymart resource ID for the plugin.
* @param bStatsId The bStats resource ID for the plugin. * @param bStatsId The bStats resource ID for the plugin.
* @param color The color of the plugin (used in messages, using standard formatting) * @param color The color of the plugin (used in messages, using standard formatting)
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId, protected EcoPlugin(final int resourceId,
final int bStatsId, final int bStatsId,
@NotNull final String color) { @NotNull final String color) {
@@ -230,7 +238,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param bStatsId The bStats resource ID for the plugin. * @param bStatsId The bStats resource ID for the plugin.
* @param color The color of the plugin (used in messages, using standard formatting) * @param color The color of the plugin (used in messages, using standard formatting)
* @param supportingExtensions If the plugin supports extensions. * @param supportingExtensions If the plugin supports extensions.
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId, protected EcoPlugin(final int resourceId,
final int bStatsId, final int bStatsId,
@NotNull final String color, @NotNull final String color,
@@ -245,7 +255,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param bStatsId The bStats resource ID for the plugin. * @param bStatsId The bStats resource ID for the plugin.
* @param proxyPackage The package where proxy implementations are stored. * @param proxyPackage The package where proxy implementations are stored.
* @param color The color of the plugin (used in messages, using standard formatting) * @param color The color of the plugin (used in messages, using standard formatting)
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId, protected EcoPlugin(final int resourceId,
final int bStatsId, final int bStatsId,
@NotNull final String proxyPackage, @NotNull final String proxyPackage,
@@ -261,21 +273,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param proxyPackage The package where proxy implementations are stored. * @param proxyPackage The package where proxy implementations are stored.
* @param color The color of the plugin (used in messages, using standard formatting) * @param color The color of the plugin (used in messages, using standard formatting)
* @param supportingExtensions If the plugin supports extensions. * @param supportingExtensions If the plugin supports extensions.
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId, protected EcoPlugin(final int resourceId,
final int bStatsId, final int bStatsId,
@NotNull final String proxyPackage, @NotNull final String proxyPackage,
@NotNull final String color, @NotNull final String color,
final boolean supportingExtensions) { final boolean supportingExtensions) {
this( this(PluginProps.createSimple(resourceId, bStatsId, proxyPackage, color, supportingExtensions));
PluginProps.createSimple(
resourceId,
bStatsId,
proxyPackage,
color,
supportingExtensions
)
);
} }
/** /**
@@ -325,13 +331,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
PluginProps props = this.mutateProps(generatedProps); PluginProps props = this.mutateProps(generatedProps);
props.validate(); props.validate();
this.resourceId = props.getResourceId(); this.props = props;
this.bStatsId = props.getBStatsId();
this.proxyPackage = props.getProxyPackage();
this.color = props.getColor();
this.supportingExtensions = props.isSupportingExtensions();
this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.get().createProxyFactory(this); this.proxyFactory = this.props.getProxyPackage().equalsIgnoreCase("") ? null : Eco.get().createProxyFactory(this);
this.logger = Eco.get().createLogger(this); this.logger = Eco.get().createLogger(this);
this.getLogger().info("Initializing " + this.getColor() + this.getName()); this.getLogger().info("Initializing " + this.getColor() + this.getName());
@@ -363,14 +365,14 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
they have an outdated version of eco installed. they have an outdated version of eco installed.
*/ */
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.get().getEcoPlugin().getDescription().getVersion()); Version runningVersion = new Version(Eco.get().getEcoPlugin().getDescription().getVersion());
DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(this.getMinimumEcoVersion()); Version requiredVersion = new Version(this.getMinimumEcoVersion());
if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) { if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) {
this.getLogger().severe("You are running an outdated version of eco!"); this.getLogger().severe("You are running an outdated version of eco!");
this.getLogger().severe("You must be on at least" + this.getMinimumEcoVersion()); this.getLogger().severe("You must be on at least" + this.getMinimumEcoVersion());
this.getLogger().severe("Download the newest version here:"); this.getLogger().severe("Download the newest version here:");
this.getLogger().severe("https://polymart.org/download/773/recent/JSpprMspkuyecf5y1wQ2Jn8OoLQSQ_IW"); this.getLogger().severe("https://polymart.org/download/773/recent/JSpprMspkuyecf5y1wQ2Jn8OoLQSQ_IW");
Bukkit.getPluginManager().disablePlugin(this); throw new OutdatedEcoVersionError("This plugin requires at least eco version " + this.getMinimumEcoVersion() + " to run.");
} }
} }
@@ -381,13 +383,12 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public final void onEnable() { public final void onEnable() {
super.onEnable(); super.onEnable();
this.getLogger().info("");
this.getLogger().info("Loading " + this.getColor() + this.getName()); this.getLogger().info("Loading " + this.getColor() + this.getName());
if (this.getResourceId() != 0 && !Eco.get().getEcoPlugin().getConfigYml().getBool("no-update-checker")) { if (this.getResourceId() != 0 && !Eco.get().getEcoPlugin().getConfigYml().getBool("no-update-checker")) {
new UpdateChecker(this).getVersion(version -> { new UpdateChecker(this).getVersion(version -> {
DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion()); Version currentVersion = new Version(this.getDescription().getVersion());
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version); Version mostRecentVersion = new Version(version);
if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) { if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) {
this.outdated = true; this.outdated = true;
this.getLogger().warning(this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")"); this.getLogger().warning(this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
@@ -401,10 +402,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
Eco.get().registerBStats(this); Eco.get().registerBStats(this);
} }
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()) Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).map(String::toLowerCase).collect(Collectors.toSet());
.map(Plugin::getName)
.map(String::toLowerCase)
.collect(Collectors.toSet());
if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) { if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) {
Eco.get().createPAPIIntegration(this); Eco.get().createPAPIIntegration(this);
@@ -412,14 +410,21 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.loadIntegrationLoaders().forEach(integrationLoader -> { this.loadIntegrationLoaders().forEach(integrationLoader -> {
if (enabledPlugins.contains(integrationLoader.getPluginName().toLowerCase())) { if (enabledPlugins.contains(integrationLoader.getPluginName().toLowerCase())) {
this.loadedIntegrations.add(integrationLoader.getPluginName()); try {
integrationLoader.load(); integrationLoader.load();
this.loadedIntegrations.add(integrationLoader.getPluginName());
} catch (Exception e) {
this.getLogger().warning("Failed to load integration for " + integrationLoader.getPluginName());
e.printStackTrace();
}
} }
}); });
this.loadedIntegrations.removeIf(pl -> pl.equalsIgnoreCase(this.getName())); this.loadedIntegrations.removeIf(pl -> pl.equalsIgnoreCase(this.getName()));
this.getLogger().info("Loaded integrations: " + String.join(", ", this.getLoadedIntegrations())); if (!this.getLoadedIntegrations().isEmpty()) {
this.getLogger().info("Loaded integrations: " + String.join(", ", this.getLoadedIntegrations()));
}
Prerequisite.update(); Prerequisite.update();
@@ -436,23 +441,35 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.loadPluginCommands().forEach(PluginCommand::register); this.loadPluginCommands().forEach(PluginCommand::register);
this.getScheduler().runLater(this::afterLoad, 1); // Run preliminary reload to resolve load order issues
this.getScheduler().runLater(() -> {
Logger before = this.getLogger();
// Temporary silence logger.
this.logger = Eco.get().getNOOPLogger();
this.reload(false);
this.logger = before;
}, 1);
this.getScheduler().runLater(this::afterLoad, 2);
if (this.isSupportingExtensions()) { if (this.isSupportingExtensions()) {
this.getExtensionLoader().loadExtensions(); this.getExtensionLoader().loadExtensions();
if (this.getExtensionLoader().getLoadedExtensions().isEmpty()) { if (!this.getExtensionLoader().getLoadedExtensions().isEmpty()) {
this.getLogger().info("&cNo extensions found"); List<String> loadedExtensions = this.getExtensionLoader().getLoadedExtensions().stream().map(
} else { extension -> extension.getName() + " v" + extension.getVersion()
this.getLogger().info("Extensions Loaded:"); ).toList();
this.getExtensionLoader().getLoadedExtensions().forEach(extension -> this.getLogger().info("- " + extension.getName() + " v" + extension.getVersion()));
this.getLogger().info(
"Loaded extensions: " +
String.join(", ", loadedExtensions)
);
} }
} }
this.handleEnable(); this.handleLifecycle(this.onEnable, this::handleEnable);
this.onEnable.forEach(Runnable::run);
this.getLogger().info("");
} }
/** /**
@@ -461,7 +478,18 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param task The task. * @param task The task.
*/ */
public final void onEnable(@NotNull final Runnable task) { public final void onEnable(@NotNull final Runnable task) {
this.onEnable.add(task); this.onEnable(LifecyclePosition.END, task);
}
/**
* Add new task to run on enable.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void onEnable(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.onEnable.append(position, task);
} }
/** /**
@@ -474,8 +502,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.getEventManager().unregisterAllListeners(); this.getEventManager().unregisterAllListeners();
this.getScheduler().cancelAll(); this.getScheduler().cancelAll();
this.handleDisable(); this.handleLifecycle(this.onDisable, this::handleDisable);
this.onDisable.forEach(Runnable::run);
if (this.isSupportingExtensions()) { if (this.isSupportingExtensions()) {
this.getExtensionLoader().unloadExtensions(); this.getExtensionLoader().unloadExtensions();
@@ -491,7 +518,18 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param task The task. * @param task The task.
*/ */
public final void onDisable(@NotNull final Runnable task) { public final void onDisable(@NotNull final Runnable task) {
this.onDisable.add(task); this.onDisable(LifecyclePosition.END, task);
}
/**
* Add new task to run on disable.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void onDisable(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.onDisable.append(position, task);
} }
/** /**
@@ -501,8 +539,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public final void onLoad() { public final void onLoad() {
super.onLoad(); super.onLoad();
this.handleLoad(); this.handleLifecycle(this.onLoad, this::handleLoad);
this.onLoad.forEach(Runnable::run);
} }
/** /**
@@ -511,17 +548,33 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param task The task. * @param task The task.
*/ */
public final void onLoad(@NotNull final Runnable task) { public final void onLoad(@NotNull final Runnable task) {
this.onLoad.add(task); this.onLoad(LifecyclePosition.END, task);
}
/**
* Add new task to run on load.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void onLoad(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.onLoad.append(position, task);
} }
/** /**
* Default code to be executed after the server is up. * Default code to be executed after the server is up.
*/ */
public final void afterLoad() { public final void afterLoad() {
this.displayModule = createDisplayModule(); DisplayModule module = createDisplayModule();
if (module != null) {
Display.registerDisplayModule(module);
this.displayModules.add(module);
}
if (this.getDisplayModule() != null) { for (DisplayModule displayModule : this.loadDisplayModules()) {
Display.registerDisplayModule(this.getDisplayModule()); Display.registerDisplayModule(displayModule);
this.displayModules.add(displayModule);
} }
if (Prerequisite.HAS_PROTOCOLLIB.isMet()) { if (Prerequisite.HAS_PROTOCOLLIB.isMet()) {
@@ -538,15 +591,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.getLogger().severe(""); this.getLogger().severe("");
this.getLogger().severe("You don't seem to be running paper!"); this.getLogger().severe("You don't seem to be running paper!");
this.getLogger().severe("Paper is strongly recommended for all servers,"); this.getLogger().severe("Paper is strongly recommended for all servers,");
this.getLogger().severe("and some things may not function properly without it"); this.getLogger().severe("and many features may not function properly without it");
this.getLogger().severe("Download Paper from &fhttps://papermc.io"); this.getLogger().severe("Download Paper from https://papermc.io");
this.getLogger().severe("It's a drop-in replacement for Spigot, so it's easy to switch.");
this.getLogger().severe(""); this.getLogger().severe("");
this.getLogger().severe("----------------------------"); this.getLogger().severe("----------------------------");
this.getLogger().severe(""); this.getLogger().severe("");
} }
this.handleAfterLoad(); this.handleLifecycle(this.afterLoad, this::handleAfterLoad);
this.afterLoad.forEach(Runnable::run);
this.reload(); this.reload();
@@ -554,7 +607,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
extension.handleAfterLoad(); extension.handleAfterLoad();
} }
this.getLogger().info("Loaded " + this.color + this.getName()); this.getLogger().info("Loaded " + this.props.getColor() + this.getName());
} }
/** /**
@@ -563,21 +616,47 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param task The task. * @param task The task.
*/ */
public final void afterLoad(@NotNull final Runnable task) { public final void afterLoad(@NotNull final Runnable task) {
this.afterLoad.add(task); this.afterLoad(LifecyclePosition.END, task);
}
/**
* Add new task to run after load.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void afterLoad(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.afterLoad.append(position, task);
} }
/** /**
* Reload the plugin. * Reload the plugin.
*/ */
public final void reload() { public final void reload() {
this.reload(true);
}
/**
* Reload the plugin.
*
* @param cancelTasks If tasks should be cancelled.
*/
public final void reload(final boolean cancelTasks) {
this.getConfigHandler().updateConfigs(); this.getConfigHandler().updateConfigs();
this.getScheduler().cancelAll(); if (cancelTasks) {
this.getScheduler().cancelAll();
}
this.getConfigHandler().callUpdate(); this.getConfigHandler().callUpdate();
this.getConfigHandler().callUpdate(); // Call twice to fix issues this.getConfigHandler().callUpdate(); // Call twice to fix issues
this.handleReload(); this.handleLifecycle(this.onReload, this::handleReload);
this.onReload.forEach(Runnable::run);
if (cancelTasks) {
this.handleLifecycle(this.onCreateTasks, this::createTasks);
}
for (Extension extension : this.extensionLoader.getLoadedExtensions()) { for (Extension extension : this.extensionLoader.getLoadedExtensions()) {
extension.handleReload(); extension.handleReload();
@@ -585,12 +664,43 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
} }
/** /**
* Add new task to run on enable. * Add new task to run on reload.
* *
* @param task The task. * @param task The task.
*/ */
public final void onReload(@NotNull final Runnable task) { public final void onReload(@NotNull final Runnable task) {
this.onReload.add(task); this.onReload(LifecyclePosition.END, task);
}
/**
* Add new task to run on reload.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void onReload(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.onReload.append(position, task);
}
/**
* Add new task to run on createTasks.
*
* @param task The task.
*/
public final void onCreateTasks(@NotNull final Runnable task) {
this.onCreateTasks(LifecyclePosition.END, task);
}
/**
* Add new task to run on createTasks.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void onCreateTasks(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.onCreateTasks.append(position, task);
} }
/** /**
@@ -606,6 +716,43 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
return System.currentTimeMillis() - startTime; return System.currentTimeMillis() - startTime;
} }
/**
* Handle lifecycle.
*
* @param tasks The tasks.
* @param handler The handler.
*/
private void handleLifecycle(@NotNull final ListMap<LifecyclePosition, Runnable> tasks,
@NotNull final Runnable handler) {
for (Runnable task : tasks.get(LifecyclePosition.START)) {
try {
task.run();
} catch (final Exception e) {
this.getLogger().log(Level.SEVERE, "Error while running lifecycle task!");
this.getLogger().log(Level.SEVERE, "The plugin may not function properly");
e.printStackTrace();
}
}
try {
handler.run();
} catch (final Exception e) {
this.getLogger().log(Level.SEVERE, "Error while running lifecycle task!");
this.getLogger().log(Level.SEVERE, "The plugin may not function properly");
e.printStackTrace();
}
for (Runnable task : tasks.get(LifecyclePosition.END)) {
try {
task.run();
} catch (final Exception e) {
this.getLogger().log(Level.SEVERE, "Error while running lifecycle task!");
this.getLogger().log(Level.SEVERE, "The plugin may not function properly");
e.printStackTrace();
}
}
}
/** /**
* The plugin-specific code to be executed on enable. * The plugin-specific code to be executed on enable.
* <p> * <p>
@@ -644,6 +791,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
} }
/**
* The plugin-specific code to create tasks.
* <p>
* Override when needed.
*/
protected void createTasks() {
}
/** /**
* The plugin-specific code to be executed after the server is up. * The plugin-specific code to be executed after the server is up.
* <p> * <p>
@@ -759,17 +915,25 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* Create the display module for the plugin. * Create the display module for the plugin.
* *
* @return The display module, or null. * @return The display module, or null.
* @deprecated Use {@link #loadDisplayModules()} instead.
*/ */
@Nullable @Nullable
@Deprecated(since = "6.72.0")
protected DisplayModule createDisplayModule() { protected DisplayModule createDisplayModule() {
Validate.isTrue( Validate.isTrue(this.getDisplayModule() == null, "Display module exists!");
this.getDisplayModule() == null,
"Display module exists!"
);
return null; return null;
} }
/**
* Load display modules.
*
* @return The display modules.
*/
protected List<DisplayModule> loadDisplayModules() {
return new ArrayList<>();
}
/** /**
* Get the minimum version of eco to use the plugin. * Get the minimum version of eco to use the plugin.
* *
@@ -879,13 +1043,23 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
return new HashSet<>(Eco.get().getLoadedPlugins()); return new HashSet<>(Eco.get().getLoadedPlugins());
} }
/**
* Get the plugin props. (eco.yml).
*
* @return The props.
*/
@NotNull
public PluginProps getProps() {
return this.props;
}
/** /**
* Get the polymart resource ID. * Get the polymart resource ID.
* *
* @return The resource ID. * @return The resource ID.
*/ */
public int getResourceId() { public int getResourceId() {
return this.resourceId; return this.getProps().getResourceId();
} }
/** /**
@@ -894,7 +1068,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The ID. * @return The ID.
*/ */
public int getBStatsId() { public int getBStatsId() {
return this.bStatsId; return this.getProps().getBStatsId();
} }
/** /**
@@ -903,7 +1077,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The package where proxies are contained. * @return The package where proxies are contained.
*/ */
public String getProxyPackage() { public String getProxyPackage() {
return this.proxyPackage; return this.getProps().getProxyPackage();
} }
/** /**
@@ -912,7 +1086,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The color. * @return The color.
*/ */
public String getColor() { public String getColor() {
return this.color; return this.getProps().getColor();
} }
/** /**
@@ -1001,7 +1175,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* *
* @return The config handler. * @return The config handler.
*/ */
public ConfigHandler getConfigHandler() { public @NotNull ConfigHandler getConfigHandler() {
return this.configHandler; return this.configHandler;
} }
@@ -1009,12 +1183,23 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* Get the plugin's display module. * Get the plugin's display module.
* *
* @return The display module. * @return The display module.
* @deprecated Use {@link #getDisplayModules()} instead.
*/ */
@Nullable @Nullable
@Deprecated(since = "6.72.0", forRemoval = true)
public DisplayModule getDisplayModule() { public DisplayModule getDisplayModule() {
return this.displayModule; return this.displayModule;
} }
/**
* Get the plugin's display modules.
*
* @return The display modules.
*/
public List<DisplayModule> getDisplayModules() {
return ImmutableList.copyOf(this.displayModules);
}
/** /**
* Get if the plugin is outdated. * Get if the plugin is outdated.
* *
@@ -1030,7 +1215,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return If extensions are supported. * @return If extensions are supported.
*/ */
public boolean isSupportingExtensions() { public boolean isSupportingExtensions() {
return this.supportingExtensions; return this.getProps().isSupportingExtensions();
} }
/** /**
@@ -1064,4 +1249,25 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public FixedMetadataValue createMetadataValue(@NotNull final Object value) { public FixedMetadataValue createMetadataValue(@NotNull final Object value) {
return this.getMetadataValueFactory().create(value); return this.getMetadataValueFactory().create(value);
} }
/**
* Get if all {@link com.willfp.eco.core.data.keys.PersistentDataKey}'s for this
* plugin should be saved locally (via data.yml.) even if eco is using a database.
*
* @return If using local storage.
*/
public boolean isUsingLocalStorage() {
return this.configYml.isUsingLocalStorage();
}
@Override
@NotNull
public final String getID() {
return Registry.tryFitPattern(this.getName());
}
@Override
public @NotNull File getFile() {
return super.getFile();
}
} }

View File

@@ -0,0 +1,16 @@
package com.willfp.eco.core;
/**
* Marks a position in a lifecycle (e.g. enable, reload, etc).
*/
public enum LifecyclePosition {
/**
* Run at the start of the lifecycle.
*/
START,
/**
* Run at the end of the lifecycle.
*/
END
}

View File

@@ -1,44 +0,0 @@
package com.willfp.eco.core;
import org.jetbrains.annotations.NotNull;
/**
* Quick DI class to manage passing eco plugins.
* <p>
* Basically just a quick bit of laziness if you can't be bothered to add a private field
* and a protected getter, don't use this in kotlin as you can just specify
* {@code
* private val plugin: EcoPlugin
* }
* in the constructor.
*
* @param <T> The eco plugin type.
* @deprecated Leaky inheritance, shouldn't exist.
*/
@Deprecated(since = "6.43.0", forRemoval = true)
public abstract class PluginDependent<T extends EcoPlugin> {
/**
* The {@link EcoPlugin} that is stored.
*/
@NotNull
private final T plugin;
/**
* Pass an {@link EcoPlugin} in order to interface with it.
*
* @param plugin The plugin to manage.
*/
protected PluginDependent(@NotNull final T plugin) {
this.plugin = plugin;
}
/**
* Get the plugin.
*
* @return The plugin.
*/
@NotNull
protected T getPlugin() {
return this.plugin;
}
}

View File

@@ -1,6 +1,8 @@
package com.willfp.eco.core; package com.willfp.eco.core;
import com.willfp.eco.core.config.updating.ConfigHandler; import com.willfp.eco.core.config.updating.ConfigHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -13,12 +15,13 @@ import java.util.logging.Logger;
*/ */
public interface PluginLike { public interface PluginLike {
/** /**
* Get the data folder of the object. * Get the data folder.
* <p> * <p>
* Returns the plugin data folder for a plugin, or the extension's parent plugin's folder * Returns the plugin data folder for a plugin, or the extension's parent plugin's folder
* *
* @return The data folder. * @return The data folder.
*/ */
@NotNull
File getDataFolder(); File getDataFolder();
/** /**
@@ -26,6 +29,7 @@ public interface PluginLike {
* *
* @return The config handler. * @return The config handler.
*/ */
@NotNull
ConfigHandler getConfigHandler(); ConfigHandler getConfigHandler();
/** /**
@@ -33,5 +37,16 @@ public interface PluginLike {
* *
* @return The logger. * @return The logger.
*/ */
@NotNull
Logger getLogger(); Logger getLogger();
/**
* Get the actual file.
*
* @return The file, i.e. the jar file.
*/
@Nullable
default File getFile() {
return null;
}
} }

View File

@@ -49,6 +49,16 @@ public final class PluginProps {
@Nullable @Nullable
private Boolean supportingExtensions; private Boolean supportingExtensions;
/**
* The environment variables.
*/
private final Map<String, String> environment = new HashMap<>();
/**
* If the plugin uses reflective reload.
*/
private boolean usesReflectiveReload = true;
/** /**
* Create new blank props. * Create new blank props.
*/ */
@@ -153,6 +163,46 @@ public final class PluginProps {
this.supportingExtensions = supportingExtensions; this.supportingExtensions = supportingExtensions;
} }
/**
* Get an environment variable.
*
* @param name The name.
* @return The value of the variable.
*/
@Nullable
public String getEnvironmentVariable(@NotNull final String name) {
return environment.get(name);
}
/**
* Set an environment variable.
*
* @param name The name.
* @param value The value.
*/
public void setEnvironmentVariable(@NotNull final String name,
@NotNull final String value) {
environment.put(name, value);
}
/**
* Set if the plugin uses reflective reload.
*
* @return If the plugin uses reflective reload.
*/
public boolean isUsingReflectiveReload() {
return usesReflectiveReload;
}
/**
* Set if the plugin uses reflective reload.
*
* @param usesReflectiveReload If the plugin uses reflective reload.
*/
public void setUsesReflectiveReload(final boolean usesReflectiveReload) {
this.usesReflectiveReload = usesReflectiveReload;
}
/** /**
* Ensure that all required props have been set. * Ensure that all required props have been set.
*/ */
@@ -232,7 +282,9 @@ public final class PluginProps {
* @param color The primary color of the plugin. * @param color The primary color of the plugin.
* @param supportsExtensions If the plugin should attempt to look for extensions. * @param supportsExtensions If the plugin should attempt to look for extensions.
* @return The props. * @return The props.
* @deprecated Moving to force the usage of eco.yml.
*/ */
@Deprecated(since = "6.53.0")
static PluginProps createSimple(final int resourceId, static PluginProps createSimple(final int resourceId,
final int bStatsId, final int bStatsId,
@NotNull final String proxyPackage, @NotNull final String proxyPackage,

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.core; package com.willfp.eco.core;
import com.willfp.eco.core.integrations.economy.EconomyManager;
import com.willfp.eco.core.proxy.ProxyConstants; import com.willfp.eco.core.proxy.ProxyConstants;
import com.willfp.eco.util.ClassUtils; import com.willfp.eco.util.ClassUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -39,21 +38,51 @@ public class Prerequisite {
); );
/** /**
* Requires the server to have vault installed. * Requires the server to be running 1.21.
*
* @deprecated Use {@link EconomyManager#hasRegistrations()} instead.
*/ */
@Deprecated(forRemoval = true) public static final Prerequisite HAS_1_21 = new Prerequisite(
public static final Prerequisite HAS_VAULT = new Prerequisite( () -> ProxyConstants.NMS_VERSION.contains("1_21"),
() -> ClassUtils.exists("net.milkbowl.vault.economy.Economy"), "Requires server to be running 1.21+"
"Requires server to have vault" );
/**
* Requires the server to be running 1.20.5.
*/
public static final Prerequisite HAS_1_20_5 = new Prerequisite(
() -> (ProxyConstants.NMS_VERSION.contains("1_20_") && !ProxyConstants.NMS_VERSION.contains("R"))
|| HAS_1_21.isMet(),
"Requires server to be running 1.20.5+"
);
/**
* Requires the server to be running 1.20.3.
*/
public static final Prerequisite HAS_1_20_3 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("20_R3") || HAS_1_20_5.isMet(),
"Requires server to be running 1.20.3+"
);
/**
* Requires the server to be running 1.20.
*/
public static final Prerequisite HAS_1_20 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("20") || HAS_1_20_3.isMet(),
"Requires server to be running 1.20+"
);
/**
* Requires the server to be running 1.19.4.
*/
public static final Prerequisite HAS_1_19_4 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("19_R3") || HAS_1_20.isMet(),
"Requires server to be running 1.19.4+"
); );
/** /**
* Requires the server to be running 1.19. * Requires the server to be running 1.19.
*/ */
public static final Prerequisite HAS_1_19 = new Prerequisite( public static final Prerequisite HAS_1_19 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("19"), () -> ProxyConstants.NMS_VERSION.contains("19") || HAS_1_20.isMet(),
"Requires server to be running 1.19+" "Requires server to be running 1.19+"
); );
@@ -65,17 +94,6 @@ public class Prerequisite {
"Requires server to be running 1.18+" "Requires server to be running 1.18+"
); );
/**
* Requires the server to be running 1.17.
*
* @deprecated eco no longer supports versions before 1.17.
*/
@Deprecated(since = "6.25.2", forRemoval = true)
public static final Prerequisite HAS_1_17 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("17") || HAS_1_18.isMet(),
"Requires server to be running 1.17+"
);
/** /**
* Requires the server to be running an implementation of BungeeCord. * Requires the server to be running an implementation of BungeeCord.
* *

View File

@@ -14,7 +14,7 @@ import java.util.List;
* *
* @deprecated Internal command implementations have been removed from the API. * @deprecated Internal command implementations have been removed from the API.
*/ */
@Deprecated(forRemoval = true, since = "6.49.0") @Deprecated(since = "6.49.0", forRemoval = true)
public final class DelegatedBukkitCommand extends Command implements TabCompleter, PluginIdentifiableCommand { public final class DelegatedBukkitCommand extends Command implements TabCompleter, PluginIdentifiableCommand {
/** /**
* The delegate command. * The delegate command.

View File

@@ -16,6 +16,8 @@ import org.jetbrains.annotations.NotNull;
*/ */
public abstract class ExtendableConfig extends LoadableConfigWrapper { public abstract class ExtendableConfig extends LoadableConfigWrapper {
/** /**
* Create a new extendable config.
*
* @param configName The name of the config * @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update. * @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin. * @param plugin The plugin.

View File

@@ -26,6 +26,8 @@ import java.util.Map;
@Deprecated(since = "6.44.0", forRemoval = true) @Deprecated(since = "6.44.0", forRemoval = true)
public class TransientConfig extends ConfigWrapper<Config> { public class TransientConfig extends ConfigWrapper<Config> {
/** /**
* Create new transient config from bukkit config.
*
* @param config The ConfigurationSection handle. * @param config The ConfigurationSection handle.
*/ */
public TransientConfig(@NotNull final ConfigurationSection config) { public TransientConfig(@NotNull final ConfigurationSection config) {
@@ -42,6 +44,8 @@ public class TransientConfig extends ConfigWrapper<Config> {
} }
/** /**
* Create a transient config from an input stream.
*
* @param stream The InputStream. * @param stream The InputStream.
*/ */
public TransientConfig(@Nullable final InputStream stream) { public TransientConfig(@Nullable final InputStream stream) {
@@ -51,15 +55,8 @@ public class TransientConfig extends ConfigWrapper<Config> {
} }
/** /**
* @param file The File. * Load a file to a config.
* @deprecated Specify the config type to prevent bugs. *
*/
@Deprecated(since = "6.30.0", forRemoval = true)
public TransientConfig(@Nullable final File file) {
this(file, ConfigType.YAML);
}
/**
* @param file The file. * @param file The file.
* @param type The config type to try read from. * @param type The config type to try read from.
*/ */
@@ -97,6 +94,8 @@ public class TransientConfig extends ConfigWrapper<Config> {
} }
/** /**
* Load a config from a string.
*
* @param contents The contents of the config. * @param contents The contents of the config.
* @param type The config type. * @param type The config type.
*/ */

View File

@@ -9,6 +9,11 @@ import org.jetbrains.annotations.NotNull;
* Default plugin config.yml. * Default plugin config.yml.
*/ */
public class ConfigYml extends BaseConfig { public class ConfigYml extends BaseConfig {
/**
* The use local storage key.
*/
public static final String KEY_USES_LOCAL_STORAGE = "use-local-storage";
/** /**
* Config.yml. * Config.yml.
* *
@@ -52,4 +57,13 @@ public class ConfigYml extends BaseConfig {
final boolean removeUnused) { final boolean removeUnused) {
super(name, plugin, removeUnused, ConfigType.YAML); super(name, plugin, removeUnused, ConfigType.YAML);
} }
/**
* Get if the plugin is using local storage.
*
* @return The prefix.
*/
public boolean isUsingLocalStorage() {
return this.getBool(KEY_USES_LOCAL_STORAGE);
}
} }

View File

@@ -6,6 +6,7 @@ import com.willfp.eco.core.config.Configs;
import com.willfp.eco.core.placeholder.AdditionalPlayer; import com.willfp.eco.core.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.InjectablePlaceholder; import com.willfp.eco.core.placeholder.InjectablePlaceholder;
import com.willfp.eco.core.placeholder.PlaceholderInjectable; import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import com.willfp.eco.core.placeholder.context.PlaceholderContext;
import com.willfp.eco.util.NumberUtils; import com.willfp.eco.util.NumberUtils;
import com.willfp.eco.util.StringUtils; import com.willfp.eco.util.StringUtils;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
@@ -14,6 +15,7 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@@ -30,16 +32,6 @@ import java.util.Set;
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public interface Config extends Cloneable, PlaceholderInjectable { public interface Config extends Cloneable, PlaceholderInjectable {
/**
* Clears cache.
* <p>
* Configs no longer have caches as they have in previous versions.
*/
@Deprecated(since = "6.31.1", forRemoval = true)
default void clearCache() {
// Do nothing.
}
/** /**
* Convert the config into readable text. * Convert the config into readable text.
* *
@@ -144,7 +136,7 @@ public interface Config extends Cloneable, PlaceholderInjectable {
* @return The computed value, or 0 if not found or invalid. * @return The computed value, or 0 if not found or invalid.
*/ */
default int getIntFromExpression(@NotNull String path) { default int getIntFromExpression(@NotNull String path) {
return getIntFromExpression(path, null); return getIntFromExpression(path, PlaceholderContext.of(this));
} }
/** /**
@@ -173,6 +165,18 @@ public interface Config extends Cloneable, PlaceholderInjectable {
return Double.valueOf(getDoubleFromExpression(path, player, additionalPlayers)).intValue(); return Double.valueOf(getDoubleFromExpression(path, player, additionalPlayers)).intValue();
} }
/**
* Get a decimal value via a mathematical expression.
*
* @param path The key to fetch the value from.
* @param context The placeholder context.
* @return The computed value, or 0 if not found or invalid.
*/
default int getIntFromExpression(@NotNull String path,
@NotNull PlaceholderContext context) {
return Double.valueOf(getDoubleFromExpression(path, context)).intValue();
}
/** /**
* Get an integer from config. * Get an integer from config.
@@ -266,6 +270,22 @@ public interface Config extends Cloneable, PlaceholderInjectable {
return getString(path, true, option); return getString(path, true, option);
} }
/**
* Get a formatted string from config.
*
* @param path The key to fetch the value from.
* @param context The placeholder context.
* @return The found value, or an empty string if not found.
*/
@NotNull
default String getFormattedString(@NotNull String path,
@NotNull PlaceholderContext context) {
return Objects.requireNonNullElse(
getFormattedStringOrNull(path, context),
""
);
}
/** /**
* Get a string from config. * Get a string from config.
* <p> * <p>
@@ -298,7 +318,7 @@ public interface Config extends Cloneable, PlaceholderInjectable {
* Get a formatted string from config. * Get a formatted string from config.
* *
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @return The found value, or an empty string if not found. * @return The found value, or null if not found.
*/ */
@Nullable @Nullable
default String getFormattedStringOrNull(@NotNull String path) { default String getFormattedStringOrNull(@NotNull String path) {
@@ -310,7 +330,7 @@ public interface Config extends Cloneable, PlaceholderInjectable {
* *
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @param option The format option. * @param option The format option.
* @return The found value, or an empty string if not found. * @return The found value, or null if not found.
*/ */
@Nullable @Nullable
default String getFormattedStringOrNull(@NotNull String path, default String getFormattedStringOrNull(@NotNull String path,
@@ -318,6 +338,25 @@ public interface Config extends Cloneable, PlaceholderInjectable {
return getStringOrNull(path, true, option); return getStringOrNull(path, true, option);
} }
/**
* Get a formatted string from config.
*
* @param path The key to fetch the value from.
* @param context The placeholder context.
* @return The found value, or null if not found.
*/
@Nullable
default String getFormattedStringOrNull(@NotNull String path,
@NotNull PlaceholderContext context) {
String nullable = getStringOrNull(path);
if (nullable == null) {
return null;
}
return StringUtils.format(nullable, context.withInjectableContext(this));
}
/** /**
* Get a string from config. * Get a string from config.
* <p> * <p>
@@ -372,6 +411,24 @@ public interface Config extends Cloneable, PlaceholderInjectable {
return getStrings(path, true, option); return getStrings(path, true, option);
} }
/**
* Get a list of strings from config.
* <p>
* Formatted.
*
* @param path The key to fetch the value from.
* @param context The placeholder context.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
default List<String> getFormattedStrings(@NotNull String path,
@NotNull PlaceholderContext context) {
return Objects.requireNonNullElse(
getFormattedStringsOrNull(path, context),
new ArrayList<>()
);
}
/** /**
* Get a list of strings from config. * Get a list of strings from config.
* <p> * <p>
@@ -428,6 +485,30 @@ public interface Config extends Cloneable, PlaceholderInjectable {
return getStringsOrNull(path, true, option); return getStringsOrNull(path, true, option);
} }
/**
* Get a list of strings from config.
* <p>
* Formatted.
*
* @param path The key to fetch the value from.
* @param context The placeholder context.
* @return The found value, or null if not found.
*/
@Nullable
default List<String> getFormattedStringsOrNull(@NotNull String path,
@NotNull PlaceholderContext context) {
List<String> nullable = getStringsOrNull(path);
if (nullable == null) {
return null;
}
return StringUtils.formatList(
nullable,
context.withInjectableContext(this)
);
}
/** /**
* Get a list of strings from config. * Get a list of strings from config.
* <p> * <p>
@@ -473,7 +554,7 @@ public interface Config extends Cloneable, PlaceholderInjectable {
* @return The computed value, or 0 if not found or invalid. * @return The computed value, or 0 if not found or invalid.
*/ */
default double getDoubleFromExpression(@NotNull String path) { default double getDoubleFromExpression(@NotNull String path) {
return getDoubleFromExpression(path, null); return getDoubleFromExpression(path, PlaceholderContext.of(this));
} }
/** /**
@@ -485,21 +566,41 @@ public interface Config extends Cloneable, PlaceholderInjectable {
*/ */
default double getDoubleFromExpression(@NotNull String path, default double getDoubleFromExpression(@NotNull String path,
@Nullable Player player) { @Nullable Player player) {
return NumberUtils.evaluateExpression(this.getString(path), player, this); return getDoubleFromExpression(path, player, Collections.emptyList());
} }
/** /**
* Get a decimal value via a mathematical expression. * Get a decimal value via a mathematical expression.
* *
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @param player The player to evaluate placeholders with respect to. * @param player The player to evaluate placeholders with respect to.
* @param additionalPlayers The additional players to evaluate placeholders with respect to. * @param additionalPlayers The additional players to evaluate placeholders with respect to.
* @return The computed value, or 0 if not found or invalid. * @return The computed value, or 0 if not found or invalid.
*/ */
default double getDoubleFromExpression(@NotNull String path, default double getDoubleFromExpression(@NotNull String path,
@Nullable Player player, @Nullable Player player,
@NotNull Collection<AdditionalPlayer> additionalPlayers) { @NotNull Collection<AdditionalPlayer> additionalPlayers) {
return NumberUtils.evaluateExpression(this.getString(path), player, this, additionalPlayers); return getDoubleFromExpression(path, new PlaceholderContext(
player,
null,
this,
additionalPlayers
));
}
/**
* Get a decimal value via a mathematical expression.
*
* @param path The key to fetch the value from.
* @param context The placeholder context.
* @return The computed value, or 0 if not found or invalid.
*/
default double getDoubleFromExpression(@NotNull String path,
@NotNull PlaceholderContext context) {
return Objects.requireNonNullElseGet(
this.getDoubleOrNull(path),
() -> NumberUtils.evaluateExpression(this.getString(path), context.withInjectableContext(this))
);
} }
/** /**
@@ -551,6 +652,32 @@ public interface Config extends Cloneable, PlaceholderInjectable {
@Nullable @Nullable
List<? extends Config> getSubsectionsOrNull(@NotNull String path); List<? extends Config> getSubsectionsOrNull(@NotNull String path);
/**
* Get a big decimal from config.
*
* @param path The key to fetch the value from.
* @return The found value, or 0 if not found.
*/
@NotNull
default BigDecimal getBigDecimal(@NotNull final String path) {
return Objects.requireNonNullElse(getBigDecimalOrNull(path), BigDecimal.ZERO);
}
/**
* Get a big decimal from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
default BigDecimal getBigDecimalOrNull(@NotNull final String path) {
if (this.has(path)) {
return new BigDecimal(this.getString(path));
} else {
return null;
}
}
/** /**
* Get config type. * Get config type.
* *

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.core.config.interfaces;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -30,6 +29,22 @@ public interface LoadableConfig extends Config {
*/ */
void save() throws IOException; void save() throws IOException;
/**
* Save the config asynchronously.
*/
default void saveAsync() {
// This default implementation exists purely for backwards compatibility
// with legacy Config implementations that don't have saveAsync().
// Default eco implementations of Config have saveAsync() implemented.
new Thread(() -> {
try {
this.save();
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
/** /**
* Get the config file. * Get the config file.
* *
@@ -44,21 +59,6 @@ public interface LoadableConfig extends Config {
*/ */
String getName(); String getName();
/**
* Get bukkit {@link YamlConfiguration}.
* <p>
* This used to represent the underlying config, but since 6.30.0 configs use
* their own implementations internally, without relying on bukkit.
*
* @return The config, or null if config is not yaml-based.
* @deprecated Use toBukkit() instead.
*/
@Nullable
@Deprecated(since = "6.30.0", forRemoval = true)
default YamlConfiguration getBukkitHandle() {
return this.toBukkit();
}
/** /**
* Convert the config to a bukkit {@link YamlConfiguration}. * Convert the config to a bukkit {@link YamlConfiguration}.
*/ */

View File

@@ -38,9 +38,16 @@ import java.lang.annotation.Target;
* <p> * <p>
* By having a plugin as a parameter, you shouldn't really need getInstance() * By having a plugin as a parameter, you shouldn't really need getInstance()
* calls in your code. * calls in your code.
* <p>
* While flexible, this can lead to long initialization times, so this feature
* can be disabled in eco.yml with the uses-reflective-reload option.
*
* @deprecated This has been deprecated due to the poor control flow and long startup times.
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Documented @Documented
@Deprecated(since = "6.67.0", forRemoval = true)
@SuppressWarnings("DeprecatedIsStillUsed")
public @interface ConfigUpdater { public @interface ConfigUpdater {
} }

View File

@@ -19,7 +19,7 @@ import java.util.Set;
* *
* @param <T> The type of the handle. * @param <T> The type of the handle.
*/ */
@SuppressWarnings({"MethodDoesntCallSuperMethod", "removal"}) @SuppressWarnings("MethodDoesntCallSuperMethod")
public abstract class ConfigWrapper<T extends Config> implements Config { public abstract class ConfigWrapper<T extends Config> implements Config {
/** /**
* Configs from eco have an internal implementation, * Configs from eco have an internal implementation,
@@ -42,12 +42,6 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
this.handle = handle; this.handle = handle;
} }
@Override
@Deprecated(since = "6.31.1", forRemoval = true)
public void clearCache() {
handle.clearCache();
}
@Override @Override
public String toPlaintext() { public String toPlaintext() {
return handle.toPlaintext(); return handle.toPlaintext();

View File

@@ -87,6 +87,10 @@ public interface ExtendedPersistentDataContainer {
* @return The extended container. * @return The extended container.
*/ */
static ExtendedPersistentDataContainer extend(@NotNull PersistentDataContainer base) { static ExtendedPersistentDataContainer extend(@NotNull PersistentDataContainer base) {
if (base instanceof ExtendedPersistentDataContainer) {
return (ExtendedPersistentDataContainer) base;
}
return Eco.get().adaptPdc(base); return Eco.get().adaptPdc(base);
} }

View File

@@ -0,0 +1,148 @@
package com.willfp.eco.core.data;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
/**
* A simple store key-value store for data to be stored outside of plugins.
*/
@SuppressWarnings("unchecked")
public final class ExternalDataStore {
/**
* The store.
*/
private static final Map<String, Object> DATA = new HashMap<>();
/**
* The store adapters.
*/
private static final List<ExternalDataStoreObjectAdapter<?, ?>> STORE_ADAPTERS = new ArrayList<>();
/**
* Put data into the store.
*
* @param key The key.
* @param value The value.
*/
public static void put(@NotNull final String key,
@NotNull final Object value) {
doPut(key, value);
}
/**
* Put data into the store.
*
* @param key The key.
* @param value The value.
* @param <A> The stored type.
*/
private static <A> void doPut(@NotNull final String key,
@NotNull final A value) {
Object storedValue = value;
for (ExternalDataStoreObjectAdapter<?, ?> unknownAdapter : STORE_ADAPTERS) {
if (unknownAdapter.getAccessedClass().isInstance(value)) {
ExternalDataStoreObjectAdapter<A, ?> adapter = (ExternalDataStoreObjectAdapter<A, ?>) unknownAdapter;
storedValue = adapter.toStoredObject(value);
break;
}
}
DATA.put(key, storedValue);
}
/**
* Get data from the store.
*
* @param key The key.
* @param clazz The class.
* @param <T> The type.
* @return The value.
*/
@Nullable
public static <T> T get(@NotNull final String key,
@NotNull final Class<T> clazz) {
return doGet(key, clazz);
}
/**
* Get data from the store.
*
* @param key The key.
* @param clazz The class.
* @param <A> The accessed type.
* @param <S> The stored type.
* @return The value.
*/
@Nullable
private static <A, S> A doGet(@NotNull final String key,
@NotNull final Class<A> clazz) {
Object value = DATA.get(key);
for (ExternalDataStoreObjectAdapter<?, ?> unknownAdapter : STORE_ADAPTERS) {
if (unknownAdapter.getStoredClass().isInstance(value) && unknownAdapter.getAccessedClass().equals(clazz)) {
ExternalDataStoreObjectAdapter<A, S> adapter = (ExternalDataStoreObjectAdapter<A, S>) unknownAdapter;
value = adapter.toAccessedObject((S) value);
break;
}
}
if (clazz.isInstance(value)) {
return clazz.cast(value);
} else {
return null;
}
}
/**
* Get data from the store.
*
* @param key The key.
* @param clazz The class.
* @param defaultValue The default value.
* @param <T> The type.
* @return The value.
*/
@NotNull
public static <T> T get(@NotNull final String key,
@NotNull final Class<T> clazz,
@NotNull final T defaultValue) {
T value = get(key, clazz);
return value == null ? defaultValue : value;
}
/**
* Get data from the store.
*
* @param key The key.
* @param clazz The class.
* @param defaultValue The default value.
* @param <T> The type.
* @return The value.
*/
@NotNull
public static <T> T get(@NotNull final String key,
@NotNull final Class<T> clazz,
@NotNull final Supplier<T> defaultValue) {
return get(key, clazz, defaultValue.get());
}
/**
* Register a new adapter.
*
* @param adapter The adapter.
*/
public static void registerAdapter(@NotNull final ExternalDataStoreObjectAdapter<?, ?> adapter) {
STORE_ADAPTERS.add(adapter);
}
private ExternalDataStore() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

View File

@@ -0,0 +1,69 @@
package com.willfp.eco.core.data;
import org.jetbrains.annotations.NotNull;
/**
* An adapter for objects stored in {@link ExternalDataStore}.
*
* @param <A> The accessed class.
* @param <S> The stored class.
*/
public abstract class ExternalDataStoreObjectAdapter<A, S> {
/**
* The class that is accessed (read / written).
*/
private final Class<? extends A> accessedClass;
/**
* The class that is stored internally.
*/
private final Class<? extends S> storedClass;
/**
* Create a new adapter.
*
* @param accessedClass The class that is accessed (read / written).
* @param storedClass The class that is stored internally.
*/
protected ExternalDataStoreObjectAdapter(@NotNull final Class<? extends A> accessedClass,
@NotNull final Class<? extends S> storedClass) {
this.accessedClass = accessedClass;
this.storedClass = storedClass;
}
/**
* Convert an object to the stored object.
*
* @param obj The object.
* @return The stored object.
*/
@NotNull
public abstract S toStoredObject(@NotNull final A obj);
/**
* Convert an object to the accessed object.
*
* @param obj The object.
* @return The accessed object.
*/
@NotNull
public abstract A toAccessedObject(@NotNull final S obj);
/**
* Get the class that is accessed (read / written).
*
* @return The class.
*/
public Class<? extends A> getAccessedClass() {
return accessedClass;
}
/**
* Get the class that is stored internally.
*
* @return The class.
*/
public Class<? extends S> getStoredClass() {
return storedClass;
}
}

View File

@@ -9,6 +9,22 @@ import org.jetbrains.annotations.NotNull;
* Profiles save automatically, so there is no need to save after changes. * Profiles save automatically, so there is no need to save after changes.
*/ */
public interface ServerProfile extends Profile { public interface ServerProfile extends Profile {
/**
* Get the server ID.
*
* @return The server ID.
*/
@NotNull
String getServerID();
/**
* Get the local server ID.
*
* @return The local server ID.
*/
@NotNull
String getLocalServerID();
/** /**
* Load the server profile. * Load the server profile.
* *

View File

@@ -29,6 +29,31 @@ public final class PersistentDataKey<T> {
*/ */
private final PersistentDataKeyType<T> type; private final PersistentDataKeyType<T> type;
/**
* If the key uses local storage.
*/
private final boolean isLocal;
/**
* Create a new Persistent Data Key.
*
* @param key The key.
* @param type The data type.
* @param defaultValue The default value.
* @param isLocal If the key uses local storage.
*/
public PersistentDataKey(@NotNull final NamespacedKey key,
@NotNull final PersistentDataKeyType<T> type,
@NotNull final T defaultValue,
final boolean isLocal) {
this.key = key;
this.defaultValue = defaultValue;
this.type = type;
this.isLocal = isLocal;
Eco.get().registerPersistentKey(this);
}
/** /**
* Create a new Persistent Data Key. * Create a new Persistent Data Key.
* *
@@ -42,6 +67,7 @@ public final class PersistentDataKey<T> {
this.key = key; this.key = key;
this.defaultValue = defaultValue; this.defaultValue = defaultValue;
this.type = type; this.type = type;
this.isLocal = false;
Eco.get().registerPersistentKey(this); Eco.get().registerPersistentKey(this);
} }
@@ -83,41 +109,12 @@ public final class PersistentDataKey<T> {
} }
/** /**
* In older eco versions, keys would have to be categorized in order * Get if the key uses local storage.
* to register the columns in the MySQL database. This is no longer needed.
* <p>
* Old description is below:
* <p>
* Categorize key as a server key, will register new column to MySQL
* database immediately rather than waiting for auto-categorization.
* <p>
* This will improve performance.
* *
* @return The key. * @return If the key uses local storage.
* @deprecated Not required since the new MySQL data handler was introduced.
*/ */
@Deprecated(since = "6.40.0", forRemoval = true) public boolean isLocal() {
public PersistentDataKey<T> server() { return this.isLocal;
return this;
}
/**
* In older eco versions, keys would have to be categorized in order
* to register the columns in the MySQL database. This is no longer needed.
* <p>
* Old description is below:
* <p>
* Categorize key as a player key, will register new column to MySQL
* database immediately rather than waiting for auto-categorization.
* <p>
* This will improve performance.
*
* @return The key.
* @deprecated Not required since the new MySQL data handler was introduced.
*/
@Deprecated(since = "6.40.0", forRemoval = true)
public PersistentDataKey<T> player() {
return this;
} }
/** /**

View File

@@ -4,6 +4,7 @@ import com.willfp.eco.core.config.interfaces.Config;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@@ -22,55 +23,43 @@ public final class PersistentDataKeyType<T> {
/** /**
* String. * String.
*/ */
public static final PersistentDataKeyType<String> STRING = new PersistentDataKeyType<>(String.class, "STRING"); public static final PersistentDataKeyType<String> STRING = new PersistentDataKeyType<>("STRING");
/** /**
* Boolean. * Boolean.
*/ */
public static final PersistentDataKeyType<Boolean> BOOLEAN = new PersistentDataKeyType<>(Boolean.class, "BOOLEAN"); public static final PersistentDataKeyType<Boolean> BOOLEAN = new PersistentDataKeyType<>("BOOLEAN");
/** /**
* Int. * Int.
*/ */
public static final PersistentDataKeyType<Integer> INT = new PersistentDataKeyType<>(Integer.class, "INT"); public static final PersistentDataKeyType<Integer> INT = new PersistentDataKeyType<>("INT");
/** /**
* Double. * Double.
*/ */
public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>(Double.class, "DOUBLE"); public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>("DOUBLE");
/** /**
* String List. * String List.
*/ */
public static final PersistentDataKeyType<List<String>> STRING_LIST = new PersistentDataKeyType<>(null, "STRING_LIST"); public static final PersistentDataKeyType<List<String>> STRING_LIST = new PersistentDataKeyType<>("STRING_LIST");
/** /**
* Config. * Config.
*/ */
public static final PersistentDataKeyType<Config> CONFIG = new PersistentDataKeyType<>(Config.class, "CONFIG"); public static final PersistentDataKeyType<Config> CONFIG = new PersistentDataKeyType<>("CONFIG");
/** /**
* The class of the type. * Big Decimal.
*/ */
private final Class<T> typeClass; public static final PersistentDataKeyType<BigDecimal> BIG_DECIMAL = new PersistentDataKeyType<>("BIG_DECIMAL");
/** /**
* The name of the key type. * The name of the key type.
*/ */
private final String name; private final String name;
/**
* Get the class of the type.
*
* @return The class.
* @deprecated String list type will return null.
*/
@Deprecated(since = "6.36.0", forRemoval = true)
@Nullable
public Class<T> getTypeClass() {
return typeClass;
}
/** /**
* Get the name of the key type. * Get the name of the key type.
* *
@@ -83,14 +72,11 @@ public final class PersistentDataKeyType<T> {
/** /**
* Create new PersistentDataKeyType. * Create new PersistentDataKeyType.
* *
* @param typeClass The type class.
* @param name The name. * @param name The name.
*/ */
private PersistentDataKeyType(@Nullable final Class<T> typeClass, private PersistentDataKeyType(@NotNull final String name) {
@NotNull final String name) {
VALUES.add(this); VALUES.add(this);
this.typeClass = typeClass;
this.name = name; this.name = name;
} }

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.display; package com.willfp.eco.core.display;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.fast.FastItemStack; import com.willfp.eco.core.fast.FastItemStack;
import com.willfp.eco.core.integrations.guidetection.GUIDetectionManager; import com.willfp.eco.core.integrations.guidetection.GUIDetectionManager;
import com.willfp.eco.util.NamespacedKeyUtils; import com.willfp.eco.util.NamespacedKeyUtils;
@@ -68,8 +69,10 @@ public final class Display {
Display.revert(itemStack); Display.revert(itemStack);
if (!itemStack.hasItemMeta()) { if (!Eco.get().getEcoPlugin().getConfigYml().getBool("display-without-meta")) {
return itemStack; if (!itemStack.hasItemMeta()) {
return itemStack;
}
} }
ItemStack original = itemStack.clone(); ItemStack original = itemStack.clone();
@@ -208,12 +211,22 @@ public final class Display {
new ArrayList<>() new ArrayList<>()
); );
modules.removeIf(it -> it.getPluginName().equalsIgnoreCase(module.getPluginName()));
modules.add(module); modules.add(module);
REGISTERED_MODULES.put(module.getWeight(), modules); REGISTERED_MODULES.put(module.getWeight(), modules);
} }
/**
* Unregister a display module.
*
* @param module The module.
*/
public static void unregisterDisplayModule(@NotNull final DisplayModule module) {
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
modules.remove(module);
}
}
private Display() { private Display() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }

View File

@@ -112,23 +112,6 @@ public abstract class DisplayModule {
return this.getPlugin().getName(); return this.getPlugin().getName();
} }
/**
* Get the display priority.
*
* @return The priority.
* @deprecated Use getWeight instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public DisplayPriority getPriority() {
return switch (this.weight) {
case 100 -> DisplayPriority.LOWEST;
case 200 -> DisplayPriority.LOW;
case 300 -> DisplayPriority.HIGH;
case 400 -> DisplayPriority.HIGHEST;
default -> DisplayPriority.CUSTOM;
};
}
/** /**
* Get the display weight. * Get the display weight.
* *

View File

@@ -6,7 +6,10 @@ package com.willfp.eco.core.display;
public enum DisplayPriority { public enum DisplayPriority {
/** /**
* Custom weight. * Custom weight.
*
* @deprecated Will never be used.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
CUSTOM(250), CUSTOM(250),
/** /**

View File

@@ -20,6 +20,13 @@ public abstract class CustomGoal<T extends Mob> implements EntityGoal<T>, Target
*/ */
private final Set<GoalFlag> flags = EnumSet.noneOf(GoalFlag.class); private final Set<GoalFlag> flags = EnumSet.noneOf(GoalFlag.class);
/**
* Create a new custom goal.
*/
protected CustomGoal() {
}
/** /**
* Initialize the goal with a mob. * Initialize the goal with a mob.
* <p> * <p>

View File

@@ -28,6 +28,8 @@ public record EntityGoalTempt(
boolean canBeScared boolean canBeScared
) implements EntityGoal<Mob> { ) implements EntityGoal<Mob> {
/** /**
* Create a new entity goal.
*
* @param speed The speed at which the entity follows the item. * @param speed The speed at which the entity follows the item.
* @param item The item that the entity will be attracted by. * @param item The item that the entity will be attracted by.
* @param canBeScared If the entity can be scared and lose track of the item. * @param canBeScared If the entity can be scared and lose track of the item.

View File

@@ -30,6 +30,8 @@ public record TargetGoalNearestAttackable(
@NotNull Predicate<LivingEntity> targetFilter @NotNull Predicate<LivingEntity> targetFilter
) implements TargetGoal<Raider> { ) implements TargetGoal<Raider> {
/** /**
* Create a new target goal.
*
* @param target The type of entities to attack. * @param target The type of entities to attack.
* @param checkVisibility If visibility should be checked. * @param checkVisibility If visibility should be checked.
* @param checkCanNavigate If navigation should be checked. * @param checkCanNavigate If navigation should be checked.

View File

@@ -30,6 +30,8 @@ public record TargetGoalNearestAttackableWitch(
@NotNull Predicate<LivingEntity> targetFilter @NotNull Predicate<LivingEntity> targetFilter
) implements TargetGoal<Raider> { ) implements TargetGoal<Raider> {
/** /**
* Create a new target goal.
*
* @param target The type of entities to attack. * @param target The type of entities to attack.
* @param checkVisibility If visibility should be checked. * @param checkVisibility If visibility should be checked.
* @param checkCanNavigate If navigation should be checked. * @param checkCanNavigate If navigation should be checked.

View File

@@ -26,6 +26,8 @@ public record TargetGoalNearestHealableRaider(
@NotNull Predicate<LivingEntity> targetFilter @NotNull Predicate<LivingEntity> targetFilter
) implements TargetGoal<Raider> { ) implements TargetGoal<Raider> {
/** /**
* Create a new target goal.
*
* @param target The target. * @param target The target.
* @param checkVisibility If visibility should be checked. * @param checkVisibility If visibility should be checked.
*/ */

View File

@@ -26,6 +26,8 @@ public record TargetGoalNonTameRandom(
@NotNull Predicate<LivingEntity> targetFilter @NotNull Predicate<LivingEntity> targetFilter
) implements TargetGoal<Tameable> { ) implements TargetGoal<Tameable> {
/** /**
* Create a new target goal.
*
* @param target The types of entities to heal. * @param target The types of entities to heal.
* @param checkVisibility If visibility should be checked. * @param checkVisibility If visibility should be checked.
*/ */

View File

@@ -7,6 +7,8 @@ import java.util.function.Consumer;
import java.util.function.Predicate; import java.util.function.Predicate;
/** /**
* The result of an arg parses.
*
* @param test The test for the entity. * @param test The test for the entity.
* @param modifier The modifier to apply to the entity. * @param modifier The modifier to apply to the entity.
* @see EntityArgParser * @see EntityArgParser

View File

@@ -27,7 +27,7 @@ public class DropQueuePushEvent extends PlayerEvent implements Cancellable {
/** /**
* The items. * The items.
*/ */
private final Collection<? extends ItemStack> items; private Collection<? extends ItemStack> items;
/** /**
* The xp. * The xp.
@@ -114,6 +114,15 @@ public class DropQueuePushEvent extends PlayerEvent implements Cancellable {
return items; return items;
} }
/**
* Set the items to be dropped.
*
* @param items The items.
*/
public void setItems(Collection<? extends ItemStack> items) {
this.items = items;
}
/** /**
* Get the xp to be dropped. * Get the xp to be dropped.
* *

View File

@@ -135,20 +135,26 @@ public abstract class Extension implements PluginLike {
} }
@Override @Override
public File getDataFolder() { public @NotNull File getDataFolder() {
return this.plugin.getDataFolder(); return this.plugin.getDataFolder();
} }
@Override @Override
public ConfigHandler getConfigHandler() { public @NotNull ConfigHandler getConfigHandler() {
return this.plugin.getConfigHandler(); return this.plugin.getConfigHandler();
} }
@Override @Override
public Logger getLogger() { public @NotNull Logger getLogger() {
return this.plugin.getLogger(); return this.plugin.getLogger();
} }
@Override
public @NotNull File getFile() {
Validate.notNull(metadata, "Metadata cannot be null!");
return this.metadata.file();
}
/** /**
* Get the plugin for the extension. * Get the plugin for the extension.
* *

View File

@@ -0,0 +1,17 @@
package com.willfp.eco.core.extensions;
import org.jetbrains.annotations.NotNull;
/**
* Generic exception in extension loading.
*/
public class ExtensionLoadException extends RuntimeException {
/**
* Create a new ExtensionLoadException.
*
* @param errorMessage The error message to show.
*/
public ExtensionLoadException(@NotNull final String errorMessage) {
super(errorMessage);
}
}

View File

@@ -1,7 +1,10 @@
package com.willfp.eco.core.extensions; package com.willfp.eco.core.extensions;
import com.willfp.eco.core.version.Version;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.File;
/** /**
* The extension's metadata. * The extension's metadata.
* <p> * <p>
@@ -10,9 +13,28 @@ import org.jetbrains.annotations.NotNull;
* @param version The extension version. * @param version The extension version.
* @param name The extension name. * @param name The extension name.
* @param author The extension's author. * @param author The extension's author.
* @param file The extension's file.
* @param minimumPluginVersion The minimum plugin version required for this extension.
*/ */
public record ExtensionMetadata(@NotNull String version, public record ExtensionMetadata(@NotNull String version,
@NotNull String name, @NotNull String name,
@NotNull String author) { @NotNull String author,
@NotNull File file,
@NotNull Version minimumPluginVersion) {
/**
* Legacy constructor.
*
* @param version The extension version.
* @param name The extension name.
* @param author The extension's author.
* @deprecated Use {@link ExtensionMetadata#ExtensionMetadata(String, String, String, File, Version)} instead.
*/
@SuppressWarnings("ConstantConditions")
@Deprecated(since = "6.57.0", forRemoval = true)
public ExtensionMetadata(@NotNull String version,
@NotNull String name,
@NotNull String author) {
this(version, name, author, null, null);
throw new UnsupportedOperationException("Legacy constructor is not supported.");
}
} }

View File

@@ -7,7 +7,7 @@ import org.jetbrains.annotations.NotNull;
* Missing or invalid extension.yml. * Missing or invalid extension.yml.
* Invalid filetype. * Invalid filetype.
*/ */
public class MalformedExtensionException extends RuntimeException { public class MalformedExtensionException extends ExtensionLoadException {
/** /**
* Create a new MalformedExtensionException. * Create a new MalformedExtensionException.
* *

View File

@@ -20,18 +20,6 @@ import java.util.Set;
* FastItemStack contains methods to modify and read items faster than in default bukkit. * FastItemStack contains methods to modify and read items faster than in default bukkit.
*/ */
public interface FastItemStack extends PersistentDataHolder { public interface FastItemStack extends PersistentDataHolder {
/**
* Get all enchantments on an item.
*
* @param checkStored If stored NBT should also be checked.
* @return A map of all enchantments.
* @deprecated Poorly named method. Use getEnchants instead.
*/
@Deprecated(since = "6.24.0", forRemoval = true)
default Map<Enchantment, Integer> getEnchantmentsOnItem(boolean checkStored) {
return getEnchants(checkStored);
}
/** /**
* Get all enchantments on an item. * Get all enchantments on an item.
* Does not account for stored enchants. * Does not account for stored enchants.
@@ -51,33 +39,6 @@ public interface FastItemStack extends PersistentDataHolder {
@NotNull @NotNull
Map<Enchantment, Integer> getEnchants(boolean checkStored); Map<Enchantment, Integer> getEnchants(boolean checkStored);
/**
* Get the level of an enchantment on an item.
*
* @param enchantment The enchantment.
* @return The enchantment level, or 0 if not found.
* @deprecated Poorly named method. Use getEnchantmentLevel instead.
*/
@Deprecated(since = "6.34.0", forRemoval = true)
default int getLevelOnItem(@NotNull Enchantment enchantment) {
return getEnchantmentLevel(enchantment, false);
}
/**
* Get the level of an enchantment on an item.
*
* @param enchantment The enchantment.
* @param checkStored If the stored NBT should also be checked.
* @return The enchantment level, or 0 if not found.
* @deprecated Poorly named method. Use getEnchantmentLevel instead.
*/
@Deprecated(since = "6.34.0", forRemoval = true)
@SuppressWarnings("DeprecatedIsStillUsed")
default int getLevelOnItem(@NotNull Enchantment enchantment,
boolean checkStored) {
return getEnchantmentLevel(enchantment, checkStored);
}
/** /**
* Get the level of an enchantment. * Get the level of an enchantment.
* *
@@ -85,7 +46,7 @@ public interface FastItemStack extends PersistentDataHolder {
* @return The enchantment level, or 0 if not found. * @return The enchantment level, or 0 if not found.
*/ */
default int getEnchantmentLevel(@NotNull Enchantment enchantment) { default int getEnchantmentLevel(@NotNull Enchantment enchantment) {
return getLevelOnItem(enchantment, false); return getEnchantmentLevel(enchantment, false);
} }
/** /**
@@ -203,15 +164,23 @@ public interface FastItemStack extends PersistentDataHolder {
* The returned PersistentDataContainer will not modify the item until the tag is set. * The returned PersistentDataContainer will not modify the item until the tag is set.
* *
* @return The base NBT tag. * @return The base NBT tag.
* @deprecated Items are now component-based.
*/ */
PersistentDataContainer getBaseTag(); @Deprecated(forRemoval = true, since = "6.70.0")
default PersistentDataContainer getBaseTag() {
throw new UnsupportedOperationException("Not supported in 1.20.5+");
}
/** /**
* Set the base NBT tag (Not PublicBukkitValues, the base) from a PersistentDataContainer. * Set the base NBT tag (Not PublicBukkitValues, the base) from a PersistentDataContainer.
* *
* @param container The PersistentDataContainer. * @param container The PersistentDataContainer.
* @deprecated Items are now component-based.
*/ */
void setBaseTag(@Nullable PersistentDataContainer container); @Deprecated(forRemoval = true, since = "6.70.0")
default void setBaseTag(@Nullable PersistentDataContainer container) {
throw new UnsupportedOperationException("Not supported in 1.20.5+");
}
/** /**
* Get the type of the item. * Get the type of the item.

View File

@@ -3,20 +3,15 @@ package com.willfp.eco.core.gui.menu;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.page.Page; import com.willfp.eco.core.gui.page.Page;
import com.willfp.eco.core.gui.slot.Slot; import com.willfp.eco.core.gui.slot.Slot;
import com.willfp.eco.util.NamespacedKeyUtils;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/** /**
* GUI version of {@link Inventory}. * GUI version of {@link Inventory}.
@@ -240,58 +235,6 @@ public interface Menu {
return Objects.requireNonNullElse(pageState, Integer.MAX_VALUE); return Objects.requireNonNullElse(pageState, Integer.MAX_VALUE);
} }
/**
* Write data.
*
* @param player The player.
* @param key The key.
* @param type The type.
* @param value The value.
* @param <T> The type.
* @param <Z> The type.
* @deprecated Use addState instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
default <T, Z> void writeData(@NotNull final Player player,
@NotNull final NamespacedKey key,
@NotNull final PersistentDataType<T, Z> type,
@NotNull final Z value) {
this.setState(player, key.toString(), value);
}
/**
* Read data.
*
* @param player The player.
* @param key The key.
* @param type The type.
* @param <T> The type.
* @param <Z> The type.
* @return The data.
* @deprecated Use getState instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
default @Nullable <T, Z> T readData(@NotNull final Player player,
@NotNull final NamespacedKey key,
@NotNull final PersistentDataType<T, Z> type) {
return this.getState(player, key.toString());
}
/**
* Get all data keys for a player.
*
* @param player The player.
* @return The keys.
* @deprecated Use getState instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
default Set<NamespacedKey> getKeys(@NotNull final Player player) {
return this.getState(player).keySet().stream()
.map(NamespacedKeyUtils::fromStringOrNull)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
}
/** /**
* Create a builder with a given amount of rows. * Create a builder with a given amount of rows.
* *

View File

@@ -142,6 +142,26 @@ public interface MenuBuilder extends PageBuilder {
return this.onRender((player, menu) -> menu.setState(player, Page.MAX_PAGE_KEY, pages.apply(player))); return this.onRender((player, menu) -> menu.setState(player, Page.MAX_PAGE_KEY, pages.apply(player)));
} }
/**
* Set the default page.
*
* @param page The page.
* @return The builder.
*/
default MenuBuilder defaultPage(final int page) {
return this.maxPages(player -> page);
}
/**
* Set the default page dynamically for a player.
*
* @param page The default page.
* @return The builder.
*/
default MenuBuilder defaultPage(@NotNull final Function<Player, Integer> page) {
return this.onOpen((player, menu) -> menu.setState(player, Page.PAGE_KEY, page.apply(player)));
}
/** /**
* Add a menu close handler. * Add a menu close handler.
* *

View File

@@ -5,6 +5,8 @@ import org.jetbrains.annotations.NotNull;
/** /**
* Handles menu events. * Handles menu events.
*
* @param <T> The type of event to handle.x
*/ */
public abstract class MenuEventHandler<T extends MenuEvent> { public abstract class MenuEventHandler<T extends MenuEvent> {
/** /**

View File

@@ -86,7 +86,7 @@ public class ConfigSlot extends CustomSlot {
for (String command : config.getStrings(configKey)) { for (String command : config.getStrings(configKey)) {
if (command.startsWith("console:")) { if (command.startsWith("console:")) {
commands.add(new CommandToDispatch( commands.add(new CommandToDispatch(
StringUtils.removePrefix("console:", command), StringUtils.removePrefix(command, "console:"),
true true
)); ));
} else { } else {

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.gui.slot;
import com.willfp.eco.core.gui.menu.Menu; import com.willfp.eco.core.gui.menu.Menu;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -76,6 +77,15 @@ public abstract class CustomSlot implements Slot {
return delegate; return delegate;
} }
@Override
public boolean shouldRenderOnClick(@NotNull final ClickType clickType) {
if (delegate == null) {
throw new IllegalStateException("Custom Slot was not initialized!");
}
return delegate.shouldRenderOnClick(clickType);
}
@Override @Override
public final int getRows() { public final int getRows() {
return Slot.super.getRows(); return Slot.super.getRows();
@@ -90,17 +100,4 @@ public abstract class CustomSlot implements Slot {
public final Slot getSlotAt(int row, int column) { public final Slot getSlotAt(int row, int column) {
return Slot.super.getSlotAt(row, column); return Slot.super.getSlotAt(row, column);
} }
/**
* Get the delegate slot.
* <p>
* This is not required to add the slot to a menu, but is instead used internally.
*
* @return The slot.
* @deprecated Replaced with {@link Slot#getActionableSlot(Player, Menu)}
*/
@Deprecated(since = "6.43.0", forRemoval = true)
public Slot getDelegate() {
return this.delegate;
}
} }

View File

@@ -7,6 +7,7 @@ import com.willfp.eco.core.gui.slot.functional.SlotProvider;
import com.willfp.eco.core.items.TestableItem; import com.willfp.eco.core.items.TestableItem;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -92,6 +93,27 @@ public interface Slot extends GUIComponent {
return false; return false;
} }
/**
* If the slot should re-render the menu if clicked.
*
* @return If the slot should re-render.
* @deprecated Use {@link Slot#shouldRenderOnClick(ClickType)} instead.
*/
@Deprecated(since = "6.66.0", forRemoval = true)
default boolean shouldRenderOnClick() {
return shouldRenderOnClick(ClickType.LEFT);
}
/**
* If the slot should re-render the menu if clicked.
*
* @param clickType The click type.
* @return If the slot should re-render.
*/
default boolean shouldRenderOnClick(@NotNull final ClickType clickType) {
return true;
}
@Override @Override
default int getRows() { default int getRows() {
return 1; return 1;
@@ -158,27 +180,4 @@ public interface Slot extends GUIComponent {
static SlotBuilder builder(@NotNull final SlotProvider provider) { static SlotBuilder builder(@NotNull final SlotProvider provider) {
return Eco.get().createSlotBuilder(provider); return Eco.get().createSlotBuilder(provider);
} }
/**
* If the slot is not captive for a player.
*
* @param player The player.
* @return If not captive for the player.
* @deprecated Captivity is now reactive, this method can produce incorrect results.
*/
@Deprecated(since = "6.43.0", forRemoval = true)
default boolean isNotCaptiveFor(@NotNull Player player) {
return false;
}
/**
* If the slot is captive. (Can items be placed in it).
*
* @return If captive.
* @deprecated Captivity is now reactive, this method can produce incorrect results.
*/
@Deprecated(since = "6.43.0", forRemoval = true)
default boolean isCaptive() {
return false;
}
} }

View File

@@ -196,6 +196,7 @@ public interface SlotBuilder {
* @deprecated Use {@link SlotBuilder#setUpdater(SlotUpdater)} instead. * @deprecated Use {@link SlotBuilder#setUpdater(SlotUpdater)} instead.
*/ */
@Deprecated @Deprecated
@SuppressWarnings("DeprecatedIsStillUsed")
default SlotBuilder setModifier(@NotNull SlotModifier modifier) { default SlotBuilder setModifier(@NotNull SlotModifier modifier) {
return setUpdater((player, menu, previous) -> { return setUpdater((player, menu, previous) -> {
modifier.modify(player, menu, previous); modifier.modify(player, menu, previous);

View File

@@ -1,13 +1,22 @@
package com.willfp.eco.core.integrations; package com.willfp.eco.core.integrations;
import com.willfp.eco.core.registry.Registrable;
import com.willfp.eco.core.registry.Registry;
import org.jetbrains.annotations.NotNull;
/** /**
* Abstract class for integrations. * Abstract class for integrations.
*/ */
public interface Integration { public interface Integration extends Registrable {
/** /**
* Get the name of integration. * Get the name of integration.
* *
* @return The name. * @return The name.
*/ */
String getPluginName(); String getPluginName();
@Override
default @NotNull String getID() {
return Registry.tryFitPattern(this.getPluginName());
}
} }

View File

@@ -0,0 +1,138 @@
package com.willfp.eco.core.integrations;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.registry.Registry;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* Registry for integrations.
*
* @param <T> The type of integration.
*/
public class IntegrationRegistry<T extends Integration> extends Registry<T> {
/**
* Create a new integration registry.
*/
public IntegrationRegistry() {
super();
}
@Override
public @NotNull T register(@NotNull final T element) {
return executeSafely(() -> super.register(element), element);
}
/**
* Iterate over all integrations, safely.
*
* @param action The action to perform.
*/
public void forEachSafely(@NotNull final Consumer<T> action) {
for (T integration : new HashSet<>(this.values())) {
executeSafely(() -> action.accept(integration), integration);
}
}
/**
* If any integrations return true, safely.
*
* @param predicate The predicate to test.
* @return If any integrations return true.
*/
public boolean anySafely(@NotNull final Predicate<T> predicate) {
for (T integration : new HashSet<>(this.values())) {
Boolean result = executeSafely(() -> predicate.test(integration), integration);
if (result != null && result) {
return true;
}
}
return false;
}
/**
* Get the first integration that returns a value, safely.
*
* @param function The function to apply.
* @param defaultValue The default value.
* @param <R> The type of value.
* @return The first value that returns a value.
*/
@NotNull
public <R> R firstSafely(@NotNull final Function<T, R> function,
@NotNull final R defaultValue) {
if (this.isEmpty()) {
return defaultValue;
}
T integration = this.iterator().next();
return executeSafely(() -> function.apply(integration), integration, defaultValue);
}
/**
* Executes a given action safely, catching any exceptions and logging the issue.
*
* @param action The action to execute.
* @param integration The integration to apply the action on.
*/
private void executeSafely(@NotNull final Runnable action,
@NotNull final T integration) {
executeSafely(() -> {
action.run();
return null;
}, integration);
}
/**
* Executes a given action safely, catching any exceptions and logging the issue.
*
* @param action The action to execute.
* @param integration The integration to apply the action on.
* @param <R> The return type of the action.
* @return The result of the action, or null if an exception was thrown.
*/
private <R> R executeSafely(@NotNull final Supplier<R> action,
@NotNull final T integration) {
return executeSafely(action, integration, null);
}
/**
* Executes a given action safely, catching any exceptions and logging the issue.
*
* @param action The action to execute.
* @param integration The integration to apply the action on.
* @param defaultValue The default value to return if an exception is thrown.
* @param <R> The return type of the action.
* @return The result of the action, or the default value if an exception was thrown.
*/
private <R> R executeSafely(@NotNull final Supplier<R> action,
@NotNull final T integration,
@Nullable final R defaultValue) {
try {
return action.get();
} catch (final Exception | LinkageError e) {
Eco.get().getEcoPlugin().getLogger().warning("Integration for " + integration.getPluginName() + " threw an exception!");
Eco.get().getEcoPlugin().getLogger().warning("The integration will be disabled.");
e.printStackTrace();
this.remove(integration);
return defaultValue;
}
}
/**
* If all integrations return true, safely.
*
* @param predicate The predicate to test.
* @return If all integrations return true.
*/
public boolean allSafely(@NotNull final Predicate<T> predicate) {
return !this.anySafely(predicate.negate());
}
}

View File

@@ -1,11 +1,9 @@
package com.willfp.eco.core.integrations.afk; package com.willfp.eco.core.integrations.afk;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/** /**
* Class to handle afk integrations. * Class to handle afk integrations.
*/ */
@@ -13,7 +11,7 @@ public final class AFKManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<AFKIntegration> REGISTERED = new HashSet<>(); private static final IntegrationRegistry<AFKIntegration> REGISTRY = new IntegrationRegistry<>();
/** /**
* Register a new integration. * Register a new integration.
@@ -21,8 +19,7 @@ public final class AFKManager {
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final AFKIntegration integration) { public static void register(@NotNull final AFKIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); REGISTRY.register(integration);
REGISTERED.add(integration);
} }
/** /**
@@ -32,13 +29,7 @@ public final class AFKManager {
* @return If afk. * @return If afk.
*/ */
public static boolean isAfk(@NotNull final Player player) { public static boolean isAfk(@NotNull final Player player) {
for (AFKIntegration integration : REGISTERED) { return REGISTRY.anySafely(integration -> integration.isAfk(player));
if (integration.isAfk(player)) {
return true;
}
}
return false;
} }
private AFKManager() { private AFKManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.afk;
/**
* Wrapper class for afk integrations.
*
* @deprecated Use AFKIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface AFKWrapper extends AFKIntegration {
}

View File

@@ -1,14 +1,11 @@
package com.willfp.eco.core.integrations.anticheat; package com.willfp.eco.core.integrations.anticheat;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/** /**
* Class to handle anticheat integrations. * Class to handle anticheat integrations.
*/ */
@@ -16,20 +13,7 @@ public final class AnticheatManager {
/** /**
* A set of all registered anticheats. * A set of all registered anticheats.
*/ */
private static final Set<AnticheatIntegration> ANTICHEATS = new HashSet<>(); private static final IntegrationRegistry<AnticheatIntegration> REGISTRY = new IntegrationRegistry<>();
/**
* Register a new anticheat.
*
* @param plugin The plugin.
* @param anticheat The anticheat to register.
* @deprecated Don't pass instance of eco.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public static void register(@NotNull final EcoPlugin plugin,
@NotNull final AnticheatIntegration anticheat) {
register(anticheat);
}
/** /**
* Register a new anticheat. * Register a new anticheat.
@@ -40,8 +24,7 @@ public final class AnticheatManager {
if (anticheat instanceof Listener) { if (anticheat instanceof Listener) {
Eco.get().getEcoPlugin().getEventManager().registerListener((Listener) anticheat); Eco.get().getEcoPlugin().getEventManager().registerListener((Listener) anticheat);
} }
ANTICHEATS.removeIf(it -> it.getPluginName().equalsIgnoreCase(anticheat.getPluginName())); REGISTRY.register(anticheat);
ANTICHEATS.add(anticheat);
} }
/** /**
@@ -50,17 +33,16 @@ public final class AnticheatManager {
* @param player The player to exempt. * @param player The player to exempt.
*/ */
public static void exemptPlayer(@NotNull final Player player) { public static void exemptPlayer(@NotNull final Player player) {
ANTICHEATS.forEach(anticheat -> anticheat.exempt(player)); REGISTRY.forEachSafely(anticheat -> anticheat.exempt(player));
} }
/** /**
* Unexempt a player from triggering anticheats. * Unexempt a player from triggering anticheats.
* This is ran a tick after it is called to ensure that there are no event timing conflicts.
* *
* @param player The player to remove the exemption. * @param player The player to remove the exemption.
*/ */
public static void unexemptPlayer(@NotNull final Player player) { public static void unexemptPlayer(@NotNull final Player player) {
ANTICHEATS.forEach(anticheat -> anticheat.unexempt(player)); REGISTRY.forEachSafely(anticheat -> anticheat.unexempt(player));
} }
private AnticheatManager() { private AnticheatManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.anticheat;
/**
* Wrapper class for anticheat integrations.
*
* @deprecated Use AnticheatIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface AnticheatWrapper extends AnticheatIntegration {
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.integrations.antigrief; package com.willfp.eco.core.integrations.antigrief;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
@@ -16,7 +17,7 @@ public final class AntigriefManager {
/** /**
* Registered antigriefs. * Registered antigriefs.
*/ */
private static final Set<AntigriefIntegration> REGISTERED = new HashSet<>(); private static final IntegrationRegistry<AntigriefIntegration> REGISTRY = new IntegrationRegistry<>();
/** /**
* Register a new AntiGrief/Land Management integration. * Register a new AntiGrief/Land Management integration.
@@ -24,8 +25,7 @@ public final class AntigriefManager {
* @param antigrief The integration to register. * @param antigrief The integration to register.
*/ */
public static void register(@NotNull final AntigriefIntegration antigrief) { public static void register(@NotNull final AntigriefIntegration antigrief) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName())); REGISTRY.register(antigrief);
REGISTERED.add(antigrief);
} }
/** /**
@@ -34,8 +34,7 @@ public final class AntigriefManager {
* @param antigrief The integration to unregister. * @param antigrief The integration to unregister.
*/ */
public static void unregister(@NotNull final AntigriefIntegration antigrief) { public static void unregister(@NotNull final AntigriefIntegration antigrief) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName())); REGISTRY.remove(antigrief);
REGISTERED.remove(antigrief);
} }
/** /**
@@ -47,7 +46,7 @@ public final class AntigriefManager {
*/ */
public static boolean canPickupItem(@NotNull final Player player, public static boolean canPickupItem(@NotNull final Player player,
@NotNull final Location location) { @NotNull final Location location) {
return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canPickupItem(player, location)); return REGISTRY.allSafely(integration -> integration.canPickupItem(player, location));
} }
/** /**
@@ -59,7 +58,7 @@ public final class AntigriefManager {
*/ */
public static boolean canBreakBlock(@NotNull final Player player, public static boolean canBreakBlock(@NotNull final Player player,
@NotNull final Block block) { @NotNull final Block block) {
return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canBreakBlock(player, block)); return REGISTRY.allSafely(integration -> integration.canBreakBlock(player, block));
} }
/** /**
@@ -71,7 +70,7 @@ public final class AntigriefManager {
*/ */
public static boolean canCreateExplosion(@NotNull final Player player, public static boolean canCreateExplosion(@NotNull final Player player,
@NotNull final Location location) { @NotNull final Location location) {
return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canCreateExplosion(player, location)); return REGISTRY.allSafely(integration -> integration.canCreateExplosion(player, location));
} }
/** /**
@@ -83,7 +82,7 @@ public final class AntigriefManager {
*/ */
public static boolean canPlaceBlock(@NotNull final Player player, public static boolean canPlaceBlock(@NotNull final Player player,
@NotNull final Block block) { @NotNull final Block block) {
return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canPlaceBlock(player, block)); return REGISTRY.allSafely(integration -> integration.canPlaceBlock(player, block));
} }
/** /**
@@ -95,7 +94,7 @@ public final class AntigriefManager {
*/ */
public static boolean canInjure(@NotNull final Player player, public static boolean canInjure(@NotNull final Player player,
@NotNull final LivingEntity victim) { @NotNull final LivingEntity victim) {
return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canInjure(player, victim)); return REGISTRY.allSafely(integration -> integration.canInjure(player, victim));
} }
private AntigriefManager() { private AntigriefManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.antigrief;
/**
* Wrapper class for antigrief integrations.
*
* @deprecated Use AntigriefIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface AntigriefWrapper extends AntigriefIntegration {
}

View File

@@ -1,10 +1,8 @@
package com.willfp.eco.core.integrations.customentities; package com.willfp.eco.core.integrations.customentities;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/** /**
* Class to handle custom entity integrations. * Class to handle custom entity integrations.
*/ */
@@ -12,7 +10,7 @@ public final class CustomEntitiesManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<CustomEntitiesIntegration> REGISTERED = new HashSet<>(); private static final IntegrationRegistry<CustomEntitiesIntegration> REGISTRY = new IntegrationRegistry<>();
/** /**
* Register a new integration. * Register a new integration.
@@ -20,8 +18,7 @@ public final class CustomEntitiesManager {
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final CustomEntitiesIntegration integration) { public static void register(@NotNull final CustomEntitiesIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); REGISTRY.register(integration);
REGISTERED.add(integration);
} }
/** /**
@@ -30,9 +27,7 @@ public final class CustomEntitiesManager {
* @see com.willfp.eco.core.entities.Entities * @see com.willfp.eco.core.entities.Entities
*/ */
public static void registerAllEntities() { public static void registerAllEntities() {
for (CustomEntitiesIntegration integration : REGISTERED) { REGISTRY.forEachSafely(CustomEntitiesIntegration::registerAllEntities);
integration.registerAllEntities();
}
} }
private CustomEntitiesManager() { private CustomEntitiesManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.customentities;
/**
* Wrapper class for custom item integrations.
*
* @deprecated Use CustomEntitiesIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface CustomEntitiesWrapper extends CustomEntitiesIntegration {
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.integrations.customitems; package com.willfp.eco.core.integrations.customitems;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet; import java.util.HashSet;
@@ -12,7 +13,7 @@ public final class CustomItemsManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<CustomItemsIntegration> REGISTERED = new HashSet<>(); private static final IntegrationRegistry<CustomItemsIntegration> REGISTRY = new IntegrationRegistry<>();
/** /**
* Register a new integration. * Register a new integration.
@@ -20,8 +21,7 @@ public final class CustomItemsManager {
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final CustomItemsIntegration integration) { public static void register(@NotNull final CustomItemsIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); REGISTRY.register(integration);
REGISTERED.add(integration);
} }
/** /**
@@ -30,9 +30,7 @@ public final class CustomItemsManager {
* @see com.willfp.eco.core.items.Items * @see com.willfp.eco.core.items.Items
*/ */
public static void registerAllItems() { public static void registerAllItems() {
for (CustomItemsIntegration customItemsIntegration : REGISTERED) { REGISTRY.forEachSafely(CustomItemsIntegration::registerAllItems);
customItemsIntegration.registerAllItems();
}
} }
/** /**
@@ -41,9 +39,7 @@ public final class CustomItemsManager {
* @see com.willfp.eco.core.items.Items * @see com.willfp.eco.core.items.Items
*/ */
public static void registerProviders() { public static void registerProviders() {
for (CustomItemsIntegration customItemsIntegration : REGISTERED) { REGISTRY.forEachSafely(CustomItemsIntegration::registerProvider);
customItemsIntegration.registerProvider();
}
} }
private CustomItemsManager() { private CustomItemsManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.customitems;
/**
* Wrapper class for custom item integrations.
*
* @deprecated Use CustomItemsIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface CustomItemsWrapper extends CustomItemsIntegration {
}

View File

@@ -1,11 +1,10 @@
package com.willfp.eco.core.integrations.economy; package com.willfp.eco.core.integrations.economy;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Set;
/** /**
* Class to handle economy. * Class to handle economy.
@@ -14,7 +13,7 @@ public final class EconomyManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<EconomyIntegration> REGISTERED = new HashSet<>(); private static final IntegrationRegistry<EconomyIntegration> REGISTRY = new IntegrationRegistry<>();
/** /**
* Register a new integration. * Register a new integration.
@@ -22,8 +21,7 @@ public final class EconomyManager {
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final EconomyIntegration integration) { public static void register(@NotNull final EconomyIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); REGISTRY.register(integration);
REGISTERED.add(integration);
} }
/** /**
@@ -32,7 +30,7 @@ public final class EconomyManager {
* @return If any economy. * @return If any economy.
*/ */
public static boolean hasRegistrations() { public static boolean hasRegistrations() {
return !REGISTERED.isEmpty(); return REGISTRY.isNotEmpty();
} }
/** /**
@@ -56,11 +54,10 @@ public final class EconomyManager {
*/ */
public static boolean hasAmount(@NotNull final OfflinePlayer player, public static boolean hasAmount(@NotNull final OfflinePlayer player,
final BigDecimal amount) { final BigDecimal amount) {
for (EconomyIntegration integration : REGISTERED) { return REGISTRY.firstSafely(
return integration.hasAmount(player, amount); integration -> integration.hasAmount(player, amount),
} false
);
return false;
} }
/** /**
@@ -84,11 +81,10 @@ public final class EconomyManager {
*/ */
public static boolean giveMoney(@NotNull final OfflinePlayer player, public static boolean giveMoney(@NotNull final OfflinePlayer player,
@NotNull final BigDecimal amount) { @NotNull final BigDecimal amount) {
for (EconomyIntegration integration : REGISTERED) { return REGISTRY.firstSafely(
return integration.giveMoney(player, amount); integration -> integration.giveMoney(player, amount),
} false
);
return false;
} }
/** /**
@@ -112,11 +108,10 @@ public final class EconomyManager {
*/ */
public static boolean removeMoney(@NotNull final OfflinePlayer player, public static boolean removeMoney(@NotNull final OfflinePlayer player,
@NotNull final BigDecimal amount) { @NotNull final BigDecimal amount) {
for (EconomyIntegration integration : REGISTERED) { return REGISTRY.firstSafely(
return integration.removeMoney(player, amount); integration -> integration.removeMoney(player, amount),
} false
);
return false;
} }
/** /**
@@ -136,11 +131,10 @@ public final class EconomyManager {
* @return The balance. * @return The balance.
*/ */
public static BigDecimal getExactBalance(@NotNull final OfflinePlayer player) { public static BigDecimal getExactBalance(@NotNull final OfflinePlayer player) {
for (EconomyIntegration integration : REGISTERED) { return REGISTRY.firstSafely(
return integration.getExactBalance(player); integration -> integration.getExactBalance(player),
} BigDecimal.ZERO
);
return BigDecimal.ZERO;
} }
private EconomyManager() { private EconomyManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.economy;
/**
* Wrapper class for economy integrations.
*
* @deprecated Use EconomyIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface EconomyWrapper extends EconomyIntegration {
}

View File

@@ -1,12 +1,10 @@
package com.willfp.eco.core.integrations.guidetection; package com.willfp.eco.core.integrations.guidetection;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import com.willfp.eco.util.MenuUtils; import com.willfp.eco.util.MenuUtils;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/** /**
* Class to handle GUI detection. * Class to handle GUI detection.
*/ */
@@ -14,7 +12,7 @@ public final class GUIDetectionManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<GUIDetectionIntegration> REGISTERED = new HashSet<>(); private static final IntegrationRegistry<GUIDetectionIntegration> REGISTRY = new IntegrationRegistry<>();
/** /**
* Register a new integration. * Register a new integration.
@@ -22,8 +20,7 @@ public final class GUIDetectionManager {
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final GUIDetectionIntegration integration) { public static void register(@NotNull final GUIDetectionIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); REGISTRY.register(integration);
REGISTERED.add(integration);
} }
/** /**
@@ -37,13 +34,7 @@ public final class GUIDetectionManager {
return true; return true;
} }
for (GUIDetectionIntegration integration : REGISTERED) { return REGISTRY.anySafely(integration -> integration.hasGUIOpen(player));
if (integration.hasGUIOpen(player)) {
return true;
}
}
return false;
} }
private GUIDetectionManager() { private GUIDetectionManager() {

View File

@@ -1,11 +1,10 @@
package com.willfp.eco.core.integrations.hologram; package com.willfp.eco.core.integrations.hologram;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.Location; import org.bukkit.Location;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
* Class to handle hologram integrations. * Class to handle hologram integrations.
@@ -14,7 +13,7 @@ public final class HologramManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<HologramIntegration> REGISTERED = new HashSet<>(); private static final IntegrationRegistry<HologramIntegration> REGISTRY = new IntegrationRegistry<>();
/** /**
* Register a new integration. * Register a new integration.
@@ -22,8 +21,7 @@ public final class HologramManager {
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final HologramIntegration integration) { public static void register(@NotNull final HologramIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); REGISTRY.register(integration);
REGISTERED.add(integration);
} }
/** /**
@@ -35,11 +33,10 @@ public final class HologramManager {
*/ */
public static Hologram createHologram(@NotNull final Location location, public static Hologram createHologram(@NotNull final Location location,
@NotNull final List<String> contents) { @NotNull final List<String> contents) {
for (HologramIntegration integration : REGISTERED) { return REGISTRY.firstSafely(
return integration.createHologram(location, contents); integration -> integration.createHologram(location, contents),
} new DummyHologram()
);
return new DummyHologram();
} }
private HologramManager() { private HologramManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.hologram;
/**
* Wrapper class for hologram integrations.
*
* @deprecated Use HologramIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface HologramWrapper extends HologramIntegration {
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.integrations.mcmmo; package com.willfp.eco.core.integrations.mcmmo;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -14,7 +15,7 @@ public final class McmmoManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<McmmoIntegration> REGISTERED = new HashSet<>(); private static final IntegrationRegistry<McmmoIntegration> REGISTERED = new IntegrationRegistry<>();
/** /**
* Register a new integration. * Register a new integration.
@@ -22,8 +23,7 @@ public final class McmmoManager {
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final McmmoIntegration integration) { public static void register(@NotNull final McmmoIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); REGISTERED.register(integration);
REGISTERED.add(integration);
} }
/** /**
@@ -34,13 +34,11 @@ public final class McmmoManager {
*/ */
public static int getBonusDropCount(@NotNull final Block block) { public static int getBonusDropCount(@NotNull final Block block) {
int finalValue = 0; int finalValue = 0;
for (McmmoIntegration mcmmoIntegration : REGISTERED) { for (McmmoIntegration mcmmoIntegration : REGISTERED) {
finalValue += mcmmoIntegration.getBonusDropCount(block); finalValue += mcmmoIntegration.getBonusDropCount(block);
} }
return finalValue; return finalValue;
} }
@@ -51,13 +49,7 @@ public final class McmmoManager {
* @return If the event is fake. * @return If the event is fake.
*/ */
public static boolean isFake(@NotNull final Event event) { public static boolean isFake(@NotNull final Event event) {
for (McmmoIntegration mcmmoIntegration : REGISTERED) { return REGISTERED.anySafely(integration -> integration.isFake(event));
if (mcmmoIntegration.isFake(event)) {
return true;
}
}
return false;
} }
private McmmoManager() { private McmmoManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.mcmmo;
/**
* Wrapper class for mcmmo integrations.
*
* @deprecated Use McmmoIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface McmmoWrapper extends McmmoIntegration {
}

View File

@@ -1,190 +0,0 @@
package com.willfp.eco.core.integrations.placeholder;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.placeholder.Placeholder;
import com.willfp.eco.core.placeholder.PlayerPlaceholder;
import com.willfp.eco.core.placeholder.PlayerlessPlaceholder;
import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import java.util.function.Function;
/**
* A placeholder entry is a placeholder in and of itself.
* <p>
* It should be fairly straightforward.
*
* @deprecated Confusing functionality with inconsistent nullability and poor naming.
*/
@Deprecated(since = "6.28.0", forRemoval = true)
public class PlaceholderEntry {
/**
* The name of the placeholder, used in lookups.
*/
private final String identifier;
/**
* The lambda to retrieve the output of the placeholder given a player.
*/
private final Function<Player, String> function;
/**
* If the placeholder requires a player to lookup.
*/
private final boolean requiresPlayer;
/**
* The plugin for the placeholder.
*/
@Nullable
private final EcoPlugin plugin;
/**
* Create a placeholder entry that doesn't require a player.
*
* @param identifier The identifier of the placeholder.
* @param function A lambda to get the result of the placeholder given a player.
* @deprecated Specify a plugin.
*/
@Deprecated
public PlaceholderEntry(@NotNull final String identifier,
@NotNull final Function<Player, String> function) {
this(identifier, function, false);
}
/**
* Create a placeholder entry that may require a player.
*
* @param identifier The identifier of the placeholder.
* @param function A lambda to get the result of the placeholder.
* @param requiresPlayer If the placeholder requires a player.
* @deprecated Specify a plugin.
*/
@Deprecated
public PlaceholderEntry(@NotNull final String identifier,
@NotNull final Function<Player, String> function,
final boolean requiresPlayer) {
this(null, identifier, function, requiresPlayer);
}
/**
* Create a placeholder entry that doesn't require a player.
*
* @param plugin The plugin for the placeholder.
* @param identifier The identifier of the placeholder.
* @param function A lambda to get the result of the placeholder given a player.
*/
public PlaceholderEntry(@Nullable final EcoPlugin plugin,
@NotNull final String identifier,
@NotNull final Function<Player, String> function) {
this(plugin, identifier, function, false);
}
/**
* Create a placeholder entry that may require a player.
*
* @param plugin The plugin for the placeholder.
* @param identifier The identifier of the placeholder.
* @param function A lambda to get the result of the placeholder.
* @param requiresPlayer If the placeholder requires a player.
*/
public PlaceholderEntry(@Nullable final EcoPlugin plugin,
@NotNull final String identifier,
@NotNull final Function<Player, String> function,
final boolean requiresPlayer) {
this.plugin = plugin;
this.identifier = identifier;
this.function = function;
this.requiresPlayer = requiresPlayer;
}
/**
* Get the result of the placeholder with respect to a player.
*
* @param player The player to translate with respect to.
* @return The result of the placeholder.
*/
public String getResult(@Nullable final Player player) {
if (player == null) {
Validate.isTrue(!requiresPlayer, "null player passed to requiresPlayer placeholder.");
}
return this.function.apply(player);
}
/**
* Get if the placeholder requires a player to get a result.
*
* @return If the placeholder requires a player.
*/
public boolean requiresPlayer() {
return requiresPlayer;
}
/**
* Get the identifier.
*
* @return The identifier.
*/
public String getIdentifier() {
return identifier;
}
/**
* Get the plugin.
*
* @return The plugin.
*/
@Nullable
public EcoPlugin getPlugin() {
return plugin;
}
/**
* Register the placeholder.
*/
public void register() {
PlaceholderManager.registerPlaceholder(this.toModernPlaceholder());
}
/**
* Convert the placeholder to a modern placeholder.
*
* @return The placeholder.
*/
Placeholder toModernPlaceholder() {
if (this.requiresPlayer) {
return new PlayerPlaceholder(
Objects.requireNonNullElse(plugin, Eco.get().getEcoPlugin()),
identifier,
function
);
} else {
return new PlayerlessPlaceholder(
Objects.requireNonNullElse(plugin, Eco.get().getEcoPlugin()),
identifier,
() -> function.apply(null)
);
}
}
@Override
public boolean equals(@Nullable final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof PlaceholderEntry entry)) {
return false;
}
return Objects.equals(this.getIdentifier(), entry.getIdentifier())
&& Objects.equals(this.getPlugin(), entry.getPlugin());
}
@Override
public int hashCode() {
return Objects.hash(this.getIdentifier(), this.getPlugin());
}
}

View File

@@ -9,7 +9,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* Wrapper class for placeholder integrations. * Wrapper class for arguments integrations.
*/ */
public interface PlaceholderIntegration extends Integration { public interface PlaceholderIntegration extends Integration {
/** /**

View File

@@ -1,21 +1,15 @@
package com.willfp.eco.core.integrations.placeholder; package com.willfp.eco.core.integrations.placeholder;
import com.github.benmanes.caffeine.cache.Cache; import com.google.common.collect.ImmutableSet;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.map.DefaultMap;
import com.willfp.eco.core.placeholder.AdditionalPlayer; import com.willfp.eco.core.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.DynamicPlaceholder;
import com.willfp.eco.core.placeholder.InjectablePlaceholder; import com.willfp.eco.core.placeholder.InjectablePlaceholder;
import com.willfp.eco.core.placeholder.Placeholder; import com.willfp.eco.core.placeholder.Placeholder;
import com.willfp.eco.core.placeholder.PlaceholderInjectable; import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import com.willfp.eco.core.placeholder.PlayerDynamicPlaceholder; import com.willfp.eco.core.placeholder.RegistrablePlaceholder;
import com.willfp.eco.core.placeholder.PlayerPlaceholder; import com.willfp.eco.core.placeholder.context.PlaceholderContext;
import com.willfp.eco.core.placeholder.PlayerStaticPlaceholder;
import com.willfp.eco.core.placeholder.PlayerlessPlaceholder;
import com.willfp.eco.core.placeholder.StaticPlaceholder;
import com.willfp.eco.util.StringUtils;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -23,61 +17,41 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Objects;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
* Class to handle placeholder integrations. * Class to handle arguments integrations.
*/ */
@SuppressWarnings("removal")
public final class PlaceholderManager { public final class PlaceholderManager {
/** /**
* All registered placeholders. * All registered placeholders.
*/ */
private static final Map<EcoPlugin, Map<Pattern, Placeholder>> REGISTERED_PLACEHOLDERS = new HashMap<>(); private static final DefaultMap<EcoPlugin, Set<Placeholder>> REGISTERED_PLACEHOLDERS = new DefaultMap<>(HashSet::new);
/** /**
* All registered placeholder integrations. * All registered arguments integrations.
*/ */
private static final Set<PlaceholderIntegration> REGISTERED_INTEGRATIONS = new HashSet<>(); private static final Set<PlaceholderIntegration> REGISTERED_INTEGRATIONS = new HashSet<>();
/**
* Placeholder Lookup Cache.
*/
private static final Cache<PlaceholderLookup, Optional<Placeholder>> PLACEHOLDER_LOOKUP_CACHE = Caffeine.newBuilder()
.expireAfterWrite(1, TimeUnit.SECONDS)
.build();
/**
* Placeholder Cache.
*/
private static final LoadingCache<EntryWithPlayer, String> PLACEHOLDER_CACHE = Caffeine.newBuilder()
.expireAfterWrite(50, TimeUnit.MILLISECONDS)
.build(key -> key.entry.getValue(key.player));
/**
* Dynamic Placeholder Cache.
*/
private static final LoadingCache<DynamicEntryWithPlayer, String> DYNAMIC_PLACEHOLDER_CACHE = Caffeine.newBuilder()
.expireAfterWrite(50, TimeUnit.MILLISECONDS)
.build(key -> key.entry.getValue(key.args, key.player));
/** /**
* The default PlaceholderAPI pattern; brought in for compatibility. * The default PlaceholderAPI pattern; brought in for compatibility.
*/ */
private static final Pattern PATTERN = Pattern.compile("%([^% ]+)%"); private static final Pattern PATTERN = Pattern.compile("%([^% ]+)%");
/** /**
* Empty injectable object. * Empty injectableContext object.
*/ */
public static final PlaceholderInjectable EMPTY_INJECTABLE = new PlaceholderInjectable() { public static final PlaceholderInjectable EMPTY_INJECTABLE = new PlaceholderInjectable() {
@Override
public void addInjectablePlaceholder(@NotNull Iterable<InjectablePlaceholder> placeholders) {
// Do nothing.
}
@Override @Override
public void clearInjectedPlaceholders() { public void clearInjectedPlaceholders() {
// Do nothing. // Do nothing.
@@ -101,122 +75,69 @@ public final class PlaceholderManager {
} }
/** /**
* Register a placeholder. * Register a arguments.
* *
* @param placeholder The placeholder to register. * @param placeholder The arguments to register.
* @deprecated Use {@link #registerPlaceholder(RegistrablePlaceholder)} instead.
*/ */
@Deprecated(since = "6.56.0", forRemoval = true)
public static void registerPlaceholder(@NotNull final Placeholder placeholder) { public static void registerPlaceholder(@NotNull final Placeholder placeholder) {
if (placeholder instanceof StaticPlaceholder || placeholder instanceof PlayerStaticPlaceholder) { if (!(placeholder instanceof RegistrablePlaceholder)) {
throw new IllegalArgumentException("Static placeholders cannot be registered!"); throw new IllegalArgumentException("Placeholder must be RegistrablePlaceholder!");
} }
EcoPlugin plugin = placeholder.getPlugin() == null ? Eco.get().getEcoPlugin() : placeholder.getPlugin(); registerPlaceholder((RegistrablePlaceholder) placeholder);
Map<Pattern, Placeholder> pluginPlaceholders = REGISTERED_PLACEHOLDERS
.getOrDefault(plugin, new HashMap<>());
pluginPlaceholders.put(placeholder.getPattern(), placeholder);
REGISTERED_PLACEHOLDERS.put(plugin, pluginPlaceholders);
} }
/** /**
* Register a placeholder. * Register a arguments.
* *
* @param placeholder The placeholder to register. * @param placeholder The arguments to register.
* @deprecated Uses old placeholder system.
*/ */
@Deprecated(since = "6.28.0", forRemoval = true) public static void registerPlaceholder(@NotNull final RegistrablePlaceholder placeholder) {
public static void registerPlaceholder(@NotNull final PlaceholderEntry placeholder) { // Storing as immutable set leads to slower times to register placeholders, but much
registerPlaceholder(placeholder.toModernPlaceholder()); // faster times to access registrations.
Set<Placeholder> pluginPlaceholders = new HashSet<>(REGISTERED_PLACEHOLDERS.get(placeholder.getPlugin()));
pluginPlaceholders.removeIf(p -> p.getPattern().equals(placeholder.getPattern()));
pluginPlaceholders.add(placeholder);
REGISTERED_PLACEHOLDERS.put(placeholder.getPlugin(), ImmutableSet.copyOf(pluginPlaceholders));
} }
/** /**
* Get the result of a placeholder with respect to a player. * Get the result of a placeholder with respect to a player.
* *
* @param player The player to get the result from. * @param player The player to get the result from.
* @param identifier The placeholder identifier. * @param identifier The placeholder args.
* @return The value of the placeholder. * @param plugin The plugin for the arguments.
* @deprecated Specify a plugin to get the result from. * @return The value of the arguments.
*/
@Deprecated
public static String getResult(@Nullable final Player player,
@NotNull final String identifier) {
return getResult(player, identifier, null);
}
/**
* Get the result of a placeholder with respect to a player.
*
* @param player The player to get the result from.
* @param identifier The placeholder identifier.
* @param plugin The plugin for the placeholder.
* @return The value of the placeholder.
*/ */
@NotNull @NotNull
public static String getResult(@Nullable final Player player, public static String getResult(@Nullable final Player player,
@NotNull final String identifier, @NotNull final String identifier,
@Nullable final EcoPlugin plugin) { @Nullable final EcoPlugin plugin) {
// This is really janky, and it sucks, but it works so? return Objects.requireNonNullElse(
// Compensating for regex being slow so that's why we get it. getResult(
Placeholder placeholder = PLACEHOLDER_LOOKUP_CACHE.get( plugin,
new PlaceholderLookup(identifier, plugin), identifier,
(it) -> { new PlaceholderContext(player)
EcoPlugin owner = plugin == null ? Eco.get().getEcoPlugin() : plugin; ),
""
);
}
// I hate the streams API. /**
Optional<Placeholder> found = REGISTERED_PLACEHOLDERS * Get the result of a placeholder given a plugin and arguments.
.getOrDefault(owner, new HashMap<>()) *
.entrySet() * @param plugin The plugin for the placeholder.
.stream().filter(entry -> entry.getKey().matcher(identifier).matches()) * @param args The arguments.
.map(Map.Entry::getValue) * @param context The context.
.findFirst(); * @return The value of the arguments.
*/
if (found.isEmpty() && plugin != null) { @Nullable
// Here we go again! Something about legacy support? I don't remember. public static String getResult(@Nullable final EcoPlugin plugin,
// I won't touch it though, I'm scared of the placeholder system. @NotNull final String args,
found = REGISTERED_PLACEHOLDERS @NotNull final PlaceholderContext context) {
.getOrDefault(Eco.get().getEcoPlugin(), new HashMap<>()) return Eco.get().getPlaceholderValue(plugin, args, context);
.entrySet()
.stream().filter(entry -> entry.getKey().matcher(identifier).matches())
.map(Map.Entry::getValue)
.findFirst();
}
return found;
}
).orElse(null);
if (placeholder == null) {
return "";
}
/*
This code here is *really* not very good. It's mega externalized logic hacked
together and made worse by the addition of dynamic placeholders. But it works,
and it means I don't have to rewrite the whole placeholder system. So it's
good enough for me.
*/
if (placeholder instanceof PlayerPlaceholder playerPlaceholder) {
if (player == null) {
return "";
} else {
return PLACEHOLDER_CACHE.get(new EntryWithPlayer(playerPlaceholder, player));
}
} else if (placeholder instanceof PlayerlessPlaceholder playerlessPlaceholder) {
return playerlessPlaceholder.getValue();
} else if (placeholder instanceof PlayerDynamicPlaceholder playerDynamicPlaceholder) {
if (player == null) {
return "";
} else {
return DYNAMIC_PLACEHOLDER_CACHE.get(new DynamicEntryWithPlayer(playerDynamicPlaceholder, identifier, player));
}
} else if (placeholder instanceof DynamicPlaceholder dynamicPlaceholder) {
return dynamicPlaceholder.getValue(identifier);
} else {
return "";
}
} }
/** /**
@@ -225,7 +146,11 @@ public final class PlaceholderManager {
* @param text The text that may contain placeholders to translate. * @param text The text that may contain placeholders to translate.
* @param player The player to translate the placeholders with respect to. * @param player The player to translate the placeholders with respect to.
* @return The text, translated. * @return The text, translated.
* @deprecated Use {@link #translatePlaceholders(String, PlaceholderContext)} instead.
*/ */
@Deprecated(since = "6.56.0", forRemoval = true)
@NotNull
@SuppressWarnings("DeprecatedIsStillUsed")
public static String translatePlaceholders(@NotNull final String text, public static String translatePlaceholders(@NotNull final String text,
@Nullable final Player player) { @Nullable final Player player) {
return translatePlaceholders(text, player, EMPTY_INJECTABLE); return translatePlaceholders(text, player, EMPTY_INJECTABLE);
@@ -236,29 +161,25 @@ public final class PlaceholderManager {
* *
* @param text The text that may contain placeholders to translate. * @param text The text that may contain placeholders to translate.
* @param player The player to translate the placeholders with respect to. * @param player The player to translate the placeholders with respect to.
* @param statics Extra static placeholders. * @param context The injectableContext parseContext.
* @return The text, translated.
* @deprecated Use new static system.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public static String translatePlaceholders(@NotNull final String text,
@Nullable final Player player,
@NotNull final List<StaticPlaceholder> statics) {
return translatePlaceholders(text, player, EMPTY_INJECTABLE);
}
/**
* Translate all placeholders with respect to a player.
*
* @param text The text that may contain placeholders to translate.
* @param player The player to translate the placeholders with respect to.
* @param context The injectable context.
* @return The text, translated. * @return The text, translated.
* @deprecated Use {@link #translatePlaceholders(String, PlaceholderContext)} instead.
*/ */
@Deprecated(since = "6.56.0", forRemoval = true)
@NotNull
@SuppressWarnings("DeprecatedIsStillUsed")
public static String translatePlaceholders(@NotNull final String text, public static String translatePlaceholders(@NotNull final String text,
@Nullable final Player player, @Nullable final Player player,
@NotNull final PlaceholderInjectable context) { @NotNull final PlaceholderInjectable context) {
return translatePlaceholders(text, player, context, new ArrayList<>()); return translatePlaceholders(
text,
new PlaceholderContext(
player,
null,
context,
new ArrayList<>()
)
);
} }
/** /**
@@ -266,79 +187,51 @@ public final class PlaceholderManager {
* *
* @param text The text that may contain placeholders to translate. * @param text The text that may contain placeholders to translate.
* @param player The player to translate the placeholders with respect to. * @param player The player to translate the placeholders with respect to.
* @param context The injectable context. * @param context The injectableContext parseContext.
* @param additionalPlayers Additional players to translate placeholders for. * @param additionalPlayers Additional players to translate placeholders for.
* @return The text, translated. * @return The text, translated.
* @deprecated Use {@link #translatePlaceholders(String, PlaceholderContext)} instead.
*/ */
@Deprecated(since = "6.56.0", forRemoval = true)
@NotNull
@SuppressWarnings("DeprecatedIsStillUsed")
public static String translatePlaceholders(@NotNull final String text, public static String translatePlaceholders(@NotNull final String text,
@Nullable final Player player, @Nullable final Player player,
@NotNull final PlaceholderInjectable context, @NotNull final PlaceholderInjectable context,
@NotNull final Collection<AdditionalPlayer> additionalPlayers) { @NotNull final Collection<AdditionalPlayer> additionalPlayers) {
String processed = text; return translatePlaceholders(
text,
new PlaceholderContext(
player,
null,
context,
additionalPlayers
)
);
}
/* /**
* Translate all placeholders without a placeholder context.
*
* @param text The text that may contain placeholders to translate.
* @return The text, translated.
*/
@NotNull
public static String translatePlaceholders(@NotNull final String text) {
return Eco.get().translatePlaceholders(text, PlaceholderContext.EMPTY);
}
Why am I doing statics at the start, but player statics at the end? /**
* Translate all placeholders in a translation context.
Additional players let you use something like victim as a player to parse in relation to, *
for example doing %victim_player_health%, which would parse the health of the victim. * @param text The text that may contain placeholders to translate.
* @param context The translation context.
However, something like libreforge will also inject %victim_max_health%, which is unrelated * @return The text, translated.
to additional players, and instead holds a constant value. So, eco saw this, smartly thought */
"ah, it's an additional player, let's parse it", and then tried to parse %max_health% with @NotNull
relation to the victim, which resolved to zero. So, we have to parse statics and player statics public static String translatePlaceholders(@NotNull final String text,
that might include a prefix first, then additional players, then player statics with the support @NotNull final PlaceholderContext context) {
of additional players. return Eco.get().translatePlaceholders(text, context);
This was a massive headache and took so many reports before I clocked what was going on.
Oh well, at least it's fixed now.
*/
for (InjectablePlaceholder injection : context.getPlaceholderInjections()) {
if (injection instanceof StaticPlaceholder placeholder) {
processed = processed.replace("%" + placeholder.getIdentifier() + "%", placeholder.getValue());
} else if (injection instanceof PlayerStaticPlaceholder placeholder && player != null) {
processed = processed.replace("%" + placeholder.getIdentifier() + "%", placeholder.getValue(player));
}
}
// Prevent running 2 scans if there are no additional players.
if (!additionalPlayers.isEmpty()) {
List<String> found = findPlaceholdersIn(text);
for (AdditionalPlayer additionalPlayer : additionalPlayers) {
for (String placeholder : found) {
String prefix = "%" + additionalPlayer.getIdentifier() + "_";
if (placeholder.startsWith(prefix)) {
processed = processed.replace(
placeholder,
translatePlaceholders(
"%" + StringUtils.removePrefix(prefix, placeholder),
additionalPlayer.getPlayer()
)
);
}
}
}
}
for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
processed = integration.translate(processed, player);
}
// DON'T REMOVE THIS, IT'S NOT DUPLICATE CODE.
for (InjectablePlaceholder injection : context.getPlaceholderInjections()) {
// Do I know this is a bad way of doing this? Yes.
if (injection instanceof PlayerStaticPlaceholder placeholder && player != null) {
processed = processed.replace("%" + placeholder.getIdentifier() + "%", placeholder.getValue(player));
}
}
return processed;
} }
/** /**
@@ -350,12 +243,9 @@ public final class PlaceholderManager {
public static List<String> findPlaceholdersIn(@NotNull final String text) { public static List<String> findPlaceholdersIn(@NotNull final String text) {
Set<String> found = new HashSet<>(); Set<String> found = new HashSet<>();
// Mock PAPI for those without it installed Matcher matcher = PATTERN.matcher(text);
if (REGISTERED_INTEGRATIONS.isEmpty()) { while (matcher.find()) {
Matcher matcher = PATTERN.matcher(text); found.add(matcher.group());
while (matcher.find()) {
found.add(matcher.group());
}
} }
for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) { for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
@@ -365,20 +255,23 @@ public final class PlaceholderManager {
return new ArrayList<>(found); return new ArrayList<>(found);
} }
private record PlaceholderLookup(@NotNull String identifier, /**
@Nullable EcoPlugin plugin) { * Get all registered placeholder integrations.
*
* @return The integrations.
*/
public static Set<PlaceholderIntegration> getRegisteredIntegrations() {
return Set.copyOf(REGISTERED_INTEGRATIONS);
} }
private record EntryWithPlayer(@NotNull PlayerPlaceholder entry, /**
@NotNull Player player) { * Get all registered placeholders for a plugin.
*
} * @param plugin The plugin.
* @return The placeholders.
private record DynamicEntryWithPlayer(@NotNull PlayerDynamicPlaceholder entry, */
@NotNull String args, public static Set<Placeholder> getRegisteredPlaceholders(@NotNull final EcoPlugin plugin) {
@NotNull Player player) { return REGISTERED_PLACEHOLDERS.get(plugin);
} }
private PlaceholderManager() { private PlaceholderManager() {

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.integrations.shop; package com.willfp.eco.core.integrations.shop;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import com.willfp.eco.core.price.Price; import com.willfp.eco.core.price.Price;
import com.willfp.eco.core.price.impl.PriceFree; import com.willfp.eco.core.price.impl.PriceFree;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -13,11 +14,12 @@ import java.util.Set;
/** /**
* Class to handle shop integrations. * Class to handle shop integrations.
*/ */
@SuppressWarnings("DeprecatedIsStillUsed")
public final class ShopManager { public final class ShopManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<ShopIntegration> REGISTERED = new HashSet<>(); private static final IntegrationRegistry<ShopIntegration> REGISTRY = new IntegrationRegistry<>();
/** /**
* Register a new integration. * Register a new integration.
@@ -25,17 +27,14 @@ public final class ShopManager {
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final ShopIntegration integration) { public static void register(@NotNull final ShopIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); REGISTRY.register(integration);
REGISTERED.add(integration);
} }
/** /**
* Register eco item provider for shop plugins. * Register eco item provider for shop plugins.
*/ */
public static void registerEcoProvider() { public static void registerEcoProvider() {
for (ShopIntegration shopIntegration : REGISTERED) { REGISTRY.forEachSafely(ShopIntegration::registerEcoProvider);
shopIntegration.registerEcoProvider();
}
} }
/** /**
@@ -51,11 +50,7 @@ public final class ShopManager {
return false; return false;
} }
for (ShopIntegration integration : REGISTERED) { return REGISTRY.anySafely(integration -> integration.isSellable(itemStack, player));
return integration.isSellable(itemStack, player);
}
return false;
} }
/** /**
@@ -74,11 +69,10 @@ public final class ShopManager {
return new PriceFree(); return new PriceFree();
} }
for (ShopIntegration integration : REGISTERED) { return REGISTRY.firstSafely(
return integration.getUnitValue(itemStack, player); integration -> integration.getUnitValue(itemStack, player),
} new PriceFree()
);
return new PriceFree();
} }
/** /**
@@ -108,11 +102,10 @@ public final class ShopManager {
return 0.0; return 0.0;
} }
for (ShopIntegration shopIntegration : REGISTERED) { return REGISTRY.firstSafely(
return shopIntegration.getUnitValue(itemStack, player).getValue(player, itemStack.getAmount()); integration -> integration.getUnitValue(itemStack, player).getValue(player, itemStack.getAmount()),
} 0.0
);
return 0.0;
} }
/** /**
@@ -121,7 +114,7 @@ public final class ShopManager {
* @return The integrations. * @return The integrations.
*/ */
public static Set<ShopIntegration> getRegisteredIntegrations() { public static Set<ShopIntegration> getRegisteredIntegrations() {
return new HashSet<>(REGISTERED); return new HashSet<>(REGISTRY.values());
} }
private ShopManager() { private ShopManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.shop;
/**
* Wrapper class for shop integrations.
*
* @deprecated Use ShopIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface ShopWrapper extends ShopIntegration {
}

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.core.items; package com.willfp.eco.core.items;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -55,7 +54,7 @@ public class CustomItem implements TestableItem {
*/ */
Eco.get().getEcoPlugin().getScheduler().runLater(() -> { Eco.get().getEcoPlugin().getScheduler().runLater(() -> {
if (!matches(getItem())) { if (!matches(getItem())) {
Bukkit.getLogger().severe("Item with key " + key + " is invalid!"); Eco.get().getEcoPlugin().getLogger().severe("Item with key " + key + " is invalid!");
} }
}, 1); }, 1);
} }

View File

@@ -13,6 +13,7 @@ import com.willfp.eco.core.recipe.parts.TestableStack;
import com.willfp.eco.core.recipe.parts.UnrestrictedMaterialTestableItem; import com.willfp.eco.core.recipe.parts.UnrestrictedMaterialTestableItem;
import com.willfp.eco.util.NamespacedKeyUtils; import com.willfp.eco.util.NamespacedKeyUtils;
import com.willfp.eco.util.NumberUtils; import com.willfp.eco.util.NumberUtils;
import kotlin.Suppress;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
@@ -515,8 +516,11 @@ public final class Items {
* *
* @param itemStack The ItemStack. * @param itemStack The ItemStack.
* @return The base NBT. * @return The base NBT.
* @deprecated Items are now component-based.
*/ */
@NotNull @NotNull
@Deprecated(since = "6.70.0", forRemoval = true)
@SuppressWarnings("removal")
public static PersistentDataContainer getBaseNBT(@NotNull final ItemStack itemStack) { public static PersistentDataContainer getBaseNBT(@NotNull final ItemStack itemStack) {
return FastItemStack.wrap(itemStack).getBaseTag(); return FastItemStack.wrap(itemStack).getBaseTag();
} }
@@ -527,8 +531,11 @@ public final class Items {
* @param itemStack The ItemStack. * @param itemStack The ItemStack.
* @param container The base NBT tag. * @param container The base NBT tag.
* @return The ItemStack, modified. Not required to use, as this modifies the instance.¬ * @return The ItemStack, modified. Not required to use, as this modifies the instance.¬
* @deprecated Items are now component-based.
*/ */
@NotNull @NotNull
@Deprecated(since = "6.70.0", forRemoval = true)
@SuppressWarnings("removal")
public static ItemStack setBaseNBT(@NotNull final ItemStack itemStack, public static ItemStack setBaseNBT(@NotNull final ItemStack itemStack,
@Nullable final PersistentDataContainer container) { @Nullable final PersistentDataContainer container) {
FastItemStack fis = FastItemStack.wrap(itemStack); FastItemStack fis = FastItemStack.wrap(itemStack);
@@ -568,6 +575,42 @@ public final class Items {
return EMPTY_TESTABLE_ITEM.matches(itemStack); return EMPTY_TESTABLE_ITEM.matches(itemStack);
} }
/**
* Get if an item matches any items.
*
* @param itemStack The item.
* @param items The items.
* @return If matches any.
*/
public static boolean matchesAny(@Nullable final ItemStack itemStack,
@NotNull final Collection<TestableItem> items) {
for (TestableItem item : items) {
if (item.matches(itemStack)) {
return true;
}
}
return false;
}
/**
* Get if any item matches any item.
*
* @param itemStacks The items.
* @param items The items.
* @return If matches any.
*/
public static boolean matchesAny(@NotNull final Collection<ItemStack> itemStacks,
@NotNull final Collection<TestableItem> items) {
for (ItemStack itemStack : itemStacks) {
if (matchesAny(itemStack, items)) {
return true;
}
}
return false;
}
private Items() { private Items() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }

View File

@@ -7,6 +7,7 @@ import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Supplier;
/** /**
* A map with a default value. * A map with a default value.
@@ -23,7 +24,7 @@ public class DefaultMap<K, V> implements Map<K, V> {
/** /**
* The default value. * The default value.
*/ */
private final V defaultValue; private final Supplier<V> defaultValue;
/** /**
* Create a new default map. * Create a new default map.
@@ -31,8 +32,16 @@ public class DefaultMap<K, V> implements Map<K, V> {
* @param defaultValue The default value. * @param defaultValue The default value.
*/ */
public DefaultMap(@NotNull final V defaultValue) { public DefaultMap(@NotNull final V defaultValue) {
this.map = new HashMap<>(); this(() -> defaultValue);
this.defaultValue = defaultValue; }
/**
* Create a new default map.
*
* @param defaultValue The default value.
*/
public DefaultMap(@NotNull final Supplier<V> defaultValue) {
this(new HashMap<>(), defaultValue);
} }
/** /**
@@ -41,7 +50,19 @@ public class DefaultMap<K, V> implements Map<K, V> {
* @param map The map. * @param map The map.
* @param defaultValue The default value. * @param defaultValue The default value.
*/ */
public DefaultMap(@NotNull final Map<K, V> map, @NotNull final V defaultValue) { public DefaultMap(@NotNull final Map<K, V> map,
@NotNull final V defaultValue) {
this(map, () -> defaultValue);
}
/**
* Create a new default map.
*
* @param map The map.
* @param defaultValue The default value.
*/
public DefaultMap(@NotNull final Map<K, V> map,
@NotNull final Supplier<V> defaultValue) {
this.map = map; this.map = map;
this.defaultValue = defaultValue; this.defaultValue = defaultValue;
} }
@@ -51,11 +72,11 @@ public class DefaultMap<K, V> implements Map<K, V> {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public V get(@Nullable final Object key) { public V get(@Nullable final Object key) {
if (key == null) { if (key == null) {
return defaultValue; return defaultValue.get();
} }
if (map.get(key) == null) { if (map.get(key) == null) {
map.put((K) key, defaultValue); map.put((K) key, defaultValue.get());
} }
return map.get(key); return map.get(key);
@@ -129,7 +150,7 @@ public class DefaultMap<K, V> implements Map<K, V> {
*/ */
@NotNull @NotNull
public static <K, K1, V> DefaultMap<K, Map<K1, V>> createNestedMap() { public static <K, K1, V> DefaultMap<K, Map<K1, V>> createNestedMap() {
return new DefaultMap<>(new HashMap<>()); return new DefaultMap<>(HashMap::new);
} }
/** /**
@@ -142,6 +163,6 @@ public class DefaultMap<K, V> implements Map<K, V> {
*/ */
@NotNull @NotNull
public static <K, K1, V> DefaultMap<K, ListMap<K1, V>> createNestedListMap() { public static <K, K1, V> DefaultMap<K, ListMap<K1, V>> createNestedListMap() {
return new DefaultMap<>(new ListMap<>()); return new DefaultMap<>(ListMap::new);
} }
} }

View File

@@ -16,7 +16,7 @@ public class ListMap<K, V> extends DefaultMap<K, List<V>> {
* Create a new list map. * Create a new list map.
*/ */
public ListMap() { public ListMap() {
super(new ArrayList<>()); super(ArrayList::new);
} }
/** /**
@@ -25,9 +25,8 @@ public class ListMap<K, V> extends DefaultMap<K, List<V>> {
* @param key The key. * @param key The key.
* @param value The value. * @param value The value.
*/ */
void append(@NotNull final K key, public void append(@NotNull final K key,
@NotNull final V value) { @NotNull final V value) {
this.get(key).add(value); this.get(key).add(value);
} }
} }

View File

@@ -3,27 +3,25 @@ package com.willfp.eco.core.math;
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager; import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
import com.willfp.eco.core.placeholder.AdditionalPlayer; import com.willfp.eco.core.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.PlaceholderInjectable; import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import com.willfp.eco.core.placeholder.context.PlaceholderContext;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Objects;
/** /**
* Represents a context to do math in. * Represents a context to parse math in.
* *
* @param injectableContext The PlaceholderInjectable context. * @deprecated Use {@link PlaceholderContext} instead.
* @param player The player.
* @param additionalPlayers The additional players.
*/ */
public record MathContext( @SuppressWarnings("DeprecatedIsStillUsed")
@NotNull PlaceholderInjectable injectableContext, @Deprecated(since = "6.56.0", forRemoval = true)
@Nullable Player player, public class MathContext {
@NotNull Collection<AdditionalPlayer> additionalPlayers
) {
/** /**
* Empty math context. * Returns an empty math parseContext.
*/ */
public static final MathContext EMPTY = new MathContext( public static final MathContext EMPTY = new MathContext(
PlaceholderManager.EMPTY_INJECTABLE, PlaceholderManager.EMPTY_INJECTABLE,
@@ -32,9 +30,157 @@ public record MathContext(
); );
/** /**
* Create MathContext of a PlaceholderInjectable context. * The PlaceholderInjectable parse context.
*/
@NotNull
private final PlaceholderInjectable injectableContext;
/**
* The player.
*/
@Nullable
private final Player player;
/**
* The additional players.
*/
@NotNull
private final Collection<AdditionalPlayer> additionalPlayers;
/**
* Constructs a new MathContext with the given parameters.
* *
* @param injectableContext The PlaceholderInjectable context. * @param injectableContext The PlaceholderInjectable parseContext.
* @param player The player.
* @param additionalPlayers The additional players.
*/
public MathContext(@NotNull PlaceholderInjectable injectableContext,
@Nullable Player player,
@NotNull Collection<AdditionalPlayer> additionalPlayers) {
this.injectableContext = injectableContext;
this.player = player;
this.additionalPlayers = additionalPlayers;
}
/**
* Returns the PlaceholderInjectable parse context.
* <p>
* Duplicate method because MathContext used to be a record.
*
* @return The injectable context.
* @deprecated Use {@link #getInjectableContext()} instead.
*/
@Deprecated(since = "6.56.0", forRemoval = true)
public PlaceholderInjectable injectableContext() {
return injectableContext;
}
/**
* Returns the PlaceholderInjectable parse context.
*
* @return The injectable context.
*/
@NotNull
public PlaceholderInjectable getInjectableContext() {
return injectableContext;
}
/**
* Returns the player.
* <p>
* Duplicate method because MathContext used to be a record.
*
* @return The player.
* @deprecated Use {@link #getPlayer()} instead.
*/
@Deprecated(since = "6.56.0", forRemoval = true)
@Nullable
public Player player() {
return player;
}
/**
* Returns the player.
*
* @return The player.
*/
@Nullable
public Player getPlayer() {
return player;
}
/**
* Returns the additional players.
* <p>
* Duplicate method because MathContext used to be a record.
*
* @return The additional players.
* @deprecated Use {@link #getAdditionalPlayers()} instead.
*/
@Deprecated(since = "6.56.0", forRemoval = true)
@NotNull
public Collection<AdditionalPlayer> additionalPlayers() {
return additionalPlayers;
}
/**
* Returns the additional players.
*
* @return The additional players.
*/
@NotNull
public Collection<AdditionalPlayer> getAdditionalPlayers() {
return additionalPlayers;
}
/**
* Convert to PlaceholderContext.
*
* @return The PlaceholderContext.
*/
@NotNull
public PlaceholderContext toPlaceholderContext() {
return new PlaceholderContext(
this.player,
null,
this.injectableContext,
this.additionalPlayers
);
}
@Override
public String toString() {
return "MathContext{" +
"injectableContext=" + injectableContext +
", player=" + player +
", additionalPlayers=" + additionalPlayers +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof MathContext that)) {
return false;
}
return injectableContext.equals(that.injectableContext) &&
Objects.equals(player, that.player) &&
additionalPlayers.equals(that.additionalPlayers);
}
@Override
public int hashCode() {
return Objects.hash(injectableContext, player, additionalPlayers);
}
/**
* Create MathContext of a PlaceholderInjectable parseContext.
*
* @param injectableContext The PlaceholderInjectable parseContext.
* @return The MathContext. * @return The MathContext.
*/ */
public static MathContext of(@NotNull final PlaceholderInjectable injectableContext) { public static MathContext of(@NotNull final PlaceholderInjectable injectableContext) {
@@ -48,16 +194,16 @@ public record MathContext(
/** /**
* Copy a MathContext with a player. * Copy a MathContext with a player.
* *
* @param context The context. * @param context The parseContext.
* @param player The player. * @param player The player.
* @return The new MathContext. * @return The new MathContext.
*/ */
public static MathContext copyWithPlayer(@NotNull final MathContext context, public static MathContext copyWithPlayer(@NotNull final MathContext context,
@Nullable final Player player) { @Nullable final Player player) {
return new MathContext( return new MathContext(
context.injectableContext(), context.injectableContext,
player, player,
context.additionalPlayers() context.additionalPlayers
); );
} }
} }

View File

@@ -8,6 +8,13 @@ import org.jetbrains.annotations.NotNull;
* Empty (invalid) particle that is spawned when an invalid key is provided. * Empty (invalid) particle that is spawned when an invalid key is provided.
*/ */
public final class EmptyParticle implements SpawnableParticle { public final class EmptyParticle implements SpawnableParticle {
/**
* Instantiate a new empty particle.
*/
public EmptyParticle() {
}
@Override @Override
public void spawn(@NotNull final Location location, public void spawn(@NotNull final Location location,
final int amount) { final int amount) {

View File

@@ -1,7 +1,7 @@
package com.willfp.eco.core.placeholder; package com.willfp.eco.core.placeholder;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager; import com.willfp.eco.core.placeholder.context.PlaceholderContext;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -12,24 +12,24 @@ import java.util.regex.Pattern;
/** /**
* A placeholder that does not require a player and supports dynamic styles. * A placeholder that does not require a player and supports dynamic styles.
*/ */
public final class DynamicPlaceholder implements Placeholder { public final class DynamicPlaceholder implements RegistrablePlaceholder {
/** /**
* The placeholder pattern. * The arguments pattern.
*/ */
private final Pattern pattern; private final Pattern pattern;
/** /**
* The function to retrieve the output of the placeholder. * The function to retrieve the output of the arguments.
*/ */
private final Function<String, String> function; private final Function<@NotNull String, @Nullable String> function;
/** /**
* The plugin for the placeholder. * The plugin for the arguments.
*/ */
private final EcoPlugin plugin; private final EcoPlugin plugin;
/** /**
* Create a new dynamic placeholder. * Create a new dynamic arguments.
* *
* @param plugin The plugin. * @param plugin The plugin.
* @param pattern The pattern. * @param pattern The pattern.
@@ -37,31 +37,33 @@ public final class DynamicPlaceholder implements Placeholder {
*/ */
public DynamicPlaceholder(@NotNull final EcoPlugin plugin, public DynamicPlaceholder(@NotNull final EcoPlugin plugin,
@NotNull final Pattern pattern, @NotNull final Pattern pattern,
@NotNull final Function<String, String> function) { @NotNull final Function<@NotNull String, @Nullable String> function) {
this.plugin = plugin; this.plugin = plugin;
this.pattern = pattern; this.pattern = pattern;
this.function = function; this.function = function;
} }
/** @Override
* Get the value of the placeholder. @Nullable
* public String getValue(@NotNull final String args,
* @param args The args. @NotNull final PlaceholderContext context) {
* @return The value.
*/
@NotNull
public String getValue(@NotNull final String args) {
return function.apply(args); return function.apply(args);
} }
/** /**
* Register the placeholder. * Get the value of the arguments.
* *
* @return The placeholder. * @param args The args.
* @return The value.
* @deprecated Use {@link #getValue(String, PlaceholderContext)} instead.
*/ */
public DynamicPlaceholder register() { @Deprecated(since = "6.56.0", forRemoval = true)
PlaceholderManager.registerPlaceholder(this); @NotNull
return this; public String getValue(@NotNull final String args) {
return Objects.requireNonNullElse(
function.apply(args),
""
);
} }
@Override @Override
@@ -69,18 +71,17 @@ public final class DynamicPlaceholder implements Placeholder {
return this.plugin; return this.plugin;
} }
@Override
@Deprecated
public @NotNull String getIdentifier() {
return "dynamic";
}
@NotNull @NotNull
@Override @Override
public Pattern getPattern() { public Pattern getPattern() {
return this.pattern; return this.pattern;
} }
@Override
public @NotNull DynamicPlaceholder register() {
return (DynamicPlaceholder) RegistrablePlaceholder.super.register();
}
@Override @Override
public boolean equals(@Nullable final Object o) { public boolean equals(@Nullable final Object o) {
if (this == o) { if (this == o) {
@@ -97,6 +98,6 @@ public final class DynamicPlaceholder implements Placeholder {
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(this.getIdentifier(), this.getPlugin()); return Objects.hash(this.getPattern(), this.getPlugin());
} }
} }

View File

@@ -1,15 +1,20 @@
package com.willfp.eco.core.placeholder; package com.willfp.eco.core.placeholder;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable;
/** /**
* Placeholders that can be injected into {@link PlaceholderInjectable} objects. * Placeholders that can be injected into {@link PlaceholderInjectable} objects.
*/ */
public sealed interface InjectablePlaceholder extends Placeholder permits PlayerStaticPlaceholder, StaticPlaceholder { public interface InjectablePlaceholder extends Placeholder {
/**
* Get the plugin that holds the arguments.
*
* @return The plugin.
*/
@Nullable
@Override @Override
default @NotNull EcoPlugin getPlugin() { default EcoPlugin getPlugin() {
return Eco.get().getEcoPlugin(); return null;
} }
} }

View File

@@ -1,6 +1,7 @@
package com.willfp.eco.core.placeholder; package com.willfp.eco.core.placeholder;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.placeholder.context.PlaceholderContext;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -9,10 +10,9 @@ import java.util.regex.Pattern;
/** /**
* A placeholder represents a string that can hold a value. * A placeholder represents a string that can hold a value.
*/ */
public sealed interface Placeholder permits PlayerPlaceholder, PlayerlessPlaceholder, public interface Placeholder {
DynamicPlaceholder, PlayerDynamicPlaceholder, InjectablePlaceholder {
/** /**
* Get the plugin that holds the placeholder. * Get the plugin that holds the arguments.
* *
* @return The plugin. * @return The plugin.
*/ */
@@ -20,20 +20,45 @@ public sealed interface Placeholder permits PlayerPlaceholder, PlayerlessPlaceho
EcoPlugin getPlugin(); EcoPlugin getPlugin();
/** /**
* Get the identifier for the placeholder. * Get the value of the arguments.
* *
* @return The identifier. * @param args The args.
* @param context The context.
* @return The value.
*/ */
@NotNull @Nullable
String getIdentifier(); String getValue(@NotNull String args,
@NotNull PlaceholderContext context);
/** /**
* Get the pattern for the placeholder. * Get the pattern for the arguments.
* *
* @return The pattern. * @return The pattern.
*/ */
@NotNull @NotNull
default Pattern getPattern() { Pattern getPattern();
return Pattern.compile(this.getIdentifier());
/**
* Try to translate all instances of this placeholder in text quickly.
*
* @param text The text to translate.
* @param context The context.
* @return The translated text.
*/
default String tryTranslateQuickly(@NotNull final String text,
@NotNull final PlaceholderContext context) {
return text;
}
/**
* Get the identifier for the arguments.
*
* @return The identifier.
* @deprecated Some arguments may not have an identifier. Use {@link #getPattern()} instead.
*/
@Deprecated(since = "6.56.0", forRemoval = true)
@NotNull
default String getIdentifier() {
return this.getPattern().pattern();
} }
} }

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.core.placeholder;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@@ -10,16 +9,16 @@ import java.util.List;
*/ */
public interface PlaceholderInjectable { public interface PlaceholderInjectable {
/** /**
* Inject placeholder. * Inject arguments.
* *
* @param placeholders The placeholders. * @param placeholders The placeholders.
*/ */
default void injectPlaceholders(@NotNull StaticPlaceholder... placeholders) { default void injectPlaceholders(@NotNull StaticPlaceholder... placeholders) {
this.injectPlaceholders(List.of(placeholders)); this.addInjectablePlaceholder(List.of(placeholders));
} }
/** /**
* Inject placeholder. * Inject arguments.
* *
* @param placeholders The placeholders. * @param placeholders The placeholders.
*/ */
@@ -27,71 +26,27 @@ public interface PlaceholderInjectable {
this.addInjectablePlaceholder(List.of(placeholders)); this.addInjectablePlaceholder(List.of(placeholders));
} }
/**
* Inject placeholder.
*
* @param placeholders The placeholders.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
default void injectPlaceholders(@NotNull Iterable<StaticPlaceholder> placeholders) {
List<InjectablePlaceholder> toInject = new ArrayList<>();
for (StaticPlaceholder placeholder : placeholders) {
toInject.add(placeholder);
}
this.addInjectablePlaceholder(toInject);
}
/** /**
* Inject placeholders. * Inject placeholders.
* <p> * <p>
* When implementing a PlaceholderInjectable object, override this method. * If a placeholder already has the same pattern, it should be replaced.
* *
* @param placeholders The placeholders. * @param placeholders The placeholders.
*/ */
default void addInjectablePlaceholder(@NotNull Iterable<InjectablePlaceholder> placeholders) { void addInjectablePlaceholder(@NotNull Iterable<InjectablePlaceholder> placeholders);
List<StaticPlaceholder> toInject = new ArrayList<>();
for (InjectablePlaceholder placeholder : placeholders) {
if (placeholder instanceof StaticPlaceholder staticPlaceholder) {
toInject.add(staticPlaceholder);
}
}
this.injectPlaceholders(toInject);
}
/** /**
* Clear injected placeholders. * Clear injected placeholders.
*/ */
void clearInjectedPlaceholders(); void clearInjectedPlaceholders();
/**
* Get injected placeholders.
*
* @return Injected placeholders.
* @deprecated Use getPlaceholderInjections.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
@NotNull
default List<StaticPlaceholder> getInjectedPlaceholders() {
List<StaticPlaceholder> found = new ArrayList<>();
for (InjectablePlaceholder placeholder : getPlaceholderInjections()) {
if (placeholder instanceof StaticPlaceholder staticPlaceholder) {
found.add(staticPlaceholder);
}
}
return found;
}
/** /**
* Get injected placeholders. * Get injected placeholders.
* <p> * <p>
* Override this method in implementations. * This method should always return an immutable list.
* *
* @return Injected placeholders. * @return Injected placeholders.
*/ */
@NotNull @NotNull
default List<InjectablePlaceholder> getPlaceholderInjections() { List<InjectablePlaceholder> getPlaceholderInjections();
return new ArrayList<>(getInjectedPlaceholders());
}
} }

View File

@@ -1,7 +1,7 @@
package com.willfp.eco.core.placeholder; package com.willfp.eco.core.placeholder;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager; import com.willfp.eco.core.placeholder.context.PlaceholderContext;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -11,26 +11,26 @@ import java.util.function.BiFunction;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
* A placeholder that does not require a player and supports dynamic styles. * A arguments that does not require a player and supports dynamic styles.
*/ */
public final class PlayerDynamicPlaceholder implements Placeholder { public final class PlayerDynamicPlaceholder implements RegistrablePlaceholder {
/** /**
* The placeholder pattern. * The arguments pattern.
*/ */
private final Pattern pattern; private final Pattern pattern;
/** /**
* The function to retrieve the output of the placeholder. * The function to retrieve the output of the arguments.
*/ */
private final BiFunction<String, Player, String> function; private final BiFunction<@NotNull String, @NotNull Player, @Nullable String> function;
/** /**
* The plugin for the placeholder. * The plugin for the arguments.
*/ */
private final EcoPlugin plugin; private final EcoPlugin plugin;
/** /**
* Create a new dynamic placeholder. * Create a new dynamic arguments.
* *
* @param plugin The plugin. * @param plugin The plugin.
* @param pattern The pattern. * @param pattern The pattern.
@@ -38,33 +38,40 @@ public final class PlayerDynamicPlaceholder implements Placeholder {
*/ */
public PlayerDynamicPlaceholder(@NotNull final EcoPlugin plugin, public PlayerDynamicPlaceholder(@NotNull final EcoPlugin plugin,
@NotNull final Pattern pattern, @NotNull final Pattern pattern,
@NotNull final BiFunction<String, Player, String> function) { @NotNull final BiFunction<@NotNull String, @NotNull Player, @Nullable String> function) {
this.plugin = plugin; this.plugin = plugin;
this.pattern = pattern; this.pattern = pattern;
this.function = function; this.function = function;
} }
/** @Override
* Get the value of the placeholder. public @Nullable String getValue(@NotNull final String args,
* @NotNull final PlaceholderContext context) {
* @param args The args. Player player = context.getPlayer();
* @param player The player.
* @return The value. if (player == null) {
*/ return null;
@NotNull }
public String getValue(@NotNull final String args,
@NotNull final Player player) {
return function.apply(args, player); return function.apply(args, player);
} }
/** /**
* Register the placeholder. * Get the value of the arguments.
* *
* @return The placeholder. * @param args The args.
* @param player The player.
* @return The value.
* @deprecated Use {@link #getValue(String, PlaceholderContext)} instead.
*/ */
public PlayerDynamicPlaceholder register() { @Deprecated(since = "6.56.0", forRemoval = true)
PlaceholderManager.registerPlaceholder(this); @NotNull
return this; public String getValue(@NotNull final String args,
@NotNull final Player player) {
return Objects.requireNonNullElse(
function.apply(args, player),
""
);
} }
@Override @Override
@@ -72,18 +79,17 @@ public final class PlayerDynamicPlaceholder implements Placeholder {
return this.plugin; return this.plugin;
} }
@Override
@Deprecated
public @NotNull String getIdentifier() {
return "dynamic";
}
@NotNull @NotNull
@Override @Override
public Pattern getPattern() { public Pattern getPattern() {
return this.pattern; return this.pattern;
} }
@Override
public @NotNull PlayerDynamicPlaceholder register() {
return (PlayerDynamicPlaceholder) RegistrablePlaceholder.super.register();
}
@Override @Override
public boolean equals(@Nullable final Object o) { public boolean equals(@Nullable final Object o) {
if (this == o) { if (this == o) {
@@ -100,6 +106,6 @@ public final class PlayerDynamicPlaceholder implements Placeholder {
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(this.getIdentifier(), this.getPlugin()); return Objects.hash(this.getPattern(), this.getPlugin());
} }
} }

View File

@@ -1,7 +1,8 @@
package com.willfp.eco.core.placeholder; package com.willfp.eco.core.placeholder;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager; import com.willfp.eco.core.placeholder.context.PlaceholderContext;
import com.willfp.eco.util.PatternUtils;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -11,31 +12,26 @@ import java.util.function.Function;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
* A placeholder that requires a player. * A arguments that requires a player.
*/ */
public final class PlayerPlaceholder implements Placeholder { public final class PlayerPlaceholder implements RegistrablePlaceholder {
/** /**
* The name of the placeholder. * The arguments pattern.
*/
private final String identifier;
/**
* The placeholder pattern.
*/ */
private final Pattern pattern; private final Pattern pattern;
/** /**
* The function to retrieve the output of the placeholder given a player. * The function to retrieve the output of the arguments given a player.
*/ */
private final Function<Player, String> function; private final Function<@NotNull Player, @Nullable String> function;
/** /**
* The plugin for the placeholder. * The plugin for the arguments.
*/ */
private final EcoPlugin plugin; private final EcoPlugin plugin;
/** /**
* Create a new player placeholder. * Create a new player arguments.
* *
* @param plugin The plugin. * @param plugin The plugin.
* @param identifier The identifier. * @param identifier The identifier.
@@ -43,32 +39,38 @@ public final class PlayerPlaceholder implements Placeholder {
*/ */
public PlayerPlaceholder(@NotNull final EcoPlugin plugin, public PlayerPlaceholder(@NotNull final EcoPlugin plugin,
@NotNull final String identifier, @NotNull final String identifier,
@NotNull final Function<Player, String> function) { @NotNull final Function<@NotNull Player, @Nullable String> function) {
this.plugin = plugin; this.plugin = plugin;
this.identifier = identifier; this.pattern = PatternUtils.compileLiteral(identifier);
this.pattern = Pattern.compile(identifier);
this.function = function; this.function = function;
} }
/** @Override
* Get the value of the placeholder for a given player. public @Nullable String getValue(@NotNull final String args,
* @NotNull final PlaceholderContext context) {
* @param player The player. Player player = context.getPlayer();
* @return The value.
*/ if (player == null) {
@NotNull return null;
public String getValue(@NotNull final Player player) { }
return function.apply(player); return function.apply(player);
} }
/** /**
* Register the placeholder. * Get the value of the arguments for a given player.
* *
* @return The placeholder. * @param player The player.
* @return The value.
* @deprecated Use {@link #getValue(String, PlaceholderContext)} instead.
*/ */
public PlayerPlaceholder register() { @Deprecated(since = "6.56.0", forRemoval = true)
PlaceholderManager.registerPlaceholder(this); @NotNull
return this; public String getValue(@NotNull final Player player) {
return Objects.requireNonNullElse(
function.apply(player),
""
);
} }
@Override @Override
@@ -76,17 +78,17 @@ public final class PlayerPlaceholder implements Placeholder {
return this.plugin; return this.plugin;
} }
@Override
public @NotNull String getIdentifier() {
return this.identifier;
}
@NotNull @NotNull
@Override @Override
public Pattern getPattern() { public Pattern getPattern() {
return this.pattern; return this.pattern;
} }
@Override
public @NotNull PlayerPlaceholder register() {
return (PlayerPlaceholder) RegistrablePlaceholder.super.register();
}
@Override @Override
public boolean equals(@Nullable final Object o) { public boolean equals(@Nullable final Object o) {
if (this == o) { if (this == o) {
@@ -95,12 +97,12 @@ public final class PlayerPlaceholder implements Placeholder {
if (!(o instanceof PlayerPlaceholder that)) { if (!(o instanceof PlayerPlaceholder that)) {
return false; return false;
} }
return Objects.equals(this.getIdentifier(), that.getIdentifier()) return Objects.equals(this.getPattern(), that.getPattern())
&& Objects.equals(this.getPlugin(), that.getPlugin()); && Objects.equals(this.getPlugin(), that.getPlugin());
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(this.getIdentifier(), this.getPlugin()); return Objects.hash(this.getPattern(), this.getPlugin());
} }
} }

View File

@@ -1,5 +1,8 @@
package com.willfp.eco.core.placeholder; package com.willfp.eco.core.placeholder;
import com.willfp.eco.core.placeholder.context.PlaceholderContext;
import com.willfp.eco.util.PatternUtils;
import com.willfp.eco.util.StringUtils;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -13,47 +16,72 @@ import java.util.regex.Pattern;
*/ */
public final class PlayerStaticPlaceholder implements InjectablePlaceholder { public final class PlayerStaticPlaceholder implements InjectablePlaceholder {
/** /**
* The name of the placeholder. * The identifier.
*/ */
private final String identifier; private final String identifier;
/** /**
* The placeholder pattern. * The arguments pattern.
*/ */
private final Pattern pattern; private final Pattern pattern;
/** /**
* The function to retrieve the output of the placeholder. * The function to retrieve the output of the arguments.
*/ */
private final Function<Player, String> function; private final Function<@NotNull Player, @Nullable String> function;
/** /**
* Create a new player placeholder. * Create a new player arguments.
* *
* @param identifier The identifier. * @param identifier The identifier.
* @param function The function to retrieve the value. * @param function The function to retrieve the value.
*/ */
public PlayerStaticPlaceholder(@NotNull final String identifier, public PlayerStaticPlaceholder(@NotNull final String identifier,
@NotNull final Function<Player, String> function) { @NotNull final Function<@NotNull Player, @Nullable String> function) {
this.identifier = identifier; this.identifier = "%" + identifier + "%";
this.pattern = Pattern.compile(identifier); this.pattern = PatternUtils.compileLiteral(identifier);
this.function = function; this.function = function;
} }
@Override
public @Nullable String getValue(@NotNull final String args,
@NotNull final PlaceholderContext context) {
Player player = context.getPlayer();
if (player == null) {
return null;
}
return this.getValue(player);
}
/** /**
* Get the value of the placeholder. * Get the value of the arguments.
* *
* @param player The player. * @param player The player.
* @return The value. * @return The value.
* @deprecated Use {@link #getValue(String, PlaceholderContext)} instead.
*/ */
@Deprecated(since = "6.56.0", forRemoval = true)
@NotNull @NotNull
public String getValue(@NotNull final Player player) { public String getValue(@NotNull final Player player) {
return function.apply(player); return Objects.requireNonNullElse(
function.apply(player),
""
);
} }
@Override @Override
public @NotNull String getIdentifier() { public String tryTranslateQuickly(@NotNull final String text,
return this.identifier; @NotNull final PlaceholderContext context) {
return StringUtils.replaceQuickly(
text,
this.identifier,
Objects.requireNonNullElse(
this.getValue(identifier, context),
""
)
);
} }
@NotNull @NotNull
@@ -70,11 +98,11 @@ public final class PlayerStaticPlaceholder implements InjectablePlaceholder {
if (!(o instanceof PlayerStaticPlaceholder that)) { if (!(o instanceof PlayerStaticPlaceholder that)) {
return false; return false;
} }
return Objects.equals(this.getIdentifier(), that.getIdentifier()); return Objects.equals(this.getPattern(), that.getPattern());
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(this.getIdentifier()); return Objects.hash(this.getPattern());
} }
} }

View File

@@ -1,7 +1,8 @@
package com.willfp.eco.core.placeholder; package com.willfp.eco.core.placeholder;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager; import com.willfp.eco.core.placeholder.context.PlaceholderContext;
import com.willfp.eco.util.PatternUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -10,31 +11,26 @@ import java.util.function.Supplier;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
* A placeholder that does not require a player. * A arguments that does not require a player.
*/ */
public final class PlayerlessPlaceholder implements Placeholder { public final class PlayerlessPlaceholder implements RegistrablePlaceholder {
/** /**
* The placeholder identifier. * The arguments pattern.
*/
private final String identifier;
/**
* The placeholder pattern.
*/ */
private final Pattern pattern; private final Pattern pattern;
/** /**
* The function to retrieve the output of the placeholder. * The function to retrieve the output of the arguments.
*/ */
private final Supplier<String> function; private final Supplier<@Nullable String> function;
/** /**
* The plugin for the placeholder. * The plugin for the arguments.
*/ */
private final EcoPlugin plugin; private final EcoPlugin plugin;
/** /**
* Create a new player placeholder. * Create a new player arguments.
* *
* @param plugin The plugin. * @param plugin The plugin.
* @param identifier The identifier. * @param identifier The identifier.
@@ -42,30 +38,31 @@ public final class PlayerlessPlaceholder implements Placeholder {
*/ */
public PlayerlessPlaceholder(@NotNull final EcoPlugin plugin, public PlayerlessPlaceholder(@NotNull final EcoPlugin plugin,
@NotNull final String identifier, @NotNull final String identifier,
@NotNull final Supplier<String> function) { @NotNull final Supplier<@Nullable String> function) {
this.plugin = plugin; this.plugin = plugin;
this.identifier = identifier; this.pattern = PatternUtils.compileLiteral(identifier);
this.pattern = Pattern.compile(identifier);
this.function = function; this.function = function;
} }
/** @Override
* Get the value of the placeholder. public @Nullable String getValue(@NotNull final String args,
* @NotNull final PlaceholderContext context) {
* @return The value.
*/
public String getValue() {
return function.get(); return function.get();
} }
/** /**
* Register the placeholder. * Get the value of the arguments.
* *
* @return The placeholder. * @return The value.
* @deprecated Use {@link #getValue(String, PlaceholderContext)} instead.
*/ */
public PlayerlessPlaceholder register() { @Deprecated(since = "6.56.0", forRemoval = true)
PlaceholderManager.registerPlaceholder(this); @NotNull
return this; public String getValue() {
return Objects.requireNonNullElse(
this.function.get(),
""
);
} }
@Override @Override
@@ -73,17 +70,17 @@ public final class PlayerlessPlaceholder implements Placeholder {
return this.plugin; return this.plugin;
} }
@Override
public @NotNull String getIdentifier() {
return this.identifier;
}
@NotNull @NotNull
@Override @Override
public Pattern getPattern() { public Pattern getPattern() {
return this.pattern; return this.pattern;
} }
@Override
public @NotNull PlayerlessPlaceholder register() {
return (PlayerlessPlaceholder) RegistrablePlaceholder.super.register();
}
@Override @Override
public boolean equals(@Nullable final Object o) { public boolean equals(@Nullable final Object o) {
if (this == o) { if (this == o) {
@@ -92,12 +89,12 @@ public final class PlayerlessPlaceholder implements Placeholder {
if (!(o instanceof PlayerlessPlaceholder that)) { if (!(o instanceof PlayerlessPlaceholder that)) {
return false; return false;
} }
return Objects.equals(this.getIdentifier(), that.getIdentifier()) return Objects.equals(this.getPattern(), that.getPattern())
&& Objects.equals(this.getPlugin(), that.getPlugin()); && Objects.equals(this.getPlugin(), that.getPlugin());
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(this.getIdentifier(), this.getPlugin()); return Objects.hash(this.getPattern(), this.getPlugin());
} }
} }

View File

@@ -0,0 +1,31 @@
package com.willfp.eco.core.placeholder;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
import org.jetbrains.annotations.NotNull;
/**
* Represents a placeholder that can be registered.
*/
public interface RegistrablePlaceholder extends Placeholder {
/**
* Get the plugin that holds the arguments.
*
* @return The plugin.
*/
@NotNull
@Override
EcoPlugin getPlugin();
/**
* Register the arguments.
*
* @return The arguments.
*/
@NotNull
default RegistrablePlaceholder register() {
PlaceholderManager.registerPlaceholder(this);
return this;
}
}

View File

@@ -1,5 +1,8 @@
package com.willfp.eco.core.placeholder; package com.willfp.eco.core.placeholder;
import com.willfp.eco.core.placeholder.context.PlaceholderContext;
import com.willfp.eco.util.PatternUtils;
import com.willfp.eco.util.StringUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -8,50 +11,66 @@ import java.util.function.Supplier;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
* A placeholder that cannot be registered, and exists purely in injection. * A arguments that cannot be registered, and exists purely in injection.
*/ */
public final class StaticPlaceholder implements InjectablePlaceholder { public final class StaticPlaceholder implements InjectablePlaceholder {
/** /**
* The name of the placeholder. * The name of the arguments.
*/ */
private final String identifier; private final String identifier;
/** /**
* The placeholder pattern. * The arguments pattern.
*/ */
private final Pattern pattern; private final Pattern pattern;
/** /**
* The function to retrieve the output of the placeholder. * The function to retrieve the output of the arguments.
*/ */
private final Supplier<String> function; private final Supplier<@Nullable String> function;
/** /**
* Create a new player placeholder. * Create a new player arguments.
* *
* @param identifier The identifier. * @param identifier The identifier.
* @param function The function to retrieve the value. * @param function The function to retrieve the value.
*/ */
public StaticPlaceholder(@NotNull final String identifier, public StaticPlaceholder(@NotNull final String identifier,
@NotNull final Supplier<String> function) { @NotNull final Supplier<@Nullable String> function) {
this.identifier = identifier; this.identifier = "%" + identifier + "%";
this.pattern = Pattern.compile(identifier); this.pattern = PatternUtils.compileLiteral(identifier);
this.function = function; this.function = function;
} }
/** @Override
* Get the value of the placeholder. public @Nullable String getValue(@NotNull final String args,
* @NotNull final PlaceholderContext context) {
* @return The value.
*/
@NotNull
public String getValue() {
return function.get(); return function.get();
} }
/**
* Get the value of the arguments.
*
* @return The value.
* @deprecated Use {@link #getValue(String, PlaceholderContext)} instead.
*/
@Deprecated(since = "6.56.0", forRemoval = true)
@NotNull
public String getValue() {
return Objects.requireNonNullElse(
function.get(),
""
);
}
@Override @Override
public @NotNull String getIdentifier() { public String tryTranslateQuickly(@NotNull final String text,
return this.identifier; @NotNull final PlaceholderContext context) {
return StringUtils.replaceQuickly(
text,
this.identifier,
Objects.requireNonNullElse(this.getValue(this.identifier, context), "")
);
} }
@NotNull @NotNull
@@ -68,11 +87,11 @@ public final class StaticPlaceholder implements InjectablePlaceholder {
if (!(o instanceof StaticPlaceholder that)) { if (!(o instanceof StaticPlaceholder that)) {
return false; return false;
} }
return Objects.equals(this.getIdentifier(), that.getIdentifier()); return Objects.equals(this.getPattern(), that.getPattern());
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(this.getIdentifier()); return Objects.hash(this.getPattern());
} }
} }

View File

@@ -0,0 +1,92 @@
package com.willfp.eco.core.placeholder.context;
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* A merged injectable context.
*/
public class MergedInjectableContext implements PlaceholderInjectable {
/**
* The base context.
*/
private final PlaceholderInjectable baseContext;
/**
* The additional context.
*/
private final PlaceholderInjectable additionalContext;
/**
* Extra injections.
*/
private final Set<InjectablePlaceholder> extraInjections = new HashSet<>();
/**
* Create a new merged injectable context.
*
* @param baseContext The base context.
* @param additionalContext The additional context.
*/
public MergedInjectableContext(@NotNull final PlaceholderInjectable baseContext,
@NotNull final PlaceholderInjectable additionalContext) {
this.baseContext = baseContext;
this.additionalContext = additionalContext;
}
@Override
public void addInjectablePlaceholder(@NotNull final Iterable<InjectablePlaceholder> placeholders) {
for (InjectablePlaceholder placeholder : placeholders) {
extraInjections.add(placeholder);
}
}
@Override
public void clearInjectedPlaceholders() {
baseContext.clearInjectedPlaceholders();
additionalContext.clearInjectedPlaceholders();
extraInjections.clear();
}
@Override
public @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
List<InjectablePlaceholder> base = baseContext.getPlaceholderInjections();
List<InjectablePlaceholder> additional = additionalContext.getPlaceholderInjections();
List<InjectablePlaceholder> injections = new ArrayList<>(base.size() + additional.size() + extraInjections.size());
injections.addAll(base);
injections.addAll(additional);
injections.addAll(extraInjections);
return injections;
}
@Override
public boolean equals(@Nullable final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof MergedInjectableContext that)) {
return false;
}
return Objects.equals(baseContext, that.baseContext)
&& Objects.equals(additionalContext, that.additionalContext)
&& Objects.equals(extraInjections, that.extraInjections);
}
@Override
public int hashCode() {
return Objects.hash(baseContext, additionalContext, extraInjections);
}
}

View File

@@ -0,0 +1,252 @@
package com.willfp.eco.core.placeholder.context;
import com.willfp.eco.core.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/**
* Represents a context to translate placeholders in.
*/
public class PlaceholderContext {
/**
* An empty injectable.
*/
private static final PlaceholderInjectable EMPTY_INJECTABLE = new PlaceholderInjectable() {
@Override
public void addInjectablePlaceholder(@NotNull final Iterable<InjectablePlaceholder> placeholders) {
// Do nothing.
}
@Override
public void clearInjectedPlaceholders() {
// Do nothing.
}
@Override
public @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
return Collections.emptyList();
}
};
/**
* An empty context.
*/
public static final PlaceholderContext EMPTY = new PlaceholderContext(
null,
null,
null,
Collections.emptyList()
);
/**
* The player.
*/
@Nullable
private final Player player;
/**
* The ItemStack.
*/
@Nullable
private final ItemStack itemStack;
/**
* The PlaceholderInjectable context.
*/
@NotNull
private final PlaceholderInjectable injectableContext;
/**
* The additional players.
*/
@NotNull
private final Collection<AdditionalPlayer> additionalPlayers;
/**
* Create an empty PlaceholderContext.
*/
public PlaceholderContext() {
this(null, null, null, Collections.emptyList());
}
/**
* Create a PlaceholderContext for a player.
*
* @param player The player.
*/
public PlaceholderContext(@Nullable final Player player) {
this(player, null, null, Collections.emptyList());
}
/**
* Constructs a new PlaceholderContext with the given parameters.
*
* @param player The player.
* @param itemStack The ItemStack.
* @param injectableContext The PlaceholderInjectable parseContext.
* @param additionalPlayers The additional players.
*/
public PlaceholderContext(@Nullable final Player player,
@Nullable final ItemStack itemStack,
@Nullable final PlaceholderInjectable injectableContext,
@NotNull final Collection<AdditionalPlayer> additionalPlayers) {
this.player = player;
this.itemStack = itemStack;
this.injectableContext = Objects.requireNonNullElse(injectableContext, EMPTY_INJECTABLE);
this.additionalPlayers = additionalPlayers;
}
/**
* Get the player.
*
* @return The player.
*/
@Nullable
public Player getPlayer() {
return player;
}
/**
* Get the ItemStack.
*
* @return The ItemStack.
*/
@Nullable
public ItemStack getItemStack() {
return itemStack;
}
/**
* Get the PlaceholderInjectable context.
*
* @return The PlaceholderInjectable context.
*/
@NotNull
public PlaceholderInjectable getInjectableContext() {
return injectableContext;
}
/**
* Get the additional players.
*
* @return The additional players.
*/
@NotNull
public Collection<AdditionalPlayer> getAdditionalPlayers() {
return additionalPlayers;
}
/**
* Convert to a {@link com.willfp.eco.core.math.MathContext}.
*
* @return The math context.
* @deprecated MathContext is deprecated, use {@link PlaceholderContext} instead.
*/
@Deprecated(since = "6.56.0", forRemoval = true)
@SuppressWarnings({"removal", "DeprecatedIsStillUsed"})
public com.willfp.eco.core.math.MathContext toMathContext() {
return new com.willfp.eco.core.math.MathContext(this.getInjectableContext(), this.getPlayer(), this.getAdditionalPlayers());
}
/**
* Copy with a player.
*
* @param player The player.
* @return The new context.
*/
public PlaceholderContext copyWithPlayer(@Nullable final Player player) {
return new PlaceholderContext(
player,
this.getItemStack(),
this.getInjectableContext(),
this.getAdditionalPlayers()
);
}
/**
* Copy with an item.
*
* @param itemStack The ItemStack.
* @return The new context.
*/
public PlaceholderContext copyWithItem(@Nullable final ItemStack itemStack) {
return new PlaceholderContext(
this.getPlayer(),
itemStack,
this.getInjectableContext(),
this.getAdditionalPlayers()
);
}
/**
* Copy with an extra injectable context.
*
* @param injectableContext The injectable context to add.
* @return The new context.
*/
public PlaceholderContext withInjectableContext(@NotNull final PlaceholderInjectable injectableContext) {
return new PlaceholderContext(
this.getPlayer(),
this.getItemStack(),
new MergedInjectableContext(this.getInjectableContext(), injectableContext),
this.getAdditionalPlayers()
);
}
@Override
public String toString() {
return "PlaceholderContext{" +
"player=" + player +
", itemStack=" + itemStack +
", injectableContext=" + injectableContext +
", additionalPlayers=" + additionalPlayers +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof PlaceholderContext that)) {
return false;
}
return Objects.equals(
getPlayer(), that.getPlayer())
&& Objects.equals(getItemStack(), that.getItemStack())
&& getInjectableContext().equals(that.getInjectableContext())
&& getAdditionalPlayers().equals(that.getAdditionalPlayers()
);
}
@Override
public int hashCode() {
return Objects.hash(getPlayer(), getItemStack(), getInjectableContext(), getAdditionalPlayers());
}
/**
* Create PlaceholderContext of a PlaceholderInjectable parseContext.
*
* @param injectableContext The PlaceholderInjectable parseContext.
* @return The context.
*/
public static PlaceholderContext of(@NotNull final PlaceholderInjectable injectableContext) {
return new PlaceholderContext(
null,
null,
injectableContext,
Collections.emptyList()
);
}
}

View File

@@ -0,0 +1,19 @@
package com.willfp.eco.core.placeholder.context;
import org.jetbrains.annotations.NotNull;
/**
* A supplier that takes a {@link PlaceholderContext} and returns a value.
*
* @param <T> The type of value to return.
*/
public interface PlaceholderContextSupplier<T> {
/**
* Get the value.
*
* @param context The context.
* @return The value.
*/
@NotNull
T get(@NotNull PlaceholderContext context);
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.placeholder.templates;
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import java.util.regex.Pattern;
/**
* A template class for dynamic placeholders.
*/
public abstract class DynamicInjectablePlaceholder implements InjectablePlaceholder {
/**
* The placeholder pattern.
*/
private final Pattern pattern;
/**
* Create a new dynamic injectable placeholder.
*
* @param pattern The pattern.
*/
protected DynamicInjectablePlaceholder(@NotNull final Pattern pattern) {
this.pattern = pattern;
}
@Override
public @NotNull Pattern getPattern() {
return pattern;
}
@Override
public String toString() {
return "DynamicInjectablePlaceholder{" +
"pattern='" + pattern + '\'' +
'}';
}
@Override
public boolean equals(@NotNull final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof DynamicInjectablePlaceholder that)) {
return false;
}
return Objects.equals(pattern, that.getPattern());
}
@Override
public int hashCode() {
return Objects.hash(pattern);
}
}

View File

@@ -0,0 +1,73 @@
package com.willfp.eco.core.placeholder.templates;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.placeholder.RegistrablePlaceholder;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import java.util.regex.Pattern;
/**
* A template class for dynamic placeholders.
*/
public abstract class DynamicPlaceholder implements RegistrablePlaceholder {
/**
* The plugin.
*/
private final EcoPlugin plugin;
/**
* The placeholder pattern.
*/
private final Pattern pattern;
/**
* Create a new dynamic placeholder.
*
* @param plugin The plugin.
* @param pattern The pattern.
*/
protected DynamicPlaceholder(@NotNull final EcoPlugin plugin,
@NotNull final Pattern pattern) {
this.plugin = plugin;
this.pattern = pattern;
}
@Override
public @NotNull Pattern getPattern() {
return pattern;
}
@NotNull
@Override
public EcoPlugin getPlugin() {
return plugin;
}
@Override
public String toString() {
return "DynamicPlaceholder{" +
"plugin='" + plugin + '\'' +
"pattern='" + pattern + '\'' +
'}';
}
@Override
public boolean equals(@NotNull final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof DynamicPlaceholder that)) {
return false;
}
return Objects.equals(pattern, that.getPattern())
&& Objects.equals(plugin, that.getPlugin());
}
@Override
public int hashCode() {
return Objects.hash(pattern, plugin);
}
}

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