Compare commits

..

442 Commits

Author SHA1 Message Date
Auxilor
32c416ef8e Fixed bugs 2021-11-11 13:09:09 +00:00
Auxilor
a1e22540d4 Improved async warning 2021-11-11 13:05:36 +00:00
Auxilor
1b66843992 Codestyle 2 2021-11-11 13:03:07 +00:00
Auxilor
55d316cb9d Codestyle 2021-11-11 12:59:22 +00:00
Auxilor
ac7a47a0f7 Merge remote-tracking branch 'origin/master' into develop 2021-11-11 12:45:06 +00:00
Will FP
70cd23d39a Merge pull request #51
Updated Lands integration a bit && Renamed async-display.enabled to async-display.always-enabled
2021-11-11 12:44:39 +00:00
Auxilor
44d39c4f5f Updated README 2021-11-11 12:36:45 +00:00
Auxilor
779323e280 Updated to 6.13.6 2021-11-10 19:06:11 +00:00
Auxilor
5c8a8ca3e4 Delombok 10/10 - Removed lombok dependency, cleaned up 2021-11-10 19:05:49 +00:00
Auxilor
4e4f792bcc Delombok 9/? - Delomboked EcoPlugin 2021-11-10 19:02:38 +00:00
_OfTeN_
48ae8ebe65 Updated Lands integration a bit
Renamed async-display.enabled to async-display.always-enabled
2021-11-10 22:00:47 +03:00
Auxilor
f8c65898d8 Delombok 8/? - Delomboked packets, PluginDependent, and Prerequisite 2021-11-10 18:57:44 +00:00
Auxilor
dbe514f97c Delombok 6/? - Delomboked items, GUIs, recipes, and tuples 2021-11-10 18:56:12 +00:00
Auxilor
b244be6dd6 Delombok 6/? - Delomboked events and extensions 2021-11-10 18:49:14 +00:00
Auxilor
4870f7f0d1 Delombok 5/? - Delomboked data 2021-11-10 18:44:56 +00:00
Auxilor
27888da33a Delombok 4/? - Delomboked config 2021-11-10 18:44:04 +00:00
Auxilor
33c132065d Delombok 3/? - Delomboked commands 2021-11-10 18:42:50 +00:00
Auxilor
ec09dbddf4 Delombok 2/? - Removed @UtilityClas 2021-11-10 18:39:30 +00:00
Auxilor
3811b01e81 Delomboked Utils 2021-11-10 18:31:38 +00:00
Auxilor
f883f8fe1d Updated to 6.13.5 2021-11-08 21:09:44 +00:00
Auxilor
80f43238e0 Fixed major fuckup 2021-11-08 21:09:33 +00:00
Auxilor
18e7548c23 Updated to 6.13.4 2021-11-08 14:05:32 +00:00
Auxilor
40020b0503 Added Extension#onAfterLoad and Extension#onReload 2021-11-08 14:04:24 +00:00
Auxilor
830f92bbdb Dropped Velocity and worked on bungee 2021-11-08 13:15:42 +00:00
Auxilor
c6e39e89fd Updated to 6.13.3 2021-11-08 10:58:26 +00:00
Auxilor
7d38d7db15 Saved player name changes 2021-11-08 10:58:18 +00:00
Auxilor
a6f139c47e Fixed plugin.yml 2021-11-05 14:40:56 +00:00
Auxilor
1bae159f94 Added velocity data listener 2021-11-05 14:30:43 +00:00
Auxilor
43d2835087 Prerequisite changes 2021-11-05 14:18:35 +00:00
Auxilor
cb2d4d6a34 Added ServerDisconnectEvent listener 2021-11-05 14:16:41 +00:00
Auxilor
9bb73d8e90 Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	eco-core/core-plugin/src/main/kotlin/com/willfp/eco/spigot/data/storage/MySQLDataHandler.kt
2021-11-05 14:06:22 +00:00
Auxilor
86c4867206 Added BungeeDataListener and IridiumSkyblock support 2021-11-04 20:28:47 +00:00
Auxilor
43e13248d6 SQL changes (Please be done) and Antigrief changes 2021-11-04 20:15:26 +00:00
Auxilor
f6ff45228a Merge branch 'master' into develop 2021-11-04 20:02:29 +00:00
Will FP
af1c20f5c5 Merge pull request #49
Added DeluxeCombat integration
2021-11-04 20:01:59 +00:00
Auxilor
9ac564c345 Finally got exposed to shut up 2021-11-04 20:00:13 +00:00
Auxilor
857d51a7a1 Added PersistentDataKey#values 2021-11-04 19:16:38 +00:00
Auxilor
ab5f8cee5a Cleaned up DataHandler 2021-11-04 19:04:59 +00:00
Auxilor
bdd518b280 More Persistent Data changes 2021-11-04 19:00:47 +00:00
_OfTeN_
494c1a87b2 Added DeluxeCombat integration 2021-11-04 19:30:16 +03:00
Auxilor
f78f92b5f6 Fixed writing 2021-11-04 15:26:31 +00:00
Auxilor
048b56c58c Disabled Exposed logging 2021-11-04 14:06:09 +00:00
Auxilor
75dec2bf49 Re-added writeSafely to optionally specify predefined player ResultRow 2021-11-04 13:36:35 +00:00
Auxilor
7119da13b7 Bug Fixes 2021-11-04 13:32:23 +00:00
Auxilor
6a8637922b More SQL changes 2021-11-04 13:15:21 +00:00
Auxilor
abce7b898c Changed shutdown order 2021-11-04 13:02:23 +00:00
Auxilor
562d7f382c Updated to 6.13.2 2021-11-04 12:59:52 +00:00
Auxilor
c72b15c3a6 Several performance and stability improvements 2021-11-04 12:57:39 +00:00
Auxilor
54b7e99c82 Updated to 6.13.1 2021-11-03 11:32:41 +00:00
Auxilor
4b6a0ee05d Added option to blacklist inventory types from async display, fixing anvils 2021-11-03 11:32:31 +00:00
Auxilor
89e5d8898b Merge branch 'master' into develop
# Conflicts:
#	eco-core/core-plugin/src/main/resources/config.yml
2021-11-03 11:00:25 +00:00
Auxilor
08c14f4def Cleaned up BentoBox 2021-11-02 19:28:19 +00:00
Auxilor
0fa6f972c0 Fixed BentoBox 2021-11-02 19:26:34 +00:00
Auxilor
8837fecfa0 Added support for BentoBox 2021-11-02 19:24:34 +00:00
Auxilor
af1841770e (Hopefully) fixed HologramCMI 2021-11-02 18:54:21 +00:00
Auxilor
1d85dbf08d Altered rate limit settings 2021-11-02 18:52:57 +00:00
Auxilor
ba9812534a Increased timeframe to 2 2021-11-02 18:46:28 +00:00
Auxilor
1f95a33385 Added log errors option for async display 2021-11-02 18:39:29 +00:00
Auxilor
bc652a8154 MySQLDataHandler changes 2021-11-02 18:37:01 +00:00
Auxilor
0c2e1f0cae Fixed ServerUtils 2021-11-02 18:29:17 +00:00
Auxilor
39d6eb7f9a Updated to 6.13.0 2021-11-02 18:17:57 +00:00
Auxilor
61bae6de55 Rearranged config.yml 2021-11-02 18:17:40 +00:00
Auxilor
86f230c836 Added in config.yml warning 2021-11-02 17:46:47 +00:00
Auxilor
aa4ac4c6d1 Added option to set rate limit timeframe 2021-11-02 17:44:57 +00:00
Auxilor
7141b12e95 Removed redundant explicit type 2021-11-02 17:42:27 +00:00
Auxilor
2382548629 Added in rate limiting for PacketWindowItems.kt 2021-11-02 17:39:41 +00:00
Auxilor
0c4bd182f7 Ignored async exceptions in PacketWindowItems.kt 2021-11-02 17:09:48 +00:00
Auxilor
e90e053b45 Added emergency async display and ServerUtils 2021-11-02 16:50:04 +00:00
Auxilor
742c1abb00 Cleaned up async display 2021-11-02 14:10:57 +00:00
Auxilor
c0686ca386 Added guava and asynchronous window items processing 2021-11-02 13:53:30 +00:00
Auxilor
db2ea7daa9 Updated to 6.12.2 2021-11-02 09:24:23 +00:00
Auxilor
ed4f0b2ab6 Fixed EconomyManager and ListUtils 2021-11-02 09:24:16 +00:00
Auxilor
6decc68d1b Updated to 6.12.1 2021-11-02 08:30:39 +00:00
Auxilor
1e061313a4 Codestyle 2021-11-02 08:30:27 +00:00
Auxilor
4762004e94 @NotNull'ed PlayerProfile#read 2021-11-02 08:29:00 +00:00
Auxilor
0d9889ef43 Fixed paste calling the callback three times 2021-11-01 21:14:56 +00:00
Auxilor
b2a23e80a1 Added missing nullable annotation 2021-11-01 21:06:50 +00:00
Auxilor
0e439db7b3 Auto-registered PersistentDataKeys 2021-11-01 21:01:57 +00:00
Auxilor
f615006b23 Added missing PlayerProfile javadoc 2021-11-01 21:00:58 +00:00
Auxilor
d952dbc61b Added ListUtils#listToFrequencyMap 2021-11-01 20:00:46 +00:00
Auxilor
d95a96f4c6 Added in support for economy via vault 2021-11-01 19:55:47 +00:00
Auxilor
33940f5778 Improved MySQLDataHandler.kt 2021-11-01 19:38:30 +00:00
Auxilor
173d04595f Removed duplicate uuid field from Players table 2021-11-01 19:04:16 +00:00
Auxilor
c7c4ca3777 Updated plugin.yml 2021-11-01 19:02:40 +00:00
Auxilor
cbf7316db9 Fixed public static variable in display 2021-11-01 18:55:01 +00:00
Auxilor
601cadd582 Fixed weird IntelliJ bug 2021-11-01 18:54:25 +00:00
Auxilor
877647db03 Fixed various codestyle issues 2021-11-01 18:53:36 +00:00
Auxilor
81196bb132 Added PotionUtils 2021-11-01 18:44:44 +00:00
Auxilor
ef701f1f86 Added BlockUtils#isPlayerPlaced 2021-11-01 18:38:58 +00:00
Auxilor
58d8f72cf5 Fixed javadoc 2021-11-01 16:21:44 +00:00
Auxilor
3abf916f18 Fixed SuperiorSkyblock2 integration 2021-11-01 16:18:31 +00:00
Auxilor
b459a746e3 Merge branch 'master' into develop
# Conflicts:
#	eco-core/core-plugin/build.gradle
2021-11-01 16:15:00 +00:00
Will FP
30c37078a2 Merge pull request #47
Added SuperiorSkyblock2 Antigrief integration
2021-11-01 16:14:35 +00:00
Auxilor
36ccfb5fc6 Fixed McmmoIntegrationImpl.kt 2021-11-01 16:13:51 +00:00
Auxilor
c84f1a060a Fixed KingdomsX version 2021-11-01 16:12:23 +00:00
Auxilor
d8d5609f6b Renamed consumer to callback 2021-11-01 16:09:23 +00:00
Auxilor
462abd46c6 Marked Handler as internal 2021-11-01 16:07:14 +00:00
Auxilor
e89008cf97 Fixed SkullUtils#getSkullTexture 2021-11-01 16:00:38 +00:00
Auxilor
d34e43797d Registering a duplicate key will now replace the existing key 2021-11-01 15:51:22 +00:00
Auxilor
63ee83c795 Added Essentials / CMI AFK integrations 2021-11-01 15:50:10 +00:00
Auxilor
2eec17698e Updated paste 2021-11-01 15:34:02 +00:00
Auxilor
ad52c2a086 Improved EcoPlayerProfileHandler.kt 2021-11-01 15:31:10 +00:00
Auxilor
6e482cccda Registered player name key 2021-11-01 15:24:11 +00:00
Auxilor
899b4297f7 Added saved display name utils with persistent meta 2021-11-01 14:17:29 +00:00
Auxilor
ceb95e20b5 Added in hologram integrations for CMI/GHolo/HolographicDisplays 2021-11-01 14:09:41 +00:00
Auxilor
bdfeb9a0ab Updated to 6.12.0 2021-11-01 13:29:03 +00:00
Auxilor
e0707e2afa Added missing handler implementations 2021-11-01 13:28:51 +00:00
Auxilor
e8048f5a0a Added in persistent data storage 2021-11-01 13:25:14 +00:00
0ft3n
a36018e31a Merge branch 'Auxilor:master' into master 2021-10-27 22:45:29 +03:00
_OfTeN_
a34c63161d Added SuperiorSkyblock2 Antigrief integration 2021-10-27 22:44:45 +03:00
Auxilor
2eb350977c Updated to 6.11.2 2021-10-26 19:51:21 +01:00
Auxilor
8a89a63c5f PacketSetCreativeSlot and PacketSetSlot now clear frames 2021-10-26 19:51:06 +01:00
Auxilor
5c26e6e782 DisplayFrames now include the ItemStacks as well as the hashes: larger memory footprint should be fine with ttl and frequent clearing 2021-10-26 19:49:49 +01:00
Auxilor
f88b914fa6 Fixed gradient modifier issues 2021-10-26 19:41:38 +01:00
Auxilor
15ff6b3ea3 Merge branch 'master' into develop 2021-10-26 19:28:37 +01:00
Auxilor
b14eed696c Added alice anticheat support 2021-10-26 19:21:34 +01:00
Auxilor
cffae33c87 StringUtils change 2021-10-26 19:11:01 +01:00
Auxilor
adf6d1c800 Updated to 6.11.1 2021-10-15 10:27:58 +01:00
Auxilor
2b7c8962e7 Merge remote-tracking branch 'origin/master' 2021-10-15 10:27:51 +01:00
Auxilor
b60cbfce2c Fixed unpredicatable config behaviour 2021-10-15 10:27:44 +01:00
Auxilor
910ad18703 Updated towny 2021-10-15 10:25:32 +01:00
Auxilor
8a4a71ebc1 Updated lands integration 2021-10-15 10:24:18 +01:00
Will FP
2e748b1723 Update README.md 2021-10-12 20:12:09 +01:00
Auxilor
cb28726bc3 Cleaned up Multiverse-Inventories integration 2021-10-12 12:04:52 +01:00
Auxilor
c0c20d63bb Merge remote-tracking branch 'origin/master' into develop 2021-10-12 11:59:26 +01:00
Will FP
3b11610c45 Merge pull request #44
Multiverse-Inventories integration
2021-10-12 11:58:41 +01:00
Auxilor
232048022e Added extra config constructors 2021-10-12 11:51:22 +01:00
Auxilor
9abfe0ab01 Updated to 6.11.0 2021-10-12 11:36:07 +01:00
Auxilor
e7ac05278c Added lots of display frame options 2021-10-12 11:31:02 +01:00
Auxilor
85ba40c279 Added PluginLike, allowing extensions to have their own configs 2021-10-12 11:17:58 +01:00
_OfTeN_
1acf86492e Added Multiverse-Inventories integration (additional ArmorChangeEvent call for all effect to reapply for new players inventory. 2021-10-12 11:09:09 +03:00
Auxilor
4609d38389 Updated to 6.10.1 2021-10-08 10:50:57 +01:00
Auxilor
2d6836cc93 Moved frames to only affect player inventories 2021-10-08 10:50:47 +01:00
Auxilor
8e21617345 Finished up ChatComponent 2021-10-07 20:50:15 +01:00
Auxilor
2f99a17d02 TODO: Finish Components 2021-10-07 16:16:07 +01:00
Auxilor
34edf1d7b4 Switched mapChildrenDeep to mapChildren 2021-10-07 16:01:49 +01:00
Auxilor
be85ba5706 Fixed Stack Overflow 2021-10-07 15:44:59 +01:00
Auxilor
b817b00ca4 Updated ChatComponent to include siblings 2021-10-07 15:37:35 +01:00
Auxilor
ee02528abc Downgraded Reflections 2021-10-07 15:07:24 +01:00
Auxilor
794948c8f9 Altered Reflections constructor (again) 2021-10-07 15:01:35 +01:00
Auxilor
7c70dec2e7 Added AntigriefManager#unregister 2021-10-07 15:00:54 +01:00
Auxilor
d1f20b7111 Updated Reflections constructor 2021-10-07 14:49:52 +01:00
Auxilor
595751a094 Fixed build warnings 2021-10-07 14:45:42 +01:00
Auxilor
8231afdcbf Fixed dependency-related issues (Reflections) 2021-10-07 14:39:44 +01:00
Auxilor
4f55d66096 Updated to 6.10.0 2021-10-07 14:36:03 +01:00
Auxilor
d350febbdc Minor change 2021-10-07 14:35:52 +01:00
Auxilor
78755b0e9a (Hopefully) massively optimized display (PacketWindowItems) with DisplayFrame.kt 2021-10-07 14:34:40 +01:00
Auxilor
63d7bdab6b Re-Added Head Database integration 2021-10-07 13:58:42 +01:00
Auxilor
344032b7e3 Added ItemProvider 2021-10-07 13:45:45 +01:00
Auxilor
3ae5c8a72c Moved ArmorEquipEvent code to kotlin, finally 2021-10-07 13:13:33 +01:00
Auxilor
e4f2bc2e39 Finally recoded remaining java in NMS to kotlin 2021-10-07 13:03:19 +01:00
Auxilor
90ba0a0391 Updated dependencies 2021-10-07 12:50:53 +01:00
Auxilor
801a3cd4f9 Merge remote-tracking branch 'origin/master' 2021-10-07 12:48:44 +01:00
Will FP
ce9cada75a Merge pull request #35
Bump ProtocolLib from 4.6.0-SNAPSHOT to 4.7.1-SNAPSHOT
2021-10-07 12:48:24 +01:00
Will FP
ae551dd0f7 Merge pull request #36
Bump junit-jupiter-engine from 5.3.1 to 5.8.1
2021-10-07 12:47:38 +01:00
Will FP
1b3dd53fb8 Merge pull request #37
Bump reflections from 0.9.12 to 0.10.1
2021-10-07 12:47:29 +01:00
Will FP
dda4224e6e Merge pull request #38
Bump lombok from 1.18.20 to 1.18.22
2021-10-07 12:47:19 +01:00
dependabot[bot]
6e14265655 Bump lombok from 1.18.20 to 1.18.22
Bumps [lombok](https://github.com/projectlombok/lombok) from 1.18.20 to 1.18.22.
- [Release notes](https://github.com/projectlombok/lombok/releases)
- [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown)
- [Commits](https://github.com/projectlombok/lombok/compare/v1.18.20...v1.18.22)

---
updated-dependencies:
- dependency-name: org.projectlombok:lombok
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-07 11:47:09 +00:00
dependabot[bot]
77fd99d215 Bump reflections from 0.9.12 to 0.10.1
Bumps [reflections](https://github.com/ronmamo/reflections) from 0.9.12 to 0.10.1.
- [Release notes](https://github.com/ronmamo/reflections/releases)
- [Commits](https://github.com/ronmamo/reflections/compare/0.9.12...0.10.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-07 11:47:01 +00:00
Will FP
cf05efc2ff Merge pull request #26
Bump kotlin-gradle-plugin from 1.5.21 to 1.5.31
2021-10-07 12:46:59 +01:00
dependabot[bot]
0e8c759a4c Bump junit-jupiter-engine from 5.3.1 to 5.8.1
Bumps [junit-jupiter-engine](https://github.com/junit-team/junit5) from 5.3.1 to 5.8.1.
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.3.1...r5.8.1)

---
updated-dependencies:
- dependency-name: org.junit.jupiter:junit-jupiter-engine
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-07 11:46:18 +00:00
Will FP
ba7bfb828b Merge pull request #30
Bump adventure-text-serializer-gson from 4.8.1 to 4.9.2
2021-10-07 12:46:13 +01:00
dependabot[bot]
8dd1239b99 Bump ProtocolLib from 4.6.0-SNAPSHOT to 4.7.1-SNAPSHOT
Bumps ProtocolLib from 4.6.0-SNAPSHOT to 4.7.1-SNAPSHOT.

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-07 11:46:04 +00:00
Will FP
edada09966 Merge pull request #31
Bump mcMMO from 2.1.157 to 2.1.202
2021-10-07 12:46:01 +01:00
Auxilor
19c300bbf3 Merge remote-tracking branch 'origin/master' 2021-10-07 12:45:45 +01:00
Will FP
4fc9c21034 Merge pull request #32
Bump Towny from 0.97.1.0 to 0.97.2.5
2021-10-07 12:45:20 +01:00
Auxilor
2366dcd293 Merge remote-tracking branch 'origin/master' 2021-10-07 12:44:48 +01:00
Auxilor
054e6a53c0 Fixed dumb Any? constraint 2021-10-07 11:51:42 +01:00
Auxilor
46f590fe3e Recoded PacketChat 2021-10-07 11:50:26 +01:00
dependabot[bot]
b46aaf547f Bump Towny from 0.97.1.0 to 0.97.2.5
Bumps [Towny](https://github.com/TownyAdvanced/Towny) from 0.97.1.0 to 0.97.2.5.
- [Release notes](https://github.com/TownyAdvanced/Towny/releases)
- [Commits](https://github.com/TownyAdvanced/Towny/compare/0.97.1.0...0.97.2.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-05 21:23:42 +00:00
dependabot[bot]
0f7125e1c8 Bump mcMMO from 2.1.157 to 2.1.202
Bumps [mcMMO](https://github.com/mcMMO-Dev/mcMMO) from 2.1.157 to 2.1.202.
- [Release notes](https://github.com/mcMMO-Dev/mcMMO/releases)
- [Changelog](https://github.com/mcMMO-Dev/mcMMO/blob/master/Changelog.txt)
- [Commits](https://github.com/mcMMO-Dev/mcMMO/commits)

---
updated-dependencies:
- dependency-name: com.gmail.nossr50.mcMMO:mcMMO
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-05 21:20:47 +00:00
dependabot[bot]
6cb99819f3 Bump adventure-text-serializer-gson from 4.8.1 to 4.9.2
Bumps [adventure-text-serializer-gson](https://github.com/KyoriPowered/adventure) from 4.8.1 to 4.9.2.
- [Release notes](https://github.com/KyoriPowered/adventure/releases)
- [Commits](https://github.com/KyoriPowered/adventure/compare/v4.8.1...v4.9.2)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-text-serializer-gson
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-04 21:34:25 +00:00
Auxilor
a018a1fca5 Cleaned up dependencies 2021-10-03 18:57:52 +01:00
Auxilor
8a7b8f2b03 Cleaned up dependencies 2021-10-03 18:56:56 +01:00
Auxilor
abf3dc1e9e Updated to 6.9.4 2021-10-03 18:56:27 +01:00
Auxilor
e92cc41be6 Fixed BukkitAudiences bug on outdated versions of paper 2021-10-03 17:37:45 +01:00
Auxilor
49570c841b Reverted publication changes 2021-10-03 13:00:01 +01:00
Auxilor
9aa465844d Finally fixed Adventure + MiniMessage shading / Dependency issues 2021-10-03 12:54:38 +01:00
Auxilor
a692fbee01 Moved Adventure to api implementation, Removed GriefDefender 2021-10-03 11:51:55 +01:00
Auxilor
4223e8f17a Updated to 6.9.2 2021-10-02 12:20:37 +01:00
Auxilor
5f26b23a53 Adventure bug fixing 2021-10-02 12:20:27 +01:00
Auxilor
c8c179981c Adventure bug fixing 2021-10-02 12:20:05 +01:00
dependabot[bot]
4bb8bb62f9 Bump kotlin-gradle-plugin from 1.5.21 to 1.5.31
Bumps [kotlin-gradle-plugin](https://github.com/JetBrains/kotlin) from 1.5.21 to 1.5.31.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.5.31/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.5.21...v1.5.31)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-gradle-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-01 21:29:48 +00:00
Auxilor
c1b3bec67c Moved adventure off to implementation and relocated 2021-10-01 18:57:00 +01:00
Auxilor
f2535ce75c Updated to 6.9.1 2021-10-01 18:33:14 +01:00
Auxilor
049d64821e Added adventure-api to plugin.yml 2021-10-01 18:32:57 +01:00
Auxilor
bf5766e61c Fixed minimessage bug 2021-10-01 15:32:38 +01:00
Auxilor
38da5fe6d1 Fixed adventure audience bug 2021-10-01 14:05:16 +01:00
Auxilor
e16649873b Moved MiniMessage to being shaded 2021-10-01 13:56:29 +01:00
Will FP
a3b0b4f847 Updated kotlin lib loader to 1.5.31 2021-10-01 12:09:08 +01:00
Will FP
d9f1ddd188 Merge pull request #19 from Auxilor/dependabot/gradle/me.clip-placeholderapi-2.10.10
Bump placeholderapi from 2.10.9 to 2.10.10
2021-10-01 12:07:54 +01:00
Will FP
14a4d9291b Merge pull request #20 from Auxilor/dependabot/gradle/org.jetbrains.kotlin-kotlin-stdlib-1.5.31
Bump kotlin-stdlib from 1.5.21 to 1.5.31
2021-10-01 12:07:40 +01:00
dependabot[bot]
6630044546 Bump placeholderapi from 2.10.9 to 2.10.10
Bumps placeholderapi from 2.10.9 to 2.10.10.

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-01 11:07:15 +00:00
Will FP
1043981fe4 Merge pull request #22 from Auxilor/dependabot/gradle/com.github.TechFortress-GriefPrevention-16.17.1
Bump GriefPrevention from 16.14.0 to 16.17.1
2021-10-01 12:06:54 +01:00
Will FP
fb0b7c52cf Merge pull request #18 from Auxilor/dependabot/gradle/org.spigotmc-spigot-api-1.17.1-R0.1-SNAPSHOT
Bump spigot-api from 1.17-R0.1-SNAPSHOT to 1.17.1-R0.1-SNAPSHOT
2021-10-01 12:06:26 +01:00
dependabot[bot]
74e5464f7d Bump GriefPrevention from 16.14.0 to 16.17.1
Bumps [GriefPrevention](https://github.com/TechFortress/GriefPrevention) from 16.14.0 to 16.17.1.
- [Release notes](https://github.com/TechFortress/GriefPrevention/releases)
- [Commits](https://github.com/TechFortress/GriefPrevention/compare/16.14.0...16.17.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-01 11:02:04 +00:00
dependabot[bot]
2ad1ff4cdb Bump kotlin-stdlib from 1.5.21 to 1.5.31
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.5.21 to 1.5.31.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.5.31/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.5.21...v1.5.31)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-stdlib
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-01 11:01:47 +00:00
dependabot[bot]
2d47c18be6 Bump spigot-api from 1.17-R0.1-SNAPSHOT to 1.17.1-R0.1-SNAPSHOT
Bumps spigot-api from 1.17-R0.1-SNAPSHOT to 1.17.1-R0.1-SNAPSHOT.

---
updated-dependencies:
- dependency-name: org.spigotmc:spigot-api
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-01 11:00:17 +00:00
Will FP
69e67be436 Create dependabot.yml 2021-10-01 11:59:52 +01:00
Auxilor
c144723d5b Updated to 6.9.0 2021-10-01 11:13:01 +01:00
Auxilor
108375f545 Added formatToComponent throughout StringUtils 2021-10-01 11:12:48 +01:00
Auxilor
83d5b3e96e Closed adventure on disable 2021-10-01 11:09:25 +01:00
Auxilor
37e09a470e Added config thread-safety (hopefully) 2021-10-01 11:05:45 +01:00
Auxilor
1f064110b7 Added MiniMessage markdown (discord flavor) support 2021-10-01 11:01:40 +01:00
Auxilor
94a0b4de5d Moved order of StringUtils#format 2021-10-01 10:57:46 +01:00
Auxilor
8a68666f86 Added adventure into eco 2021-10-01 10:56:05 +01:00
Auxilor
2c218d1088 Internal menu changes 2021-10-01 10:38:46 +01:00
Auxilor
3fa95d82a6 Fixed gradient div by zero exception 2021-10-01 10:34:47 +01:00
Auxilor
9648b42c4d Added MiniMessage support to StringUtils#format 2021-10-01 10:33:09 +01:00
Auxilor
66887f0a3a Updated to 6.8.6 2021-09-30 12:22:16 +01:00
Auxilor
410cdfe7e3 Improved WorldGuard code 2021-09-30 12:22:03 +01:00
Auxilor
bbffdc7e23 Improved WorldGuard code 2021-09-30 12:21:55 +01:00
Will FP
0d267e2bec Merge pull request #16
Fixed WorldGuard AntiGrief manager using damage-animals flag only
2021-09-30 12:15:38 +01:00
Auxilor
578256f89b Updated to 6.8.5 2021-09-29 10:32:24 +01:00
Auxilor
90ecbfce00 Added use-lower-protocollib-priority 2021-09-29 10:32:12 +01:00
_OfTeN_
9945704338 Fixed WorldGuard AntiGrief manager using damage-animals flag only 2021-09-29 00:42:53 +03:00
Auxilor
5c7a7876d8 Improved GriefDefender support 2021-09-27 14:11:42 +01:00
Will FP
94df0e67a6 Merge pull request #15
GriefDefender support
2021-09-27 14:07:56 +01:00
_OfTeN_
92c4e62709 Hopefully added GriefDefender support 2021-09-26 15:00:05 +03:00
Auxilor
e094a1e934 Merge remote-tracking branch 'origin/master' 2021-09-24 09:50:12 +01:00
Auxilor
26c07a20e7 Updated to 6.8.3 2021-09-24 09:50:05 +01:00
Auxilor
ad68e1efef Fixed legacyToJson nullability bug 2021-09-24 09:49:54 +01:00
Auxilor
d8c3a3befa Removed redundant suppression 2021-09-21 19:18:01 +01:00
Auxilor
aa52dcdf94 Updated to 6.8.2 2021-09-20 17:01:39 +01:00
Auxilor
9d3ba7ea88 Improved towny integration 2021-09-20 17:01:16 +01:00
Auxilor
e2b417af74 Updated eco resource ID 2021-09-19 11:14:03 +01:00
Auxilor
77394d3038 Updated to 6.8.1 2021-09-19 11:12:45 +01:00
Auxilor
fcc7f82b38 Removed references to spigotmc. eco will now check polymart for updates 2021-09-19 11:11:01 +01:00
Auxilor
396f4dac44 Added more gradient syntaxes 2021-09-18 17:48:41 +01:00
Auxilor
3341093735 Fixed non-final params 2021-09-17 19:56:54 +01:00
Auxilor
714d04e48f Added missing javadoc 2021-09-17 19:55:29 +01:00
Auxilor
73b7ccea3a Merge branch 'dev'
# Conflicts:
#	gradle.properties
2021-09-17 19:53:40 +01:00
Auxilor
606bf8fcd2 Updated to 6.8.0 2021-09-17 19:53:24 +01:00
Auxilor
fbbf893d64 Added requirements into eco 2021-09-17 19:52:49 +01:00
Auxilor
36001373eb Removed redundant default methods from DisplayHandler 2021-09-16 15:07:37 +01:00
Auxilor
9ac34288eb EcoDisplayHandler.kt changes 2021-09-16 15:04:24 +01:00
Auxilor
6345d1fe92 Moved display impl code off to internals 2021-09-16 14:56:56 +01:00
Auxilor
a7fa0ecf26 Updated to 6.7.5 2021-09-14 08:35:02 +01:00
Auxilor
a65f16cfac Improved PR 2021-09-14 08:34:51 +01:00
Will FP
49965c091b Merge pull request #13
Added silent lightning option
2021-09-14 08:33:38 +01:00
Auxilor
f9bc2aba99 Merge remote-tracking branch 'origin/master' into dev 2021-09-13 12:12:33 +01:00
Auxilor
5627582bd5 Updated to 6.7.4 2021-09-13 10:10:14 +01:00
Auxilor
ab8065d06e Fixed ShopGUIPlus softdepend 2021-09-13 10:09:54 +01:00
Auxilor
444764e481 Fixed ShopGUIPlus integration not working 2021-09-13 10:09:34 +01:00
_OfTeN_
c240e94a6b Removed NPE warning in the console if Oraxen returns null on OraxenItems#getIdByItem 2021-09-12 23:03:04 +03:00
_OfTeN_
9da28a1dff Added boolean silent param to LightningUtils#strike method to make a lightning with sound only played locally for nearest players 2021-09-12 22:45:41 +03:00
Auxilor
cf3c1f8394 Added destructuring support to pairs 2021-09-10 13:48:50 +01:00
Auxilor
f98befbdce Used FastItemStack on display reverting 2021-09-09 13:03:24 +01:00
Auxilor
d0d8ea07e4 Added JSON updatable configs 2021-09-08 10:59:11 +01:00
Auxilor
109347a601 Updated to 6.7.3 2021-09-06 15:07:15 +01:00
Auxilor
43bef762bf Removed buggy headdb integration 2021-09-06 15:07:06 +01:00
Auxilor
69a2e0e247 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	eco-api/src/main/java/com/willfp/eco/core/items/args/EnchantmentArgParser.java
#	eco-api/src/main/java/com/willfp/eco/core/items/args/LookupArgParser.java
#	eco-api/src/main/java/com/willfp/eco/core/items/args/TextureArgParser.java
2021-09-06 15:05:32 +01:00
Auxilor
874a9b4f32 Updated to 6.7.2 2021-09-05 12:53:33 +01:00
Auxilor
5690221c27 Fixed crafting 2021-09-05 12:53:22 +01:00
Auxilor
f19b143804 Added validation to testable items 2021-09-05 12:02:35 +01:00
Auxilor
10a313bef5 Added missing javadoc 2021-09-05 11:08:05 +01:00
Auxilor
9ae40ae09e Removed redundant nullability 2021-09-05 11:07:15 +01:00
Auxilor
7b4e1d8d24 Updated to 6.7.1 2021-09-05 11:05:33 +01:00
Auxilor
7035280731 Item checks and improvements related to EmptyTestableItem 2021-09-05 11:05:23 +01:00
Auxilor
a1e3d53cd2 Janky HeadDB fix 2021-09-04 16:44:15 +01:00
Auxilor
d7885f05c3 Optimised placeholders 2021-09-04 13:59:46 +01:00
Auxilor
415c425097 Fixed bugs 2021-09-04 11:03:04 +01:00
Auxilor
cb4d992e7d Added option to create custom lang.yml and config.yml implementations 2021-09-04 10:59:49 +01:00
Auxilor
cb64d088d1 Added nullability annotations to all utility methods 2021-09-04 10:53:06 +01:00
Auxilor
bbbf19c041 Added missing javadoc 2021-09-03 13:03:28 +01:00
Auxilor
61ace5c8e5 Updated to 6.7.0 2021-09-03 12:50:23 +01:00
Auxilor
94b73ef35c Improved Arg Parser javadoc 2021-09-03 12:49:59 +01:00
Auxilor
5cfc2068e7 Added arg parser lookup system 2021-09-03 12:47:23 +01:00
Auxilor
0ce7d1dd6c Added texture:<base64> to Items.lookup 2021-09-03 12:28:03 +01:00
Auxilor
19eefaf879 Improved Items.lookup javadoc 2021-09-03 11:54:48 +01:00
Auxilor
1ebf7fb875 Added Head Database integration 2021-09-03 11:45:34 +01:00
Auxilor
e8afd15d80 Updated to 6.6.4 2021-09-02 18:55:49 +01:00
Auxilor
d024c9238e Switched TestableStack display to only show recipe lore in recipes 2021-09-02 18:55:37 +01:00
Auxilor
1356bd1f26 ItemsAdder fix 2021-09-02 18:50:01 +01:00
Auxilor
407ccca5e0 TestableStack changes don't stop ever 2021-09-02 11:49:48 +01:00
Auxilor
82de602d47 Hopefully fixed crafting exploit 2021-09-02 10:53:14 +01:00
Auxilor
b0873112af Added ItemsAdder and Oraxen to plugin.yml 2021-09-02 10:50:40 +01:00
Auxilor
3a0b81b7de Updated to 6.6.3 2021-09-02 10:50:12 +01:00
Auxilor
5142b9ce92 More Items#lookup improvements 2021-09-02 10:46:25 +01:00
Auxilor
9403a1cbcb Marked item:amount system as legacy and replaced it with item amount 2021-09-02 10:42:29 +01:00
Auxilor
e4ebea354d Added ItemsAdder support 2021-09-02 10:35:03 +01:00
Auxilor
d32b31f1e5 Updated to 6.6.2 2021-09-01 15:35:57 +01:00
Auxilor
384657f1dc Fixed menu inventory registration memory leak 2021-09-01 15:35:33 +01:00
Auxilor
7c9d226bc3 Updated to 6.6.1 2021-08-31 14:52:52 +01:00
Auxilor
031401bb8e Added option to lang.yml 2021-08-31 14:52:37 +01:00
Auxilor
1a5c429b67 Fixed villager trade display with players 2021-08-31 14:51:45 +01:00
Auxilor
d028cf5bf3 Added ShopGuiPlus to softdepend 2021-08-29 16:35:16 +01:00
Auxilor
fdd1581ce3 Removed redundant code 2021-08-29 16:34:26 +01:00
Auxilor
3d07e10543 Fixed ItemFlag application 2021-08-29 16:33:31 +01:00
Auxilor
c851e35347 Added ItemFlags to FastItemStack 2021-08-29 16:32:42 +01:00
Auxilor
4cbb33b1fd More code cleanup 2021-08-29 16:03:14 +01:00
Auxilor
2ff1458772 Fixed config wrappers missing methods 2021-08-29 15:56:39 +01:00
Auxilor
e71ad9f034 Updated to 6.6.0 2021-08-29 15:51:49 +01:00
Auxilor
196a651ab3 Added ShopGuiPlus integration 2021-08-29 15:51:38 +01:00
Auxilor
253a8c24ad Improved kotlin codestyle conventions 2021-08-29 15:38:27 +01:00
Auxilor
ac265d0260 Added more formatting options 2021-08-29 15:30:25 +01:00
Auxilor
ad861b10bb Updated to 6.5.2 2021-08-23 17:14:41 +01:00
Auxilor
db5b7f89f6 Fixed null placeholder bug and improved config loading 2021-08-23 17:14:23 +01:00
Auxilor
2c33ce25c0 Merge remote-tracking branch 'origin/master' 2021-08-22 23:14:30 +01:00
Auxilor
9c3ca429c9 Fixed recipe stack bug 2021-08-22 23:14:24 +01:00
Auxilor
70e294501a Fixed enchanted books in Items.lookup modifier 2021-08-21 13:50:33 +01:00
Will FP
65a0a0ecc7 Update README.md 2021-08-21 01:22:16 +01:00
Auxilor
d4431e7569 Changes 2021-08-20 23:02:45 +01:00
Auxilor
a6191b0870 Added data read/write to menu, updated to 6.5.0, removed event deprecation 2021-08-20 22:29:25 +01:00
Auxilor
5eecef83ee Merge remote-tracking branch 'origin/master' 2021-08-20 17:35:34 +01:00
Auxilor
82a02f3738 Updated to 6.4.2 2021-08-20 17:35:30 +01:00
Auxilor
804142799b Fixed NPE 2021-08-20 17:35:20 +01:00
Will FP
e1de9b9ab3 Update README.md 2021-08-18 15:15:50 +01:00
Will FP
cc56343041 Update README.md 2021-08-18 15:15:36 +01:00
Auxilor
69d28e8bc2 Updated to 6.4.1 2021-08-15 14:34:40 +01:00
Auxilor
6878a74724 Fixed NPE 2021-08-15 14:34:19 +01:00
Auxilor
ebc76bba76 Changed display 2021-08-12 16:30:15 +01:00
Auxilor
378218b7da Minor display change 2021-08-12 16:13:59 +01:00
Auxilor
e053514b94 Added mask materials option 2021-08-12 13:56:29 +01:00
Auxilor
341a30e6da Removed unused var 2021-08-12 13:40:19 +01:00
Auxilor
70eb6d4420 Removed logging 2021-08-12 13:40:01 +01:00
Auxilor
aa368909ae Finished GUI 2021-08-12 13:38:14 +01:00
Auxilor
606a54bcf8 Your brain gets smart but your head gets dumb 2021-08-12 13:17:52 +01:00
Auxilor
7f8fb3d87b Didn't make sense not to live for fun 2021-08-12 13:00:31 +01:00
Auxilor
e97d454ff6 Fed to the rules and I hit the ground running 2021-08-12 01:51:47 +01:00
Auxilor
109b9aa3f3 And the changes start coming and they don't stop coming 2021-08-12 01:46:32 +01:00
Auxilor
4a90385b27 The gui changes don't stop 2021-08-12 01:38:20 +01:00
Auxilor
0edd50832c Even more GUI 2021-08-12 01:05:47 +01:00
Auxilor
46415268b7 More GUI 2021-08-12 00:24:35 +01:00
Auxilor
b652dbad2d Added captivator slots 2021-08-11 23:56:09 +01:00
Auxilor
50550d077a Added ? syntax to recipes 2021-08-11 23:07:25 +01:00
Auxilor
60c3b58a33 Updated to 6.3.3 2021-08-10 18:19:46 +01:00
Auxilor
7216d0b09f Fixed component serialization 2021-08-10 18:18:09 +01:00
Auxilor
97eeea8d48 Updated to 6.3.2 2021-08-10 16:18:49 +01:00
Auxilor
82061ee6a3 Added get/set repair cost methods to FastItemStack 2021-08-09 17:30:09 +01:00
Auxilor
f274b9045e Being absolutely sure 2021-08-07 23:17:39 +01:00
Auxilor
2241a5c90f I'm actually going to die 2021-08-07 23:16:59 +01:00
Auxilor
bbc38ae801 Frantic-est fixing 2021-08-07 23:08:12 +01:00
Auxilor
e77346ed62 Even frantic-er fixing 2021-08-07 23:07:06 +01:00
Auxilor
6117abca56 Frantic fixing 2021-08-07 23:00:23 +01:00
Auxilor
2e2a061ebe Updated to 6.3.1 2021-08-07 22:11:08 +01:00
Auxilor
cdc89ac397 Fixed FastItemStack 2021-08-07 22:10:54 +01:00
Auxilor
e758cebe77 Fixed FastItemStack bug 2021-08-07 22:09:50 +01:00
Auxilor
a408e3436a Fixed italic lore 2021-08-07 15:44:16 +01:00
Auxilor
3df977c1bc Fixed FastItemStack#setLore being italicised 2021-08-07 15:10:54 +01:00
Auxilor
136f1841b4 Fixed FastItemStack#setLore being italicised 2021-08-07 15:07:29 +01:00
Auxilor
1086a59a6a Added message about deprecated events 2021-08-07 14:02:52 +01:00
Auxilor
d9147f9918 Changed bStats message 2021-08-07 13:44:21 +01:00
Auxilor
d144df4048 Fixed proxy interface package 2021-08-07 13:33:58 +01:00
Auxilor
061f77e911 Fixed 1.16 proxy package 2021-08-07 13:32:44 +01:00
Auxilor
5cebe2fce8 Moved metric handler 2021-08-07 13:27:12 +01:00
Auxilor
1e712dcae6 Skull.kt now uses lateinit var 2021-08-07 13:24:36 +01:00
Auxilor
09d444da58 Added format cache to yaml configs 2021-08-07 13:18:36 +01:00
Auxilor
09f45c0ab5 Cleaned up FastItemStack 2021-08-07 13:11:09 +01:00
Auxilor
f64d69f084 Switched proxy interfaces to kotlin 2021-08-07 13:02:44 +01:00
Auxilor
86a948738f Moved EcoProxyFactory to kotlin, removing java from eco-backend 2021-08-07 02:29:36 +01:00
Auxilor
8f9c5e7ed8 Moved most 1.16.5 proxies off to kotlin 2021-08-06 23:27:30 +01:00
Auxilor
ae897b7493 Moved most 1.17 proxies to kotlin 2021-08-06 23:22:32 +01:00
Auxilor
f1a7c9d50e Moved FastItemStackUtils to companion object 2021-08-06 23:16:53 +01:00
Auxilor
83ee8fe4cd Fixed 1.17 mapping bug with kotlin 2021-08-06 23:14:25 +01:00
Auxilor
465f885e22 Fixed kotlin bugs 2021-08-06 23:09:47 +01:00
Auxilor
d4141735a9 Moved 1_17_R1 NMSFastItemStack to kotlin for testing reasons 2021-08-06 22:47:26 +01:00
Auxilor
b9b4ce1937 Fixed NumberUtils 2021-08-06 22:31:51 +01:00
Auxilor
56234e6c83 Added tests for NumberUtilsTest 2021-08-06 22:22:18 +01:00
Auxilor
2dda34097e Fixed .gitignore 2021-08-06 22:02:34 +01:00
Auxilor
155a349569 Removed saveAllConfigs on disable 2021-08-06 22:00:04 +01:00
Auxilor
ce231934a3 Fixed DropManager.kt 2021-08-06 21:53:19 +01:00
Auxilor
5cbb7bfe47 Added warnings to servers without bStats 2021-08-06 21:49:12 +01:00
Auxilor
06e0ec0295 Updated bStats 2021-08-06 21:30:29 +01:00
Auxilor
02ed583674 Updated gitignore 2021-08-06 20:21:36 +01:00
Auxilor
8e4cbdd1aa Kotlin cleaning 2021-08-06 20:20:50 +01:00
Auxilor
8828f8e45d Moved EcoConfigHandler to kotlin 2021-08-06 20:05:57 +01:00
Auxilor
d15524ee9e Moved extension loader to kotlin 2021-08-06 19:57:38 +01:00
Auxilor
d45e66d71e Kotlin cleanup 2021-08-06 19:43:48 +01:00
Auxilor
6b1dde7540 Removed lombok from kotlin 2021-08-06 17:40:00 +01:00
Auxilor
abf2964c48 Fixed kotlin class names 2021-08-06 17:37:49 +01:00
Auxilor
db51c4c761 Moved integrations to kotlin 2021-08-06 17:28:21 +01:00
Auxilor
cbb574acec Switched most event listeners to kotlin 2021-08-06 17:25:34 +01:00
Auxilor
93c044ef09 Fixed kotlin errors and warnings 2021-08-06 16:46:48 +01:00
Auxilor
1cc39fe40a Fixed EcoMenuBuilder.kt 2021-08-06 16:45:10 +01:00
Auxilor
edfd561fcd EcoMenu error fix 2021-08-06 16:41:29 +01:00
Auxilor
bd7f22cb02 Fixed kotlin errors 2021-08-06 16:40:47 +01:00
Auxilor
3233bad307 More backend kotlinining 2021-08-06 16:38:12 +01:00
Auxilor
3cefcbe0bb Switched most internals to kotlin 2021-08-06 16:15:29 +01:00
Auxilor
49bce53724 Rename .java to .kt 2021-08-06 16:15:29 +01:00
Auxilor
2b86159b30 Fixed handler 2021-08-06 03:15:50 +01:00
Auxilor
d028511a48 Fixed kotlin being shaded 2021-08-06 03:14:43 +01:00
Auxilor
5ad1ef33b8 Kotlining 2021-08-06 03:10:00 +01:00
Auxilor
634d6194d6 Began kotlin 2021-08-06 03:08:00 +01:00
Auxilor
7f7eb4f45a Fixed trailing spaces 2021-08-05 00:43:18 +01:00
Auxilor
bd90ae996b Fixed deprecation warnings 2021-08-04 17:52:09 +01:00
Auxilor
1bc57dec08 Fixed annotations 2021-08-04 15:22:52 +01:00
Auxilor
ce44d40f0f Reverted BlockUtils 2021-08-04 14:53:16 +01:00
Auxilor
68824fb4d0 Updated gradient regexes 2021-08-04 14:38:18 +01:00
Auxilor
fd96b0d2cf Fixed HAS_VAULT 2021-08-04 14:36:24 +01:00
Auxilor
2669569e81 Removed vault and loadbefore 2021-08-04 14:36:10 +01:00
Auxilor
067f740bcc Improved ArmorEquipEvent javadoc 2021-08-04 14:29:17 +01:00
Auxilor
2ce96ab0b1 Added FastItemStack#unwrap again 2021-08-04 14:27:45 +01:00
Auxilor
027f9be194 Definitely not code smells 2021-08-04 00:25:07 +01:00
Auxilor
a09018d1f0 Added vault and Prerequisite#HAS_VAULT 2021-08-03 23:55:13 +01:00
Auxilor
a1da83173d Deprecated ArmorEquipEvent 2021-08-03 23:43:17 +01:00
Auxilor
8ac30283f8 Deprecated ArmorEquipEvent 2021-08-03 23:42:58 +01:00
Auxilor
6099b5d64d Removed javadoc for private methods 2021-08-03 23:35:53 +01:00
Auxilor
19d2e0788b Added PlaceholderEntry#register 2021-08-03 23:34:39 +01:00
Auxilor
1b223b3736 Added null safety to Customitem 2021-08-03 23:30:31 +01:00
Auxilor
d6d1f01704 FastItemStack refactoring 2021-08-03 20:47:01 +01:00
Auxilor
51231939c0 Added <gradient:#> support 2021-08-03 19:59:21 +01:00
Auxilor
72fb20ecd9 Switched to adventure for legacy / json conversions 2021-08-03 19:57:52 +01:00
Auxilor
58a386922c Removed FastItemStack benchmarks 2021-08-03 19:19:06 +01:00
Auxilor
12824c7f6c FastItemStack cache changes 2021-08-03 19:10:22 +01:00
Auxilor
b5236b8db6 More FastItemStack 2021-08-03 18:54:45 +01:00
Auxilor
3ffbb861d1 More FastItemStack changes 2021-08-03 17:00:49 +01:00
Auxilor
f8fad15f0b More FastItemStack changes 2021-08-03 16:48:13 +01:00
Auxilor
a0e96fca35 Fixed typo 2021-08-03 16:21:19 +01:00
Auxilor
6cf9a53a65 Continued FastItemStack development 2021-08-03 16:20:05 +01:00
Auxilor
a4909453d7 Codestyle 2021-08-01 23:39:04 +01:00
Auxilor
a10666f792 Renamed to EcoFastItemStack 2021-08-01 23:38:42 +01:00
Auxilor
a845cda9ed Fixed mapped jar output issues 2021-08-01 23:18:06 +01:00
Auxilor
ed5f1ccb5e Switched to 1.17 mojang mappings and began FastItemStack 2021-08-01 22:09:18 +01:00
Auxilor
c6e59e1d62 Updated to 6.3.0 2021-08-01 19:16:43 +01:00
Auxilor
ed24b6278e Began FastItemStack shti 2021-08-01 19:16:33 +01:00
Auxilor
3aea7b4077 Fixed CombatLogX codestyle 2021-08-01 17:00:04 +01:00
Auxilor
f53c29cd56 Updated to 6.2.1 2021-07-31 16:59:46 +01:00
Auxilor
6845152a09 Fixed extension classloader bug with unclosed classloaders 2021-07-31 16:59:33 +01:00
Auxilor
7eaf2dc8ed Fixed Javadoc 2021-07-27 19:02:04 +01:00
Auxilor
310485402f Updated to 6.2.0 2021-07-27 19:01:08 +01:00
Auxilor
727dc25083 Added ArmorChangeEvent 2021-07-27 19:00:50 +01:00
Auxilor
364f36d502 Added player option to display, added setters to commands 2021-07-27 18:48:10 +01:00
Auxilor
b6086bc4bd JSON config changes 2021-07-27 18:36:51 +01:00
Auxilor
dd3beaa548 Added dynamic world height check 2021-07-27 18:34:23 +01:00
Auxilor
c36c0c247f Fixed enchant support in crafting recipes 2021-07-26 19:02:11 +01:00
Auxilor
6611a0f82c Fixed missing javadoc 2021-07-26 18:39:18 +01:00
Auxilor
625b981b81 Added support for enchantments in recipes 2021-07-26 18:38:12 +01:00
Auxilor
d8607917a1 Updated to 6.1.0 2021-07-26 18:26:13 +01:00
Auxilor
30d5f54459 Added EcoPlugin#reloadWithTime 2021-07-26 18:25:56 +01:00
Auxilor
a59c05174f Fixed bug with unloaded plugins 2021-07-26 18:21:52 +01:00
Auxilor
cf01abcf87 Added out of world check to blocks 2021-07-26 18:20:13 +01:00
Auxilor
70a4a06d4f Updated to 6.0.6 2021-07-24 01:12:55 +01:00
Auxilor
bbee18fd8a JSON config files now have same deletion behaviour as yaml config files 2021-07-24 01:12:46 +01:00
Auxilor
26ab9a327d Added warnings to invalid extensions 2021-07-23 22:14:14 +01:00
Auxilor
0676f5fa33 Updated to 6.0.5 2021-07-23 22:11:41 +01:00
Auxilor
051b95ad88 Extension loading change 2021-07-23 22:11:32 +01:00
Auxilor
d786014cbc Updated to 6.0.4 2021-07-22 18:40:17 +01:00
Auxilor
b62bb48bb6 Fixed loadable config reloading 2021-07-22 18:39:59 +01:00
Auxilor
b238a10209 Fixed EcoUpdatableYamlConfig not automatically registering itsefl 2021-07-22 18:34:00 +01:00
Auxilor
251049f1f1 Updated to 6.0.3 2021-07-22 16:42:00 +01:00
Auxilor
16d146dba0 Fixed ArrowUtils 2021-07-22 16:41:43 +01:00
348 changed files with 11363 additions and 5879 deletions

11
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "gradle" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"

1
.gitignore vendored
View File

@@ -14,6 +14,7 @@ bin/
# Gradle # Gradle
.gradle .gradle
**/build/ **/build/
**/out/
!eco-api/src/**/build/ !eco-api/src/**/build/
.gradletasknamecache .gradletasknamecache
!gradle-wrapper.jar !gradle-wrapper.jar

View File

@@ -5,20 +5,17 @@
- The pull request must not have any checkstyle issues. - The pull request must not have any checkstyle issues.
- Every method and field must have a javadoc attached. - Every method and field must have a javadoc attached.
2. Use lombok wherever possible. 2. Use JetBrains annotations
- @Getter, @Setter, @UtilityClass only.
3. Use JetBrains annotations
- Every parameter should be annotated with @NotNull or @Nullable - Every parameter should be annotated with @NotNull or @Nullable
- Use @NotNull over lombok @NonNull - Use @NotNull over lombok @NonNull
4. Imports 3. Imports
- No group (*) imports. - No group (*) imports.
- No static imports. - No static imports.
## Dependency Injection ## Dependency Injection
- eco uses Dependency Injection - eco uses Dependency Injection
- Any calls to AbstractEcoPlugin#getInstance are code smells and should never be used unless **absolutely necessary**. - Any calls to Eco#getHandler#getEcoPlugin are code smells and should never be used unless **absolutely necessary**.
- NamespacedKeys, FixedMetadataValues, Runnables, and Schedules should be managed using AbstractEcoPlugin through DI. - NamespacedKeys, FixedMetadataValues, Runnables, and Schedules should be managed using AbstractEcoPlugin through DI.
- Any DI class should extend PluginDependent where possible. If the class extends another, then you **must** store the plugin instance in a private final variable called **plugin** with a private or protected getter. - Any DI class should extend PluginDependent where possible. If the class extends another, then you **must** store the plugin instance in a private final variable called **plugin** with a private or protected getter.

120
README.md
View File

@@ -1,22 +1,37 @@
<h1 align="center"> # eco
<br> eco is a powerful Spigot development library that simplifies the process of plugin creation and supercharges
<img src="https://i.imgur.com/p5uR2Qp.png" alt="eco logo" width="256"> your plugins.
<br> It's the engine behind [EcoEnchants](https://polymart.org/resource/490), [Reforges](https://polymart.org/resource/1330),
</h1> [EcoItems](https://polymart.org/resource/1247), [EcoSkills](https://polymart.org/resource/1351),
[EcoArmor](https://polymart.org/resource/687), [Talismans](https://polymart.org/resource/611),
and many more.
<h4 align="center">eco - Simplify spigot development.</h4> <p>
<a href="https://github.com/Auxilor/eco/releases">
<img alt="spigot" src="https://img.shields.io/github/v/release/Auxilor/eco?color=informational"/>
</a>
<a href="https://bstats.org/plugin/bukkit/EcoEnchants" alt="bstats servers">
<img src="https://img.shields.io/bstats/servers/7666?color=informational"/>
</a>
<a href="https://bstats.org/plugin/bukkit/EcoEnchants" alt="bstats players">
<img src="https://img.shields.io/bstats/players/7666?color=informational"/>
</a>
<a href="https://plugins.auxilor.io/" alt="Docs (gitbook)">
<img src="https://img.shields.io/badge/docs-gitbook-informational"/>
</a>
<a href="https://discord.gg/ZcwpSsE/" alt="Discord">
<img src="https://img.shields.io/discord/452518336627081236?label=discord&color=informational"/>
</a>
</p>
### Plugin Information # For server owners
- Requires ProtocolLib to be installed: get the latest version [here](https://www.spigotmc.org/resources/protocollib.1997/) - Requires ProtocolLib to be installed: get the latest version [here](https://www.spigotmc.org/resources/protocollib.1997/)
- Supports 1.16.5+ - Supports 1.16.5+
### bStats # For developers
<img src="https://bstats.org/signatures/bukkit/eco.svg" width="512">
# Information for development
## Javadoc ## Javadoc
The 6.0.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.0.0/javadoc/) The 6.13.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.13.0/javadoc/)
## Plugin Information ## Plugin Information
@@ -31,7 +46,6 @@ depend:
eco is available from any of these places: eco is available from any of these places:
- [GitHub](https://github.com/Auxilor/eco/releases) - [GitHub](https://github.com/Auxilor/eco/releases)
- [Spigot](https://www.spigotmc.org/resources/eco.87955/)
- [Polymart](https://polymart.org/resource/eco.773) - [Polymart](https://polymart.org/resource/eco.773)
- [Build it locally](https://github.com/Auxilor/eco#build-locally). - [Build it locally](https://github.com/Auxilor/eco#build-locally).
@@ -52,7 +66,7 @@ dependencies {
} }
``` ```
Replace `Tag` with a release tag for eco, eg `6.0.0`. Replace `Tag` with a release tag for eco, eg `6.13.0`.
Maven: Maven:
@@ -72,7 +86,7 @@ Maven:
</dependency> </dependency>
``` ```
Replace `Tag` with a release tag for eco, eg `6.0.0`. Replace `Tag` with a release tag for eco, eg `6.13.0`.
## Build locally: ## Build locally:
@@ -85,81 +99,21 @@ cd eco
./gradlew build ./gradlew build
``` ```
# Features
Here's a list of some (not all) of the features of eco:
- Command system with subcommands
- Reworked config system
- JSON Config Support
- Client-Side item display
- World drop system
- Event manager
- PlayerJumpEvent
- ArmorEquipEvent
- EntityDeathByEntityEvent
- NaturalExpGainEvent
- Plugin extensions (Plugins for plugins)
- GUI System
- Integration system for external plugins
- Anticheat support
- AAC
- Matrix
- NCP
- Spartan
- Vulcan
- Antigrief/Combat support
- CombatLogX (V10 + V11)
- FactionsUUID
- GriefPrevention
- Kingdoms
- Lands
- Towny
- WorldGuard
- mcMMO support
- Custom Items support
- Oraxen
- PlaceholderAPI support
- NMS Proxy / Wrapper system built in
- Custom Items system
- Crafting Recipe handler
- Tuples
- Support uploading to / downloading from hastebin
- Packet System (via ProtocolLib)
- Dependency Injection systems
- Prerequisite system
- API additions (via utility classes)
- Get bow from arrow
- Break a block as a player
- Get a vein of blocks
- Create 2D lists
- Create NamespacedKeys safely
- Random number, distribution, roman numerals
- Set skull texture
- Format all strings
- Hex Support
- Gradient Support
- Placeholder Support
- Get a scoreboard team from any color
- Telekinesis (Drops straight to inventory) system
- More vector options
- Update checker
- bStats integration
- Reworked systems for:
- NamespacedKey
- MetadataValue
- Runnables / Scheduling
... and a lot more!
## License ## License
*Click here to read [the entire license](https://github.com/Auxilor/eco/blob/master/LICENSE.md).* *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!
<br> <br>
<div style="width: 50%; margin: 0 auto;">
<br>
<a href="https://gamersupps.gg/discount/Auxilor?afmc=Auxilor" target="_blank">
<img src="https://i.imgur.com/7mFhlQO.png" alt="supps banner">
</a>
<a href="https://dedimc.promo/Auxilor" target="_blank"> <a href="https://dedimc.promo/Auxilor" target="_blank">
<img src="https://i.imgur.com/zdDLhFA.png" alt="dedimc banner"> <img src="https://i.imgur.com/x9aeH38.png" alt="dedimc banner">
</a> </a>
<br> <br>
</div>
</h1> </h1>

View File

@@ -7,7 +7,11 @@ plugins {
dependencies { dependencies {
implementation project(":eco-api") implementation project(":eco-api")
implementation project(":eco-core").getSubprojects() implementation project(":eco-core:core-plugin")
implementation project(":eco-core:core-proxy")
implementation project(":eco-core:core-backend")
implementation project(":eco-core:core-nms:v1_16_R3")
implementation project(path: ":eco-core:core-nms:v1_17_R1", configuration: 'mapped')
} }
allprojects { allprojects {
@@ -21,13 +25,16 @@ allprojects {
mavenLocal() mavenLocal()
maven { url 'https://jitpack.io' } maven { url 'https://jitpack.io' }
// SuperiorSkyblock2
maven { url 'https://repo.bg-software.com/repository/api/' }
// NMS (for jitpack compilation) // NMS (for jitpack compilation)
maven { url 'https://repo.codemc.org/repository/nms/' } maven { url 'https://repo.codemc.org/repository/nms/' }
// bStats, mcMMO // bStats, mcMMO, BentoBox
maven { url 'https://repo.codemc.org/repository/maven-public' } maven { url 'https://repo.codemc.org/repository/maven-public/' }
// Spigot API // Spigot API, Bungee API
maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' } maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
// PlaceholderAPI // PlaceholderAPI
@@ -47,16 +54,17 @@ allprojects {
// CombatLogX // CombatLogX
maven { url 'https://nexus.sirblobman.xyz/repository/public/' } maven { url 'https://nexus.sirblobman.xyz/repository/public/' }
// IridiumSkyblock
maven { url 'https://nexus.iridiumdevelopment.net/repository/maven-releases/' }
} }
dependencies { dependencies {
compileOnly 'org.jetbrains:annotations:19.0.0' compileOnly 'org.jetbrains:annotations:19.0.0'
// Lombok // Test
compileOnly 'org.projectlombok:lombok:1.18.20' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
annotationProcessor 'org.projectlombok:lombok:1.18.20' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
testCompileOnly 'org.projectlombok:lombok:1.18.20'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
} }
tasks.withType(JavaCompile) { tasks.withType(JavaCompile) {
@@ -75,7 +83,8 @@ allprojects {
} }
shadowJar { shadowJar {
relocate('org.bstats.bukkit', 'com.willfp.eco.shaded.bstats') relocate('org.bstats', 'com.willfp.eco.shaded.bstats')
relocate('net.kyori.adventure.text.minimessage', 'com.willfp.eco.shaded.minimessage')
} }
jar { jar {
@@ -92,6 +101,18 @@ allprojects {
withSourcesJar() withSourcesJar()
} }
test {
useJUnitPlatform()
// Always run tests, even when nothing changed.
dependsOn cleanTest
// Show test results.
testLogging {
events "passed", "skipped", "failed"
}
}
compileJava.options.encoding = 'UTF-8' compileJava.options.encoding = 'UTF-8'
compileJava.dependsOn clean compileJava.dependsOn clean

View File

@@ -45,7 +45,7 @@
--> -->
<property name="severity" value="error"/> <property name="severity" value="error"/>
<property name="fileExtensions" value="java, properties, xml"/> <property name="fileExtensions" value="java, properties, xml, kt"/>
<!-- Excludes all 'module-info.java' files --> <!-- Excludes all 'module-info.java' files -->
<!-- See https://checkstyle.org/config_filefilters.html --> <!-- See https://checkstyle.org/config_filefilters.html -->
@@ -66,6 +66,7 @@
<module name="FileLength"/> <module name="FileLength"/>
<module name="LineLength"> <module name="LineLength">
<property name="fileExtensions" value="java"/> <property name="fileExtensions" value="java"/>
<property name="fileExtensions" value="kt"/>
<property name="max" value="200"/> <property name="max" value="200"/>
</module> </module>

View File

@@ -6,19 +6,24 @@ group 'com.willfp'
version rootProject.version version rootProject.version
dependencies { dependencies {
compileOnly 'org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT' // Adventure
compileOnly 'org.apache.maven:maven-artifact:3.0.3' compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
compileOnly 'org.bstats:bstats-bukkit:1.7' compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.0-SNAPSHOT' compileOnly 'net.kyori:adventure-api:4.9.2'
compileOnly 'com.google.code.gson:gson:2.8.7' compileOnly 'net.kyori:adventure-text-serializer-gson:4.9.2'
compileOnly 'net.kyori:adventure-text-serializer-legacy:4.9.2'
// Other
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
compileOnly 'org.apache.maven:maven-artifact:3.8.1'
compileOnly 'com.comphenix.protocol:ProtocolLib:4.7.1-SNAPSHOT'
compileOnly 'com.google.code.gson:gson:2.8.8'
} }
java { java {
withJavadocJar() withJavadocJar()
} }
compileJava.options.encoding = 'UTF-8'
compileJava.dependsOn clean
build.dependsOn publishToMavenLocal build.dependsOn publishToMavenLocal

View File

@@ -6,7 +6,6 @@ import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.events.PacketEvent;
import lombok.Getter;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -26,7 +25,6 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
* <p> * <p>
* Useful for monitor priority adapters that <b>must</b> be ran last. * Useful for monitor priority adapters that <b>must</b> be ran last.
*/ */
@Getter
private final boolean postLoad; private final boolean postLoad;
/** /**
@@ -134,4 +132,13 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
ProtocolLibrary.getProtocolManager().addPacketListener(this); ProtocolLibrary.getProtocolManager().addPacketListener(this);
} }
} }
/**
* Get if the packet adapter should be loaded last.
*
* @return If post load.
*/
public boolean isPostLoad() {
return this.postLoad;
}
} }

View File

@@ -1,7 +1,5 @@
package com.willfp.eco.core; package com.willfp.eco.core;
import lombok.Getter;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -11,30 +9,46 @@ import org.jetbrains.annotations.NotNull;
* *
* @see Handler * @see Handler
*/ */
@UtilityClass public final class Eco {
public class Eco {
/** /**
* Instance of eco handler. * Instance of eco handler.
*/
@ApiStatus.Internal
private static Handler handler;
/**
* Set the handler.
* @param handler The handler.
*/
@ApiStatus.Internal
public static void setHandler(@NotNull final Handler handler) {
Validate.isTrue(Eco.handler == null, "Already initialized!");
Eco.handler = handler;
}
/**
* Get the instance of the eco handler.
* <p> * <p>
* The handler is, in essence, a way to interface between the eco-api * The handler is, in essence, a way to interface between the eco-api
* frontend module, and the eco-backend implementations. * frontend module, and the eco-backend implementations.
* <p> * <p>
* There shouldn't really be any reason to ever use the handler * There shouldn't really be any reason to ever use the handler
* in your own plugins, but if you want to then you can - it's * in your own plugins, and you are likely to break things. All parts of
* just a part of the API like any other. * the handler are abstracted into logically named parts of the API.
*/ * <p>
@Getter * In versions of eco before 6.12.0, the handler was considered part of
private Handler handler; * the eco API, however it has since been moved into an internal component
* that shouldn't be used in your plugins.
/**
* Set the handler.
* *
* @param handler The handler. * @return The handler.
*/ */
@ApiStatus.Internal @ApiStatus.Internal
public void setHandler(@NotNull final Handler handler) { public static Handler getHandler() {
Validate.isTrue(Eco.handler == null, "Already initialized!"); return handler;
}
Eco.handler = handler; private Eco() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }
} }

View File

@@ -7,6 +7,7 @@ import com.willfp.eco.core.config.updating.ConfigHandler;
import com.willfp.eco.core.display.Display; import com.willfp.eco.core.display.Display;
import com.willfp.eco.core.display.DisplayModule; import com.willfp.eco.core.display.DisplayModule;
import com.willfp.eco.core.events.EventManager; import com.willfp.eco.core.events.EventManager;
import com.willfp.eco.core.extensions.Extension;
import com.willfp.eco.core.extensions.ExtensionLoader; import com.willfp.eco.core.extensions.ExtensionLoader;
import com.willfp.eco.core.factory.MetadataValueFactory; import com.willfp.eco.core.factory.MetadataValueFactory;
import com.willfp.eco.core.factory.NamespacedKeyFactory; import com.willfp.eco.core.factory.NamespacedKeyFactory;
@@ -17,10 +18,8 @@ import com.willfp.eco.core.proxy.AbstractProxy;
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 com.willfp.eco.core.web.UpdateChecker; import com.willfp.eco.core.web.UpdateChecker;
import lombok.Getter;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@@ -52,77 +51,66 @@ 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>
*/ */
public abstract class EcoPlugin extends JavaPlugin { @SuppressWarnings("unused")
public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
/** /**
* The spigot resource ID of the plugin. * The polymart resource ID of the plugin.
*/ */
@Getter
private final int resourceId; private final int resourceId;
/** /**
* The bStats resource ID of the plugin. * The bStats resource ID of the plugin.
*/ */
@Getter
private final int bStatsId; private final int bStatsId;
/** /**
* The package where proxy implementations are. * The package where proxy implementations are.
*/ */
@Getter
private final String proxyPackage; private final String proxyPackage;
/** /**
* The color of the plugin, used in messages. * The color of the plugin, used in messages.
*/ */
@Getter
private final String color; private final String color;
/** /**
* Loaded integrations. * Loaded integrations.
*/ */
@Getter
private final Set<String> loadedIntegrations = new HashSet<>(); private final Set<String> loadedIntegrations = new HashSet<>();
/** /**
* The internal plugin scheduler. * The internal plugin scheduler.
*/ */
@Getter
private final Scheduler scheduler; private final Scheduler scheduler;
/** /**
* The internal plugin Event Manager. * The internal plugin Event Manager.
*/ */
@Getter
private final EventManager eventManager; private final EventManager eventManager;
/** /**
* Config.yml. * Config.yml.
*/ */
@Getter
private final ConfigYml configYml; private final ConfigYml configYml;
/** /**
* Lang.yml. * Lang.yml.
*/ */
@Getter
private final LangYml langYml; private final LangYml langYml;
/** /**
* The internal factory to produce {@link org.bukkit.NamespacedKey}s. * The internal factory to produce {@link org.bukkit.NamespacedKey}s.
*/ */
@Getter
private final NamespacedKeyFactory namespacedKeyFactory; private final NamespacedKeyFactory namespacedKeyFactory;
/** /**
* The internal factory to produce {@link org.bukkit.metadata.FixedMetadataValue}s. * The internal factory to produce {@link org.bukkit.metadata.FixedMetadataValue}s.
*/ */
@Getter
private final MetadataValueFactory metadataValueFactory; private final MetadataValueFactory metadataValueFactory;
/** /**
* The internal factory to produce {@link com.willfp.eco.core.scheduling.RunnableTask}s. * The internal factory to produce {@link com.willfp.eco.core.scheduling.RunnableTask}s.
*/ */
@Getter
private final RunnableFactory runnableFactory; private final RunnableFactory runnableFactory;
/** /**
@@ -130,19 +118,16 @@ public abstract class EcoPlugin extends JavaPlugin {
* *
* @see com.willfp.eco.core.extensions.Extension * @see com.willfp.eco.core.extensions.Extension
*/ */
@Getter
private final ExtensionLoader extensionLoader; private final ExtensionLoader extensionLoader;
/** /**
* The handler class for updatable classes. * The handler class for updatable classes.
*/ */
@Getter
private final ConfigHandler configHandler; private final ConfigHandler configHandler;
/** /**
* The display module for the plugin. * The display module for the plugin.
*/ */
@Getter
private DisplayModule displayModule; private DisplayModule displayModule;
/** /**
@@ -153,30 +138,28 @@ public abstract class EcoPlugin extends JavaPlugin {
/** /**
* If the server is running an outdated version of the plugin. * If the server is running an outdated version of the plugin.
*/ */
@Getter
private boolean outdated = false; private boolean outdated = false;
/** /**
* If the plugin supports extensions. * If the plugin supports extensions.
*/ */
@Getter
private final boolean supportingExtensions; private final boolean supportingExtensions;
/** /**
* The proxy factory. * The proxy factory.
*/ */
@Getter @Nullable
private final ProxyFactory proxyFactory; private final ProxyFactory proxyFactory;
/** /**
* Create a new plugin without a specified color, proxy support, spigot, or bStats. * Create a new plugin without a specified color, proxy support, polymart, or bStats.
*/ */
protected EcoPlugin() { protected EcoPlugin() {
this("&f"); this("&f");
} }
/** /**
* Create a new plugin without proxy support, spigot, or bStats. * Create a new plugin without proxy support, polymart, or bStats.
* *
* @param color The color. * @param color The color.
*/ */
@@ -186,7 +169,7 @@ public abstract class EcoPlugin extends JavaPlugin {
/** /**
* Create a new plugin unlinked to spigot and bStats. * Create a new plugin unlinked to polymart and bStats.
* *
* @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)
@@ -199,7 +182,7 @@ public abstract class EcoPlugin extends JavaPlugin {
/** /**
* Create a new plugin without proxy or extension support. * Create a new plugin without proxy or extension support.
* *
* @param resourceId The spigot 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)
*/ */
@@ -212,7 +195,7 @@ public abstract class EcoPlugin extends JavaPlugin {
/** /**
* Create a new plugin without proxy support. * Create a new plugin without proxy support.
* *
* @param resourceId The spigot 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)
* @param supportingExtensions If the plugin supports extensions. * @param supportingExtensions If the plugin supports extensions.
@@ -227,7 +210,7 @@ public abstract class EcoPlugin extends JavaPlugin {
/** /**
* Create a new plugin without extension support. * Create a new plugin without extension support.
* *
* @param resourceId The spigot 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 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)
@@ -242,7 +225,7 @@ public abstract class EcoPlugin extends JavaPlugin {
/** /**
* Create a new plugin. * Create a new plugin.
* *
* @param resourceId The spigot 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 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)
@@ -305,10 +288,27 @@ public abstract class EcoPlugin extends JavaPlugin {
this.logger = Eco.getHandler().createLogger(this); this.logger = Eco.getHandler().createLogger(this);
this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.getHandler().createProxyFactory(this); this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.getHandler().createProxyFactory(this);
this.langYml = new LangYml(this); this.langYml = this.createLangYml();
this.configYml = new ConfigYml(this); this.configYml = this.createConfigYml();
Eco.getHandler().addNewPlugin(this); Eco.getHandler().addNewPlugin(this);
/*
The minimum eco version check was moved here because it's very common
to add a lot of code in the constructor of plugins; meaning that the plugin
can throw errors without it being obvious to the user that the reason is
because they have an outdated version of eco installed.
*/
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.getHandler().getEcoPlugin().getDescription().getVersion());
DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(this.getMinimumEcoVersion());
if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) {
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("Download the newest version here:");
this.getLogger().severe("https://polymart.org/download/773/recent/JSpprMspkuyecf5y1wQ2Jn8OoLQSQ_IW");
Bukkit.getPluginManager().disablePlugin(this);
}
} }
/** /**
@@ -336,29 +336,22 @@ public abstract class EcoPlugin extends JavaPlugin {
}); });
} }
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.getHandler().getEcoPlugin().getDescription().getVersion());
DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(this.getMinimumEcoVersion());
if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) {
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("Download the newest version here:");
this.getLogger().severe("https://polymart.org/download/773/recent/JSpprMspkuyecf5y1wQ2Jn8OoLQSQ_IW");
Bukkit.getPluginManager().disablePlugin(this);
}
if (this.getBStatsId() != 0) { if (this.getBStatsId() != 0) {
new Metrics(this, this.getBStatsId()); Eco.getHandler().registerBStats(this);
} }
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).collect(Collectors.toSet()); Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins())
.map(Plugin::getName)
.map(String::toLowerCase)
.collect(Collectors.toSet());
if (enabledPlugins.contains("PlaceholderAPI")) { if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) {
this.loadedIntegrations.add("PlaceholderAPI"); this.loadedIntegrations.add("PlaceholderAPI");
PlaceholderManager.addIntegration(Eco.getHandler().createPAPIIntegration(this)); PlaceholderManager.addIntegration(Eco.getHandler().createPAPIIntegration(this));
} }
this.loadIntegrationLoaders().forEach((integrationLoader -> { this.loadIntegrationLoaders().forEach((integrationLoader -> {
if (enabledPlugins.contains(integrationLoader.getPluginName())) { if (enabledPlugins.contains(integrationLoader.getPluginName().toLowerCase())) {
this.loadedIntegrations.add(integrationLoader.getPluginName()); this.loadedIntegrations.add(integrationLoader.getPluginName());
integrationLoader.load(); integrationLoader.load();
} }
@@ -405,7 +398,6 @@ public abstract class EcoPlugin extends JavaPlugin {
this.getEventManager().unregisterAllListeners(); this.getEventManager().unregisterAllListeners();
this.getScheduler().cancelAll(); this.getScheduler().cancelAll();
this.getConfigHandler().saveAllConfigs();
this.handleDisable(); this.handleDisable();
@@ -460,11 +452,15 @@ public abstract class EcoPlugin extends JavaPlugin {
this.reload(); this.reload();
for (Extension extension : this.getExtensionLoader().getLoadedExtensions()) {
extension.handleAfterLoad();
}
this.getLogger().info("Loaded " + this.color + this.getName()); this.getLogger().info("Loaded " + this.color + this.getName());
} }
/** /**
* Default code to be executed on plugin reload. * Reload the plugin.
*/ */
public final void reload() { public final void reload() {
this.getConfigHandler().updateConfigs(); this.getConfigHandler().updateConfigs();
@@ -474,6 +470,23 @@ public abstract class EcoPlugin extends JavaPlugin {
this.getScheduler().cancelAll(); this.getScheduler().cancelAll();
this.handleReload(); this.handleReload();
for (Extension extension : this.extensionLoader.getLoadedExtensions()) {
extension.handleReload();
}
}
/**
* Reload the plugin and return the time taken to reload.
*
* @return The time.
*/
public final long reloadWithTime() {
long startTime = System.currentTimeMillis();
this.reload();
return System.currentTimeMillis() - startTime;
} }
/** /**
@@ -559,6 +572,28 @@ public abstract class EcoPlugin extends JavaPlugin {
*/ */
protected abstract List<Listener> loadListeners(); protected abstract List<Listener> loadListeners();
/**
* Useful for custom LangYml implementations.
* <p>
* Override if needed.
*
* @return lang.yml.
*/
protected LangYml createLangYml() {
return new LangYml(this);
}
/**
* Useful for custom ConfigYml implementations.
* <p>
* Override if needed.
*
* @return config.yml.
*/
protected ConfigYml createConfigYml() {
return new ConfigYml(this);
}
/** /**
* Create the display module for the plugin. * Create the display module for the plugin.
* *
@@ -601,7 +636,7 @@ public abstract class EcoPlugin extends JavaPlugin {
* @param <T> The proxy type. * @param <T> The proxy type.
* @return The proxy. * @return The proxy.
*/ */
public <T extends AbstractProxy> T getProxy(@NotNull final Class<T> proxyClass) { public final <T extends AbstractProxy> T getProxy(@NotNull final Class<T> proxyClass) {
Validate.notNull(proxyFactory, "Plugin does not support proxy!"); Validate.notNull(proxyFactory, "Plugin does not support proxy!");
return proxyFactory.getProxy(proxyClass); return proxyFactory.getProxy(proxyClass);
@@ -680,4 +715,168 @@ public abstract class EcoPlugin extends JavaPlugin {
public static Set<String> getPluginNames() { public static Set<String> getPluginNames() {
return new HashSet<>(Eco.getHandler().getLoadedPlugins()); return new HashSet<>(Eco.getHandler().getLoadedPlugins());
} }
/**
* Get the polymart resource ID.
*
* @return The resource ID.
*/
public int getResourceId() {
return this.resourceId;
}
/**
* Get the bStats ID.
*
* @return The ID.
*/
public int getBStatsId() {
return this.bStatsId;
}
/**
* Get the proxy package.
*
* @return The package where proxies are contained.
*/
public String getProxyPackage() {
return this.proxyPackage;
}
/**
* Get the plugin color (uses legacy formatting).
*
* @return The color.
*/
public String getColor() {
return this.color;
}
/**
* Get all loaded integration names.
*
* @return The integrations.
*/
public Set<String> getLoadedIntegrations() {
return this.loadedIntegrations;
}
/**
* Get the scheduler.
*
* @return The scheduler.
*/
public Scheduler getScheduler() {
return this.scheduler;
}
/**
* Get the event manager.
*
* @return The event manager.
*/
public EventManager getEventManager() {
return this.eventManager;
}
/**
* Get config.yml.
*
* @return config.yml.
*/
public ConfigYml getConfigYml() {
return this.configYml;
}
/**
* Get lang.yml.
*
* @return lang.yml.
*/
public LangYml getLangYml() {
return this.langYml;
}
/**
* Get the NamespacedKey factory.
*
* @return The factory.
*/
public NamespacedKeyFactory getNamespacedKeyFactory() {
return this.namespacedKeyFactory;
}
/**
* Get the metadata value factory.
*
* @return The factory.
*/
public MetadataValueFactory getMetadataValueFactory() {
return this.metadataValueFactory;
}
/**
* Get the runnable factory.
*
* @return The runnable factory.
*/
public RunnableFactory getRunnableFactory() {
return this.runnableFactory;
}
/**
* Get the extension loader.
*
* @return The extension loader.
*/
public ExtensionLoader getExtensionLoader() {
return this.extensionLoader;
}
/**
* Get the config handler.
*
* @return The config handler.
*/
public ConfigHandler getConfigHandler() {
return this.configHandler;
}
/**
* Get the plugin's display module.
*
* @return The display module.
*/
@Nullable
public DisplayModule getDisplayModule() {
return this.displayModule;
}
/**
* Get if the plugin is outdated.
*
* @return If outdated.
*/
public boolean isOutdated() {
return this.outdated;
}
/**
* Get if the plugin supports extensions.
*
* @return If extensions are supported.
*/
public boolean isSupportingExtensions() {
return this.supportingExtensions;
}
/**
* Get the proxy factory.
*
* @return The proxy factory.
*/
@Nullable
public ProxyFactory getProxyFactory() {
return this.proxyFactory;
}
} }

View File

@@ -2,25 +2,34 @@ package com.willfp.eco.core;
import com.willfp.eco.core.config.updating.ConfigHandler; import com.willfp.eco.core.config.updating.ConfigHandler;
import com.willfp.eco.core.config.wrapper.ConfigFactory; import com.willfp.eco.core.config.wrapper.ConfigFactory;
import com.willfp.eco.core.data.keys.KeyRegistry;
import com.willfp.eco.core.data.PlayerProfileHandler;
import com.willfp.eco.core.drops.DropQueueFactory; import com.willfp.eco.core.drops.DropQueueFactory;
import com.willfp.eco.core.events.EventManager; import com.willfp.eco.core.events.EventManager;
import com.willfp.eco.core.extensions.ExtensionLoader; import com.willfp.eco.core.extensions.ExtensionLoader;
import com.willfp.eco.core.factory.MetadataValueFactory; 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.fast.FastItemStack;
import com.willfp.eco.core.gui.GUIFactory; import com.willfp.eco.core.gui.GUIFactory;
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration; import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
import com.willfp.eco.core.proxy.Cleaner; import com.willfp.eco.core.proxy.Cleaner;
import com.willfp.eco.core.proxy.ProxyFactory; import com.willfp.eco.core.proxy.ProxyFactory;
import com.willfp.eco.core.requirement.RequirementFactory;
import com.willfp.eco.core.scheduling.Scheduler; import com.willfp.eco.core.scheduling.Scheduler;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;
/** /**
* @see Eco * @see Eco#getHandler()
*/ */
@ApiStatus.Internal
public interface Handler { public interface Handler {
/** /**
* Create a scheduler. * Create a scheduler.
@@ -28,6 +37,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The scheduler. * @return The scheduler.
*/ */
@NotNull
Scheduler createScheduler(@NotNull EcoPlugin plugin); Scheduler createScheduler(@NotNull EcoPlugin plugin);
/** /**
@@ -36,6 +46,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The event manager. * @return The event manager.
*/ */
@NotNull
EventManager createEventManager(@NotNull EcoPlugin plugin); EventManager createEventManager(@NotNull EcoPlugin plugin);
/** /**
@@ -44,6 +55,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The factory. * @return The factory.
*/ */
@NotNull
NamespacedKeyFactory createNamespacedKeyFactory(@NotNull EcoPlugin plugin); NamespacedKeyFactory createNamespacedKeyFactory(@NotNull EcoPlugin plugin);
/** /**
@@ -52,6 +64,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The factory. * @return The factory.
*/ */
@NotNull
MetadataValueFactory createMetadataValueFactory(@NotNull EcoPlugin plugin); MetadataValueFactory createMetadataValueFactory(@NotNull EcoPlugin plugin);
/** /**
@@ -60,6 +73,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The factory. * @return The factory.
*/ */
@NotNull
RunnableFactory createRunnableFactory(@NotNull EcoPlugin plugin); RunnableFactory createRunnableFactory(@NotNull EcoPlugin plugin);
/** /**
@@ -68,6 +82,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The factory. * @return The factory.
*/ */
@NotNull
ExtensionLoader createExtensionLoader(@NotNull EcoPlugin plugin); ExtensionLoader createExtensionLoader(@NotNull EcoPlugin plugin);
/** /**
@@ -76,6 +91,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The handler. * @return The handler.
*/ */
@NotNull
ConfigHandler createConfigHandler(@NotNull EcoPlugin plugin); ConfigHandler createConfigHandler(@NotNull EcoPlugin plugin);
/** /**
@@ -84,6 +100,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The logger. * @return The logger.
*/ */
@NotNull
Logger createLogger(@NotNull EcoPlugin plugin); Logger createLogger(@NotNull EcoPlugin plugin);
/** /**
@@ -92,6 +109,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The integration. * @return The integration.
*/ */
@NotNull
PlaceholderIntegration createPAPIIntegration(@NotNull EcoPlugin plugin); PlaceholderIntegration createPAPIIntegration(@NotNull EcoPlugin plugin);
/** /**
@@ -100,6 +118,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The factory. * @return The factory.
*/ */
@NotNull
ProxyFactory createProxyFactory(@NotNull EcoPlugin plugin); ProxyFactory createProxyFactory(@NotNull EcoPlugin plugin);
/** /**
@@ -107,6 +126,7 @@ public interface Handler {
* *
* @return The plugin. * @return The plugin.
*/ */
@NotNull
EcoPlugin getEcoPlugin(); EcoPlugin getEcoPlugin();
/** /**
@@ -114,6 +134,7 @@ public interface Handler {
* *
* @return The factory. * @return The factory.
*/ */
@NotNull
ConfigFactory getConfigFactory(); ConfigFactory getConfigFactory();
/** /**
@@ -121,6 +142,7 @@ public interface Handler {
* *
* @return The factory. * @return The factory.
*/ */
@NotNull
DropQueueFactory getDropQueueFactory(); DropQueueFactory getDropQueueFactory();
/** /**
@@ -128,6 +150,7 @@ public interface Handler {
* *
* @return The factory. * @return The factory.
*/ */
@NotNull
GUIFactory getGUIFactory(); GUIFactory getGUIFactory();
/** /**
@@ -135,6 +158,7 @@ public interface Handler {
* *
* @return The cleaner. * @return The cleaner.
*/ */
@NotNull
Cleaner getCleaner(); Cleaner getCleaner();
/** /**
@@ -150,6 +174,7 @@ public interface Handler {
* @param name The name. * @param name The name.
* @return The plugin. * @return The plugin.
*/ */
@Nullable
EcoPlugin getPluginByName(@NotNull String name); EcoPlugin getPluginByName(@NotNull String name);
/** /**
@@ -157,5 +182,53 @@ public interface Handler {
* *
* @return A list of plugin names in lowercase. * @return A list of plugin names in lowercase.
*/ */
@NotNull
List<String> getLoadedPlugins(); List<String> getLoadedPlugins();
/**
* Create a FastItemStack.
*
* @param itemStack The base ItemStack.
* @return The FastItemStack.
*/
@NotNull
FastItemStack createFastItemStack(@NotNull ItemStack itemStack);
/**
* Register bStats metrics.
*
* @param plugin The plugin.
*/
void registerBStats(@NotNull EcoPlugin plugin);
/**
* Get the requirement factory.
*
* @return The factory.
*/
@NotNull
RequirementFactory getRequirementFactory();
/**
* Get Adventure audiences.
*
* @return The audiences.
*/
@Nullable
BukkitAudiences getAdventure();
/**
* Get the key registry.
*
* @return The registry.
*/
@NotNull
KeyRegistry getKeyRegistry();
/**
* Get the PlayerProfile handler.
*
* @return The handler.
*/
PlayerProfileHandler getPlayerProfileHandler();
} }

View File

@@ -1,7 +1,5 @@
package com.willfp.eco.core; package com.willfp.eco.core;
import lombok.AccessLevel;
import lombok.Getter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
@@ -13,7 +11,7 @@ public abstract class PluginDependent<T extends EcoPlugin> {
/** /**
* The {@link EcoPlugin} that is stored. * The {@link EcoPlugin} that is stored.
*/ */
@Getter(AccessLevel.PROTECTED) @NotNull
private final T plugin; private final T plugin;
/** /**
@@ -24,4 +22,14 @@ public abstract class PluginDependent<T extends EcoPlugin> {
protected PluginDependent(@NotNull final T plugin) { protected PluginDependent(@NotNull final T plugin) {
this.plugin = plugin; this.plugin = plugin;
} }
/**
* Get the plugin.
*
* @return The plugin.
*/
@NotNull
protected T getPlugin() {
return this.plugin;
}
} }

View File

@@ -0,0 +1,29 @@
package com.willfp.eco.core;
import com.willfp.eco.core.config.updating.ConfigHandler;
import java.io.File;
/**
* Represents any class that acts like a plugin, for example {@link EcoPlugin}
* or {@link com.willfp.eco.core.extensions.Extension}. This exists to create
* things such as extension base configs rather than needing to pass an instance
* of the owning plugin.
*/
public interface PluginLike {
/**
* Get the data folder of the object.
* <p>
* Returns the plugin data folder for a plugin, or the extension's parent plugin's folder
*
* @return The data folder.
*/
File getDataFolder();
/**
* Get the handler class for updatable classes.
*
* @return The config handler.
*/
ConfigHandler getConfigHandler();
}

View File

@@ -1,8 +1,8 @@
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 lombok.Getter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
@@ -30,6 +30,17 @@ public class Prerequisite {
"Requires server to be running paper (or a fork)" "Requires server to be running paper (or a fork)"
); );
/**
* Requires the server to have vault installed.
*
* @deprecated Use {@link EconomyManager#hasRegistrations()} instead.
*/
@Deprecated
public static final Prerequisite HAS_VAULT = new Prerequisite(
() -> ClassUtils.exists("net.milkbowl.vault.economy.Economy"),
"Requires server to have vault"
);
/** /**
* Requires the server to be running 1.17. * Requires the server to be running 1.17.
*/ */
@@ -38,10 +49,25 @@ public class Prerequisite {
"Requires server to be running 1.17+" "Requires server to be running 1.17+"
); );
/**
* Requires the server to be running an implementation of BungeeCord.
*/
public static final Prerequisite HAS_BUNGEECORD = new Prerequisite(
() -> ClassUtils.exists("net.md_5.bungee.api.event.ServerConnectedEvent"),
"Requires server to be running BungeeCord (or a fork)"
);
/**
* Requires the server to be running an implementation of Velocity.
*/
public static final Prerequisite HAS_VELOCITY = new Prerequisite(
() -> ClassUtils.exists("com.velocitypowered.api.event.player.ServerConnectedEvent"),
"Requires server to be running Velocity (or a fork)"
);
/** /**
* If the necessary prerequisite condition has been met. * If the necessary prerequisite condition has been met.
*/ */
@Getter
private boolean isMet; private boolean isMet;
/** /**
@@ -52,7 +78,6 @@ public class Prerequisite {
/** /**
* The description of the requirements of the prerequisite. * The description of the requirements of the prerequisite.
*/ */
@Getter
private final String description; private final String description;
/** /**
@@ -97,4 +122,22 @@ public class Prerequisite {
static { static {
update(); update();
} }
/**
* Get if the prerequisite is met.
*
* @return If the condition is met.
*/
public boolean isMet() {
return this.isMet;
}
/**
* Get the description.
*
* @return The description.
*/
public String getDescription() {
return this.description;
}
} }

View File

@@ -42,10 +42,24 @@ public interface CommandBase {
*/ */
CommandHandler getHandler(); CommandHandler getHandler();
/**
* Set the handler.
*
* @param handler The handler.
*/
void setHandler(@NotNull CommandHandler handler);
/** /**
* Get the tab completer. * Get the tab completer.
* *
* @return The tab completer. * @return The tab completer.
*/ */
TabCompleteHandler getTabCompleter(); TabCompleteHandler getTabCompleter();
/**
* Set the tab completer.
*
* @param handler The handler.
*/
void setTabCompleter(@NotNull TabCompleteHandler handler);
} }

View File

@@ -5,8 +5,6 @@ import com.willfp.eco.core.PluginDependent;
import com.willfp.eco.core.command.CommandBase; import com.willfp.eco.core.command.CommandBase;
import com.willfp.eco.core.command.CommandHandler; import com.willfp.eco.core.command.CommandHandler;
import com.willfp.eco.core.command.TabCompleteHandler; import com.willfp.eco.core.command.TabCompleteHandler;
import lombok.AccessLevel;
import lombok.Getter;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil; import org.bukkit.util.StringUtil;
@@ -29,7 +27,6 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
/** /**
* The name of the command. * The name of the command.
*/ */
@Getter
private final String name; private final String name;
/** /**
@@ -37,7 +34,6 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
* <p> * <p>
* Written out as a string for flexibility with subclasses. * Written out as a string for flexibility with subclasses.
*/ */
@Getter
private final String permission; private final String permission;
/** /**
@@ -45,13 +41,23 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
* <p> * <p>
* In other worlds, only allowed to be executed by console. * In other worlds, only allowed to be executed by console.
*/ */
@Getter
private final boolean playersOnly; private final boolean playersOnly;
/**
* The actual code to be executed in the command.
*/
private CommandHandler handler = (sender, args) -> {
// Do nothing by default
};
/**
* The tab completion code to be executed in the command.
*/
private TabCompleteHandler tabCompleter = (sender, args) -> new ArrayList<>();
/** /**
* All subcommands for the command. * All subcommands for the command.
*/ */
@Getter(AccessLevel.PROTECTED)
private final List<CommandBase> subcommands; private final List<CommandBase> subcommands;
/** /**
@@ -164,14 +170,6 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
return this.getTabCompleter().tabComplete(sender, Arrays.asList(args)); return this.getTabCompleter().tabComplete(sender, Arrays.asList(args));
} }
@Override
public abstract CommandHandler getHandler();
@Override
public TabCompleteHandler getTabCompleter() {
return (sender, args) -> new ArrayList<>();
}
/** /**
* If a sender can execute the command. * If a sender can execute the command.
* *
@@ -195,4 +193,76 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
return true; return true;
} }
/**
* Get the command name.
*
* @return The name.
*/
public String getName() {
return this.name;
}
/**
* Get the permission required to execute the command.
*
* @return The permission.
*/
public String getPermission() {
return this.permission;
}
/**
* Get if the command can only be executed by players.
*
* @return If players only.
*/
public boolean isPlayersOnly() {
return this.playersOnly;
}
/**
* Get the actual code to be executed in the command.
*
* @return The code.
*/
public CommandHandler getHandler() {
return this.handler;
}
/**
* Get the tab completion code to be executed in the command.
*
* @return The code.
*/
public TabCompleteHandler getTabCompleter() {
return this.tabCompleter;
}
/**
* Get the subcommands of the command.
*
* @return The subcommands.
*/
public List<CommandBase> getSubcommands() {
return this.subcommands;
}
/**
* Set the command handler.
*
* @param handler The handler.
*/
public void setHandler(@NotNull final CommandHandler handler) {
this.handler = handler;
}
/**
* Set the tab completer.
*
* @param tabCompleter The tab completer.
*/
public void setTabCompleter(@NotNull final TabCompleteHandler tabCompleter) {
this.tabCompleter = tabCompleter;
}
} }

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.config.base;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.config.yaml.YamlBaseConfig; import com.willfp.eco.core.config.yaml.YamlBaseConfig;
import com.willfp.eco.util.StringUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
@@ -42,6 +43,18 @@ public class LangYml extends YamlBaseConfig {
* @return The message with a prefix appended. * @return The message with a prefix appended.
*/ */
public String getMessage(@NotNull final String message) { public String getMessage(@NotNull final String message) {
return getPrefix() + this.getString("messages." + message); return getMessage(message, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a chat message.
*
* @param message The key of the message.
* @param option The format options.
* @return The message with a prefix appended.
*/
public String getMessage(@NotNull final String message,
@NotNull final StringUtils.FormatOption option) {
return getPrefix() + this.getString("messages." + message, option);
} }
} }

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.config.interfaces; package com.willfp.eco.core.config.interfaces;
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;
@@ -165,7 +166,9 @@ public interface Config extends Cloneable {
* @return The found value, or an empty string if not found. * @return The found value, or an empty string if not found.
*/ */
@NotNull @NotNull
String getString(@NotNull String path); default String getString(@NotNull String path) {
return getString(path, true);
}
/** /**
* Get a string from config. * Get a string from config.
@@ -175,8 +178,36 @@ public interface Config extends Cloneable {
* @return The found value, or an empty string if not found. * @return The found value, or an empty string if not found.
*/ */
@NotNull @NotNull
default String getString(@NotNull String path,
boolean format) {
return this.getString(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @param option The format option.
* @return The found value, or an empty string if not found.
*/
@NotNull
default String getString(@NotNull String path,
@NotNull final StringUtils.FormatOption option) {
return this.getString(path, true, option);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @param format If the string should be formatted.
* @param option The format option.
* @return The found value, or an empty string if not found.
*/
@NotNull
String getString(@NotNull String path, String getString(@NotNull String path,
boolean format); boolean format,
@NotNull StringUtils.FormatOption option);
/** /**
* Get a string from config. * Get a string from config.
@@ -185,7 +216,9 @@ public interface Config extends Cloneable {
* @return The found value, or null if not found. * @return The found value, or null if not found.
*/ */
@Nullable @Nullable
String getStringOrNull(@NotNull String path); default String getStringOrNull(@NotNull String path) {
return getStringOrNull(path, true);
}
/** /**
* Get a string from config. * Get a string from config.
@@ -195,8 +228,36 @@ public interface Config extends Cloneable {
* @return The found value, or null if not found. * @return The found value, or null if not found.
*/ */
@Nullable @Nullable
default String getStringOrNull(@NotNull String path,
boolean format) {
return this.getStringOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @param option The format option.
* @return The found value, or null if not found.
*/
@Nullable
default String getStringOrNull(@NotNull String path,
@NotNull StringUtils.FormatOption option) {
return this.getStringOrNull(path, true, option);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @param format If the string should be formatted.
* @param option The format option.
* @return The found value, or null if not found.
*/
@Nullable
String getStringOrNull(@NotNull String path, String getStringOrNull(@NotNull String path,
boolean format); boolean format,
@NotNull StringUtils.FormatOption option);
/** /**
* Get a list of strings from config. * Get a list of strings from config.
@@ -207,7 +268,9 @@ public interface Config extends Cloneable {
* @return The found value, or a blank {@link java.util.ArrayList} if not found. * @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/ */
@NotNull @NotNull
List<String> getStrings(@NotNull String path); default List<String> getStrings(@NotNull String path) {
return getStrings(path, true);
}
/** /**
* Get a list of strings from config. * Get a list of strings from config.
@@ -217,8 +280,36 @@ public interface Config extends Cloneable {
* @return The found value, or a blank {@link java.util.ArrayList} if not found. * @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/ */
@NotNull @NotNull
default List<String> getStrings(@NotNull String path,
boolean format) {
return this.getStrings(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @param option The format option.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@Nullable
default List<String> getStrings(@NotNull String path,
@NotNull StringUtils.FormatOption option) {
return getStrings(path, true, option);
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @param format If the strings should be formatted.
* @param option The option.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
List<String> getStrings(@NotNull String path, List<String> getStrings(@NotNull String path,
boolean format); boolean format,
@NotNull StringUtils.FormatOption option);
/** /**
* Get a list of strings from config. * Get a list of strings from config.
@@ -227,7 +318,9 @@ public interface Config extends Cloneable {
* @return The found value, or null if not found. * @return The found value, or null if not found.
*/ */
@Nullable @Nullable
List<String> getStringsOrNull(@NotNull String path); default List<String> getStringsOrNull(@NotNull String path) {
return getStringsOrNull(path, true);
}
/** /**
* Get a list of strings from config. * Get a list of strings from config.
@@ -237,8 +330,36 @@ public interface Config extends Cloneable {
* @return The found value, or null if not found. * @return The found value, or null if not found.
*/ */
@Nullable @Nullable
default List<String> getStringsOrNull(@NotNull String path,
boolean format) {
return getStringsOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @param option The format option.
* @return The found value, or null if not found.
*/
@Nullable
default List<String> getStringsOrNull(@NotNull String path,
@NotNull StringUtils.FormatOption option) {
return getStringsOrNull(path, true, option);
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @param format If the strings should be formatted.
* @param option The format option.
* @return The found value, or null if not found.
*/
@Nullable
List<String> getStringsOrNull(@NotNull String path, List<String> getStringsOrNull(@NotNull String path,
boolean format); boolean format,
@NotNull StringUtils.FormatOption option);
/** /**
* Get a decimal from config. * Get a decimal from config.

View File

@@ -29,6 +29,27 @@ public interface JSONConfig extends Config {
@Nullable @Nullable
List<JSONConfig> getSubsectionsOrNull(@NotNull String path); List<JSONConfig> getSubsectionsOrNull(@NotNull String path);
/**
* Get subsection from config.
*
* @param path The key to check.
* @return The subsection. Throws NPE if not found.
*/
@Override
@NotNull
JSONConfig getSubsection(@NotNull String path);
/**
* Get subsection from config.
*
* @param path The key to check.
* @return The subsection, or null if not found.
*/
@Override
@Nullable
JSONConfig getSubsectionOrNull(@NotNull String path);
@Override @Override
JSONConfig clone(); JSONConfig clone();
} }

View File

@@ -34,7 +34,7 @@ public interface LoadableConfig {
File getConfigFile(); File getConfigFile();
/** /**
* Get the config name (including extension) * Get the config name (including extension).
* *
* @return The name. * @return The name.
*/ */

View File

@@ -0,0 +1,78 @@
package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Config implementation for configs present in the plugin's base directory (eg config.json).
* <p>
* Automatically updates.
*/
public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
*/
protected JSONBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin,
@NotNull final String... updateBlacklist) {
super(
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused, updateBlacklist
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
*/
protected JSONBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin) {
super(
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
*/
protected JSONBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final String... updateBlacklist) {
this(configName, removeUnused, (PluginLike) plugin, updateBlacklist);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
*/
protected JSONBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin) {
this(configName, removeUnused, (PluginLike) plugin);
}
}

View File

@@ -0,0 +1,60 @@
package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Config implementation for configs present in one of two places:
* <ul>
* <li>Plugin base directory (eg config.yml, lang.yml)</li>
* <li>Other extension's configs</li>
* </ul>
* <p>
* Automatically updates.
*/
public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper {
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
*/
protected JSONExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
super(
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
configName,
plugin,
subDirectoryPath,
source,
removeUnused,
updateBlacklist
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
*/
protected JSONExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
this(configName, removeUnused, (PluginLike) plugin, source, subDirectoryPath, updateBlacklist);
}
}

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.config.json;
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.PluginLike;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper; import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -18,7 +19,20 @@ public abstract class JSONStaticBaseConfig extends LoadableJSONConfigWrapper {
* @param plugin The plugin. * @param plugin The plugin.
*/ */
protected JSONStaticBaseConfig(@NotNull final String configName, protected JSONStaticBaseConfig(@NotNull final String configName,
@NotNull final EcoPlugin plugin) { @NotNull final PluginLike plugin) {
super(Eco.getHandler().getConfigFactory().createLoadableJSONConfig(configName, plugin, "", plugin.getClass())); super(Eco.getHandler().getConfigFactory().createLoadableJSONConfig(configName, plugin, "", plugin.getClass()));
} }
/**
* Config implementation for configs present in the plugin's base directory (eg config.json, lang.json).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
*/
protected JSONStaticBaseConfig(@NotNull final String configName,
@NotNull final EcoPlugin plugin) {
this(configName, (PluginLike) plugin);
}
} }

View File

@@ -31,6 +31,16 @@ public abstract class JSONConfigWrapper extends ConfigWrapper<JSONConfig> implem
return this.getHandle().getSubsectionsOrNull(path); return this.getHandle().getSubsectionsOrNull(path);
} }
@Override
public @NotNull JSONConfig getSubsection(@NotNull final String path) {
return this.getHandle().getSubsection(path);
}
@Override
public @Nullable JSONConfig getSubsectionOrNull(@NotNull final String path) {
return this.getHandle().getSubsectionOrNull(path);
}
@Override @Override
public JSONConfig clone() { public JSONConfig clone() {
return this.getHandle().clone(); return this.getHandle().clone();

View File

@@ -4,7 +4,7 @@ import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
* Every {@link com.willfp.eco.core.EcoPlugin} has a config handler. * Every {@link com.willfp.eco.core.PluginLike} has a config handler.
* <p> * <p>
* Handles updating and saving configs. * Handles updating and saving configs.
*/ */

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.core.config.wrapper; package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.interfaces.Config; import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.interfaces.JSONConfig; import com.willfp.eco.core.config.interfaces.JSONConfig;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
@@ -24,12 +24,30 @@ public interface ConfigFactory {
* @return The config implementation. * @return The config implementation.
*/ */
Config createUpdatableYamlConfig(@NotNull String configName, Config createUpdatableYamlConfig(@NotNull String configName,
@NotNull EcoPlugin plugin, @NotNull PluginLike plugin,
@NotNull String subDirectoryPath, @NotNull String subDirectoryPath,
@NotNull Class<?> source, @NotNull Class<?> source,
boolean removeUnused, boolean removeUnused,
@NotNull String... updateBlacklist); @NotNull String... updateBlacklist);
/**
* Updatable config.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @return The config implementation.
*/
JSONConfig createUpdatableJSONConfig(@NotNull String configName,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source,
boolean removeUnused,
@NotNull String... updateBlacklist);
/** /**
* JSON loadable config. * JSON loadable config.
* *
@@ -40,7 +58,7 @@ public interface ConfigFactory {
* @return The config implementation. * @return The config implementation.
*/ */
JSONConfig createLoadableJSONConfig(@NotNull String configName, JSONConfig createLoadableJSONConfig(@NotNull String configName,
@NotNull EcoPlugin plugin, @NotNull PluginLike plugin,
@NotNull String subDirectoryPath, @NotNull String subDirectoryPath,
@NotNull Class<?> source); @NotNull Class<?> source);
@@ -54,7 +72,7 @@ public interface ConfigFactory {
* @return The config implementation. * @return The config implementation.
*/ */
Config createLoadableYamlConfig(@NotNull String configName, Config createLoadableYamlConfig(@NotNull String configName,
@NotNull EcoPlugin plugin, @NotNull PluginLike plugin,
@NotNull String subDirectoryPath, @NotNull String subDirectoryPath,
@NotNull Class<?> source); @NotNull Class<?> source);

View File

@@ -1,7 +1,7 @@
package com.willfp.eco.core.config.wrapper; package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.config.interfaces.Config; import com.willfp.eco.core.config.interfaces.Config;
import lombok.Getter; 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;
@@ -26,7 +26,6 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
* <p> * <p>
* In general use, though, the handle isn't necessary. * In general use, though, the handle isn't necessary.
*/ */
@Getter
private final T handle; private final T handle;
/** /**
@@ -125,48 +124,33 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
return handle.getBoolsOrNull(path); return handle.getBoolsOrNull(path);
} }
@Override
public @NotNull String getString(@NotNull final String path) {
return handle.getString(path);
}
@Override @Override
public @NotNull String getString(@NotNull final String path, public @NotNull String getString(@NotNull final String path,
final boolean format) { final boolean format,
return handle.getString(path, format); @NotNull final StringUtils.FormatOption option) {
} return handle.getString(path, format, option);
@Override
public @Nullable String getStringOrNull(@NotNull final String path) {
return handle.getStringOrNull(path);
} }
@Override @Override
public @Nullable String getStringOrNull(@NotNull final String path, public @Nullable String getStringOrNull(@NotNull final String path,
final boolean format) { final boolean format,
return handle.getStringOrNull(path, format); @NotNull final StringUtils.FormatOption option) {
} return handle.getStringOrNull(path, format, option);
@Override
public @NotNull List<String> getStrings(@NotNull final String path) {
return handle.getStrings(path);
} }
@Override @Override
public @NotNull List<String> getStrings(@NotNull final String path, public @NotNull List<String> getStrings(@NotNull final String path,
final boolean format) { final boolean format,
return handle.getStrings(path, format); @NotNull final StringUtils.FormatOption option) {
} return handle.getStrings(path, format, option);
@Override
public @Nullable List<String> getStringsOrNull(@NotNull final String path) {
return handle.getStringsOrNull(path);
} }
@Override @Override
public @Nullable List<String> getStringsOrNull(@NotNull final String path, public @Nullable List<String> getStringsOrNull(@NotNull final String path,
final boolean format) { final boolean format,
return handle.getStringsOrNull(path, format); @NotNull final StringUtils.FormatOption option) {
return handle.getStringsOrNull(path, format, option);
} }
@Override @Override
@@ -193,4 +177,13 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
public Config clone() { public Config clone() {
return handle.clone(); return handle.clone();
} }
/**
* Get the handle.
*
* @return The handle.
*/
public T getHandle() {
return this.handle;
}
} }

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.config.yaml;
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.PluginLike;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper; import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -19,7 +20,7 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
*/ */
protected YamlBaseConfig(@NotNull final String configName, protected YamlBaseConfig(@NotNull final String configName,
final boolean removeUnused, final boolean removeUnused,
@NotNull final EcoPlugin plugin, @NotNull final PluginLike plugin,
@NotNull final String... updateBlacklist) { @NotNull final String... updateBlacklist) {
super( super(
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig( Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
@@ -39,7 +40,7 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
*/ */
protected YamlBaseConfig(@NotNull final String configName, protected YamlBaseConfig(@NotNull final String configName,
final boolean removeUnused, final boolean removeUnused,
@NotNull final EcoPlugin plugin) { @NotNull final PluginLike plugin) {
super( super(
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig( Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
configName, configName,
@@ -50,4 +51,28 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
) )
); );
} }
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
*/
protected YamlBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final String... updateBlacklist) {
this(configName, removeUnused, (PluginLike) plugin, updateBlacklist);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
*/
protected YamlBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin) {
this(configName, removeUnused, (PluginLike) plugin);
}
} }

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.config.yaml;
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.PluginLike;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper; import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -25,7 +26,7 @@ public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper {
*/ */
protected YamlExtendableConfig(@NotNull final String configName, protected YamlExtendableConfig(@NotNull final String configName,
final boolean removeUnused, final boolean removeUnused,
@NotNull final EcoPlugin plugin, @NotNull final PluginLike plugin,
@NotNull final Class<?> source, @NotNull final Class<?> source,
@NotNull final String subDirectoryPath, @NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) { @NotNull final String... updateBlacklist) {
@@ -40,4 +41,20 @@ public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper {
) )
); );
} }
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
*/
protected YamlExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
this(configName, removeUnused, (PluginLike) plugin, source, subDirectoryPath, updateBlacklist);
}
} }

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.config.yaml;
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.PluginLike;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper; import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -18,7 +19,20 @@ public abstract class YamlStaticBaseConfig extends LoadableYamlConfigWrapper {
* @param plugin The plugin. * @param plugin The plugin.
*/ */
protected YamlStaticBaseConfig(@NotNull final String configName, protected YamlStaticBaseConfig(@NotNull final String configName,
@NotNull final EcoPlugin plugin) { @NotNull final PluginLike plugin) {
super(Eco.getHandler().getConfigFactory().createLoadableYamlConfig(configName, plugin, "", plugin.getClass())); super(Eco.getHandler().getConfigFactory().createLoadableYamlConfig(configName, plugin, "", plugin.getClass()));
} }
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
*/
protected YamlStaticBaseConfig(@NotNull final String configName,
@NotNull final EcoPlugin plugin) {
this(configName, (PluginLike) plugin);
}
} }

View File

@@ -19,7 +19,6 @@ public abstract class YamlConfigWrapper extends ConfigWrapper<Config> implements
super(handle); super(handle);
} }
@Override @Override
public YamlConfiguration getBukkitHandle() { public YamlConfiguration getBukkitHandle() {
return ((WrappedYamlConfiguration) this.getHandle()).getBukkitHandle(); return ((WrappedYamlConfiguration) this.getHandle()).getBukkitHandle();

View File

@@ -0,0 +1,56 @@
package com.willfp.eco.core.data;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.data.keys.PersistentDataKey;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
/**
* Persistent data storage interface for players.
* <p>
* Profiles save automatically, so there is no need to save after changes.
*/
public interface PlayerProfile {
/**
* Write a key to a player's persistent data.
*
* @param key The key.
* @param value The value.
* @param <T> The type of the key.
*/
<T> void write(@NotNull PersistentDataKey<T> key,
@NotNull T value);
/**
* Read a key from a player's persistent data.
*
* @param key The key.
* @param <T> The type of the key.
* @return The value, or the default value if not found.
*/
<T> @NotNull T read(@NotNull PersistentDataKey<T> key);
/**
* Load a player profile.
*
* @param player The player.
* @return The profile.
*/
@NotNull
static PlayerProfile load(@NotNull final OfflinePlayer player) {
return load(player.getUniqueId());
}
/**
* Load a player profile.
*
* @param uuid The player's UUID.
* @return The profile.
*/
@NotNull
static PlayerProfile load(@NotNull final UUID uuid) {
return Eco.getHandler().getPlayerProfileHandler().load(uuid);
}
}

View File

@@ -0,0 +1,41 @@
package com.willfp.eco.core.data;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
/**
* API to handle player profiles.
*/
public interface PlayerProfileHandler {
/**
* Load a player profile.
*
* @param uuid The UUID.
* @return The profile.
*/
PlayerProfile load(@NotNull UUID uuid);
/**
* Save a player profile.
*
* @param uuid The uuid.
*/
void savePlayer(@NotNull UUID uuid);
/**
* Save all player data.
*
* @param async If the saving should be done asynchronously.
* @deprecated async is now handled automatically depending on implementation.
*/
@Deprecated
default void saveAll(boolean async) {
saveAll();
}
/**
* Save all player data.
*/
void saveAll();
}

View File

@@ -0,0 +1,24 @@
package com.willfp.eco.core.data.keys;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
/**
* API to register persistent data keys.
*/
public interface KeyRegistry {
/**
* Register a persistent data key to be stored.
*
* @param key The key.
*/
void registerKey(@NotNull PersistentDataKey<?> key);
/**
* Get all registered keys.
*
* @return The keys.
*/
Set<PersistentDataKey<?>> getRegisteredKeys();
}

View File

@@ -0,0 +1,91 @@
package com.willfp.eco.core.data.keys;
import com.willfp.eco.core.Eco;
import org.bukkit.NamespacedKey;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
/**
* A persistent data key is a key with a type that can be stored about an offline player.
*
* @param <T> The type of the data.
*/
public class PersistentDataKey<T> {
/**
* The key of the persistent data value.
*/
private final NamespacedKey key;
/**
* The default value for the key.
*/
private final T defaultValue;
/**
* The persistent data key type.
*/
private final PersistentDataKeyType type;
/**
* Create a new Persistent Data Key.
*
* @param key The key.
* @param type The data type.
* @param defaultValue The default value.
*/
public PersistentDataKey(@NotNull final NamespacedKey key,
@NotNull final PersistentDataKeyType type,
@NotNull final T defaultValue) {
this.key = key;
this.defaultValue = defaultValue;
this.type = type;
Eco.getHandler().getKeyRegistry().registerKey(this);
}
@Override
public String toString() {
return "PersistentDataKey{"
+ "key=" + key
+ ", defaultValue=" + defaultValue
+ ", type=" + type
+ '}';
}
/**
* Get all persistent data keys.
*
* @return The keys.
*/
public static Set<PersistentDataKey<?>> values() {
return Eco.getHandler().getKeyRegistry().getRegisteredKeys();
}
/**
* Get the key.
*
* @return The key.
*/
public NamespacedKey getKey() {
return this.key;
}
/**
* Get the default value.
*
* @return The default value.
*/
public T getDefaultValue() {
return this.defaultValue;
}
/**
* Get the data key type.
*
* @return The key type.
*/
public PersistentDataKeyType getType() {
return this.type;
}
}

View File

@@ -0,0 +1,26 @@
package com.willfp.eco.core.data.keys;
/**
* All storable data key types.
*/
public enum PersistentDataKeyType {
/**
* String.
*/
STRING,
/**
* Boolean.
*/
BOOLEAN,
/**
* Integer.
*/
INT,
/**
* Double.
*/
DOUBLE
}

View File

@@ -1,54 +1,24 @@
package com.willfp.eco.core.display; package com.willfp.eco.core.display;
import lombok.experimental.UtilityClass; import org.bukkit.entity.Player;
import org.apache.commons.lang.Validate;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; 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;
/** /**
* Utility class to manage client-side item display. * Utility class to manage client-side item display.
*/ */
@UtilityClass public final class Display {
public class Display {
/** /**
* The prefix for client-side lore lines. * The prefix for client-side lore lines.
*/ */
public static final String PREFIX = "§z"; public static final String PREFIX = "§z";
/** /**
* All registered display modules. * The display handler.
*/ */
private static final Map<DisplayPriority, List<DisplayModule>> MODULES = new HashMap<>(); private static DisplayHandler handler = null;
/**
* NamespacedKey for finalizing.
*/
private static NamespacedKey finalizeKey = null;
/**
* Register display module.
*
* @param module The module.
*/
public void registerDisplayModule(@NotNull final DisplayModule module) {
List<DisplayModule> modules = MODULES.get(module.getPriority());
modules.removeIf(module1 -> module1.getPluginName().equalsIgnoreCase(module.getPluginName()));
modules.add(module);
MODULES.put(module.getPriority(), modules);
}
/** /**
* Display on ItemStacks. * Display on ItemStacks.
@@ -56,37 +26,20 @@ public class Display {
* @param itemStack The item. * @param itemStack The item.
* @return The ItemStack. * @return The ItemStack.
*/ */
public ItemStack display(@NotNull final ItemStack itemStack) { public static ItemStack display(@NotNull final ItemStack itemStack) {
if (!itemStack.hasItemMeta()) { return display(itemStack, null);
return itemStack; // return early if there's no customization of the item }
}
Map<String, Object[]> pluginVarArgs = new HashMap<>(); /**
* Display on ItemStacks.
for (DisplayPriority priority : DisplayPriority.values()) { *
List<DisplayModule> modules = MODULES.get(priority); * @param itemStack The item.
for (DisplayModule module : modules) { * @param player The player.
pluginVarArgs.put(module.getPluginName(), module.generateVarArgs(itemStack)); * @return The ItemStack.
} */
} public static ItemStack display(@NotNull final ItemStack itemStack,
@Nullable final Player player) {
revert(itemStack); return handler.display(itemStack, player);
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
return itemStack;
}
for (DisplayPriority priority : DisplayPriority.values()) {
List<DisplayModule> modules = MODULES.get(priority);
for (DisplayModule module : modules) {
Object[] varargs = pluginVarArgs.get(module.getPluginName());
module.display(itemStack, varargs);
}
}
return itemStack;
} }
/** /**
@@ -95,8 +48,20 @@ public class Display {
* @param itemStack The item. * @param itemStack The item.
* @return The ItemStack. * @return The ItemStack.
*/ */
public ItemStack displayAndFinalize(@NotNull final ItemStack itemStack) { public static ItemStack displayAndFinalize(@NotNull final ItemStack itemStack) {
return finalize(display(itemStack)); return finalize(display(itemStack, null));
}
/**
* Display on ItemStacks and then finalize.
*
* @param itemStack The item.
* @param player The player.
* @return The ItemStack.
*/
public static ItemStack displayAndFinalize(@NotNull final ItemStack itemStack,
@Nullable final Player player) {
return finalize(display(itemStack, player));
} }
/** /**
@@ -105,36 +70,8 @@ public class Display {
* @param itemStack The item. * @param itemStack The item.
* @return The ItemStack. * @return The ItemStack.
*/ */
public ItemStack revert(@NotNull final ItemStack itemStack) { public static ItemStack revert(@NotNull final ItemStack itemStack) {
if (Display.isFinalized(itemStack)) { return handler.revert(itemStack);
unfinalize(itemStack);
}
if (!itemStack.hasItemMeta()) {
return itemStack;
}
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
return itemStack;
}
List<String> lore = meta.getLore();
if (lore != null && lore.removeIf(line -> line.startsWith(Display.PREFIX))) { // only apply lore modification if needed
meta.setLore(lore);
itemStack.setItemMeta(meta);
}
for (DisplayPriority priority : DisplayPriority.values()) {
List<DisplayModule> modules = MODULES.get(priority);
for (DisplayModule module : modules) {
module.revert(itemStack);
}
}
return itemStack;
} }
/** /**
@@ -143,22 +80,8 @@ public class Display {
* @param itemStack The item. * @param itemStack The item.
* @return The ItemStack. * @return The ItemStack.
*/ */
public ItemStack finalize(@NotNull final ItemStack itemStack) { public static ItemStack finalize(@NotNull final ItemStack itemStack) {
Validate.notNull(finalizeKey, "Key cannot be null!"); return handler.finalize(itemStack);
if (itemStack.getType().getMaxStackSize() > 1) {
return itemStack;
}
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
return itemStack;
}
PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(finalizeKey, PersistentDataType.INTEGER, 1);
itemStack.setItemMeta(meta);
return itemStack;
} }
/** /**
@@ -167,19 +90,8 @@ public class Display {
* @param itemStack The item. * @param itemStack The item.
* @return The ItemStack. * @return The ItemStack.
*/ */
public ItemStack unfinalize(@NotNull final ItemStack itemStack) { public static ItemStack unfinalize(@NotNull final ItemStack itemStack) {
Validate.notNull(finalizeKey, "Key cannot be null!"); return handler.unfinalize(itemStack);
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
return itemStack;
}
PersistentDataContainer container = meta.getPersistentDataContainer();
container.remove(finalizeKey);
itemStack.setItemMeta(meta);
return itemStack;
} }
/** /**
@@ -188,32 +100,82 @@ public class Display {
* @param itemStack The item. * @param itemStack The item.
* @return If finalized. * @return If finalized.
*/ */
public boolean isFinalized(@NotNull final ItemStack itemStack) { public static boolean isFinalized(@NotNull final ItemStack itemStack) {
Validate.notNull(finalizeKey, "Key cannot be null!"); return handler.isFinalized(itemStack);
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
return false;
}
PersistentDataContainer container = meta.getPersistentDataContainer();
return container.has(finalizeKey, PersistentDataType.INTEGER);
} }
/** /**
* Set key to be used for finalization. * Register a new display module.
* *
* @param finalizeKey The key. * @param module The module.
*/ */
@ApiStatus.Internal public static void registerDisplayModule(@NotNull final DisplayModule module) {
public static void setFinalizeKey(@NotNull final NamespacedKey finalizeKey) { handler.registerDisplayModule(module);
Display.finalizeKey = finalizeKey;
} }
static { /**
for (DisplayPriority priority : DisplayPriority.values()) { * Initialize the display system.
MODULES.put(priority, new ArrayList<>()); *
* @param handler The handler.
*/
@ApiStatus.Internal
public static void init(@NotNull final DisplayHandler handler) {
if (Display.handler != null) {
throw new IllegalArgumentException("Already Initialized!");
}
Display.handler = handler;
}
/**
* Extremely janky method - also internal, so don't use it. <b>This method is
* NOT part of the API and may be removed at any time!</b>
* <p>
* This calls a display module with the specified parameters, now
* you might ask why I need a static java method when the DisplayHandler
* implementation could just call it itself? Well, kotlin doesn't really
* like dealing with vararg ambiguity, and so while kotlin can't figure out
* what is and isn't a vararg when I call display with a player, java can.
* <p>
* Because of this, I need to have this part of the code in java.
*
* <b>Don't call this method as part of your plugins!</b>
* <p>
* No, seriously - don't. This skips a bunch of checks and you'll almost
* definitely break something.
*
* @param module The display module.
* @param itemStack The ItemStack.
* @param player The player.
* @param args The args.
*/
@ApiStatus.Internal
public static void callDisplayModule(@NotNull final DisplayModule module,
@NotNull final ItemStack itemStack,
@Nullable final Player player,
@NotNull final Object... args) {
module.display(itemStack, args);
if (player != null) {
module.display(itemStack, player, args);
} }
} }
/**
* Set the display handler.
* <p>
* Internal API component, you will cause bugs if you create your own handler.
*
* @param handler The handler.
*/
@ApiStatus.Internal
public static void setHandler(@NotNull final DisplayHandler handler) {
if (Display.handler != null) {
throw new IllegalStateException("Display already initialized!");
}
Display.handler = handler;
}
private Display() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
} }

View File

@@ -0,0 +1,60 @@
package com.willfp.eco.core.display;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Interface for display implementations.
*/
public interface DisplayHandler {
/**
* Register display module.
*
* @param module The module.
*/
void registerDisplayModule(@NotNull DisplayModule module);
/**
* Display on ItemStacks.
*
* @param itemStack The item.
* @param player The player.
* @return The ItemStack.
*/
ItemStack display(@NotNull ItemStack itemStack,
@Nullable Player player);
/**
* Revert on ItemStacks.
*
* @param itemStack The item.
* @return The ItemStack.
*/
ItemStack revert(@NotNull ItemStack itemStack);
/**
* Finalize an ItemStacks.
*
* @param itemStack The item.
* @return The ItemStack.
*/
ItemStack finalize(@NotNull ItemStack itemStack);
/**
* Unfinalize an ItemStacks.
*
* @param itemStack The item.
* @return The ItemStack.
*/
ItemStack unfinalize(@NotNull ItemStack itemStack);
/**
* If an item is finalized.
*
* @param itemStack The item.
* @return If finalized.
*/
boolean isFinalized(@NotNull ItemStack itemStack);
}

View File

@@ -2,9 +2,10 @@ package com.willfp.eco.core.display;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginDependent; import com.willfp.eco.core.PluginDependent;
import lombok.Getter; import org.bukkit.entity.Player;
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;
/** /**
* Class for all plugin-specific client-side item display modules. * Class for all plugin-specific client-side item display modules.
@@ -13,7 +14,6 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
/** /**
* The priority of the module. * The priority of the module.
*/ */
@Getter
private final DisplayPriority priority; private final DisplayPriority priority;
/** /**
@@ -34,8 +34,21 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
* @param itemStack The item. * @param itemStack The item.
* @param args Optional args for display. * @param args Optional args for display.
*/ */
protected void display(@NotNull final ItemStack itemStack, public void display(@NotNull final ItemStack itemStack,
@NotNull final Object... args) { @NotNull final Object... args) {
// Technically optional.
}
/**
* Display an item.
*
* @param itemStack The item.
* @param player The player.
* @param args Optional args for display.
*/
public void display(@NotNull final ItemStack itemStack,
@Nullable final Player player,
@NotNull final Object... args) {
// Technically optional. // Technically optional.
} }
@@ -44,7 +57,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
* *
* @param itemStack The item. * @param itemStack The item.
*/ */
protected void revert(@NotNull final ItemStack itemStack) { public void revert(@NotNull final ItemStack itemStack) {
// Technically optional. // Technically optional.
} }
@@ -54,7 +67,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
* @param itemStack The itemStack. * @param itemStack The itemStack.
* @return The plugin-specific varargs. * @return The plugin-specific varargs.
*/ */
protected Object[] generateVarArgs(@NotNull final ItemStack itemStack) { public Object[] generateVarArgs(@NotNull final ItemStack itemStack) {
return new Object[0]; return new Object[0];
} }
@@ -66,4 +79,13 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
public final String getPluginName() { public final String getPluginName() {
return super.getPlugin().getName(); return super.getPlugin().getName();
} }
/**
* Get the display priority.
*
* @return The priority.
*/
public DisplayPriority getPriority() {
return this.priority;
}
} }

View File

@@ -0,0 +1,84 @@
package com.willfp.eco.core.events;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* The armor change event <b>does</b> contain information about the event.
* <p>
* Unlike {@link ArmorEquipEvent}, it is called the next tick and contains previous and current armor contents.
*/
public class ArmorChangeEvent extends PlayerEvent {
/**
* Bukkit parity.
*/
private static final HandlerList HANDLERS = new HandlerList();
/**
* The armor contents before. 0 is helmet, 3 is boots.
*/
private final List<ItemStack> before;
/**
* The armor contents after. 0 is helmet, 3 is boots.
*/
private final List<ItemStack> after;
/**
* Create a new ArmorChangeEvent.
*
* @param player The player.
* @param before The armor contents before.
* @param after The armor contents after.
*/
public ArmorChangeEvent(@NotNull final Player player,
@NotNull final List<ItemStack> before,
@NotNull final List<ItemStack> after) {
super(player);
this.before = before;
this.after = after;
}
/**
* Gets a list of handlers handling this event.
*
* @return A list of handlers handling this event.
*/
@Override
@NotNull
public HandlerList getHandlers() {
return HANDLERS;
}
/**
* Bukkit parity.
*
* @return The handler list.
*/
public static HandlerList getHandlerList() {
return HANDLERS;
}
/**
* Get the contents before the change.
*
* @return The contents.
*/
public List<ItemStack> getBefore() {
return this.before;
}
/**
* Get the current contents.
*
* @return The contents.
*/
public List<ItemStack> getAfter() {
return this.after;
}
}

View File

@@ -13,8 +13,13 @@ import org.jetbrains.annotations.NotNull;
* <p> * <p>
* The event is called before the player's inventory actually updates, * The event is called before the player's inventory actually updates,
* so you can check a tick later to see the new contents. * so you can check a tick later to see the new contents.
*
* @see ArmorChangeEvent
*/ */
public class ArmorEquipEvent extends PlayerEvent { public class ArmorEquipEvent extends PlayerEvent {
/**
* Bukkit parity.
*/
private static final HandlerList HANDLERS = new HandlerList(); private static final HandlerList HANDLERS = new HandlerList();
/** /**

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.core.events; package com.willfp.eco.core.events;
import lombok.Getter;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Event; import org.bukkit.event.Event;
@@ -25,31 +24,26 @@ public class EntityDeathByEntityEvent extends Event {
/** /**
* The {@link LivingEntity} killed. * The {@link LivingEntity} killed.
*/ */
@Getter
private final LivingEntity victim; private final LivingEntity victim;
/** /**
* The {@link Entity} that killed. * The {@link Entity} that killed.
*/ */
@Getter
private final Entity killer; private final Entity killer;
/** /**
* The associated {@link EntityDeathEvent}. * The associated {@link EntityDeathEvent}.
*/ */
@Getter
private final EntityDeathEvent deathEvent; private final EntityDeathEvent deathEvent;
/** /**
* The entity drops. * The entity drops.
*/ */
@Getter
private final List<ItemStack> drops; private final List<ItemStack> drops;
/** /**
* The xp to drop. * The xp to drop.
*/ */
@Getter
private final int xp; private final int xp;
/** /**
@@ -91,4 +85,49 @@ public class EntityDeathByEntityEvent extends Event {
public static HandlerList getHandlerList() { public static HandlerList getHandlerList() {
return HANDLERS; return HANDLERS;
} }
/**
* Get the entity killed.
*
* @return The victim.
*/
public LivingEntity getVictim() {
return this.victim;
}
/**
* Get the killer.
*
* @return The killer.
*/
public Entity getKiller() {
return this.killer;
}
/**
* Get the death event that caused this event.
*
* @return The death event.
*/
public EntityDeathEvent getDeathEvent() {
return this.deathEvent;
}
/**
* Get the drops.
*
* @return The drops.
*/
public List<ItemStack> getDrops() {
return this.drops;
}
/**
* Get the experience dropped.
*
* @return The experience.
*/
public int getXp() {
return this.xp;
}
} }

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.core.events; package com.willfp.eco.core.events;
import lombok.Getter;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerExpChangeEvent; import org.bukkit.event.player.PlayerExpChangeEvent;
@@ -20,7 +19,6 @@ public class NaturalExpGainEvent extends Event {
* The associated {@link PlayerExpChangeEvent}. * The associated {@link PlayerExpChangeEvent}.
* Use this to modify event parameters. * Use this to modify event parameters.
*/ */
@Getter
private final PlayerExpChangeEvent expChangeEvent; private final PlayerExpChangeEvent expChangeEvent;
/** /**
@@ -50,4 +48,13 @@ public class NaturalExpGainEvent extends Event {
public static HandlerList getHandlerList() { public static HandlerList getHandlerList() {
return HANDLERS; return HANDLERS;
} }
/**
* Get the event that caused this event.
*
* @return The exp change event.
*/
public PlayerExpChangeEvent getExpChangeEvent() {
return this.expChangeEvent;
}
} }

View File

@@ -1,11 +1,13 @@
package com.willfp.eco.core.extensions; package com.willfp.eco.core.extensions;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import lombok.AccessLevel; import com.willfp.eco.core.PluginLike;
import lombok.Getter; import com.willfp.eco.core.config.updating.ConfigHandler;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.File;
/** /**
* An extension is a separate jar file that hooks into the base plugin jar. * An extension is a separate jar file that hooks into the base plugin jar.
* <p> * <p>
@@ -15,13 +17,12 @@ import org.jetbrains.annotations.NotNull;
* Syntactically, extensions are very similar to plugins in their own right, except that * Syntactically, extensions are very similar to plugins in their own right, except that
* they are loaded by another plugin. * they are loaded by another plugin.
* *
* @see <a href="https://ecoenchants.polymart.org">EcoEnchants extension examples.</a> * @see <a href="https://auxilor.polymart.org">Extension examples.</a>
*/ */
public abstract class Extension { public abstract class Extension implements PluginLike {
/** /**
* The {@link EcoPlugin} that this extension is for. * The {@link EcoPlugin} that this extension is for.
*/ */
@Getter(AccessLevel.PROTECTED)
private final EcoPlugin plugin; private final EcoPlugin plugin;
/** /**
@@ -53,6 +54,20 @@ public abstract class Extension {
this.onDisable(); this.onDisable();
} }
/**
* Method to handle after load.
*/
public final void handleAfterLoad() {
this.onAfterLoad();
}
/**
* Method to handle plugin reloads.
*/
public final void handleReload() {
this.onReload();
}
/** /**
* Called on enabling Extension. * Called on enabling Extension.
*/ */
@@ -63,6 +78,20 @@ public abstract class Extension {
*/ */
protected abstract void onDisable(); protected abstract void onDisable();
/**
* Called the once the base plugin is done loading.
*/
protected void onAfterLoad() {
// Override if needed
}
/**
* Called on plugin reload.
*/
protected void onReload() {
// Override if needed
}
/** /**
* Set the metadata of the extension. * Set the metadata of the extension.
* <p> * <p>
@@ -103,4 +132,23 @@ public abstract class Extension {
Validate.notNull(metadata, "Metadata cannot be null!"); Validate.notNull(metadata, "Metadata cannot be null!");
return this.metadata.version(); return this.metadata.version();
} }
@Override
public File getDataFolder() {
return this.plugin.getDataFolder();
}
@Override
public ConfigHandler getConfigHandler() {
return this.plugin.getConfigHandler();
}
/**
* Get the plugin for the extension.
*
* @return The plugin.
*/
protected EcoPlugin getPlugin() {
return this.plugin;
}
} }

View File

@@ -0,0 +1,113 @@
package com.willfp.eco.core.fast;
import com.willfp.eco.core.Eco;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
* FastItemStack contains methods to modify and read items faster than in default bukkit.
*/
public interface FastItemStack {
/**
* Get all enchantments on an item.
*
* @param checkStored If stored NBT should also be checked.
* @return A map of all enchantments.
*/
Map<Enchantment, Integer> getEnchantmentsOnItem(boolean checkStored);
/**
* 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.
*/
int getLevelOnItem(@NotNull Enchantment enchantment,
boolean checkStored);
/**
* Set the item lore.
*
* @param lore The lore.
*/
void setLore(@Nullable List<String> lore);
/**
* Get the item lore.
*
* @return The lore.
*/
List<String> getLore();
/**
* Set the rework penalty.
*
* @param cost The rework penalty to set.
*/
void setRepairCost(int cost);
/**
* Get the rework penalty.
* .
*
* @return The rework penalty found on the item.
*/
int getRepairCost();
/**
* Add ItemFlags.
*
* @param hideFlags The flags.
*/
void addItemFlags(ItemFlag... hideFlags);
/**
* Remove ItemFlags.
*
* @param hideFlags The flags.
*/
void removeItemFlags(ItemFlag... hideFlags);
/**
* Get the ItemFlags.
*
* @return The flags.
*/
Set<ItemFlag> getItemFlags();
/**
* Test the item for a flag.
*
* @param flag The flag.
* @return If the flag is present.
*/
boolean hasItemFlag(ItemFlag flag);
/**
* Get the Bukkit ItemStack again.
*
* @return The ItemStack.
*/
ItemStack unwrap();
/**
* Wrap an ItemStack to create a FastItemStack.
*
* @param itemStack The ItemStack.
* @return The FastItemStack.
*/
static FastItemStack wrap(@Nullable final ItemStack itemStack) {
return Eco.getHandler().createFastItemStack(Objects.requireNonNullElseGet(itemStack, () -> new ItemStack(Material.AIR)));
}
}

View File

@@ -2,12 +2,10 @@ package com.willfp.eco.core.gui;
import com.willfp.eco.core.gui.menu.MenuBuilder; import com.willfp.eco.core.gui.menu.MenuBuilder;
import com.willfp.eco.core.gui.slot.SlotBuilder; import com.willfp.eco.core.gui.slot.SlotBuilder;
import org.bukkit.entity.Player; import com.willfp.eco.core.gui.slot.functional.SlotProvider;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.function.Function;
/** /**
* Internal component used by {@link com.willfp.eco.core.gui.menu.Menu#builder(int)} * Internal component used by {@link com.willfp.eco.core.gui.menu.Menu#builder(int)}
* and {@link com.willfp.eco.core.gui.slot.Slot#builder(ItemStack)}. * and {@link com.willfp.eco.core.gui.slot.Slot#builder(ItemStack)}.
@@ -19,7 +17,7 @@ public interface GUIFactory {
* @param provider The provider. * @param provider The provider.
* @return The builder. * @return The builder.
*/ */
SlotBuilder createSlotBuilder(@NotNull Function<Player, ItemStack> provider); SlotBuilder createSlotBuilder(@NotNull SlotProvider provider);
/** /**
* Create menu builder. * Create menu builder.

View File

@@ -0,0 +1,19 @@
package com.willfp.eco.core.gui.menu;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.jetbrains.annotations.NotNull;
/**
* Interface to run on menu close.
*/
@FunctionalInterface
public interface CloseHandler {
/**
* Performs this operation on the given arguments.
*
* @param event The close event.
* @param menu The menu.
*/
void handle(@NotNull InventoryCloseEvent event,
@NotNull Menu menu);
}

View File

@@ -2,9 +2,16 @@ 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.slot.Slot; import com.willfp.eco.core.gui.slot.Slot;
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.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Set;
/** /**
* GUI version of {@link Inventory}. * GUI version of {@link Inventory}.
@@ -44,6 +51,51 @@ public interface Menu {
*/ */
Inventory open(@NotNull Player player); Inventory open(@NotNull Player player);
/**
* Get captive items.
*
* @param player The player.
* @return The items.
*/
List<ItemStack> getCaptiveItems(@NotNull Player player);
/**
* 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.
*/
<T, Z> void writeData(@NotNull Player player,
@NotNull NamespacedKey key,
@NotNull PersistentDataType<T, Z> type,
@NotNull Z 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.
*/
@Nullable <T, Z> T readData(@NotNull Player player,
@NotNull NamespacedKey key,
@NotNull PersistentDataType<T, Z> type);
/**
* Get all data keys for a player.
*
* @param player The player.
* @return The keys.
*/
Set<NamespacedKey> getKeys(@NotNull Player player);
/** /**
* Create a builder with a given amount of rows. * Create a builder with a given amount of rows.
* *

View File

@@ -31,6 +31,14 @@ public interface MenuBuilder {
int column, int column,
@NotNull Slot slot); @NotNull Slot slot);
/**
* Run function to modify the builder.
*
* @param modifier The modifier.
* @return The builder.
*/
MenuBuilder modfiy(@NotNull Consumer<MenuBuilder> modifier);
/** /**
* Set the menu mask. * Set the menu mask.
* *
@@ -45,7 +53,18 @@ public interface MenuBuilder {
* @param action The handler. * @param action The handler.
* @return The builder. * @return The builder.
*/ */
MenuBuilder onClose(@NotNull Consumer<InventoryCloseEvent> action); default MenuBuilder onClose(@NotNull Consumer<InventoryCloseEvent> action) {
onClose((event, menu) -> action.accept(event));
return this;
}
/**
* Set the menu close handler.
*
* @param action The handler.
* @return The builder.
*/
MenuBuilder onClose(@NotNull CloseHandler action);
/** /**
* Build the menu. * Build the menu.

View File

@@ -2,11 +2,11 @@ package com.willfp.eco.core.gui.slot;
import com.willfp.eco.core.items.builder.ItemStackBuilder; import com.willfp.eco.core.items.builder.ItemStackBuilder;
import com.willfp.eco.util.ListUtils; import com.willfp.eco.util.ListUtils;
import lombok.Getter;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@@ -28,7 +28,6 @@ public class FillerMask {
/** /**
* Mask. * Mask.
*/ */
@Getter
private final List<List<Slot>> mask; private final List<List<Slot>> mask;
/** /**
@@ -39,35 +38,55 @@ public class FillerMask {
*/ */
public FillerMask(@NotNull final Material material, public FillerMask(@NotNull final Material material,
@NotNull final String... pattern) { @NotNull final String... pattern) {
if (material == Material.AIR) { this(new MaskMaterials(material), pattern);
throw new IllegalArgumentException("Material cannot be air!"); }
/**
* Create a new filler mask.
*
* @param materials The mask materials.
* @param pattern The pattern.
*/
public FillerMask(@NotNull final MaskMaterials materials,
@NotNull final String... pattern) {
if (Arrays.stream(materials.materials()).anyMatch(material -> material == Material.AIR)) {
throw new IllegalArgumentException("Materials cannot be air!");
} }
mask = ListUtils.create2DList(6, 9); mask = ListUtils.create2DList(6, 9);
ItemStack itemStack = new ItemStackBuilder(material) for (int i = 0; i < materials.materials().length; i++) {
.setDisplayName("&r") ItemStack itemStack = new ItemStackBuilder(materials.materials()[i])
.build(); .setDisplayName("&r")
.build();
int row = 0; int row = 0;
for (String patternRow : pattern) { for (String patternRow : pattern) {
int column = 0; int column = 0;
if (patternRow.length() != 9) { if (patternRow.length() != 9) {
throw new IllegalArgumentException("Invalid amount of columns in pattern!"); throw new IllegalArgumentException("Invalid amount of columns in pattern!");
}
for (char c : patternRow.toCharArray()) {
if (c == '0') {
mask.get(row).set(column, null);
} else if (c == '1') {
mask.get(row).set(column, new FillerSlot(itemStack));
} else {
throw new IllegalArgumentException("Invalid character in pattern! (Must only be 0 and 1)");
} }
for (char c : patternRow.toCharArray()) {
if (c == '0') {
mask.get(row).set(column, null);
} else if (c == Character.forDigit(i + 1, 10)) {
mask.get(row).set(column, new FillerSlot(itemStack));
}
column++; column++;
}
row++;
} }
row++;
} }
} }
/**
* Get the mask.
*
* @return The mask.
*/
public List<List<Slot>> getMask() {
return this.mask;
}
} }

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.core.gui.slot; package com.willfp.eco.core.gui.slot;
import lombok.Getter;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -14,7 +13,6 @@ public class FillerSlot implements Slot {
/** /**
* The ItemStack. * The ItemStack.
*/ */
@Getter
private final ItemStack itemStack; private final ItemStack itemStack;
/** /**
@@ -30,4 +28,18 @@ public class FillerSlot implements Slot {
public ItemStack getItemStack(@NotNull final Player player) { public ItemStack getItemStack(@NotNull final Player player) {
return itemStack; return itemStack;
} }
@Override
public boolean isCaptive() {
return false;
}
/**
* Get the ItemStack.
*
* @return The ItemStack.
*/
public ItemStack getItemStack() {
return this.itemStack;
}
} }

View File

@@ -0,0 +1,14 @@
package com.willfp.eco.core.gui.slot;
import org.bukkit.Material;
import org.jetbrains.annotations.NotNull;
/**
* Mask materials store a set of materials which can be accessed by
* a filler mask.
*
* @param materials The materials.
*/
public record MaskMaterials(@NotNull Material... materials) {
}

View File

@@ -1,6 +1,8 @@
package com.willfp.eco.core.gui.slot; package com.willfp.eco.core.gui.slot;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -19,6 +21,22 @@ public interface Slot {
*/ */
ItemStack getItemStack(@NotNull Player player); ItemStack getItemStack(@NotNull Player player);
/**
* If the slot is captive. (Can items be placed in it).
*
* @return If captive.
*/
boolean isCaptive();
/**
* Create a builder for an ItemStack.
*
* @return The builder.
*/
static SlotBuilder builder() {
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> new ItemStack(Material.AIR));
}
/** /**
* Create a builder for an ItemStack. * Create a builder for an ItemStack.
* *
@@ -26,7 +44,7 @@ public interface Slot {
* @return The builder. * @return The builder.
*/ */
static SlotBuilder builder(@NotNull final ItemStack itemStack) { static SlotBuilder builder(@NotNull final ItemStack itemStack) {
return Eco.getHandler().getGUIFactory().createSlotBuilder(player -> itemStack); return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> itemStack);
} }
/** /**
@@ -36,6 +54,16 @@ public interface Slot {
* @return The builder. * @return The builder.
*/ */
static SlotBuilder builder(@NotNull final Function<Player, ItemStack> provider) { static SlotBuilder builder(@NotNull final Function<Player, ItemStack> provider) {
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> provider.apply(player));
}
/**
* Create a builder for a player-specific ItemStack.
*
* @param provider The provider.
* @return The builder.
*/
static SlotBuilder builder(@NotNull final SlotProvider provider) {
return Eco.getHandler().getGUIFactory().createSlotBuilder(provider); return Eco.getHandler().getGUIFactory().createSlotBuilder(provider);
} }
} }

View File

@@ -1,5 +1,7 @@
package com.willfp.eco.core.gui.slot; package com.willfp.eco.core.gui.slot;
import com.willfp.eco.core.gui.slot.functional.SlotHandler;
import com.willfp.eco.core.gui.slot.functional.SlotModifier;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -15,7 +17,17 @@ public interface SlotBuilder {
* @param action The handler. * @param action The handler.
* @return The builder. * @return The builder.
*/ */
SlotBuilder onLeftClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action); default SlotBuilder onLeftClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action) {
return onLeftClick((event, slot, menu) -> action.accept(event, slot));
}
/**
* Set click handler.
*
* @param handler The handler.
* @return The builder.
*/
SlotBuilder onLeftClick(@NotNull SlotHandler handler);
/** /**
* Set click handler. * Set click handler.
@@ -23,7 +35,17 @@ public interface SlotBuilder {
* @param action The handler. * @param action The handler.
* @return The builder. * @return The builder.
*/ */
SlotBuilder onRightClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action); default SlotBuilder onRightClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action) {
return onRightClick((event, slot, menu) -> action.accept(event, slot));
}
/**
* Set click handler.
*
* @param handler The handler.
* @return The builder.
*/
SlotBuilder onRightClick(@NotNull SlotHandler handler);
/** /**
* Set click handler. * Set click handler.
@@ -31,7 +53,17 @@ public interface SlotBuilder {
* @param action The handler. * @param action The handler.
* @return The builder. * @return The builder.
*/ */
SlotBuilder onShiftLeftClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action); default SlotBuilder onShiftLeftClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action) {
return onShiftLeftClick((event, slot, menu) -> action.accept(event, slot));
}
/**
* Set click handler.
*
* @param handler The handler.
* @return The builder.
*/
SlotBuilder onShiftLeftClick(@NotNull SlotHandler handler);
/** /**
* Set click handler. * Set click handler.
@@ -39,7 +71,17 @@ public interface SlotBuilder {
* @param action The handler. * @param action The handler.
* @return The builder. * @return The builder.
*/ */
SlotBuilder onShiftRightClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action); default SlotBuilder onShiftRightClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action) {
return onShiftRightClick((event, slot, menu) -> action.accept(event, slot));
}
/**
* Set click handler.
*
* @param handler The handler.
* @return The builder.
*/
SlotBuilder onShiftRightClick(@NotNull SlotHandler handler);
/** /**
* Set click handler. * Set click handler.
@@ -47,7 +89,32 @@ public interface SlotBuilder {
* @param action The handler. * @param action The handler.
* @return The builder. * @return The builder.
*/ */
SlotBuilder onMiddleClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action); default SlotBuilder onMiddleClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action) {
return onMiddleClick((event, slot, menu) -> action.accept(event, slot));
}
/**
* Set click handler.
*
* @param handler The handler.
* @return The builder.
*/
SlotBuilder onMiddleClick(@NotNull SlotHandler handler);
/**
* Modify the ItemStack.
*
* @param modifier The modifier.
* @return The builder.
*/
SlotBuilder setModifier(@NotNull SlotModifier modifier);
/**
* Set slot to be a captive slot.
*
* @return The builder.
*/
SlotBuilder setCaptive();
/** /**
* Build the slot. * Build the slot.

View File

@@ -0,0 +1,23 @@
package com.willfp.eco.core.gui.slot.functional;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.slot.Slot;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.jetbrains.annotations.NotNull;
/**
* Interface to run on slot click.
*/
@FunctionalInterface
public interface SlotHandler {
/**
* Performs this operation on the given arguments.
*
* @param event The click event.
* @param slot The slot
* @param menu The menu.
*/
void handle(@NotNull InventoryClickEvent event,
@NotNull Slot slot,
@NotNull Menu menu);
}

View File

@@ -0,0 +1,23 @@
package com.willfp.eco.core.gui.slot.functional;
import com.willfp.eco.core.gui.menu.Menu;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* Interface to run on slot modify.
*/
@FunctionalInterface
public interface SlotModifier {
/**
* Performs this operation on the given arguments.
*
* @param player The player.
* @param menu The menu.
* @param previous The previous ItemStack.
*/
void modify(@NotNull Player player,
@NotNull Menu menu,
@NotNull ItemStack previous);
}

View File

@@ -0,0 +1,22 @@
package com.willfp.eco.core.gui.slot.functional;
import com.willfp.eco.core.gui.menu.Menu;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* Interface to run on slot display.
*/
@FunctionalInterface
public interface SlotProvider {
/**
* Performs this operation on the given arguments.
*
* @param player The player.
* @param menu The menu.
* @return The ItemStack.
*/
ItemStack provide(@NotNull Player player,
@NotNull Menu menu);
}

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.core.integrations; package com.willfp.eco.core.integrations;
import lombok.Getter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
@@ -17,7 +16,6 @@ public class IntegrationLoader {
/** /**
* The plugin to require to load the integration. * The plugin to require to load the integration.
*/ */
@Getter
private final String pluginName; private final String pluginName;
/** /**
@@ -38,4 +36,13 @@ public class IntegrationLoader {
public void load() { public void load() {
runnable.run(); runnable.run();
} }
/**
* Get the plugin name.
*
* @return The plugin name.
*/
public String getPluginName() {
return this.pluginName;
}
} }

View File

@@ -0,0 +1,46 @@
package com.willfp.eco.core.integrations.afk;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/**
* Class to handle afk integrations.
*/
public final class AFKManager {
/**
* A set of all registered integrations.
*/
private static final Set<AFKWrapper> REGISTERED = new HashSet<>();
/**
* Register a new integration.
*
* @param integration The integration to register.
*/
public static void register(@NotNull final AFKWrapper integration) {
REGISTERED.add(integration);
}
/**
* Get if a player is afk.
*
* @param player The player.
* @return If afk.
*/
public static boolean isAfk(@NotNull final Player player) {
for (AFKWrapper afkWrapper : REGISTERED) {
if (afkWrapper.isAfk(player)) {
return true;
}
}
return false;
}
private AFKManager() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

View File

@@ -0,0 +1,18 @@
package com.willfp.eco.core.integrations.afk;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* Wrapper class for afk integrations.
*/
public interface AFKWrapper extends Integration {
/**
* Get if a player is afk.
*
* @param player The player.
* @return If afk.
*/
boolean isAfk(@NotNull Player player);
}

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.core.integrations.anticheat; package com.willfp.eco.core.integrations.anticheat;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import lombok.experimental.UtilityClass;
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;
@@ -12,12 +11,11 @@ import java.util.Set;
/** /**
* Class to handle anticheat integrations. * Class to handle anticheat integrations.
*/ */
@UtilityClass public final class AnticheatManager {
public class AnticheatManager {
/** /**
* A set of all registered anticheats. * A set of all registered anticheats.
*/ */
private final Set<AnticheatWrapper> anticheats = new HashSet<>(); private static final Set<AnticheatWrapper> ANTICHEATS = new HashSet<>();
/** /**
* Register a new anticheat. * Register a new anticheat.
@@ -25,12 +23,12 @@ public class AnticheatManager {
* @param plugin The plugin. * @param plugin The plugin.
* @param anticheat The anticheat to register. * @param anticheat The anticheat to register.
*/ */
public void register(@NotNull final EcoPlugin plugin, public static void register(@NotNull final EcoPlugin plugin,
@NotNull final AnticheatWrapper anticheat) { @NotNull final AnticheatWrapper anticheat) {
if (anticheat instanceof Listener) { if (anticheat instanceof Listener) {
plugin.getEventManager().registerListener((Listener) anticheat); plugin.getEventManager().registerListener((Listener) anticheat);
} }
anticheats.add(anticheat); ANTICHEATS.add(anticheat);
} }
/** /**
@@ -38,8 +36,8 @@ public class AnticheatManager {
* *
* @param player The player to exempt. * @param player The player to exempt.
*/ */
public void exemptPlayer(@NotNull final Player player) { public static void exemptPlayer(@NotNull final Player player) {
anticheats.forEach(anticheat -> anticheat.exempt(player)); ANTICHEATS.forEach(anticheat -> anticheat.exempt(player));
} }
/** /**
@@ -48,7 +46,11 @@ public class AnticheatManager {
* *
* @param player The player to remove the exemption. * @param player The player to remove the exemption.
*/ */
public void unexemptPlayer(@NotNull final Player player) { public static void unexemptPlayer(@NotNull final Player player) {
anticheats.forEach(anticheat -> anticheat.unexempt(player)); ANTICHEATS.forEach(anticheat -> anticheat.unexempt(player));
}
private AnticheatManager() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }
} }

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.core.integrations.antigrief; package com.willfp.eco.core.integrations.antigrief;
import lombok.experimental.UtilityClass;
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;
@@ -13,20 +12,29 @@ import java.util.Set;
/** /**
* Class to handle antigrief integrations. * Class to handle antigrief integrations.
*/ */
@UtilityClass public final class AntigriefManager {
public class AntigriefManager {
/** /**
* Registered antigriefs. * Registered antigriefs.
*/ */
private final Set<AntigriefWrapper> registered = new HashSet<>(); private static final Set<AntigriefWrapper> REGISTERED = new HashSet<>();
/** /**
* Register a new AntiGrief/Land Management integration. * Register a new AntiGrief/Land Management integration.
* *
* @param antigrief The integration to register. * @param antigrief The integration to register.
*/ */
public void register(@NotNull final AntigriefWrapper antigrief) { public static void register(@NotNull final AntigriefWrapper antigrief) {
registered.add(antigrief); REGISTERED.add(antigrief);
}
/**
* Unregister an AntiGrief/Land Management integration.
*
* @param antigrief The integration to unregister.
*/
public static void unregister(@NotNull final AntigriefWrapper antigrief) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName()));
REGISTERED.remove(antigrief);
} }
/** /**
@@ -36,9 +44,9 @@ public class AntigriefManager {
* @param block The block. * @param block The block.
* @return If player can break block. * @return If player can break block.
*/ */
public 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(antigriefWrapper -> antigriefWrapper.canBreakBlock(player, block)); return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canBreakBlock(player, block));
} }
/** /**
@@ -48,9 +56,9 @@ public class AntigriefManager {
* @param location The location. * @param location The location.
* @return If player can create explosion. * @return If player can create explosion.
*/ */
public 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(antigriefWrapper -> antigriefWrapper.canCreateExplosion(player, location)); return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canCreateExplosion(player, location));
} }
/** /**
@@ -60,9 +68,9 @@ public class AntigriefManager {
* @param block The block. * @param block The block.
* @return If player can place block. * @return If player can place block.
*/ */
public 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(antigriefWrapper -> antigriefWrapper.canPlaceBlock(player, block)); return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canPlaceBlock(player, block));
} }
/** /**
@@ -72,8 +80,12 @@ public class AntigriefManager {
* @param victim The victim. * @param victim The victim.
* @return If player can injure. * @return If player can injure.
*/ */
public 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(antigriefWrapper -> antigriefWrapper.canInjure(player, victim)); return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canInjure(player, victim));
}
private AntigriefManager() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }
} }

View File

@@ -15,7 +15,7 @@ public interface AntigriefWrapper extends Integration {
* *
* @param player The player. * @param player The player.
* @param block The block. * @param block The block.
* @return If player cna break block. * @return If player can break block.
*/ */
boolean canBreakBlock(Player player, Block block); boolean canBreakBlock(Player player, Block block);

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.core.integrations.customitems; package com.willfp.eco.core.integrations.customitems;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet; import java.util.HashSet;
@@ -9,20 +8,19 @@ import java.util.Set;
/** /**
* Class to handle custom item integrations. * Class to handle custom item integrations.
*/ */
@UtilityClass public final class CustomItemsManager {
public class CustomItemsManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private final Set<CustomItemsWrapper> registered = new HashSet<>(); private static final Set<CustomItemsWrapper> REGISTERED = new HashSet<>();
/** /**
* Register a new integration. * Register a new integration.
* *
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public void register(@NotNull final CustomItemsWrapper integration) { public static void register(@NotNull final CustomItemsWrapper integration) {
registered.add(integration); REGISTERED.add(integration);
} }
/** /**
@@ -30,9 +28,13 @@ public class CustomItemsManager {
* *
* @see com.willfp.eco.core.items.Items * @see com.willfp.eco.core.items.Items
*/ */
public void registerAllItems() { public static void registerAllItems() {
for (CustomItemsWrapper customItemsWrapper : registered) { for (CustomItemsWrapper customItemsWrapper : REGISTERED) {
customItemsWrapper.registerAllItems(); customItemsWrapper.registerAllItems();
} }
} }
private CustomItemsManager() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
} }

View File

@@ -1,9 +1,11 @@
package com.willfp.eco.core.integrations.customitems; package com.willfp.eco.core.integrations.customitems;
import com.willfp.eco.core.integrations.Integration;
/** /**
* Wrapper class for custom item integrations. * Wrapper class for custom item integrations.
*/ */
public interface CustomItemsWrapper { public interface CustomItemsWrapper extends Integration {
/** /**
* Register all the custom items for a specific plugin into eco. * Register all the custom items for a specific plugin into eco.
* *

View File

@@ -0,0 +1,101 @@
package com.willfp.eco.core.integrations.economy;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/**
* Class to handle economy.
*/
public final class EconomyManager {
/**
* A set of all registered integrations.
*/
private static final Set<EconomyWrapper> REGISTERED = new HashSet<>();
/**
* Register a new integration.
*
* @param integration The integration to register.
*/
public static void register(@NotNull final EconomyWrapper integration) {
REGISTERED.add(integration);
}
/**
* Get if any economy registrations are registered.
*
* @return If any economy.
*/
public static boolean hasRegistrations() {
return !REGISTERED.isEmpty();
}
/**
* Get if a player has a certain amount.
*
* @param player The player.
* @param amount The amount.
* @return If the player has the amount.
*/
public static boolean hasAmount(@NotNull final OfflinePlayer player,
final double amount) {
for (EconomyWrapper wrapper : REGISTERED) {
return wrapper.hasAmount(player, amount);
}
return false;
}
/**
* Give money to a player.
*
* @param player The player.
* @param amount The amount to give.
* @return If the transaction was a success.
*/
public static boolean giveMoney(@NotNull final OfflinePlayer player,
final double amount) {
for (EconomyWrapper wrapper : REGISTERED) {
return wrapper.giveMoney(player, amount);
}
return false;
}
/**
* Remove money from a player.
*
* @param player The player.
* @param amount The amount to remove.
* @return If the transaction was a success.
*/
public static boolean removeMoney(@NotNull final OfflinePlayer player,
final double amount) {
for (EconomyWrapper wrapper : REGISTERED) {
return wrapper.removeMoney(player, amount);
}
return false;
}
/**
* Get the balance of a player.
*
* @param player The player.
* @return The balance.
*/
public static double getBalance(@NotNull final OfflinePlayer player) {
for (EconomyWrapper wrapper : REGISTERED) {
return wrapper.getBalance(player);
}
return 0;
}
private EconomyManager() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

View File

@@ -0,0 +1,48 @@
package com.willfp.eco.core.integrations.economy;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
/**
* Wrapper class for economy integrations.
*/
public interface EconomyWrapper extends Integration {
/**
* Get if a player has a certain amount.
*
* @param player The player.
* @param amount The amount.
* @return If the player has the amount.
*/
boolean hasAmount(@NotNull OfflinePlayer player,
double amount);
/**
* Give money to a player.
*
* @param player The player.
* @param amount The amount to give.
* @return If the transaction was a success.
*/
boolean giveMoney(@NotNull OfflinePlayer player,
double amount);
/**
* Remove money from a player.
*
* @param player The player.
* @param amount The amount to remove.
* @return If the transaction was a success.
*/
boolean removeMoney(@NotNull OfflinePlayer player,
double amount);
/**
* Get the balance of a player.
*
* @param player The player.
* @return The balance.
*/
double getBalance(@NotNull OfflinePlayer player);
}

View File

@@ -0,0 +1,20 @@
package com.willfp.eco.core.integrations.hologram;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* Dummy hologram, created if no integrations are present on the server.
*/
class DummyHologram implements Hologram {
@Override
public void remove() {
// Do nothing.
}
@Override
public void setContents(@NotNull final List<String> contents) {
// Do nothing.
}
}

View File

@@ -0,0 +1,22 @@
package com.willfp.eco.core.integrations.hologram;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* Wrapper class for plugin-specific holograms.
*/
public interface Hologram {
/**
* Remove the hologram.
*/
void remove();
/**
* Set the hologram contents.
*
* @param contents The contents.
*/
void setContents(@NotNull List<String> contents);
}

View File

@@ -0,0 +1,47 @@
package com.willfp.eco.core.integrations.hologram;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Class to handle hologram integrations.
*/
public final class HologramManager {
/**
* A set of all registered integrations.
*/
private static final Set<HologramWrapper> REGISTERED = new HashSet<>();
/**
* Register a new integration.
*
* @param integration The integration to register.
*/
public static void register(@NotNull final HologramWrapper integration) {
REGISTERED.add(integration);
}
/**
* Create hologram.
*
* @param location The location.
* @param contents The contents for the hologram.
* @return The hologram.
*/
public static Hologram createHologram(@NotNull final Location location,
@NotNull final List<String> contents) {
for (HologramWrapper wrapper : REGISTERED) {
return wrapper.createHologram(location, contents);
}
return new DummyHologram();
}
private HologramManager() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

View File

@@ -0,0 +1,22 @@
package com.willfp.eco.core.integrations.hologram;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* Wrapper class for hologram integrations.
*/
public interface HologramWrapper extends Integration {
/**
* Create hologram.
*
* @param location The location.
* @param contents The contents for the hologram.
* @return The hologram.
*/
Hologram createHologram(@NotNull Location location,
@NotNull List<String> contents);
}

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.core.integrations.mcmmo; package com.willfp.eco.core.integrations.mcmmo;
import lombok.experimental.UtilityClass;
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;
@@ -11,20 +10,19 @@ import java.util.Set;
/** /**
* Class to handle mcmmo integrations. * Class to handle mcmmo integrations.
*/ */
@UtilityClass public final class McmmoManager {
public class McmmoManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private final Set<McmmoWrapper> regsistered = new HashSet<>(); private static final Set<McmmoWrapper> REGISTERED = new HashSet<>();
/** /**
* Register a new integration. * Register a new integration.
* *
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public void register(@NotNull final McmmoWrapper integration) { public static void register(@NotNull final McmmoWrapper integration) {
regsistered.add(integration); REGISTERED.add(integration);
} }
/** /**
@@ -33,8 +31,8 @@ public class McmmoManager {
* @param block The block. * @param block The block.
* @return The bonus drop count. * @return The bonus drop count.
*/ */
public int getBonusDropCount(@NotNull final Block block) { public static int getBonusDropCount(@NotNull final Block block) {
for (McmmoWrapper mcmmoWrapper : regsistered) { for (McmmoWrapper mcmmoWrapper : REGISTERED) {
return mcmmoWrapper.getBonusDropCount(block); return mcmmoWrapper.getBonusDropCount(block);
} }
return 0; return 0;
@@ -46,10 +44,14 @@ public class McmmoManager {
* @param event The event to check. * @param event The event to check.
* @return If the event is fake. * @return If the event is fake.
*/ */
public boolean isFake(@NotNull final Event event) { public static boolean isFake(@NotNull final Event event) {
for (McmmoWrapper mcmmoWrapper : regsistered) { for (McmmoWrapper mcmmoWrapper : REGISTERED) {
return mcmmoWrapper.isFake(event); return mcmmoWrapper.isFake(event);
} }
return false; return false;
} }
private McmmoManager() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
} }

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.Integration;
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;
@@ -7,7 +8,7 @@ import org.jetbrains.annotations.NotNull;
/** /**
* Wrapper class for mcmmo integrations. * Wrapper class for mcmmo integrations.
*/ */
public interface McmmoWrapper { public interface McmmoWrapper extends Integration {
/** /**
* Get bonus drop count of block. * Get bonus drop count of block.
* *

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.core.integrations.placeholder; package com.willfp.eco.core.integrations.placeholder;
import lombok.Getter;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -17,7 +16,6 @@ public class PlaceholderEntry {
/** /**
* The name of the placeholder, used in lookups. * The name of the placeholder, used in lookups.
*/ */
@Getter
private final String identifier; private final String identifier;
/** /**
@@ -77,4 +75,20 @@ public class PlaceholderEntry {
public boolean requiresPlayer() { public boolean requiresPlayer() {
return requiresPlayer; return requiresPlayer;
} }
/**
* Get the identifier.
*
* @return The identifier.
*/
public String getIdentifier() {
return identifier;
}
/**
* Register the placeholder.
*/
public void register() {
PlaceholderManager.registerPlaceholder(this);
}
} }

View File

@@ -1,24 +1,22 @@
package com.willfp.eco.core.integrations.placeholder; package com.willfp.eco.core.integrations.placeholder;
import lombok.experimental.UtilityClass;
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.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Optional; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
/** /**
* Class to handle placeholder integrations. * Class to handle placeholder integrations.
*/ */
@UtilityClass public final class PlaceholderManager {
public class PlaceholderManager {
/** /**
* All registered placeholders. * All registered placeholders.
*/ */
private static final Set<PlaceholderEntry> REGISTERED_PLACEHOLDERS = new HashSet<>(); private static final Map<String, PlaceholderEntry> REGISTERED_PLACEHOLDERS = new HashMap<>();
/** /**
* All registered placeholder integrations. * All registered placeholder integrations.
@@ -41,8 +39,8 @@ public class PlaceholderManager {
* @param expansion The {@link PlaceholderEntry} to register. * @param expansion The {@link PlaceholderEntry} to register.
*/ */
public static void registerPlaceholder(@NotNull final PlaceholderEntry expansion) { public static void registerPlaceholder(@NotNull final PlaceholderEntry expansion) {
REGISTERED_PLACEHOLDERS.removeIf(placeholderEntry -> placeholderEntry.getIdentifier().equalsIgnoreCase(expansion.getIdentifier())); REGISTERED_PLACEHOLDERS.remove(expansion.getIdentifier());
REGISTERED_PLACEHOLDERS.add(expansion); REGISTERED_PLACEHOLDERS.put(expansion.getIdentifier(), expansion);
} }
/** /**
@@ -54,14 +52,15 @@ public class PlaceholderManager {
*/ */
public static String getResult(@Nullable final Player player, public static String getResult(@Nullable final Player player,
@NotNull final String identifier) { @NotNull final String identifier) {
Optional<PlaceholderEntry> matching = REGISTERED_PLACEHOLDERS.stream().filter(expansion -> expansion.getIdentifier().equalsIgnoreCase(identifier)).findFirst(); PlaceholderEntry entry = REGISTERED_PLACEHOLDERS.get(identifier.toLowerCase());
if (matching.isEmpty()) { if (entry == null) {
return null; return "";
} }
PlaceholderEntry entry = matching.get();
if (player == null && entry.requiresPlayer()) { if (player == null && entry.requiresPlayer()) {
return ""; return "";
} }
return entry.getResult(player); return entry.getResult(player);
} }
@@ -74,8 +73,14 @@ public class PlaceholderManager {
*/ */
public static String translatePlaceholders(@NotNull final String text, public static String translatePlaceholders(@NotNull final String text,
@Nullable final Player player) { @Nullable final Player player) {
AtomicReference<String> translatedReference = new AtomicReference<>(text); String processed = text;
REGISTERED_INTEGRATIONS.forEach(placeholderIntegration -> translatedReference.set(placeholderIntegration.translate(translatedReference.get(), player))); for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
return translatedReference.get(); processed = integration.translate(processed, player);
}
return processed;
}
private PlaceholderManager() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }
} }

View File

@@ -0,0 +1,38 @@
package com.willfp.eco.core.integrations.shop;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/**
* Class to handle shop integrations.
*/
public final class ShopManager {
/**
* A set of all registered integrations.
*/
private static final Set<ShopWrapper> REGISTERED = new HashSet<>();
/**
* Register a new integration.
*
* @param integration The integration to register.
*/
public static void register(@NotNull final ShopWrapper integration) {
REGISTERED.add(integration);
}
/**
* Register eco item provider for shop plugins.
*/
public static void registerEcoProvider() {
for (ShopWrapper shopWrapper : REGISTERED) {
shopWrapper.registerEcoProvider();
}
}
private ShopManager() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

View File

@@ -0,0 +1,13 @@
package com.willfp.eco.core.integrations.shop;
import com.willfp.eco.core.integrations.Integration;
/**
* Wrapper class for shop integrations.
*/
public interface ShopWrapper extends Integration {
/**
* Register eco item provider for shop plugins.
*/
void registerEcoProvider();
}

View File

@@ -1,6 +1,7 @@
package com.willfp.eco.core.items; package com.willfp.eco.core.items;
import lombok.Getter; 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;
@@ -9,7 +10,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.function.Predicate; import java.util.function.Predicate;
/** /**
* A custom item has 3 components: * A custom item has 3 components.
* *
* <ul> * <ul>
* <li>The key to identify it</li> * <li>The key to identify it</li>
@@ -21,13 +22,12 @@ public class CustomItem implements TestableItem {
/** /**
* The key. * The key.
*/ */
@Getter
private final NamespacedKey key; private final NamespacedKey key;
/** /**
* The test for ItemStacks to pass. * The test for ItemStacks to pass.
*/ */
private final Predicate<ItemStack> test; private final Predicate<@NotNull ItemStack> test;
/** /**
* Example Item: what the user should see. * Example Item: what the user should see.
@@ -42,15 +42,25 @@ public class CustomItem implements TestableItem {
* @param item The example ItemStacks. * @param item The example ItemStacks.
*/ */
public CustomItem(@NotNull final NamespacedKey key, public CustomItem(@NotNull final NamespacedKey key,
@NotNull final Predicate<ItemStack> test, @NotNull final Predicate<@NotNull ItemStack> test,
@NotNull final ItemStack item) { @NotNull final ItemStack item) {
this.key = key; this.key = key;
this.test = test; this.test = test;
this.item = item; this.item = item;
Eco.getHandler().getEcoPlugin().getScheduler().runLater(() -> {
if (!matches(getItem())) {
Bukkit.getLogger().severe("Item with key " + key + " is invalid!");
}
}, 1);
} }
@Override @Override
public boolean matches(@Nullable final ItemStack itemStack) { public boolean matches(@Nullable final ItemStack itemStack) {
if (itemStack == null) {
return false;
}
return test.test(itemStack); return test.test(itemStack);
} }
@@ -65,4 +75,13 @@ public class CustomItem implements TestableItem {
public void register() { public void register() {
Items.registerCustomItem(this.getKey(), this); Items.registerCustomItem(this.getKey(), this);
} }
/**
* Get the key.
*
* @return The key.
*/
public NamespacedKey getKey() {
return this.key;
}
} }

View File

@@ -1,80 +1,238 @@
package com.willfp.eco.core.items; package com.willfp.eco.core.items;
import com.willfp.eco.core.items.args.LookupArgParser;
import com.willfp.eco.core.items.provider.ItemProvider;
import com.willfp.eco.core.recipe.parts.EmptyTestableItem; import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
import com.willfp.eco.core.recipe.parts.MaterialTestableItem; import com.willfp.eco.core.recipe.parts.MaterialTestableItem;
import com.willfp.eco.core.recipe.parts.ModifiedTestableItem;
import com.willfp.eco.core.recipe.parts.TestableStack; import com.willfp.eco.core.recipe.parts.TestableStack;
import com.willfp.eco.util.NamespacedKeyUtils; import com.willfp.eco.util.NamespacedKeyUtils;
import lombok.experimental.UtilityClass; import com.willfp.eco.util.NumberUtils;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap; import java.util.ArrayList;
import java.util.HashSet; import java.util.Arrays;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/** /**
* Class to manage all custom and vanilla items. * Class to manage all custom and vanilla items.
*/ */
@UtilityClass
public final class Items { public final class Items {
/** /**
* All recipe parts. * All recipe parts.
*/ */
private static final Map<NamespacedKey, CustomItem> REGISTRY = new HashMap<>(); private static final Map<NamespacedKey, TestableItem> REGISTRY = new ConcurrentHashMap<>();
/** /**
* Register a new recipe part. * All item providers.
*
* @param key The key of the recipe part.
* @param part The recipe part.
*/ */
public void registerCustomItem(@NotNull final NamespacedKey key, private static final Map<String, ItemProvider> PROVIDERS = new ConcurrentHashMap<>();
@NotNull final CustomItem part) {
REGISTRY.put(key, part); /**
* All recipe parts.
*/
private static final List<LookupArgParser> ARG_PARSERS = new ArrayList<>();
/**
* Register a new custom item.
*
* @param key The key of the item.
* @param item The item.
*/
public static void registerCustomItem(@NotNull final NamespacedKey key,
@NotNull final TestableItem item) {
REGISTRY.put(key, item);
} }
/** /**
* Lookup item from string. * Register a new item provider.
* <p>
* Used for recipes.
* *
* @param key The string to test. * @param provider The provider.
* @return The found testable item, or an empty item if not found.
*/ */
public TestableItem lookup(@NotNull final String key) { public static void registerItemProvider(@NotNull final ItemProvider provider) {
String[] split = key.toLowerCase().split(":"); PROVIDERS.put(provider.getNamespace(), provider);
}
/**
* Register a new arg parser.
*
* @param parser The parser.
*/
public static void registerArgParser(@NotNull final LookupArgParser parser) {
ARG_PARSERS.add(parser);
}
/**
* Remove an item.
*
* @param key The key of the recipe part.
*/
public static void removeCustomItem(@NotNull final NamespacedKey key) {
REGISTRY.remove(key);
}
/**
* This is the backbone of the entire eco item system.
* <p>
* You can lookup a TestableItem for any material, custom item,
* or item in general, and it will return it with any modifiers
* passed as parameters. This includes stack size (item amount)
* and enchantments that should be present on the item.
* <p>
* If you want to get an ItemStack instance from this, then just call
* {@link TestableItem#getItem()}.
* <p>
* The advantages of the testable item system are that there is the inbuilt
* {@link TestableItem#matches(ItemStack)} - this allows to check if any item
* is that testable item; which may sound negligible but actually it allows for
* much more power an flexibility. For example, you can have an item with an
* extra metadata tag, extra lore lines, different display name - and it
* will still work as long as the test passes. This is very important
* for custom crafting recipes where other plugins may add metadata
* values or the play may rename the item.
*
* @param key The lookup string.
* @return The testable item, or an {@link EmptyTestableItem}.
*/
public static TestableItem lookup(@NotNull final String key) {
if (key.contains("?")) {
String[] options = key.split("\\?");
for (String option : options) {
TestableItem lookup = lookup(option);
if (!(lookup instanceof EmptyTestableItem)) {
return lookup;
}
}
return new EmptyTestableItem();
}
String[] args = key.split(" ");
if (args.length == 0) {
return new EmptyTestableItem();
}
TestableItem item = null;
int stackAmount = 1;
String[] split = args[0].toLowerCase().split(":");
if (split.length == 1) { if (split.length == 1) {
Material material = Material.getMaterial(key.toUpperCase()); Material material = Material.getMaterial(args[0].toUpperCase());
if (material == null || material == Material.AIR) { if (material == null || material == Material.AIR) {
return new EmptyTestableItem(); return new EmptyTestableItem();
} }
return new MaterialTestableItem(material); item = new MaterialTestableItem(material);
} }
if (split.length == 2) { if (split.length == 2) {
CustomItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1])); String namespace = split[0];
String keyID = split[1];
NamespacedKey namespacedKey = NamespacedKeyUtils.create(namespace, keyID);
TestableItem part = REGISTRY.get(namespacedKey);
if (part == null && PROVIDERS.containsKey(namespace)) {
ItemProvider provider = PROVIDERS.get(namespace);
item = provider.provideForKey(keyID);
if (item instanceof EmptyTestableItem || item == null) {
return new EmptyTestableItem();
}
registerCustomItem(namespacedKey, item);
}
/*
Legacy id:amount format
This has been superseded by id amount
*/
if (part == null) { if (part == null) {
Material material = Material.getMaterial(split[0].toUpperCase()); Material material = Material.getMaterial(split[0].toUpperCase());
if (material == null || material == Material.AIR) { if (material == null || material == Material.AIR) {
return new EmptyTestableItem(); return new EmptyTestableItem();
} }
return new TestableStack(new MaterialTestableItem(material), Integer.parseInt(split[1])); item = new MaterialTestableItem(material);
stackAmount = Integer.parseInt(split[1]);
} else { } else {
return part; item = part;
} }
} }
/*
Legacy namespace:id:amount format
This has been superseded by namespace:id amount
*/
if (split.length == 3) { if (split.length == 3) {
CustomItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1])); TestableItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1]));
return part == null ? new EmptyTestableItem() : new TestableStack(part, Integer.parseInt(split[2])); if (part == null) {
return new EmptyTestableItem();
}
item = part;
stackAmount = Integer.parseInt(split[2]);
} }
return new EmptyTestableItem(); boolean usingNewStackFormat = false;
if (args.length >= 2) {
try {
stackAmount = Integer.parseInt(args[1]);
usingNewStackFormat = true;
} catch (NumberFormatException ignored) {
}
}
// Marked as redundant but i am covering all bases here
if (item == null || item instanceof EmptyTestableItem) {
return new EmptyTestableItem();
}
ItemStack example = item.getItem();
ItemMeta meta = example.getItemMeta();
assert meta != null;
String[] modifierArgs = Arrays.copyOfRange(args, usingNewStackFormat ? 2 : 1, args.length);
List<Predicate<ItemStack>> predicates = new ArrayList<>();
for (LookupArgParser argParser : ARG_PARSERS) {
Predicate<ItemStack> predicate = argParser.parseArguments(modifierArgs, meta);
if (predicate != null) {
predicates.add(argParser.parseArguments(modifierArgs, meta));
}
}
example.setItemMeta(meta);
if (!predicates.isEmpty()) {
item = new ModifiedTestableItem(
item,
test -> {
for (Predicate<ItemStack> predicate : predicates) {
if (!predicate.test(test)) {
return false;
}
}
return true;
},
example
);
}
if (stackAmount <= 1) {
return item;
} else {
return new TestableStack(item, stackAmount);
}
} }
/** /**
@@ -83,8 +241,8 @@ public final class Items {
* @param itemStack The itemStack to check. * @param itemStack The itemStack to check.
* @return If is recipe. * @return If is recipe.
*/ */
public boolean isCustomItem(@NotNull final ItemStack itemStack) { public static boolean isCustomItem(@NotNull final ItemStack itemStack) {
for (CustomItem item : REGISTRY.values()) { for (TestableItem item : REGISTRY.values()) {
if (item.matches(itemStack)) { if (item.matches(itemStack)) {
return true; return true;
} }
@@ -92,12 +250,53 @@ public final class Items {
return false; return false;
} }
/**
* Get custom item from item.
*
* @param itemStack The item.
* @return The custom item, or null if not exists.
*/
@Nullable
public static CustomItem getCustomItem(@NotNull final ItemStack itemStack) {
for (TestableItem item : REGISTRY.values()) {
if (item.matches(itemStack)) {
return getOrWrap(item);
}
}
return null;
}
/** /**
* Get all registered custom items. * Get all registered custom items.
* *
* @return A set of all items. * @return A set of all items.
*/ */
public Set<CustomItem> getCustomItems() { public static Set<CustomItem> getCustomItems() {
return new HashSet<>(REGISTRY.values()); return REGISTRY.values().stream().map(Items::getOrWrap).collect(Collectors.toSet());
}
/**
* Return a CustomItem instance for a given TestableItem.
* <p>
* Used internally since 6.10.0 when the registration moved from {@link CustomItem}
* to {@link TestableItem} for added flexibility.
*
* @param item The item.
* @return The CustomItem.
*/
public static CustomItem getOrWrap(@NotNull final TestableItem item) {
if (item instanceof CustomItem) {
return (CustomItem) item;
} else {
return new CustomItem(
NamespacedKeyUtils.createEcoKey("wrapped_" + NumberUtils.randInt(0, 100000)),
item::matches,
item.getItem()
);
}
}
private Items() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }
} }

View File

@@ -0,0 +1,83 @@
package com.willfp.eco.core.items.args;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;
/**
* Parses enchantment arguments.
*/
public class EnchantmentArgParser implements LookupArgParser {
@Override
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
@NotNull final ItemMeta meta) {
Map<Enchantment, Integer> requiredEnchantments = new HashMap<>();
for (String enchantArg : args) {
String[] enchantArgSplit = enchantArg.split(":");
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(enchantArgSplit[0].toLowerCase()));
if (enchantment == null) {
continue;
}
if (enchantArgSplit.length < 2) {
continue;
}
int level = Integer.parseInt(enchantArgSplit[1]);
requiredEnchantments.put(enchantment, level);
}
if (requiredEnchantments.isEmpty()) {
return null;
}
if (meta instanceof EnchantmentStorageMeta storageMeta) {
requiredEnchantments.forEach((enchantment, integer) -> storageMeta.addStoredEnchant(enchantment, integer, true));
} else {
requiredEnchantments.forEach((enchantment, integer) -> meta.addEnchant(enchantment, integer, true));
}
return test -> {
if (!test.hasItemMeta()) {
return false;
}
ItemMeta testMeta = test.getItemMeta();
assert testMeta != null;
if (testMeta instanceof EnchantmentStorageMeta storageMeta) {
for (Map.Entry<Enchantment, Integer> entry : requiredEnchantments.entrySet()) {
if (!storageMeta.hasStoredEnchant(entry.getKey())) {
return false;
}
if (storageMeta.getStoredEnchantLevel(entry.getKey()) < entry.getValue()) {
return false;
}
}
} else {
for (Map.Entry<Enchantment, Integer> entry : requiredEnchantments.entrySet()) {
if (!testMeta.hasEnchant(entry.getKey())) {
return false;
}
if (testMeta.getEnchantLevel(entry.getKey()) < entry.getValue()) {
return false;
}
}
}
return true;
};
}
}

View File

@@ -0,0 +1,25 @@
package com.willfp.eco.core.items.args;
import com.willfp.eco.core.items.TestableItem;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Predicate;
/**
* An argument parser should generate the predicate as well
* as modify the ItemMeta for {@link TestableItem#getItem()}.
*/
public interface LookupArgParser {
/**
* Parse the arguments.
*
* @param args The arguments.
* @param meta The ItemMeta to modify.
* @return The predicate test to apply to the modified item.
*/
@Nullable Predicate<ItemStack> parseArguments(@NotNull String[] args,
@NotNull ItemMeta meta);
}

View File

@@ -0,0 +1,59 @@
package com.willfp.eco.core.items.args;
import com.willfp.eco.util.SkullUtils;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Predicate;
/**
* Parse skull textures.
*/
public class TextureArgParser implements LookupArgParser {
@Override
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
@NotNull final ItemMeta meta) {
String skullTexture = null;
for (String arg : args) {
String[] argSplit = arg.split(":");
if (!argSplit[0].equalsIgnoreCase("texture")) {
continue;
}
if (argSplit.length < 2) {
continue;
}
skullTexture = argSplit[1];
}
if (meta instanceof SkullMeta skullMeta && skullTexture != null) {
SkullUtils.setSkullTexture(skullMeta, skullTexture);
}
if (skullTexture == null) {
return null;
}
String finalSkullTexture = skullTexture;
return test -> {
if (!test.hasItemMeta()) {
return false;
}
ItemMeta testMeta = test.getItemMeta();
assert testMeta != null;
if (testMeta instanceof SkullMeta skullMeta) {
return finalSkullTexture.equalsIgnoreCase(SkullUtils.getSkullTexture(skullMeta));
}
return true;
};
}
}

View File

@@ -1,8 +1,6 @@
package com.willfp.eco.core.items.builder; package com.willfp.eco.core.items.builder;
import com.willfp.eco.util.StringUtils; import com.willfp.eco.util.StringUtils;
import lombok.AccessLevel;
import lombok.Getter;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
@@ -29,13 +27,11 @@ public abstract class AbstractItemStackBuilder<T extends ItemMeta, U extends Abs
/** /**
* The ItemMeta used while building. * The ItemMeta used while building.
*/ */
@Getter(AccessLevel.PROTECTED)
private final T meta; private final T meta;
/** /**
* The ItemStack. * The ItemStack.
*/ */
@Getter(AccessLevel.PROTECTED)
private final ItemStack base; private final ItemStack base;
/** /**
@@ -73,6 +69,11 @@ public abstract class AbstractItemStackBuilder<T extends ItemMeta, U extends Abs
@Override @Override
public U addEnchantment(@NotNull final Enchantment enchantment, public U addEnchantment(@NotNull final Enchantment enchantment,
final int level) { final int level) {
//noinspection ConstantConditions
if (enchantment == null) {
return (U) this;
}
meta.addEnchant(enchantment, level, true); meta.addEnchant(enchantment, level, true);
return (U) this; return (U) this;
} }
@@ -196,4 +197,22 @@ public abstract class AbstractItemStackBuilder<T extends ItemMeta, U extends Abs
return base; return base;
} }
/**
* Get the base ItemStack.
*
* @return The base ItemStack.
*/
protected ItemStack getBase() {
return base;
}
/**
* Get the meta.
*
* @return The meta.
*/
protected T getMeta() {
return meta;
}
} }

View File

@@ -0,0 +1,47 @@
package com.willfp.eco.core.items.provider;
import com.willfp.eco.core.items.TestableItem;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Item providers are call-site registrations for items. In other words,
* they only register their items when a request is made. This is marginally
* slower, however it is required for certain plugins, and fixes bugs related to
* loading orders.
*
* @see TestableItem
*/
public abstract class ItemProvider {
/**
* The namespace.
*/
private final String namespace;
/**
* Create a new ItemProvider for a specific namespace.
*
* @param namespace The namespace.
*/
protected ItemProvider(@NotNull final String namespace) {
this.namespace = namespace;
}
/**
* Provide a TestableItem for a given key.
*
* @param key The item ID.
* @return The TestableItem, or null if not found.
*/
@Nullable
public abstract TestableItem provideForKey(@NotNull String key);
/**
* Get the namespace.
*
* @return The namespace.
*/
public String getNamespace() {
return this.namespace;
}
}

View File

@@ -1,15 +1,17 @@
package com.willfp.eco.core.proxy; package com.willfp.eco.core.proxy;
import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
/** /**
* Proxy / NMS constants. * Proxy / NMS constants.
*/ */
@UtilityClass public final class ProxyConstants {
public class ProxyConstants {
/** /**
* The NMS version that the server is running on. * The NMS version that the server is running on.
*/ */
public static final String NMS_VERSION = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; public static final String NMS_VERSION = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
private ProxyConstants() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
} }

View File

@@ -6,7 +6,6 @@ import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.items.Items; import com.willfp.eco.core.items.Items;
import com.willfp.eco.core.recipe.recipes.CraftingRecipe; import com.willfp.eco.core.recipe.recipes.CraftingRecipe;
import com.willfp.eco.core.recipe.recipes.ShapedCraftingRecipe; import com.willfp.eco.core.recipe.recipes.ShapedCraftingRecipe;
import lombok.experimental.UtilityClass;
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;
@@ -17,9 +16,8 @@ import java.util.List;
/** /**
* Utility class to manage and register crafting recipes. * Utility class to manage and register crafting recipes.
*/ */
@UtilityClass
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class Recipes { public final class Recipes {
/** /**
* Registry of all recipes. * Registry of all recipes.
*/ */
@@ -31,7 +29,7 @@ public class Recipes {
* *
* @param recipe The recipe. * @param recipe The recipe.
*/ */
public void register(@NotNull final CraftingRecipe recipe) { public static void register(@NotNull final CraftingRecipe recipe) {
RECIPES.forcePut(recipe.getKey(), recipe); RECIPES.forcePut(recipe.getKey(), recipe);
} }
@@ -42,7 +40,7 @@ public class Recipes {
* @return The match, or null if not found. * @return The match, or null if not found.
*/ */
@Nullable @Nullable
public CraftingRecipe getMatch(@NotNull final ItemStack[] matrix) { public static CraftingRecipe getMatch(@NotNull final ItemStack[] matrix) {
return RECIPES.values().stream().filter(recipe -> recipe.test(matrix)).findFirst().orElse(null); return RECIPES.values().stream().filter(recipe -> recipe.test(matrix)).findFirst().orElse(null);
} }
@@ -53,7 +51,7 @@ public class Recipes {
* @return The recipe, or null if not found. * @return The recipe, or null if not found.
*/ */
@Nullable @Nullable
public CraftingRecipe getRecipe(@NotNull final NamespacedKey key) { public static CraftingRecipe getRecipe(@NotNull final NamespacedKey key) {
CraftingRecipe recipe = RECIPES.get(key); CraftingRecipe recipe = RECIPES.get(key);
if (recipe != null) { if (recipe != null) {
return recipe; return recipe;
@@ -77,10 +75,10 @@ public class Recipes {
* @param recipeStrings The recipe. * @param recipeStrings The recipe.
* @return The recipe. * @return The recipe.
*/ */
public CraftingRecipe createAndRegisterRecipe(@NotNull final EcoPlugin plugin, public static CraftingRecipe createAndRegisterRecipe(@NotNull final EcoPlugin plugin,
@NotNull final String key, @NotNull final String key,
@NotNull final ItemStack output, @NotNull final ItemStack output,
@NotNull final List<String> recipeStrings) { @NotNull final List<String> recipeStrings) {
ShapedCraftingRecipe.Builder builder = ShapedCraftingRecipe.builder(plugin, key).setOutput(output); ShapedCraftingRecipe.Builder builder = ShapedCraftingRecipe.builder(plugin, key).setOutput(output);
for (int i = 0; i < 9; i++) { for (int i = 0; i < 9; i++) {
@@ -92,4 +90,8 @@ public class Recipes {
return recipe; return recipe;
} }
private Recipes() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
} }

View File

@@ -1,7 +1,7 @@
package com.willfp.eco.core.recipe.parts; package com.willfp.eco.core.recipe.parts;
import com.willfp.eco.core.items.TestableItem; import com.willfp.eco.core.items.TestableItem;
import lombok.Getter; import org.apache.commons.lang.Validate;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -14,7 +14,6 @@ public class MaterialTestableItem implements TestableItem {
/** /**
* The material. * The material.
*/ */
@Getter
private final Material material; private final Material material;
/** /**
@@ -23,6 +22,8 @@ public class MaterialTestableItem implements TestableItem {
* @param material The material. * @param material The material.
*/ */
public MaterialTestableItem(@NotNull final Material material) { public MaterialTestableItem(@NotNull final Material material) {
Validate.isTrue(material != Material.AIR, "You can't have air as the type!");
this.material = material; this.material = material;
} }
@@ -41,4 +42,13 @@ public class MaterialTestableItem implements TestableItem {
public ItemStack getItem() { public ItemStack getItem() {
return new ItemStack(material); return new ItemStack(material);
} }
/**
* Get the material.
*
* @return The material.
*/
public Material getMaterial() {
return this.material;
}
} }

View File

@@ -0,0 +1,79 @@
package com.willfp.eco.core.recipe.parts;
import com.willfp.eco.core.items.TestableItem;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Predicate;
/**
* Existing testable items with an extra filter.
*
* @see com.willfp.eco.core.items.CustomItem
*/
public class ModifiedTestableItem implements TestableItem {
/**
* The item.
*/
private final TestableItem handle;
/**
* The amount.
*/
private final Predicate<ItemStack> test;
/**
* The item for the modified test.
*/
private final ItemStack example;
/**
* Create a new modified testable item.
*
* @param item The item.
* @param test The test.
* @param example The example.
*/
public ModifiedTestableItem(@NotNull final TestableItem item,
@NotNull final Predicate<ItemStack> test,
@NotNull final ItemStack example) {
this.handle = item;
this.test = test;
this.example = example;
}
/**
* If the item matches the material.
*
* @param itemStack The item to test.
* @return If the item is of the specified material.
*/
@Override
public boolean matches(@Nullable final ItemStack itemStack) {
return itemStack != null && handle.matches(itemStack) && test.test(itemStack);
}
@Override
public ItemStack getItem() {
return example;
}
/**
* Get the handle.
*
* @return The handle.
*/
public TestableItem getHandle() {
return this.handle;
}
/**
* Get the test.
*
* @return The test.
*/
public Predicate<ItemStack> getTest() {
return this.test;
}
}

View File

@@ -1,17 +1,11 @@
package com.willfp.eco.core.recipe.parts; package com.willfp.eco.core.recipe.parts;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.items.TestableItem; import com.willfp.eco.core.items.TestableItem;
import lombok.Getter;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/** /**
* Stacks of items. * Stacks of items.
*/ */
@@ -24,7 +18,6 @@ public class TestableStack implements TestableItem {
/** /**
* The amount. * The amount.
*/ */
@Getter
private final int amount; private final int amount;
/** /**
@@ -35,7 +28,8 @@ public class TestableStack implements TestableItem {
*/ */
public TestableStack(@NotNull final TestableItem item, public TestableStack(@NotNull final TestableItem item,
final int amount) { final int amount) {
Validate.isTrue(!(item instanceof TestableStack)); Validate.isTrue(!(item instanceof TestableStack), "You can't stack a stack!");
Validate.isTrue(!(item instanceof EmptyTestableItem), "You can't stack air!");
this.handle = item; this.handle = item;
this.amount = amount; this.amount = amount;
@@ -55,19 +49,25 @@ public class TestableStack implements TestableItem {
@Override @Override
public ItemStack getItem() { public ItemStack getItem() {
ItemStack temp = handle.getItem().clone(); ItemStack temp = handle.getItem().clone();
ItemMeta meta = temp.getItemMeta();
assert meta != null;
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
assert lore != null;
lore.add("");
String add = Eco.getHandler().getEcoPlugin().getLangYml().getString("multiple-in-craft");
add = add.replace("%amount%", String.valueOf(amount));
lore.add(add);
meta.setLore(lore);
temp.setItemMeta(meta);
temp.setAmount(amount); temp.setAmount(amount);
return temp; return temp;
} }
/**
* Get the handle.
*
* @return The handle.
*/
public TestableItem getHandle() {
return this.handle;
}
/**
* Get the amount in the stack.
*
* @return The amount.
*/
public int getAmount() {
return this.amount;
}
} }

View File

@@ -1,7 +1,5 @@
package com.willfp.eco.core.recipe.recipes; package com.willfp.eco.core.recipe.recipes;
import lombok.Getter;
/** /**
* Positions in a 3x3 crafting recipe. * Positions in a 3x3 crafting recipe.
*/ */
@@ -54,7 +52,6 @@ public enum RecipePosition {
/** /**
* The index within a crafting table matrix. * The index within a crafting table matrix.
*/ */
@Getter
private final int index; private final int index;
/** /**
@@ -65,4 +62,13 @@ public enum RecipePosition {
RecipePosition(final int index) { RecipePosition(final int index) {
this.index = index; this.index = index;
} }
/**
* Get the index within a crafting table matrix.
*
* @return The index.
*/
public int getIndex() {
return index;
}
} }

View File

@@ -1,16 +1,18 @@
package com.willfp.eco.core.recipe.recipes; package com.willfp.eco.core.recipe.recipes;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginDependent; import com.willfp.eco.core.PluginDependent;
import com.willfp.eco.core.items.TestableItem; import com.willfp.eco.core.items.TestableItem;
import com.willfp.eco.core.recipe.Recipes; import com.willfp.eco.core.recipe.Recipes;
import com.willfp.eco.core.recipe.parts.EmptyTestableItem; import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
import lombok.Getter; import com.willfp.eco.core.recipe.parts.TestableStack;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.RecipeChoice; import org.bukkit.inventory.RecipeChoice;
import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
@@ -24,25 +26,21 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
/** /**
* Recipe parts. * Recipe parts.
*/ */
@Getter
private final List<TestableItem> parts; private final List<TestableItem> parts;
/** /**
* The key of the recipe. * The key of the recipe.
*/ */
@Getter
private final NamespacedKey key; private final NamespacedKey key;
/** /**
* The key of the displayed recipe. * The key of the displayed recipe.
*/ */
@Getter
private final NamespacedKey displayedKey; private final NamespacedKey displayedKey;
/** /**
* The recipe's output. * The recipe's output.
*/ */
@Getter
private final ItemStack output; private final ItemStack output;
private ShapedCraftingRecipe(@NotNull final EcoPlugin plugin, private ShapedCraftingRecipe(@NotNull final EcoPlugin plugin,
@@ -79,6 +77,10 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
ShapedRecipe shapedRecipe = new ShapedRecipe(this.getKey(), this.getOutput()); ShapedRecipe shapedRecipe = new ShapedRecipe(this.getKey(), this.getOutput());
shapedRecipe.shape("012", "345", "678"); shapedRecipe.shape("012", "345", "678");
for (int i = 0; i < 9; i++) { for (int i = 0; i < 9; i++) {
if (parts.get(i) instanceof EmptyTestableItem) {
continue;
}
char character = String.valueOf(i).toCharArray()[0]; char character = String.valueOf(i).toCharArray()[0];
shapedRecipe.setIngredient(character, parts.get(i).getItem().getType()); shapedRecipe.setIngredient(character, parts.get(i).getItem().getType());
} }
@@ -86,8 +88,28 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
ShapedRecipe displayedRecipe = new ShapedRecipe(this.getDisplayedKey(), this.getOutput()); ShapedRecipe displayedRecipe = new ShapedRecipe(this.getDisplayedKey(), this.getOutput());
displayedRecipe.shape("012", "345", "678"); displayedRecipe.shape("012", "345", "678");
for (int i = 0; i < 9; i++) { for (int i = 0; i < 9; i++) {
if (parts.get(i) instanceof EmptyTestableItem) {
continue;
}
char character = String.valueOf(i).toCharArray()[0]; char character = String.valueOf(i).toCharArray()[0];
displayedRecipe.setIngredient(character, new RecipeChoice.ExactChoice(parts.get(i).getItem())); ItemStack item = parts.get(i).getItem();
if (parts.get(i) instanceof TestableStack) {
ItemMeta meta = item.getItemMeta();
assert meta != null;
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
assert lore != null;
lore.add("");
String add = Eco.getHandler().getEcoPlugin().getLangYml().getString("multiple-in-craft");
add = add.replace("%amount%", String.valueOf(item.getAmount()));
lore.add(add);
meta.setLore(lore);
item.setItemMeta(meta);
}
displayedRecipe.setIngredient(character, new RecipeChoice.ExactChoice(item));
} }
Bukkit.getServer().addRecipe(shapedRecipe); Bukkit.getServer().addRecipe(shapedRecipe);
@@ -106,6 +128,42 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
return new Builder(plugin, key); return new Builder(plugin, key);
} }
/**
* Get the parts.
*
* @return The parts.
*/
public List<TestableItem> getParts() {
return this.parts;
}
/**
* Get the key.
*
* @return The key.
*/
public NamespacedKey getKey() {
return this.key;
}
/**
* Get the displayed key.
*
* @return The displayed key.
*/
public NamespacedKey getDisplayedKey() {
return this.displayedKey;
}
/**
* Get the output.
*
* @return The output.
*/
public ItemStack getOutput() {
return this.output;
}
/** /**
* Builder for recipes. * Builder for recipes.
*/ */

View File

@@ -0,0 +1,28 @@
package com.willfp.eco.core.requirement;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* A requirement is a defined goal that a player must meet.
*/
public abstract class Requirement {
/**
* Create a new requirement.
*/
protected Requirement() {
}
/**
* Test if the player meets the requirement.
*
* @param player The player.
* @param args The arguments.
* @return The requirement.
*/
public abstract boolean doesPlayerMeet(@NotNull Player player,
@NotNull List<String> args);
}

View File

@@ -0,0 +1,17 @@
package com.willfp.eco.core.requirement;
import org.jetbrains.annotations.NotNull;
/**
* Interface for internal requirement factory implementations.
*/
public interface RequirementFactory {
/**
* Create a requirement.
*
* @param name The name.
* @return The requirement returned for the name.
* Will return a requirement that is always true if not found.
*/
Requirement create(@NotNull String name);
}

View File

@@ -0,0 +1,43 @@
package com.willfp.eco.core.requirement;
import com.willfp.eco.core.Eco;
import org.jetbrains.annotations.NotNull;
/**
* Contains methods and fields pertaining to requirements.
*/
public final class Requirements {
/**
* Requires a player to have a permission.
*/
public static final Requirement HAS_PERMISSION = Eco.getHandler().getRequirementFactory().create("has-permission");
/**
* Placeholder equals value.
*/
public static final Requirement PLACEHOLDER_EQUALS = Eco.getHandler().getRequirementFactory().create("placeholder-equals");
/**
* Numeric placeholder greater than value.
*/
public static final Requirement PLACEHOLDER_GREATER_THAN = Eco.getHandler().getRequirementFactory().create("placeholder-greater-than");
/**
* Numeric placeholder less than value.
*/
public static final Requirement PLACEHOLDER_LESS_THAN = Eco.getHandler().getRequirementFactory().create("placeholder-less-than");
/**
* Get Requirements matching ID.
*
* @param name The ID to search for.
* @return The matching Requirements.
*/
public static Requirement getByID(@NotNull final String name) {
return Eco.getHandler().getRequirementFactory().create(name);
}
private Requirements() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

View File

@@ -1,7 +1,5 @@
package com.willfp.eco.core.tuples; package com.willfp.eco.core.tuples;
import lombok.Getter;
import lombok.Setter;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
/** /**
@@ -14,16 +12,12 @@ public class Pair<A, B> {
/** /**
* The first item in the tuple. * The first item in the tuple.
*/ */
@Getter
@Setter
@Nullable @Nullable
private A first; private A first;
/** /**
* The second item in the tuple. * The second item in the tuple.
*/ */
@Getter
@Setter
@Nullable @Nullable
private B second; private B second;
@@ -38,4 +32,62 @@ public class Pair<A, B> {
this.first = first; this.first = first;
this.second = second; this.second = second;
} }
/**
* component1 exists to allow a pair to be destructured by kotlin.
* The default kotlin pair already has this, however there is no default
* pair in java so this exists for parity.
*
* @return First.
*/
public A component1() {
return first;
}
/**
* component2 exists to allow a pair to be destructured by kotlin.
* The default kotlin pair already has this, however there is no default
* pair in java so this exists for parity.
*
* @return First.
*/
public B component2() {
return second;
}
/**
* Get the first member of the tuple.
*
* @return The first member.
*/
public @Nullable A getFirst() {
return this.first;
}
/**
* Get the second member of the tuple.
*
* @return The second member.
*/
public @Nullable B getSecond() {
return this.second;
}
/**
* Set the first member of the tuple.
*
* @param first The data to set.
*/
public void setFirst(@Nullable final A first) {
this.first = first;
}
/**
* Set the second member of the tuple.
*
* @param second The data to set.
*/
public void setSecond(@Nullable final B second) {
this.second = second;
}
} }

View File

@@ -1,7 +1,5 @@
package com.willfp.eco.core.tuples; package com.willfp.eco.core.tuples;
import lombok.Getter;
import lombok.Setter;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
/** /**
@@ -15,8 +13,6 @@ public class Triplet<A, B, C> extends Pair<A, B> {
/** /**
* The third item in the tuple. * The third item in the tuple.
*/ */
@Getter
@Setter
@Nullable @Nullable
private C third; private C third;
@@ -34,4 +30,33 @@ public class Triplet<A, B, C> extends Pair<A, B> {
this.third = third; this.third = third;
} }
/**
* component3 exists to allow a pair to be destructured by kotlin.
* The default kotlin pair already has this, however there is no default
* pair in java so this exists for parity.
*
* @return First.
*/
public C component3() {
return third;
}
/**
* Get the third member of the tuple.
*
* @return The third.
*/
public @Nullable C getThird() {
return this.third;
}
/**
* Set the third member of the tuple.
*
* @param third The data to set.
*/
public void setThird(@Nullable final C third) {
this.third = third;
}
} }

View File

@@ -1,9 +1,9 @@
package com.willfp.eco.core.web; package com.willfp.eco.core.web;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import lombok.Getter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
@@ -11,7 +11,6 @@ import java.io.InputStreamReader;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -23,7 +22,6 @@ public class Paste {
/** /**
* The contents. * The contents.
*/ */
@Getter
private final String contents; private final String contents;
/** /**
@@ -40,45 +38,42 @@ public class Paste {
* <p> * <p>
* Runs asynchronously to avoid hangups. * Runs asynchronously to avoid hangups.
* *
* @param responseHandler The consumer to accept the response token. * @param callback The consumer to accept the response token.
*/ */
public void getHastebinToken(@NotNull final Consumer<String> responseHandler) { public void getHastebinToken(@NotNull final Consumer<String> callback) {
Eco.getHandler().getEcoPlugin().getScheduler().runAsync(() -> { Eco.getHandler().getEcoPlugin().getScheduler().runAsync(() -> {
try { try {
String url = "https://hastebin.com/documents"; byte[] postData = contents.getBytes(StandardCharsets.UTF_8);
URL obj = new URL(url); int postDataLength = postData.length;
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST"); String requestURL = "https://hastebin.com/documents";
con.setRequestProperty("Content-Type", "application/json"); URL url = new URL(requestURL);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setInstanceFollowRedirects(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("User-Agent", "eco-Hastebin");
conn.setRequestProperty("Content-Length", Integer.toString(postDataLength));
conn.setUseCaches(false);
con.setDoOutput(true); String response;
DataOutputStream wr = new DataOutputStream(con.getOutputStream()); DataOutputStream wr;
wr.writeBytes(URLEncoder.encode(contents, StandardCharsets.UTF_8));
wr.flush();
wr.close();
BufferedReader iny = new BufferedReader( wr = new DataOutputStream(conn.getOutputStream());
new InputStreamReader(con.getInputStream())); wr.write(postData);
String output; BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder responseBuilder = new StringBuilder(); response = reader.readLine();
while ((output = iny.readLine()) != null) { assert response != null;
responseBuilder.append(output);
if (response.contains("\"key\"")) {
response = response.substring(response.indexOf(":") + 2, response.length() - 2);
callback.accept(response);
} }
iny.close();
String responseString = responseBuilder.toString();
responseString = responseString.replace("{\"key\":\"", "");
responseString = responseString.replace("\"}", "");
responseHandler.accept(responseString);
} catch (IOException e) { } catch (IOException e) {
responseHandler.accept(e.getMessage()); callback.accept(e.getMessage());
} }
responseHandler.accept("");
}); });
} }
@@ -96,7 +91,7 @@ public class Paste {
conn.setRequestMethod("GET"); conn.setRequestMethod("GET");
try (var reader = new BufferedReader( try (var reader = new BufferedReader(
new InputStreamReader(conn.getInputStream()))) { new InputStreamReader(conn.getInputStream()))) {
for (String line; (line = reader.readLine()) != null; ) { for (String line; (line = reader.readLine()) != null;) {
result.append(line); result.append(line);
} }
} }
@@ -107,4 +102,13 @@ public class Paste {
return null; return null;
} }
/**
* Get the contents.
*
* @return The contents.
*/
public String getContents() {
return this.contents;
}
} }

View File

@@ -26,16 +26,18 @@ public class UpdateChecker extends PluginDependent<EcoPlugin> {
/** /**
* Get the latest version of the plugin. * Get the latest version of the plugin.
* *
* @param consumer The process to run after checking. * @param callback The process to run after checking.
*/ */
public void getVersion(@NotNull final Consumer<? super String> consumer) { public void getVersion(@NotNull final Consumer<? super String> callback) {
this.getPlugin().getScheduler().runAsync(() -> { this.getPlugin().getScheduler().runAsync(() -> {
try { try {
InputStream inputStream = new URL("https://api.spigotmc.org/legacy/update.php?resource=" + this.getPlugin().getResourceId()).openStream(); InputStream inputStream = new URL(
"https://api.polymart.org/v1/getResourceInfoSimple?key=version&resource_id=" + this.getPlugin().getResourceId()
).openStream();
Scanner scanner = new Scanner(inputStream); Scanner scanner = new Scanner(inputStream);
if (scanner.hasNext()) { if (scanner.hasNext()) {
consumer.accept(scanner.next()); callback.accept(scanner.next());
} }
} catch (IOException e) { } catch (IOException e) {
this.getPlugin().getLogger().warning("Failed to check for updates: " + e.getMessage()); this.getPlugin().getLogger().warning("Failed to check for updates: " + e.getMessage());

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.util; package com.willfp.eco.util;
import lombok.experimental.UtilityClass;
import org.bukkit.entity.Arrow; import org.bukkit.entity.Arrow;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.MetadataValue; import org.bukkit.metadata.MetadataValue;
@@ -12,27 +11,29 @@ import java.util.List;
/** /**
* Utilities / API methods for arrows. * Utilities / API methods for arrows.
*/ */
@UtilityClass public final class ArrowUtils {
public class ArrowUtils {
/** /**
* Get the bow from an arrow. * Get the bow from an arrow.
* *
* @param arrow The arrow. * @param arrow The arrow.
* @return The bow. * @return The bow, or null if no bow.
*/ */
@Nullable @Nullable
public ItemStack getBow(@NotNull final Arrow arrow) { public static ItemStack getBow(@NotNull final Arrow arrow) {
List<MetadataValue> values = arrow.getMetadata("shot-from"); List<MetadataValue> values = arrow.getMetadata("shot-from");
if (values.isEmpty()) { if (values.isEmpty()) {
return null; return null;
} }
if (!(values.get(0) instanceof ItemStack)) { if (!(values.get(0).value() instanceof ItemStack)) {
return null; return null;
} }
return (ItemStack) values.get(0); return (ItemStack) values.get(0).value();
}
private ArrowUtils() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }
} }

View File

@@ -1,12 +1,14 @@
package com.willfp.eco.util; package com.willfp.eco.util;
import com.willfp.eco.core.tuples.Pair;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -18,24 +20,21 @@ import java.util.function.BiConsumer;
/** /**
* Utilities / API methods for blocks. * Utilities / API methods for blocks.
*/ */
@UtilityClass public final class BlockUtils {
public class BlockUtils {
/** /**
* If the meta set function has been set. * If the meta set function has been set.
*/ */
private boolean initialized = false; private static boolean initialized = false;
/** /**
* The block break function. * The block break function.
*/ */
private BiConsumer<Player, Block> blockBreakConsumer = null; private static BiConsumer<Player, Block> blockBreakConsumer = null;
private Pair<Block, Set<Block>> getNearbyBlocksRecursively(@NotNull final Block start,
@NotNull final List<Material> allowedMaterials,
@NotNull final Set<Block> blocks,
final int limit) {
Block last = start;
private static Set<Block> getNearbyBlocks(@NotNull final Block start,
@NotNull final List<Material> allowedMaterials,
@NotNull final Set<Block> blocks,
final int limit) {
for (BlockFace face : BlockFace.values()) { for (BlockFace face : BlockFace.values()) {
Block block = start.getRelative(face); Block block = start.getRelative(face);
if (blocks.contains(block)) { if (blocks.contains(block)) {
@@ -44,46 +43,15 @@ public class BlockUtils {
if (allowedMaterials.contains(block.getType())) { if (allowedMaterials.contains(block.getType())) {
blocks.add(block); blocks.add(block);
last = block;
if (blocks.size() > limit) { if (blocks.size() > limit || blocks.size() > 2500) {
return new Pair<>(last, blocks); return blocks;
} }
Pair<Block, Set<Block>> pair = getNearbyBlocksRecursively(last, allowedMaterials, blocks, limit); blocks.addAll(getNearbyBlocks(block, allowedMaterials, blocks, limit));
assert pair.getSecond() != null;
blocks.addAll(pair.getSecond());
} }
} }
return new Pair<>(last, blocks);
}
private Set<Block> getNearbyBlocks(@NotNull final Block start,
@NotNull final List<Material> allowedMaterials,
@NotNull final Set<Block> blocks,
final int limit) {
/*
Prevent stack overflow.
*/
int cycles = (int) Math.ceil(limit / 1024D);
int cap = limit;
Block iterStart = start;
for (int i = 0; i < cycles; i++) {
assert iterStart != null;
Pair<Block, Set<Block>> pair = getNearbyBlocksRecursively(iterStart, allowedMaterials, blocks, cap);
assert pair.getSecond() != null;
iterStart = pair.getFirst();
blocks.addAll(pair.getSecond());
cap -= 1024;
}
return blocks; return blocks;
} }
@@ -95,9 +63,10 @@ public class BlockUtils {
* @param limit The maximum size of vein to return. * @param limit The maximum size of vein to return.
* @return A set of all {@link Block}s. * @return A set of all {@link Block}s.
*/ */
public Set<Block> getVein(@NotNull final Block start, @NotNull
@NotNull final List<Material> allowedMaterials, public static Set<Block> getVein(@NotNull final Block start,
final int limit) { @NotNull final List<Material> allowedMaterials,
final int limit) {
return getNearbyBlocks(start, allowedMaterials, new HashSet<>(), limit); return getNearbyBlocks(start, allowedMaterials, new HashSet<>(), limit);
} }
@@ -107,25 +76,52 @@ public class BlockUtils {
* @param player The player to break the block as. * @param player The player to break the block as.
* @param block The block to break. * @param block The block to break.
*/ */
public void breakBlock(@NotNull final Player player, public static void breakBlock(@NotNull final Player player,
@NotNull final Block block) { @NotNull final Block block) {
Validate.isTrue(initialized, "Must be initialized!"); Validate.isTrue(initialized, "Must be initialized!");
Validate.notNull(blockBreakConsumer, "Must be initialized!"); Validate.notNull(blockBreakConsumer, "Must be initialized!");
Location location = block.getLocation();
World world = location.getWorld();
assert world != null;
if (location.getY() < world.getMinHeight() || location.getY() > world.getMaxHeight()) {
return;
}
blockBreakConsumer.accept(player, block); blockBreakConsumer.accept(player, block);
} }
/**
* Get if a block was placed by a player.
*
* @param block The block.
* @return If placed by a player.
*/
public static boolean isPlayerPlaced(@NotNull final Block block) {
Chunk chunk = block.getChunk();
return chunk.getPersistentDataContainer().has(
NamespacedKeyUtils.createEcoKey(Integer.toString(block.getLocation().hashCode(), 16)),
PersistentDataType.INTEGER
);
}
/** /**
* Initialize the block break function. * Initialize the block break function.
* *
* @param function The function. * @param function The function.
*/ */
@ApiStatus.Internal @ApiStatus.Internal
public void initialize(@NotNull final BiConsumer<Player, Block> function) { public static void initialize(@NotNull final BiConsumer<Player, Block> function) {
Validate.isTrue(!initialized, "Already initialized!"); Validate.isTrue(!initialized, "Already initialized!");
blockBreakConsumer = function; blockBreakConsumer = function;
initialized = true; initialized = true;
} }
private BlockUtils() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
} }

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