Compare commits
377 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7eb1b917dc | ||
|
|
fdba12082c | ||
|
|
516ecc1c3d | ||
|
|
cfd545c735 | ||
|
|
0ded1fe68b | ||
|
|
4fce11b149 | ||
|
|
2374e8fe03 | ||
|
|
36ccf346d7 | ||
|
|
cb480bd88d | ||
|
|
8cc96cb30e | ||
|
|
736ba0f8b0 | ||
|
|
5b5fefee8e | ||
|
|
8941e3179b | ||
|
|
19ce4c56a9 | ||
|
|
337c5d2b84 | ||
|
|
631c17aedc | ||
|
|
0ff4ac92be | ||
|
|
aa94094078 | ||
|
|
135ddcf331 | ||
|
|
e5d31e0b49 | ||
|
|
448b2e4b3f | ||
|
|
ebb30e3a70 | ||
|
|
fb89415636 | ||
|
|
36c77d81eb | ||
|
|
b6cd56ad15 | ||
|
|
1a524aea94 | ||
|
|
2ebab99a06 | ||
|
|
46663f7edb | ||
|
|
4fad66cd90 | ||
|
|
a9fafeec00 | ||
|
|
0d8308d6cd | ||
|
|
13772002e8 | ||
|
|
c9b84889e7 | ||
|
|
1513578266 | ||
|
|
89d6f2f867 | ||
|
|
8e6d98c997 | ||
|
|
5bc2cb31a4 | ||
|
|
041575a103 | ||
|
|
c88dac56b7 | ||
|
|
00da717f6d | ||
|
|
cc557378cc | ||
|
|
b5c49c79b8 | ||
|
|
28018430e7 | ||
|
|
7b6c8d68a8 | ||
|
|
ad3cb3a620 | ||
|
|
511a7e4830 | ||
|
|
5aeeafc041 | ||
|
|
9a51fb8358 | ||
|
|
eeefb9f40e | ||
|
|
aa1ce34cbc | ||
|
|
47772c3ff7 | ||
|
|
dfcac5d527 | ||
|
|
40f88f0b59 | ||
|
|
105355d967 | ||
|
|
3cddff22b8 | ||
|
|
f8e930d29e | ||
|
|
9dbe088e66 | ||
|
|
6361c0e8e9 | ||
|
|
1135672241 | ||
|
|
80891e4a81 | ||
|
|
3e0be3a629 | ||
|
|
17819de2ea | ||
|
|
209cdd6b0d | ||
|
|
fbf6b2edd9 | ||
|
|
8b9e8589a0 | ||
|
|
525cc019ea | ||
|
|
04f2d15783 | ||
|
|
f988b591a4 | ||
|
|
9ebfb124c8 | ||
|
|
b9ab263f67 | ||
|
|
bb5f68283b | ||
|
|
9bbf1cfe36 | ||
|
|
19bb5f608c | ||
|
|
a1c70d2081 | ||
|
|
979ddf0ff0 | ||
|
|
232a63c00d | ||
|
|
e65cf9be2c | ||
|
|
fbf56037d4 | ||
|
|
aa0c4ee7fa | ||
|
|
5f3375bf87 | ||
|
|
11dc6d0e67 | ||
|
|
9cccbd10ba | ||
|
|
1f0ad48480 | ||
|
|
93322dcfa5 | ||
|
|
e3b630fcb7 | ||
|
|
8690b75f4c | ||
|
|
6de792f308 | ||
|
|
e59037635e | ||
|
|
b9d50e261d | ||
|
|
15173c8369 | ||
|
|
4ee0645a4e | ||
|
|
96bd53c089 | ||
|
|
e658bf3fa8 | ||
|
|
988836b5b9 | ||
|
|
5688f41b8b | ||
|
|
4eaa6ab75c | ||
|
|
b29363cdf6 | ||
|
|
c8648a92f5 | ||
|
|
0a59b6a208 | ||
|
|
4e18a0ab78 | ||
|
|
d49405f839 | ||
|
|
e10566da66 | ||
|
|
0c64cd98e0 | ||
|
|
231af30c61 | ||
|
|
9b5cc1fd9c | ||
|
|
7628c0bbfd | ||
|
|
0beedc6b07 | ||
|
|
f3c69f1c15 | ||
|
|
a148f667e5 | ||
|
|
b2370b4b6e | ||
|
|
525bd5264a | ||
|
|
54c27a0379 | ||
|
|
989dda0a4f | ||
|
|
1f2bb3341e | ||
|
|
65221bdddf | ||
|
|
b386f2df1b | ||
|
|
969329486d | ||
|
|
aab2e8237c | ||
|
|
30457c29a1 | ||
|
|
9ad480ecf0 | ||
|
|
b0d3256d1b | ||
|
|
4ff9d82cc1 | ||
|
|
f9178e248b | ||
|
|
cc8a799438 | ||
|
|
90b81f56df | ||
|
|
1240c14c14 | ||
|
|
ed46900f2f | ||
|
|
dade3d7fbb | ||
|
|
df141875d3 | ||
|
|
50b07de5d1 | ||
|
|
e2a033c24f | ||
|
|
3fa574105f | ||
|
|
a64386f980 | ||
|
|
4c5a0f9887 | ||
|
|
cbd43f5757 | ||
|
|
01f1425557 | ||
|
|
25e8cc0837 | ||
|
|
7ff3eeef06 | ||
|
|
58faf6de23 | ||
|
|
7f42cbe32e | ||
|
|
ae12ab17fe | ||
|
|
9949ed4f5f | ||
|
|
e3f81a51e8 | ||
|
|
a06d782dea | ||
|
|
7e60ee63ea | ||
|
|
e349f47e66 | ||
|
|
f710a69455 | ||
|
|
20b06be1f2 | ||
|
|
9992820580 | ||
|
|
feebbd8ec7 | ||
|
|
5302aa07a5 | ||
|
|
d124c5b274 | ||
|
|
f188919197 | ||
|
|
388268e906 | ||
|
|
6367867d2b | ||
|
|
291357e235 | ||
|
|
07178b0645 | ||
|
|
70ef99e875 | ||
|
|
885a7835ea | ||
|
|
94e9b47f02 | ||
|
|
e8f4bdd4aa | ||
|
|
c01e409904 | ||
|
|
f1cf82160e | ||
|
|
d1c15f8699 | ||
|
|
be6e7b1f46 | ||
|
|
b78fc2fb66 | ||
|
|
23a297b8e3 | ||
|
|
4e99ca51f0 | ||
|
|
47c93a6dbe | ||
|
|
da7f47d1ba | ||
|
|
144ea0dd10 | ||
|
|
732aaa3bf1 | ||
|
|
a38387be33 | ||
|
|
582f9b08f3 | ||
|
|
638367cbb2 | ||
|
|
ec35e7d779 | ||
|
|
1cc2a585d6 | ||
|
|
aa553b96d6 | ||
|
|
feb7ecee48 | ||
|
|
c0be6a12ff | ||
|
|
1dc6b651a0 | ||
|
|
3c26c02642 | ||
|
|
343508f099 | ||
|
|
76dc4948bc | ||
|
|
8fa209a981 | ||
|
|
b3a0634ad0 | ||
|
|
97d7acc0a9 | ||
|
|
ebac75b0ee | ||
|
|
02d0fa85b5 | ||
|
|
168915868c | ||
|
|
d62d598fd6 | ||
|
|
06561c5387 | ||
|
|
c9805e91b4 | ||
|
|
e3be95ca4d | ||
|
|
2e6463aed9 | ||
|
|
2501574eeb | ||
|
|
3c237fd856 | ||
|
|
7b3fd1d0c2 | ||
|
|
e599add6de | ||
|
|
1bda970f6b | ||
|
|
eb1f694905 | ||
|
|
efd3403eda | ||
|
|
08b563d528 | ||
|
|
c3f88bf7b0 | ||
|
|
eb6d76e0c6 | ||
|
|
f2d0e8c368 | ||
|
|
5e7b9573a1 | ||
|
|
7d457ea496 | ||
|
|
806bf9a43f | ||
|
|
316f134b71 | ||
|
|
0d363b9fb6 | ||
|
|
2890083eaa | ||
|
|
694646431b | ||
|
|
86d5e9d09e | ||
|
|
8635e5f7a5 | ||
|
|
aa718649eb | ||
|
|
1dc0fa449b | ||
|
|
19e3061a13 | ||
|
|
ecafbd76de | ||
|
|
3728f2fc7a | ||
|
|
56c124dbd2 | ||
|
|
6730697fc5 | ||
|
|
c8e1c83061 | ||
|
|
a9fd5a9418 | ||
|
|
7b1179f402 | ||
|
|
f4907329d9 | ||
|
|
1e23cbaa5e | ||
|
|
863818d2eb | ||
|
|
d35285d0dc | ||
|
|
bc92f8a444 | ||
|
|
2fafef17d7 | ||
|
|
24078a2838 | ||
|
|
73d13277be | ||
|
|
0e4c23d70c | ||
|
|
ddf5094c5a | ||
|
|
925fc56cab | ||
|
|
3208d0328f | ||
|
|
317824ae78 | ||
|
|
41a4b4fc1a | ||
|
|
c528e4cd42 | ||
|
|
2724f21d4e | ||
|
|
5cb14e31b7 | ||
|
|
6b9942f412 | ||
|
|
fbe88ab0fd | ||
|
|
d042211dbe | ||
|
|
5781df011e | ||
|
|
c191ff0767 | ||
|
|
b9cbcbe7a0 | ||
|
|
6009122c48 | ||
|
|
7536794100 | ||
|
|
e80aa5f910 | ||
|
|
b4aeeac570 | ||
|
|
33515aa5f7 | ||
|
|
047b535a40 | ||
|
|
ef8093ec7f | ||
|
|
9d0f95617d | ||
|
|
b4f3988fc7 | ||
|
|
e7e1751acc | ||
|
|
e68d482aa5 | ||
|
|
c0547a7c34 | ||
|
|
183b18c0ec | ||
|
|
e026a767d9 | ||
|
|
d2966aa428 | ||
|
|
9168e68b5a | ||
|
|
51a61b65c6 | ||
|
|
76be236dac | ||
|
|
f1bbac2dd0 | ||
|
|
6e88aef572 | ||
|
|
804f187964 | ||
|
|
623b8a18f4 | ||
|
|
0d4e424582 | ||
|
|
452e499467 | ||
|
|
b2950ab035 | ||
|
|
e47d05ccb2 | ||
|
|
b9e61b8c0d | ||
|
|
0f35d5d16e | ||
|
|
3a7315d728 | ||
|
|
6f193f70b0 | ||
|
|
bab3f078f6 | ||
|
|
5b4b17b97f | ||
|
|
f0e02ca25e | ||
|
|
7426e9adba | ||
|
|
00905aa9d5 | ||
|
|
f7b57880cb | ||
|
|
c1b673e30c | ||
|
|
4cf45795d6 | ||
|
|
59d31584e6 | ||
|
|
68e1f4afac | ||
|
|
507fad186a | ||
|
|
ca6b3185a3 | ||
|
|
8e96329fdc | ||
|
|
440605f636 | ||
|
|
bb686dca17 | ||
|
|
e595ea2247 | ||
|
|
a776b60f86 | ||
|
|
db7ac55eb2 | ||
|
|
52d77d7861 | ||
|
|
f8ece2d6c7 | ||
|
|
b353b5ec04 | ||
|
|
bbc412e589 | ||
|
|
b4a474c703 | ||
|
|
75e6a3da79 | ||
|
|
a1afffdbbb | ||
|
|
f6942192de | ||
|
|
dab26cbe95 | ||
|
|
b945a3f948 | ||
|
|
b2c1d650de | ||
|
|
4b994d5f4c | ||
|
|
ed2dffb52c | ||
|
|
20c870da06 | ||
|
|
7684e431f5 | ||
|
|
abcc13685f | ||
|
|
ac902eaa08 | ||
|
|
4e52913504 | ||
|
|
7505f7732f | ||
|
|
15fae21fd5 | ||
|
|
e9d98816ce | ||
|
|
675fc07ebf | ||
|
|
b8b8fd70b5 | ||
|
|
1d9fca1fb8 | ||
|
|
9b83f6eab4 | ||
|
|
8190660b8f | ||
|
|
cbf4d111fb | ||
|
|
6a139bef67 | ||
|
|
9e3fecfd13 | ||
|
|
3b260e2e5d | ||
|
|
0c0370e256 | ||
|
|
227b748f85 | ||
|
|
c8382bd8cf | ||
|
|
df22768367 | ||
|
|
00ea3506ca | ||
|
|
521659cfec | ||
|
|
bbe5f1eba4 | ||
|
|
3d4c33860a | ||
|
|
eae5d29f8d | ||
|
|
c878d6fd12 | ||
|
|
2b97c0072f | ||
|
|
63079df745 | ||
|
|
079b41e877 | ||
|
|
1aaab459d8 | ||
|
|
db78c2eb4c | ||
|
|
02fd07b3c8 | ||
|
|
3de2e53031 | ||
|
|
cb088bb70b | ||
|
|
36fca7016f | ||
|
|
7e1137da06 | ||
|
|
0da104d614 | ||
|
|
9095de7d19 | ||
|
|
7a8abac1a2 | ||
|
|
1ddcb6e964 | ||
|
|
4d0858ad84 | ||
|
|
3d05695a36 | ||
|
|
d676be15ce | ||
|
|
16848caec1 | ||
|
|
ef26fe4629 | ||
|
|
29fbd785d7 | ||
|
|
8c73676ee0 | ||
|
|
ebf27d28d9 | ||
|
|
317bc13f65 | ||
|
|
b8ec0ee6fc | ||
|
|
307e57c902 | ||
|
|
db0d55659f | ||
|
|
548529feb3 | ||
|
|
fb56baf452 | ||
|
|
5d18b424d7 | ||
|
|
7be9a1bd10 | ||
|
|
97c39b56dd | ||
|
|
3a9f5bc139 | ||
|
|
1e5955f249 | ||
|
|
bad076bbe9 | ||
|
|
e219b2f33c | ||
|
|
2f7603409e | ||
|
|
28cdb65176 | ||
|
|
03ae9e89b3 | ||
|
|
651426ed76 | ||
|
|
1a49165656 | ||
|
|
a48c3c2fed |
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Auxilor Community Discord
|
||||
url: https://discord.gg/ZcwpSsE/
|
||||
about: Join the Auxilor discord to get help from support staff and the general community!
|
||||
- name: The most common issues people have
|
||||
url: https://github.com/Auxilor/eco/issues/78
|
||||
about: Check the list of known common issues to see if your issue has already been solved
|
||||
31
.github/ISSUE_TEMPLATE/report-a-bug.md
vendored
Normal file
31
.github/ISSUE_TEMPLATE/report-a-bug.md
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
name: Report a Bug
|
||||
about: Report an issue with the plugin
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Server Information (please complete the following information):**
|
||||
- Version: (output of `/ver` command)
|
||||
- Version of plugin and eco (`/ver eco`, `/ver <plugin>`)
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
20
.github/ISSUE_TEMPLATE/request-a-feature.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/request-a-feature.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Request a Feature
|
||||
about: Suggest an idea for this plugin
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
15
.github/workflows/checkstyle.yml
vendored
Normal file
15
.github/workflows/checkstyle.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
name: Check PR Codestyle
|
||||
on: [ pull_request ]
|
||||
|
||||
jobs:
|
||||
checkstyle:
|
||||
name: Checkstyle
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: dbelyaev/action-checkstyle@v0.5.1
|
||||
with:
|
||||
github_token: ${{ secrets.github_token }}
|
||||
reporter: github-pr-review
|
||||
level: warning
|
||||
checkstyle_config: ../../config/checkstyle/checkstyle.xml
|
||||
2
.github/workflows/java-ci.yml
vendored
2
.github/workflows/java-ci.yml
vendored
@@ -1,6 +1,6 @@
|
||||
name: Java CI
|
||||
|
||||
on: [push]
|
||||
on: [ push, pull_request ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
42
.github/workflows/test-publish.yml
vendored
Normal file
42
.github/workflows/test-publish.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
name: Publish API (Dev)
|
||||
|
||||
on: [ push, pull_request ]
|
||||
|
||||
jobs:
|
||||
publish-release:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout latest code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set outputs
|
||||
id: vars
|
||||
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
|
||||
- name: Setup build cache
|
||||
uses: actions/cache@v2.1.6
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
|
||||
|
||||
- name: Publish artifact
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# The GITHUB_REF tag comes in the format 'refs/tags/xxx'.
|
||||
# So if we split on '/' and take the 3rd value, we can get the release name.
|
||||
run: |
|
||||
NEW_VERSION=$(echo "${GITHUB_REF}" | cut -d "/" -f3)
|
||||
echo "New version: ${{ steps.vars.outputs.sha_short }}"
|
||||
echo "Github username: ${GITHUB_ACTOR}"
|
||||
./gradlew -Pversion=dev-${{ steps.vars.outputs.sha_short }} publish
|
||||
@@ -1,24 +1,38 @@
|
||||
# How to contribute to eco
|
||||
|
||||
## Codestyle
|
||||
|
||||
1. The eco checkstyle is in /config/checkstyle.xml
|
||||
|
||||
- The pull request must not have any checkstyle issues.
|
||||
- Every method and field must have a javadoc attached.
|
||||
|
||||
2. Use JetBrains annotations
|
||||
|
||||
- Every parameter should be annotated with @NotNull or @Nullable
|
||||
- Use @NotNull over lombok @NonNull
|
||||
|
||||
3. Imports
|
||||
|
||||
- No group (*) imports.
|
||||
- No static imports.
|
||||
|
||||
4. Kotlin
|
||||
|
||||
- Kotlin should be the only language used in the backend, java should be the only language used in the frontend.
|
||||
- Kotlin API extensions should only be for creating extension functions and extra niceties that aren't possible in java.
|
||||
Do not write API components in kotlin.
|
||||
- Kotlin code should never be called directly from the frontend Java API. Kotlin API extensions should always rely on
|
||||
java, not the other way round.
|
||||
|
||||
## Dependency Injection
|
||||
|
||||
- eco uses Dependency Injection
|
||||
- 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.
|
||||
- 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.
|
||||
|
||||
## Other
|
||||
|
||||
- All drops **must** be sent through a DropQueue - calls to World#dropItem will get your PR rejected.
|
||||
- eco is built with java 17.
|
||||
@@ -29,7 +29,7 @@ and many more.
|
||||
|
||||
# For server owners
|
||||
- Requires ProtocolLib to be installed: get the latest version [here](https://www.spigotmc.org/resources/protocollib.1997/)
|
||||
- Supports 1.16.5+
|
||||
- Supports 1.17+
|
||||
|
||||
## Downloads
|
||||
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10")
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id("java-library")
|
||||
id("com.github.johnrengelman.shadow") version "7.0.0"
|
||||
id("com.github.johnrengelman.shadow") version "7.1.2"
|
||||
id("maven-publish")
|
||||
id("java")
|
||||
kotlin("jvm") version "1.6.10"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -10,9 +21,8 @@ dependencies {
|
||||
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 = "reobf"))
|
||||
implementation(project(":eco-core:core-nms:v1_18_R1"))
|
||||
implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf"))
|
||||
}
|
||||
|
||||
allprojects {
|
||||
@@ -20,6 +30,7 @@ allprojects {
|
||||
apply(plugin = "java-library")
|
||||
apply(plugin = "maven-publish")
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
apply(plugin = "kotlin")
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
@@ -35,7 +46,7 @@ allprojects {
|
||||
// NMS (for jitpack compilation)
|
||||
maven("https://repo.codemc.org/repository/nms/")
|
||||
|
||||
// bStats, mcMMO, BentoBox
|
||||
// mcMMO, BentoBox
|
||||
maven("https://repo.codemc.org/repository/maven-public/")
|
||||
|
||||
// Spigot API, Bungee API
|
||||
@@ -61,19 +72,33 @@ allprojects {
|
||||
|
||||
// IridiumSkyblock
|
||||
maven("https://nexus.iridiumdevelopment.net/repository/maven-releases/")
|
||||
|
||||
// MythicMobs
|
||||
maven("https://mvn.lumine.io/repository/maven-public/")
|
||||
|
||||
// Crunch
|
||||
maven("https://redempt.dev")
|
||||
|
||||
// LibsDisguises
|
||||
maven("https://repo.md-5.net/content/groups/public/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(kotlin("stdlib", version = "1.6.10"))
|
||||
compileOnly("org.jetbrains:annotations:23.0.0")
|
||||
|
||||
// Test
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1")
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2")
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
||||
|
||||
// Adventure
|
||||
compileOnly("net.kyori:adventure-api:4.9.3")
|
||||
compileOnly("net.kyori:adventure-text-serializer-gson:4.9.3")
|
||||
compileOnly("net.kyori:adventure-text-serializer-legacy:4.9.3")
|
||||
|
||||
// Other
|
||||
compileOnly("com.google.guava:guava:31.0.1-jre")
|
||||
compileOnly("com.github.ben-manes.caffeine:caffeine:3.0.5")
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
@@ -90,7 +115,19 @@ allprojects {
|
||||
exclude(group = "com.github.cryptomorin", module = "XSeries")
|
||||
}
|
||||
|
||||
configurations.testImplementation {
|
||||
setExtendsFrom(listOf(configurations.compileOnly.get()))
|
||||
}
|
||||
|
||||
tasks {
|
||||
compileKotlin {
|
||||
kotlinOptions {
|
||||
jvmTarget = "17"
|
||||
}
|
||||
targetCompatibility = "17"
|
||||
sourceCompatibility = "17"
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
relocate("org.bstats", "com.willfp.eco.shaded.bstats")
|
||||
relocate("net.kyori.adventure.text.minimessage", "com.willfp.eco.shaded.minimessage")
|
||||
|
||||
@@ -32,10 +32,6 @@
|
||||
-->
|
||||
|
||||
<module name="Checker">
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="config/checkstyle/suppression.xml"/>
|
||||
</module>
|
||||
|
||||
<!--
|
||||
If you set the basedir property below, then all reported file
|
||||
names will be relative to the specified directory. See
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!DOCTYPE suppressions PUBLIC
|
||||
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
|
||||
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
|
||||
|
||||
<suppressions>
|
||||
<!-- Internals don't need javadoc. -->
|
||||
<suppress files="[\\/]internal[\\/]" checks="MissingJavadocMethod"/>
|
||||
<suppress files="[\\/]internal[\\/]" checks="JavadocVariable"/>
|
||||
<suppress files="[\\/]eco[\\/]spigot[\\/]" checks="MissingJavadocMethod"/>
|
||||
<suppress files="[\\/]eco[\\/]spigot[\\/]" checks="JavadocVariable"/>
|
||||
<suppress files="[\\/]eco[\\/]proxy[\\/]" checks="MissingJavadocMethod"/>
|
||||
<suppress files="[\\/]eco[\\/]proxy[\\/]" checks="JavadocVariable"/>
|
||||
|
||||
<!-- Modified version of library -->
|
||||
<suppress files="ArmorEquipEvent.java" checks="JavadocVariable"/>
|
||||
<suppress files="ArmorEquipEvent.java" checks="MissingJavadocMethod"/>
|
||||
<suppress files="ArmorEquipEvent.java" checks="JavadocStyle"/>
|
||||
<suppress files="ArmorListener.java" checks="JavadocVariable"/>
|
||||
<suppress files="ArmorListener.java" checks="MissingJavadocMethod"/>
|
||||
<suppress files="ArmorType.java" checks="JavadocVariable"/>
|
||||
<suppress files="ArmorType.java" checks="MissingJavadocMethod"/>
|
||||
</suppressions>
|
||||
@@ -1,10 +1,3 @@
|
||||
plugins {
|
||||
id 'com.github.johnrengelman.shadow'
|
||||
}
|
||||
|
||||
group 'com.willfp'
|
||||
version rootProject.version
|
||||
|
||||
dependencies {
|
||||
// Adventure
|
||||
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
||||
@@ -17,10 +10,8 @@ dependencies {
|
||||
compileOnly 'com.google.code.gson:gson:2.8.8'
|
||||
}
|
||||
|
||||
java {
|
||||
withJavadocJar()
|
||||
}
|
||||
|
||||
group 'com.willfp'
|
||||
version rootProject.version
|
||||
|
||||
build.dependsOn publishToMavenLocal
|
||||
|
||||
|
||||
@@ -4,11 +4,20 @@ import org.apache.commons.lang.Validate;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Base class to hold the handler.
|
||||
* Holds the instance of the eco handler for bridging between the frontend
|
||||
* and backend.
|
||||
*
|
||||
* @see Eco#getHandler()
|
||||
* @see Handler
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public final class Eco {
|
||||
/**
|
||||
* Instance of eco handler.
|
||||
@@ -18,6 +27,7 @@ public final class Eco {
|
||||
|
||||
/**
|
||||
* Set the handler.
|
||||
*
|
||||
* @param handler The handler.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@@ -28,18 +38,18 @@ public final class Eco {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instance of the eco handler.
|
||||
* Get the instance of the eco handler; the bridge between the api frontend
|
||||
* and the implementation backend.
|
||||
* <p>
|
||||
* The handler is, in essence, a way to interface between the eco-api
|
||||
* frontend module, and the eco-backend implementations.
|
||||
* <strong>Do not use the handler in your plugins!</strong> It can and will contain
|
||||
* breaking changes between minor versions and even patches, and you will create
|
||||
* compatibility issues by using the handler. All parts of the handler have been abstracted
|
||||
* into logically named API components that you can use.
|
||||
* <p>
|
||||
* There shouldn't really be any reason to ever use the handler
|
||||
* in your own plugins, and you are likely to break things. All parts of
|
||||
* the handler are abstracted into logically named parts of the API.
|
||||
* <p>
|
||||
* In versions of eco before 6.12.0, the handler was considered part of
|
||||
* the eco API, however it has since been moved into an internal component
|
||||
* that shouldn't be used in your plugins.
|
||||
* Prior to version 6.12.0, the handler was considered as an API component, but it has
|
||||
* since been moved into an internal component, and in 6.17.0, the first breaking change
|
||||
* was introduced to {@link com.willfp.eco.core.config.wrapper.ConfigFactory}. This means
|
||||
* that any usages of the handler can now cause problems in your plugins.
|
||||
*
|
||||
* @return The handler.
|
||||
*/
|
||||
@@ -48,6 +58,24 @@ public final class Eco {
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Eco Handler components are internals, so if a class is marked as a handler component,
|
||||
* then it should be treated the same as if it was marked with {@link ApiStatus.Internal}.
|
||||
* <p>
|
||||
* If a class is marked with {@link HandlerComponent}, <strong>Do not reference it in
|
||||
* your code!</strong> It can and will contain breaking changes between minor versions and
|
||||
* even patches, and you will create compatibility issues by using them.
|
||||
* <p>
|
||||
* Handler components should also be marked with {@link ApiStatus.Internal} in order to
|
||||
* cause compiler / IDE warnings.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target({ElementType.TYPE})
|
||||
public @interface HandlerComponent {
|
||||
|
||||
}
|
||||
|
||||
private Eco() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import com.willfp.eco.core.factory.NamespacedKeyFactory;
|
||||
import com.willfp.eco.core.factory.RunnableFactory;
|
||||
import com.willfp.eco.core.integrations.IntegrationLoader;
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
|
||||
import com.willfp.eco.core.proxy.AbstractProxy;
|
||||
import com.willfp.eco.core.proxy.ProxyFactory;
|
||||
import com.willfp.eco.core.scheduling.Scheduler;
|
||||
import com.willfp.eco.core.web.UpdateChecker;
|
||||
@@ -32,6 +31,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -152,10 +152,14 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
private final ProxyFactory proxyFactory;
|
||||
|
||||
/**
|
||||
* Create a new plugin without a specified color, proxy support, polymart, or bStats.
|
||||
* Create a new plugin.
|
||||
* <p>
|
||||
* Will read from eco.yml (like plugin.yml) to fetch values that would otherwise be passed
|
||||
* into the constructor. If no eco.yml is present, the plugin will load without extension
|
||||
* support, without proxy support, with no update-checker or bStats, and with the color white.
|
||||
*/
|
||||
protected EcoPlugin() {
|
||||
this("&f");
|
||||
this((PluginProps) null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,6 +240,23 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
@NotNull final String proxyPackage,
|
||||
@NotNull final String color,
|
||||
final boolean supportingExtensions) {
|
||||
this(
|
||||
PluginProps.createSimple(
|
||||
resourceId,
|
||||
bStatsId,
|
||||
proxyPackage,
|
||||
color,
|
||||
supportingExtensions
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new plugin.
|
||||
*
|
||||
* @param pluginProps The props. If left null, it will read from eco.yml.
|
||||
*/
|
||||
protected EcoPlugin(@Nullable final PluginProps pluginProps) {
|
||||
/*
|
||||
The handler must be initialized before any plugin's constructors
|
||||
are called, as the constructors call Eco#getHandler().
|
||||
@@ -253,15 +274,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
a standalone handler class, but then there would be an interface
|
||||
left in the API that doesn't really help anything.
|
||||
|
||||
The other alternative would be do use reflection to get a 'createHandler'
|
||||
method that only exists in EcoSpigotPlugin - but that feels really dirty
|
||||
The other alternative would be to use reflection to get a 'createHandler'
|
||||
method that only exists in EcoSpigotPlugin - but that feels filthy,
|
||||
and I'd rather only use reflection where necessary.
|
||||
*/
|
||||
|
||||
if (Eco.getHandler() == null && this instanceof Handler) {
|
||||
/*
|
||||
This code is only ever called by EcoSpigotPlugin (EcoHandler)
|
||||
as it's the first plugin to load and it is a handler.
|
||||
as it's the first plugin to load, and it is a handler.
|
||||
|
||||
Any other plugins will never call this code as the handler
|
||||
will have already been initialized.
|
||||
@@ -272,11 +293,16 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
|
||||
assert Eco.getHandler() != null;
|
||||
|
||||
this.resourceId = resourceId;
|
||||
this.bStatsId = bStatsId;
|
||||
this.proxyPackage = proxyPackage;
|
||||
this.color = color;
|
||||
this.supportingExtensions = supportingExtensions;
|
||||
PluginProps generatedProps = Eco.getHandler().getProps(pluginProps, this.getClass());
|
||||
generatedProps.validate();
|
||||
PluginProps props = this.mutateProps(generatedProps);
|
||||
props.validate();
|
||||
|
||||
this.resourceId = props.getResourceId();
|
||||
this.bStatsId = props.getBStatsId();
|
||||
this.proxyPackage = props.getProxyPackage();
|
||||
this.color = props.getColor();
|
||||
this.supportingExtensions = props.isSupportingExtensions();
|
||||
|
||||
this.scheduler = Eco.getHandler().createScheduler(this);
|
||||
this.eventManager = Eco.getHandler().createEventManager(this);
|
||||
@@ -296,8 +322,8 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
/*
|
||||
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.
|
||||
can throw errors without it being obvious to the user that the reason is that
|
||||
they have an outdated version of eco installed.
|
||||
*/
|
||||
|
||||
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.getHandler().getEcoPlugin().getDescription().getVersion());
|
||||
@@ -327,11 +353,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version);
|
||||
if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) {
|
||||
this.outdated = true;
|
||||
this.getScheduler().runTimer(() -> {
|
||||
this.getLogger().info("&c " + this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
|
||||
this.getLogger().info("&cThe newest version is &f" + version);
|
||||
this.getLogger().info("&cDownload the new version!");
|
||||
}, 0, 864000);
|
||||
this.getLogger().warning("&c" + this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
|
||||
this.getLogger().warning("&cThe newest version is &f" + version);
|
||||
this.getLogger().warning("&cDownload the new version!");
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -536,6 +560,21 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutate the plugin props.
|
||||
* <p>
|
||||
* Useful for eco-based plugin libraries to enforce certain properties, such as
|
||||
* forcing extensions to be enabled.
|
||||
* <p>
|
||||
* Props are validated both before and after calling this method.
|
||||
*
|
||||
* @param props The props.
|
||||
* @return The mutated props.
|
||||
*/
|
||||
protected PluginProps mutateProps(@NotNull final PluginProps props) {
|
||||
return props;
|
||||
}
|
||||
|
||||
/**
|
||||
* The plugin-specific integrations to be tested and loaded.
|
||||
*
|
||||
@@ -636,8 +675,8 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
* @param <T> The proxy type.
|
||||
* @return The proxy.
|
||||
*/
|
||||
public final <T extends AbstractProxy> T getProxy(@NotNull final Class<T> proxyClass) {
|
||||
Validate.notNull(proxyFactory, "Plugin does not support proxy!");
|
||||
public final <T> T getProxy(@NotNull final Class<T> proxyClass) {
|
||||
Validate.notNull(proxyFactory, "Plugin does not support proxies!");
|
||||
|
||||
return proxyFactory.getProxy(proxyClass);
|
||||
}
|
||||
@@ -655,7 +694,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
public final FileConfiguration getConfig() {
|
||||
this.getLogger().warning("Call to default config method in eco plugin!");
|
||||
|
||||
return this.getConfigYml().getBukkitHandle();
|
||||
return Objects.requireNonNull(this.getConfigYml().getBukkitHandle());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.willfp.eco.core;
|
||||
|
||||
import com.willfp.eco.core.config.updating.ConfigHandler;
|
||||
import com.willfp.eco.core.config.wrapper.ConfigFactory;
|
||||
import com.willfp.eco.core.data.PlayerProfileHandler;
|
||||
import com.willfp.eco.core.data.ProfileHandler;
|
||||
import com.willfp.eco.core.data.keys.KeyRegistry;
|
||||
import com.willfp.eco.core.drops.DropQueueFactory;
|
||||
import com.willfp.eco.core.events.EventManager;
|
||||
@@ -15,9 +15,11 @@ import com.willfp.eco.core.gui.GUIFactory;
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
|
||||
import com.willfp.eco.core.proxy.Cleaner;
|
||||
import com.willfp.eco.core.proxy.ProxyFactory;
|
||||
import com.willfp.eco.core.requirement.RequirementFactory;
|
||||
import com.willfp.eco.core.scheduling.Scheduler;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -30,6 +32,7 @@ import java.util.logging.Logger;
|
||||
* @see Eco#getHandler()
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@SuppressWarnings("removal")
|
||||
public interface Handler {
|
||||
/**
|
||||
* Create a scheduler.
|
||||
@@ -201,14 +204,6 @@ public interface Handler {
|
||||
*/
|
||||
void registerBStats(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Get the requirement factory.
|
||||
*
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
RequirementFactory getRequirementFactory();
|
||||
|
||||
/**
|
||||
* Get Adventure audiences.
|
||||
*
|
||||
@@ -230,5 +225,41 @@ public interface Handler {
|
||||
*
|
||||
* @return The handler.
|
||||
*/
|
||||
PlayerProfileHandler getPlayerProfileHandler();
|
||||
@NotNull
|
||||
ProfileHandler getProfileHandler();
|
||||
|
||||
/**
|
||||
* Create dummy entity - never spawned, exists purely in code.
|
||||
*
|
||||
* @param location The location.
|
||||
* @return The entity.
|
||||
*/
|
||||
@NotNull
|
||||
Entity createDummyEntity(@NotNull Location location);
|
||||
|
||||
/**
|
||||
* Create a {@link NamespacedKey} quickly
|
||||
* <p>
|
||||
* Bypasses the constructor, allowing for the creation of invalid keys,
|
||||
* therefore this is considered unsafe and should only be called after
|
||||
* the key has been confirmed to be valid.
|
||||
*
|
||||
* @param namespace The namespace.
|
||||
* @param key The key.
|
||||
* @return The key.
|
||||
*/
|
||||
@NotNull
|
||||
NamespacedKey createNamespacedKey(@NotNull String namespace,
|
||||
@NotNull String key);
|
||||
|
||||
/**
|
||||
* Return or get props for a plugin.
|
||||
*
|
||||
* @param existing The existing constructor props.
|
||||
* @param plugin The plugin.
|
||||
* @return The props.
|
||||
*/
|
||||
@NotNull
|
||||
PluginProps getProps(@Nullable PluginProps existing,
|
||||
@NotNull Class<? extends EcoPlugin> plugin);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,13 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Quick DI class to manage passing eco plugins.
|
||||
* <p>
|
||||
* Basically just a quick bit of laziness if you can't be bothered to add a private field
|
||||
* and a protected getter, don't use this in kotlin as you can just specify
|
||||
* {@code
|
||||
* private val plugin: EcoPlugin
|
||||
* }
|
||||
* in the constructor.
|
||||
*
|
||||
* @param <T> The eco plugin type.
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.willfp.eco.core;
|
||||
import com.willfp.eco.core.config.updating.ConfigHandler;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Represents any class that acts like a plugin, for example {@link EcoPlugin}
|
||||
@@ -26,4 +27,11 @@ public interface PluginLike {
|
||||
* @return The config handler.
|
||||
*/
|
||||
ConfigHandler getConfigHandler();
|
||||
|
||||
/**
|
||||
* Get the logger.
|
||||
*
|
||||
* @return The logger.
|
||||
*/
|
||||
Logger getLogger();
|
||||
}
|
||||
|
||||
275
eco-api/src/main/java/com/willfp/eco/core/PluginProps.java
Normal file
275
eco-api/src/main/java/com/willfp/eco/core/PluginProps.java
Normal file
@@ -0,0 +1,275 @@
|
||||
package com.willfp.eco.core;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Plugin props are the arguments related to the plugin that are required on start-up.
|
||||
* <p>
|
||||
* This class is complex in how it works intentionally. This is done so that fields can be
|
||||
* added to the props without breaking API backwards compatibility. Thus, there is no public
|
||||
* constructor and no way to instantiate props without creating a parser.
|
||||
*/
|
||||
public final class PluginProps {
|
||||
/**
|
||||
* All registered parsers.
|
||||
*/
|
||||
private static final Map<Class<?>, PropsParser<?>> REGISTERED_PARSERS = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The polymart resource ID.
|
||||
*/
|
||||
@Nullable
|
||||
private Integer resourceId;
|
||||
|
||||
/**
|
||||
* The bStats ID.
|
||||
*/
|
||||
@Nullable
|
||||
private Integer bStatsId;
|
||||
|
||||
/**
|
||||
* The proxy package.
|
||||
*/
|
||||
@Nullable
|
||||
private String proxyPackage;
|
||||
|
||||
/**
|
||||
* The color.
|
||||
*/
|
||||
@Nullable
|
||||
private String color;
|
||||
|
||||
/**
|
||||
* If extensions are supported.
|
||||
*/
|
||||
@Nullable
|
||||
private Boolean supportingExtensions;
|
||||
|
||||
/**
|
||||
* Create new blank props.
|
||||
*/
|
||||
private PluginProps() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource ID.
|
||||
*
|
||||
* @return The resource ID.
|
||||
*/
|
||||
public int getResourceId() {
|
||||
assert resourceId != null;
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set resource ID.
|
||||
*
|
||||
* @param resourceId The resource ID.
|
||||
*/
|
||||
public void setResourceId(final int resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bStats ID.
|
||||
*
|
||||
* @return The bStats ID.
|
||||
*/
|
||||
public int getBStatsId() {
|
||||
assert bStatsId != null;
|
||||
return bStatsId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set bStats ID.
|
||||
*
|
||||
* @param bStatsId The bStats ID.
|
||||
*/
|
||||
public void setBStatsId(final int bStatsId) {
|
||||
this.bStatsId = bStatsId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the proxy package.
|
||||
*
|
||||
* @return The package.
|
||||
*/
|
||||
@NotNull
|
||||
public String getProxyPackage() {
|
||||
assert proxyPackage != null;
|
||||
return proxyPackage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the proxy package.
|
||||
*
|
||||
* @param proxyPackage The proxy package.
|
||||
*/
|
||||
public void setProxyPackage(@NotNull final String proxyPackage) {
|
||||
this.proxyPackage = proxyPackage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get color.
|
||||
*
|
||||
* @return The color.
|
||||
*/
|
||||
@NotNull
|
||||
public String getColor() {
|
||||
assert color != null;
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color.
|
||||
*
|
||||
* @param color The color.
|
||||
*/
|
||||
public void setColor(@NotNull final String color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if extensions are supported.
|
||||
*
|
||||
* @return If supported.
|
||||
*/
|
||||
public boolean isSupportingExtensions() {
|
||||
assert supportingExtensions != null;
|
||||
return supportingExtensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if extensions are supported.
|
||||
*
|
||||
* @param supportingExtensions If supported.
|
||||
*/
|
||||
public void setSupportingExtensions(final boolean supportingExtensions) {
|
||||
this.supportingExtensions = supportingExtensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that all required props have been set.
|
||||
*/
|
||||
public void validate() {
|
||||
if (
|
||||
supportingExtensions == null
|
||||
|| proxyPackage == null
|
||||
|| color == null
|
||||
|| bStatsId == null
|
||||
|| resourceId == null
|
||||
) {
|
||||
throw new IllegalStateException("Missing required props!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse props from source.
|
||||
*
|
||||
* @param source The source.
|
||||
* @param sourceClass The source class.
|
||||
* @param <T> The source type.
|
||||
* @return The props.
|
||||
*/
|
||||
public static <T> PluginProps parse(@NotNull final T source,
|
||||
@NotNull final Class<? extends T> sourceClass) {
|
||||
for (Map.Entry<Class<?>, PropsParser<?>> entry : REGISTERED_PARSERS.entrySet()) {
|
||||
Class<?> clazz = entry.getKey();
|
||||
|
||||
if (clazz.equals(sourceClass)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
PropsParser<T> parser = (PropsParser<T>) entry.getValue();
|
||||
return parser.parseFrom(source);
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("No parser exists for class " + sourceClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a parser for a type.
|
||||
*
|
||||
* @param clazz The class.
|
||||
* @param parser The parser.
|
||||
* @param <T> The source type.
|
||||
*/
|
||||
public static <T> void registerParser(@NotNull final Class<T> clazz,
|
||||
@NotNull final PropsParser<T> parser) {
|
||||
REGISTERED_PARSERS.put(clazz, parser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if there is a registered parser for a class.
|
||||
*
|
||||
* @param clazz The class.
|
||||
* @return If there is a parser registered.
|
||||
*/
|
||||
public static boolean hasParserFor(@NotNull final Class<?> clazz) {
|
||||
for (Class<?> test : REGISTERED_PARSERS.keySet()) {
|
||||
if (test.equals(clazz)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new props from known values.
|
||||
*
|
||||
* Marked as internal as this method will break whenever the properties themselves
|
||||
* are updated (e.g. if a new property is added) - so to prevent any potential
|
||||
* backwards-compatibility bugs, this method cannot be invoked outside eco itself.
|
||||
*
|
||||
* @param resourceId The ID of the plugin on polymart.
|
||||
* @param bStatsId The ID of the plugin on bStats.
|
||||
* @param proxyPackage The package where proxies can be found.
|
||||
* @param color The primary color of the plugin.
|
||||
* @param supportsExtensions If the plugin should attempt to look for extensions.
|
||||
* @return The props.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
static PluginProps createSimple(final int resourceId,
|
||||
final int bStatsId,
|
||||
@NotNull final String proxyPackage,
|
||||
@NotNull final String color,
|
||||
final boolean supportsExtensions) {
|
||||
PluginProps props = new PluginProps();
|
||||
props.setResourceId(resourceId);
|
||||
props.setBStatsId(bStatsId);
|
||||
props.setProxyPackage(proxyPackage);
|
||||
props.setColor(color);
|
||||
props.setSupportingExtensions(supportsExtensions);
|
||||
return props;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse arguments into props for a plugin.
|
||||
*
|
||||
* @param <T> The type of source.
|
||||
*/
|
||||
public interface PropsParser<T> {
|
||||
/**
|
||||
* Parse props from a given source.
|
||||
*
|
||||
* @param source The source.
|
||||
* @return The props.
|
||||
*/
|
||||
PluginProps parseFrom(@NotNull T source);
|
||||
|
||||
/**
|
||||
* Get a new, blank props instance.
|
||||
*
|
||||
* @return Blank props.
|
||||
*/
|
||||
default PluginProps getBlankProps() {
|
||||
return new PluginProps();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,10 @@ public class Prerequisite {
|
||||
|
||||
/**
|
||||
* Requires the server to be running 1.17.
|
||||
*
|
||||
* @deprecated eco no longer supports versions before 1.17.
|
||||
*/
|
||||
@Deprecated(since = "6.25.2")
|
||||
public static final Prerequisite HAS_1_17 = new Prerequisite(
|
||||
() -> ProxyConstants.NMS_VERSION.contains("17") || HAS_1_18.isMet(),
|
||||
"Requires server to be running 1.17+"
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
package com.willfp.eco.core.command;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Interface for all command implementations.
|
||||
*/
|
||||
@@ -35,31 +40,77 @@ public interface CommandBase {
|
||||
*/
|
||||
CommandBase addSubcommand(@NotNull CommandBase command);
|
||||
|
||||
/**
|
||||
* Handle command execution.
|
||||
* <p>
|
||||
* Marked as default void with no implementation for backwards compatibility.
|
||||
*
|
||||
* @param sender The sender.
|
||||
* @param args The args.
|
||||
*/
|
||||
default void onExecute(@NotNull CommandSender sender,
|
||||
@NotNull List<String> args) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle tab completion.
|
||||
* <p>
|
||||
* Marked as default void with no implementation for backwards compatibility.
|
||||
*
|
||||
* @param sender The sender.
|
||||
* @param args The args.
|
||||
* @return The results.
|
||||
*/
|
||||
default List<String> tabComplete(@NotNull CommandSender sender,
|
||||
@NotNull List<String> args) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin.
|
||||
*
|
||||
* @return The plugin.
|
||||
*/
|
||||
EcoPlugin getPlugin();
|
||||
|
||||
/**
|
||||
* Get the handler.
|
||||
*
|
||||
* @return The handler.
|
||||
* @see CommandHandler
|
||||
* @deprecated Use {@link CommandBase#onExecute(CommandSender, List)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
CommandHandler getHandler();
|
||||
|
||||
/**
|
||||
* Set the handler.
|
||||
*
|
||||
* @param handler The handler.
|
||||
* @see CommandHandler
|
||||
* @deprecated Handlers have been deprecated.
|
||||
*/
|
||||
@Deprecated
|
||||
void setHandler(@NotNull CommandHandler handler);
|
||||
|
||||
/**
|
||||
* Get the tab completer.
|
||||
*
|
||||
* @return The tab completer.
|
||||
* @see TabCompleteHandler
|
||||
* @deprecated Use {@link CommandBase#tabComplete(CommandSender, List)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
TabCompleteHandler getTabCompleter();
|
||||
|
||||
/**
|
||||
* Set the tab completer.
|
||||
*
|
||||
* @param handler The handler.
|
||||
* @see TabCompleteHandler
|
||||
* @deprecated Handlers have been deprecated.
|
||||
*/
|
||||
@Deprecated
|
||||
void setTabCompleter(@NotNull TabCompleteHandler handler);
|
||||
}
|
||||
|
||||
@@ -10,9 +10,13 @@ import java.util.List;
|
||||
* A command handler handles the actual code for a command.
|
||||
* <p>
|
||||
* The replacement for {@link org.bukkit.command.CommandExecutor#onCommand(CommandSender, Command, String, String[])}
|
||||
*
|
||||
* @see CommandBase
|
||||
* @deprecated Handlers have been deprecated. This legacy system will eventually be removed,
|
||||
* update to use the new system: {@link CommandBase#onExecute(CommandSender, List)}.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
@Deprecated(since = "6.17.0")
|
||||
public interface CommandHandler {
|
||||
/**
|
||||
* The code to be called on execution.
|
||||
|
||||
@@ -10,9 +10,13 @@ import java.util.List;
|
||||
* A Tab Complete handler handles the actual tab-completion code.
|
||||
* <p>
|
||||
* The replacement for {@link org.bukkit.command.TabCompleter#onTabComplete(CommandSender, Command, String, String[])}
|
||||
*
|
||||
* @see CommandBase
|
||||
* @deprecated Handlers have been deprecated. This legacy system will eventually be removed,
|
||||
* update to use the new system: {@link CommandBase#tabComplete(CommandSender, List)}
|
||||
*/
|
||||
@FunctionalInterface
|
||||
@Deprecated(since = "6.17.0")
|
||||
public interface TabCompleteHandler {
|
||||
/**
|
||||
* Handle Tab Completion.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.willfp.eco.core.command.impl;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginDependent;
|
||||
import com.willfp.eco.core.command.CommandBase;
|
||||
import com.willfp.eco.core.command.CommandHandler;
|
||||
import com.willfp.eco.core.command.TabCompleteHandler;
|
||||
@@ -9,6 +8,7 @@ import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -23,7 +23,13 @@ import java.util.stream.Collectors;
|
||||
* in order to execute the command-specific code. It's essentially an internal
|
||||
* layer, hence why it's a package-private class.
|
||||
*/
|
||||
abstract class HandledCommand extends PluginDependent<EcoPlugin> implements CommandBase {
|
||||
@SuppressWarnings({"DeprecatedIsStillUsed"})
|
||||
abstract class HandledCommand implements CommandBase {
|
||||
/**
|
||||
* The plugin.
|
||||
*/
|
||||
private final EcoPlugin plugin;
|
||||
|
||||
/**
|
||||
* The name of the command.
|
||||
*/
|
||||
@@ -46,14 +52,16 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
||||
/**
|
||||
* The actual code to be executed in the command.
|
||||
*/
|
||||
private CommandHandler handler = (sender, args) -> {
|
||||
// Do nothing by default
|
||||
};
|
||||
@Deprecated
|
||||
@Nullable
|
||||
private CommandHandler handler = null;
|
||||
|
||||
/**
|
||||
* The tab completion code to be executed in the command.
|
||||
*/
|
||||
private TabCompleteHandler tabCompleter = (sender, args) -> new ArrayList<>();
|
||||
@Deprecated
|
||||
@Nullable
|
||||
private TabCompleteHandler tabCompleter = null;
|
||||
|
||||
/**
|
||||
* All subcommands for the command.
|
||||
@@ -74,7 +82,7 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
||||
@NotNull final String name,
|
||||
@NotNull final String permission,
|
||||
final boolean playersOnly) {
|
||||
super(plugin);
|
||||
this.plugin = plugin;
|
||||
this.name = name;
|
||||
this.permission = permission;
|
||||
this.playersOnly = playersOnly;
|
||||
@@ -94,6 +102,16 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin.
|
||||
*
|
||||
* @return The plugin.
|
||||
*/
|
||||
@Override
|
||||
public EcoPlugin getPlugin() {
|
||||
return this.plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the command.
|
||||
*
|
||||
@@ -120,7 +138,16 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
||||
}
|
||||
}
|
||||
|
||||
this.getHandler().onExecute(sender, Arrays.asList(args));
|
||||
if (this.isPlayersOnly() && !(sender instanceof Player)) {
|
||||
sender.sendMessage(this.getPlugin().getLangYml().getMessage("not-player"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.getHandler() != null) {
|
||||
this.getHandler().onExecute(sender, Arrays.asList(args));
|
||||
} else {
|
||||
this.onExecute(sender, Arrays.asList(args));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,7 +194,11 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
||||
}
|
||||
}
|
||||
|
||||
return this.getTabCompleter().tabComplete(sender, Arrays.asList(args));
|
||||
if (this.getTabCompleter() != null) {
|
||||
return this.getTabCompleter().tabComplete(sender, Arrays.asList(args));
|
||||
} else {
|
||||
return this.tabComplete(sender, Arrays.asList(args));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,11 +212,6 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
||||
public static boolean canExecute(@NotNull final CommandSender sender,
|
||||
@NotNull final CommandBase command,
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
if (command.isPlayersOnly() && !(sender instanceof Player)) {
|
||||
sender.sendMessage(plugin.getLangYml().getMessage("not-player"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sender.hasPermission(command.getPermission()) && sender instanceof Player) {
|
||||
sender.sendMessage(plugin.getLangYml().getNoPermission());
|
||||
return false;
|
||||
@@ -221,24 +247,6 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
||||
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.
|
||||
*
|
||||
@@ -248,21 +256,27 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
||||
return this.subcommands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the command handler.
|
||||
*
|
||||
* @param handler The handler.
|
||||
*/
|
||||
public void setHandler(@NotNull final CommandHandler handler) {
|
||||
@Deprecated
|
||||
@Override
|
||||
public @Nullable CommandHandler getHandler() {
|
||||
return this.handler;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public @Nullable TabCompleteHandler getTabCompleter() {
|
||||
return this.tabCompleter;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void setHandler(@Nullable final CommandHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tab completer.
|
||||
*
|
||||
* @param tabCompleter The tab completer.
|
||||
*/
|
||||
public void setTabCompleter(@NotNull final TabCompleteHandler tabCompleter) {
|
||||
@Deprecated
|
||||
@Override
|
||||
public void setTabCompleter(@Nullable final TabCompleteHandler tabCompleter) {
|
||||
this.tabCompleter = tabCompleter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* PluginCommands are the class to be used instead of CommandExecutor.
|
||||
* PluginCommands are the class to be used instead of CommandExecutor,
|
||||
* they function as the base command, e.g. {@code /ecoenchants} would be a base command, with each
|
||||
* subsequent argument functioning as subcommands.
|
||||
* <p>
|
||||
* The command will not be registered until register() is called.
|
||||
* <p>
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.willfp.eco.core.config;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.wrapper.LoadableConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
|
||||
* <p>
|
||||
* Automatically updates.
|
||||
*/
|
||||
public abstract class BaseConfig extends LoadableConfigWrapper {
|
||||
/**
|
||||
* Create new Base Config.
|
||||
*
|
||||
* @param plugin The plugin or extension.
|
||||
* @param configName The config name (excluding extension).
|
||||
* @param removeUnused If unused sections should be removed.
|
||||
* @param type The config type.
|
||||
*/
|
||||
protected BaseConfig(@NotNull final String configName,
|
||||
@NotNull final PluginLike plugin,
|
||||
final boolean removeUnused,
|
||||
@NotNull final ConfigType type) {
|
||||
super(Eco.getHandler().getConfigFactory().createUpdatableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
removeUnused,
|
||||
type
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.willfp.eco.core.config;
|
||||
|
||||
/**
|
||||
* Config types, classified by file extension.
|
||||
*/
|
||||
public enum ConfigType {
|
||||
/**
|
||||
* .json config.
|
||||
*/
|
||||
JSON,
|
||||
|
||||
/**
|
||||
* .yml config.
|
||||
*/
|
||||
YAML
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.willfp.eco.core.config;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.wrapper.LoadableConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Config implementation for configs present in one of two places:
|
||||
* <ul>
|
||||
* <li>Plugin base directory (eg config.yml, lang.json)</li>
|
||||
* <li>Other extension's configs</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Automatically updates.
|
||||
*/
|
||||
public abstract class ExtendableConfig extends LoadableConfigWrapper {
|
||||
/**
|
||||
* @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 type The config type.
|
||||
* @param source The class that owns the resource.
|
||||
*/
|
||||
protected ExtendableConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final PluginLike plugin,
|
||||
@NotNull final Class<?> source,
|
||||
@NotNull final String subDirectoryPath,
|
||||
@NotNull final ConfigType type,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
super(Eco.getHandler().getConfigFactory().createUpdatableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
subDirectoryPath,
|
||||
source,
|
||||
removeUnused,
|
||||
type,
|
||||
updateBlacklist
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.willfp.eco.core.config;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.wrapper.LoadableConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Non-updatable yaml config that exists within a plugin jar.
|
||||
*/
|
||||
public abstract class StaticBaseConfig extends LoadableConfigWrapper {
|
||||
/**
|
||||
* 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.
|
||||
* @param type The config type.
|
||||
*/
|
||||
protected StaticBaseConfig(@NotNull final String configName,
|
||||
@NotNull final PluginLike plugin,
|
||||
@NotNull final ConfigType type) {
|
||||
super(Eco.getHandler().getConfigFactory().createLoadableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
type
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.willfp.eco.core.config;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import com.willfp.eco.core.config.wrapper.ConfigWrapper;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Config that exists purely in the code, not linked to any file.
|
||||
* <p>
|
||||
* Use for inline configs to move data around or to add subsections to other configs.
|
||||
*/
|
||||
public class TransientConfig extends ConfigWrapper<Config> {
|
||||
/**
|
||||
* @param config The YamlConfiguration handle.
|
||||
*/
|
||||
public TransientConfig(@NotNull final YamlConfiguration config) {
|
||||
super(Eco.getHandler().getConfigFactory().createConfig(config));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stream The InputStream.
|
||||
*/
|
||||
public TransientConfig(@Nullable final InputStream stream) {
|
||||
super(stream != null ? Eco.getHandler().getConfigFactory().createConfig(YamlConfiguration.loadConfiguration(
|
||||
new InputStreamReader(stream)
|
||||
)) : new TransientConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new empty transient config.
|
||||
*
|
||||
* @param values The values.
|
||||
*/
|
||||
public TransientConfig(@NotNull final Map<String, Object> values) {
|
||||
super(Eco.getHandler().getConfigFactory().createConfig(values));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new empty transient config.
|
||||
*/
|
||||
public TransientConfig() {
|
||||
super(Eco.getHandler().getConfigFactory().createConfig("", ConfigType.YAML));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contents The contents of the config.
|
||||
* @param type The config type.
|
||||
*/
|
||||
public TransientConfig(@NotNull final String contents,
|
||||
@NotNull final ConfigType type) {
|
||||
super(Eco.getHandler().getConfigFactory().createConfig(contents, type));
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,21 @@
|
||||
package com.willfp.eco.core.config.base;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.config.yaml.YamlBaseConfig;
|
||||
import com.willfp.eco.core.config.BaseConfig;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Default plugin config.yml.
|
||||
*/
|
||||
public class ConfigYml extends YamlBaseConfig {
|
||||
public class ConfigYml extends BaseConfig {
|
||||
/**
|
||||
* Config.yml.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
public ConfigYml(@NotNull final EcoPlugin plugin) {
|
||||
super("config", true, plugin);
|
||||
super("config", plugin, true, ConfigType.YAML);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -25,7 +26,7 @@ public class ConfigYml extends YamlBaseConfig {
|
||||
*/
|
||||
public ConfigYml(@NotNull final EcoPlugin plugin,
|
||||
final boolean removeUnused) {
|
||||
super("config", removeUnused, plugin);
|
||||
super("config", plugin, removeUnused, ConfigType.YAML);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,7 +37,7 @@ public class ConfigYml extends YamlBaseConfig {
|
||||
*/
|
||||
public ConfigYml(@NotNull final EcoPlugin plugin,
|
||||
@NotNull final String name) {
|
||||
super(name, true, plugin);
|
||||
super(name, plugin, true, ConfigType.YAML);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,7 +50,6 @@ public class ConfigYml extends YamlBaseConfig {
|
||||
public ConfigYml(@NotNull final EcoPlugin plugin,
|
||||
@NotNull final String name,
|
||||
final boolean removeUnused) {
|
||||
super(name, removeUnused, plugin);
|
||||
super(name, plugin, removeUnused, ConfigType.YAML);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
package com.willfp.eco.core.config.base;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.config.yaml.YamlBaseConfig;
|
||||
import com.willfp.eco.core.config.BaseConfig;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.util.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Default plugin lang.yml.
|
||||
*/
|
||||
public class LangYml extends YamlBaseConfig {
|
||||
public class LangYml extends BaseConfig {
|
||||
/**
|
||||
* Lang.yml.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
public LangYml(@NotNull final EcoPlugin plugin) {
|
||||
super("lang", false, plugin);
|
||||
super("lang", plugin, false, ConfigType.YAML);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
package com.willfp.eco.core.config.interfaces;
|
||||
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.TransientConfig;
|
||||
import com.willfp.eco.util.NumberUtils;
|
||||
import com.willfp.eco.util.StringUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* All canfigs implement this interface.
|
||||
* All configs implement this interface.
|
||||
* <p>
|
||||
* Contains all methods that must exist in yaml and json configurations.
|
||||
*/
|
||||
@@ -66,10 +72,12 @@ public interface Config extends Cloneable {
|
||||
* Get subsection from config.
|
||||
*
|
||||
* @param path The key to check.
|
||||
* @return The subsection. Throws NPE if not found.
|
||||
* @return The subsection. Returns an empty section if not found.
|
||||
*/
|
||||
@NotNull
|
||||
Config getSubsection(@NotNull String path);
|
||||
default Config getSubsection(@NotNull String path) {
|
||||
return Objects.requireNonNullElse(getSubsectionOrNull(path), new TransientConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get subsection from config.
|
||||
@@ -86,7 +94,44 @@ public interface Config extends Cloneable {
|
||||
* @param path The key to fetch the value from.
|
||||
* @return The found value, or 0 if not found.
|
||||
*/
|
||||
int getInt(@NotNull String path);
|
||||
default int getInt(@NotNull String path) {
|
||||
return Objects.requireNonNullElse(getIntOrNull(path), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an integer from config with a specified default (not found) value.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param def The value to default to if not found.
|
||||
* @return The found value, or the default.
|
||||
*/
|
||||
default int getInt(@NotNull String path,
|
||||
int def) {
|
||||
return Objects.requireNonNullElse(getIntOrNull(path), def);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a decimal value via a mathematical expression.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @return The computed value, or 0 if not found or invalid.
|
||||
*/
|
||||
default int getIntFromExpression(@NotNull String path) {
|
||||
return getIntFromExpression(path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a decimal value via a mathematical expression.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param player The player to evaluate placeholders with respect to.
|
||||
* @return The computed value, or 0 if not found or invalid.
|
||||
*/
|
||||
default int getIntFromExpression(@NotNull String path,
|
||||
@Nullable Player player) {
|
||||
return Double.valueOf(getDoubleFromExpression(path, player)).intValue();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get an integer from config.
|
||||
@@ -97,16 +142,6 @@ public interface Config extends Cloneable {
|
||||
@Nullable
|
||||
Integer getIntOrNull(@NotNull String path);
|
||||
|
||||
/**
|
||||
* Get an integer from config with a specified default (not found) value.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param def The value to default to if not found.
|
||||
* @return The found value, or the default.
|
||||
*/
|
||||
int getInt(@NotNull String path,
|
||||
int def);
|
||||
|
||||
/**
|
||||
* Get a list of integers from config.
|
||||
*
|
||||
@@ -114,7 +149,9 @@ public interface Config extends Cloneable {
|
||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||
*/
|
||||
@NotNull
|
||||
List<Integer> getInts(@NotNull String path);
|
||||
default List<Integer> getInts(@NotNull String path) {
|
||||
return Objects.requireNonNullElse(getIntsOrNull(path), new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of integers from config.
|
||||
@@ -131,7 +168,9 @@ public interface Config extends Cloneable {
|
||||
* @param path The key to fetch the value from.
|
||||
* @return The found value, or false if not found.
|
||||
*/
|
||||
boolean getBool(@NotNull String path);
|
||||
default boolean getBool(@NotNull String path) {
|
||||
return Objects.requireNonNullElse(getBoolOrNull(path), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a boolean from config.
|
||||
@@ -149,7 +188,9 @@ public interface Config extends Cloneable {
|
||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||
*/
|
||||
@NotNull
|
||||
List<Boolean> getBools(@NotNull String path);
|
||||
default List<Boolean> getBools(@NotNull String path) {
|
||||
return Objects.requireNonNullElse(getBoolsOrNull(path), new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of booleans from config.
|
||||
@@ -168,7 +209,7 @@ public interface Config extends Cloneable {
|
||||
*/
|
||||
@NotNull
|
||||
default String getFormattedString(@NotNull String path) {
|
||||
return getString(path, true);
|
||||
return getString(path, true, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,25 +228,25 @@ public interface Config extends Cloneable {
|
||||
/**
|
||||
* Get a string from config.
|
||||
* <p>
|
||||
* Formatted by default.
|
||||
* Not formatted.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @return The found value, or an empty string if not found.
|
||||
*/
|
||||
@NotNull
|
||||
default String getString(@NotNull String path) {
|
||||
return getString(path, true);
|
||||
return getString(path, false, StringUtils.FormatOption.WITHOUT_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string from config.
|
||||
* <p>
|
||||
* This will be deprecated when {@link Config#getString(String)} no longer formats by default.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param format If the string should be formatted.
|
||||
* @return The found value, or an empty string if not found.
|
||||
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
|
||||
*/
|
||||
@Deprecated(since = "6.18.0")
|
||||
default String getString(@NotNull String path,
|
||||
boolean format) {
|
||||
return this.getString(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||
@@ -235,9 +276,11 @@ public interface Config extends Cloneable {
|
||||
* @return The found value, or an empty string if not found.
|
||||
*/
|
||||
@NotNull
|
||||
String getString(@NotNull String path,
|
||||
boolean format,
|
||||
@NotNull StringUtils.FormatOption option);
|
||||
default String getString(@NotNull String path,
|
||||
boolean format,
|
||||
@NotNull StringUtils.FormatOption option) {
|
||||
return Objects.requireNonNullElse(getStringOrNull(path, format, option), "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a formatted string from config.
|
||||
@@ -247,7 +290,7 @@ public interface Config extends Cloneable {
|
||||
*/
|
||||
@Nullable
|
||||
default String getFormattedStringOrNull(@NotNull String path) {
|
||||
return getStringOrNull(path, true);
|
||||
return getStringOrNull(path, true, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,19 +316,19 @@ public interface Config extends Cloneable {
|
||||
*/
|
||||
@Nullable
|
||||
default String getStringOrNull(@NotNull String path) {
|
||||
return getStringOrNull(path, true);
|
||||
return getStringOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string from config.
|
||||
* <p>
|
||||
* This will be deprecated when {@link Config#getStringOrNull(String)} no longer formats by default.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param format If the string should be formatted.
|
||||
* @return The found value, or null if not found.
|
||||
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated(since = "6.18.0")
|
||||
default String getStringOrNull(@NotNull String path,
|
||||
boolean format) {
|
||||
return this.getStringOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||
@@ -350,28 +393,26 @@ public interface Config extends Cloneable {
|
||||
/**
|
||||
* Get a list of strings from config.
|
||||
* <p>
|
||||
* Formatted by default.
|
||||
* <p>
|
||||
* This will be changed in newer versions to <b>not</b> format by default.
|
||||
* Not formatted.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||
*/
|
||||
@NotNull
|
||||
default List<String> getStrings(@NotNull String path) {
|
||||
return getStrings(path, true);
|
||||
return getStrings(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of strings from config.
|
||||
* <p>
|
||||
* This will be deprecated when {@link Config#getStrings(String)} no longer formats by default.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param format If the strings should be formatted.
|
||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
|
||||
*/
|
||||
@NotNull
|
||||
@Deprecated(since = "6.18.0")
|
||||
default List<String> getStrings(@NotNull String path,
|
||||
boolean format) {
|
||||
return this.getStrings(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||
@@ -389,7 +430,7 @@ public interface Config extends Cloneable {
|
||||
@Deprecated
|
||||
default List<String> getStrings(@NotNull String path,
|
||||
@NotNull StringUtils.FormatOption option) {
|
||||
return getStrings(path, true, option);
|
||||
return getStrings(path, false, option);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -401,14 +442,16 @@ public interface Config extends Cloneable {
|
||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||
*/
|
||||
@NotNull
|
||||
List<String> getStrings(@NotNull String path,
|
||||
boolean format,
|
||||
@NotNull StringUtils.FormatOption option);
|
||||
default List<String> getStrings(@NotNull String path,
|
||||
boolean format,
|
||||
@NotNull StringUtils.FormatOption option) {
|
||||
return Objects.requireNonNullElse(getStringsOrNull(path, format, option), new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of strings from config.
|
||||
* <p>
|
||||
* Formatted by default.
|
||||
* Formatted.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @return The found value, or null if not found.
|
||||
@@ -421,7 +464,7 @@ public interface Config extends Cloneable {
|
||||
/**
|
||||
* Get a list of strings from config.
|
||||
* <p>
|
||||
* Formatted by default.
|
||||
* Formatted.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param option The format option.
|
||||
@@ -436,7 +479,7 @@ public interface Config extends Cloneable {
|
||||
/**
|
||||
* Get a list of strings from config.
|
||||
* <p>
|
||||
* Formatted by default.
|
||||
* Not formatted.
|
||||
* <p>
|
||||
* This will be changed in newer versions to <b>not</b> format by default.
|
||||
*
|
||||
@@ -445,7 +488,7 @@ public interface Config extends Cloneable {
|
||||
*/
|
||||
@Nullable
|
||||
default List<String> getStringsOrNull(@NotNull String path) {
|
||||
return getStringsOrNull(path, true);
|
||||
return getStringsOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -454,8 +497,10 @@ public interface Config extends Cloneable {
|
||||
* @param path The key to fetch the value from.
|
||||
* @param format If the strings should be formatted.
|
||||
* @return The found value, or null if not found.
|
||||
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated(since = "6.18.0")
|
||||
default List<String> getStringsOrNull(@NotNull String path,
|
||||
boolean format) {
|
||||
return getStringsOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||
@@ -473,7 +518,7 @@ public interface Config extends Cloneable {
|
||||
@Deprecated
|
||||
default List<String> getStringsOrNull(@NotNull String path,
|
||||
@NotNull StringUtils.FormatOption option) {
|
||||
return getStringsOrNull(path, true, option);
|
||||
return getStringsOrNull(path, false, option);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -495,7 +540,31 @@ public interface Config extends Cloneable {
|
||||
* @param path The key to fetch the value from.
|
||||
* @return The found value, or 0 if not found.
|
||||
*/
|
||||
double getDouble(@NotNull String path);
|
||||
default double getDouble(@NotNull String path) {
|
||||
return Objects.requireNonNullElse(getDoubleOrNull(path), 0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a decimal value via a mathematical expression.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @return The computed value, or 0 if not found or invalid.
|
||||
*/
|
||||
default double getDoubleFromExpression(@NotNull String path) {
|
||||
return getDoubleFromExpression(path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a decimal value via a mathematical expression.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param player The player to evaluate placeholders with respect to.
|
||||
* @return The computed value, or 0 if not found or invalid.
|
||||
*/
|
||||
default double getDoubleFromExpression(@NotNull String path,
|
||||
@Nullable Player player) {
|
||||
return NumberUtils.evaluateExpression(this.getString(path), player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a decimal from config.
|
||||
@@ -513,7 +582,9 @@ public interface Config extends Cloneable {
|
||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||
*/
|
||||
@NotNull
|
||||
List<Double> getDoubles(@NotNull String path);
|
||||
default List<Double> getDoubles(@NotNull String path) {
|
||||
return Objects.requireNonNullElse(getDoublesOrNull(path), new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of decimals from config.
|
||||
@@ -524,6 +595,34 @@ public interface Config extends Cloneable {
|
||||
@Nullable
|
||||
List<Double> getDoublesOrNull(@NotNull String path);
|
||||
|
||||
/**
|
||||
* Get a list of subsections from config.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||
*/
|
||||
@NotNull
|
||||
default List<? extends Config> getSubsections(@NotNull String path) {
|
||||
return Objects.requireNonNullElse(getSubsectionsOrNull(path), new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of subsections from config.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @return The found value, or null if not found.
|
||||
*/
|
||||
@Nullable
|
||||
List<? extends Config> getSubsectionsOrNull(@NotNull String path);
|
||||
|
||||
/**
|
||||
* Get config type.
|
||||
*
|
||||
* @return The type.
|
||||
*/
|
||||
@NotNull
|
||||
ConfigType getType();
|
||||
|
||||
/**
|
||||
* Clone the config.
|
||||
*
|
||||
|
||||
@@ -3,13 +3,19 @@ package com.willfp.eco.core.config.interfaces;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* JSON configs have extra methods compared to yaml configs.
|
||||
* <p>
|
||||
* If you need to use them, then use JSONConfig instead.
|
||||
* JSON config.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
public interface JSONConfig extends Config {
|
||||
/**
|
||||
* Get a list of subsections from config.
|
||||
@@ -18,7 +24,9 @@ public interface JSONConfig extends Config {
|
||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||
*/
|
||||
@NotNull
|
||||
List<JSONConfig> getSubsections(@NotNull String path);
|
||||
default List<JSONConfig> getSubsections(@NotNull String path) {
|
||||
return Objects.requireNonNullElse(getSubsectionsOrNull(path), new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of subsections from config.
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
package com.willfp.eco.core.config.interfaces;
|
||||
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Interface for configs that physically exist as files in plugins.
|
||||
*/
|
||||
public interface LoadableConfig {
|
||||
public interface LoadableConfig extends Config {
|
||||
/**
|
||||
* Create the file.
|
||||
*/
|
||||
@@ -39,4 +43,18 @@ public interface LoadableConfig {
|
||||
* @return The name.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Get bukkit {@link YamlConfiguration}.
|
||||
* <p>
|
||||
* This method is not recommended unless absolutely required as it
|
||||
* only returns true if the type of config is {@link com.willfp.eco.core.config.ConfigType#YAML},
|
||||
* and if the handle is an {@link YamlConfiguration} specifically. This depends on the internals
|
||||
* and the implementation, and so may cause problems - it exists mostly for parity with
|
||||
* {@link JavaPlugin#getConfig()}.
|
||||
*
|
||||
* @return The config, or null if config is not yaml-based.
|
||||
*/
|
||||
@Nullable
|
||||
YamlConfiguration getBukkitHandle();
|
||||
}
|
||||
|
||||
@@ -5,8 +5,12 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
||||
/**
|
||||
* Interface for configs that wrap an {@link YamlConfiguration}.
|
||||
*
|
||||
* @see com.willfp.eco.core.config.yaml.wrapper.YamlConfigWrapper
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
public interface WrappedYamlConfiguration {
|
||||
/**
|
||||
* Get the ConfigurationSection handle.
|
||||
|
||||
@@ -3,6 +3,8 @@ 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.ConfigType;
|
||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
||||
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -10,7 +12,12 @@ import org.jetbrains.annotations.NotNull;
|
||||
* Config implementation for configs present in the plugin's base directory (eg config.json).
|
||||
* <p>
|
||||
* Automatically updates.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
@@ -23,13 +30,16 @@ public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
|
||||
@NotNull final PluginLike plugin,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
removeUnused, updateBlacklist
|
||||
)
|
||||
(JSONConfig)
|
||||
Eco.getHandler().getConfigFactory().createUpdatableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
removeUnused,
|
||||
ConfigType.JSON,
|
||||
updateBlacklist
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -42,13 +52,15 @@ public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
|
||||
final boolean removeUnused,
|
||||
@NotNull final PluginLike plugin) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
removeUnused
|
||||
)
|
||||
(JSONConfig)
|
||||
Eco.getHandler().getConfigFactory().createUpdatableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
removeUnused,
|
||||
ConfigType.JSON
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ 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.ConfigType;
|
||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
||||
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -14,7 +16,12 @@ import org.jetbrains.annotations.NotNull;
|
||||
* </ul>
|
||||
* <p>
|
||||
* Automatically updates.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper {
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
@@ -31,16 +38,19 @@ public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper {
|
||||
@NotNull final String subDirectoryPath,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
|
||||
configName,
|
||||
plugin,
|
||||
subDirectoryPath,
|
||||
source,
|
||||
removeUnused,
|
||||
updateBlacklist
|
||||
)
|
||||
(JSONConfig)
|
||||
Eco.getHandler().getConfigFactory().createUpdatableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
subDirectoryPath,
|
||||
source,
|
||||
removeUnused,
|
||||
ConfigType.JSON,
|
||||
updateBlacklist
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
|
||||
@@ -3,12 +3,19 @@ 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.ConfigType;
|
||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
||||
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Non-updatable JSON config that exists within a plugin jar.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class JSONStaticBaseConfig extends LoadableJSONConfigWrapper {
|
||||
/**
|
||||
* Config implementation for configs present in the plugin's base directory (eg config.json, lang.json).
|
||||
@@ -20,7 +27,7 @@ public abstract class JSONStaticBaseConfig extends LoadableJSONConfigWrapper {
|
||||
*/
|
||||
protected JSONStaticBaseConfig(@NotNull final String configName,
|
||||
@NotNull final PluginLike plugin) {
|
||||
super(Eco.getHandler().getConfigFactory().createLoadableJSONConfig(configName, plugin, "", plugin.getClass()));
|
||||
super((JSONConfig) Eco.getHandler().getConfigFactory().createLoadableConfig(configName, plugin, "", plugin.getClass(), ConfigType.JSON));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
package com.willfp.eco.core.config.json;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
||||
import com.willfp.eco.core.config.json.wrapper.JSONConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Raw JSON config with a map of values at its core.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public class JSONTransientConfig extends JSONConfigWrapper {
|
||||
/**
|
||||
* Config implementation for passing maps.
|
||||
@@ -18,6 +25,13 @@ public class JSONTransientConfig extends JSONConfigWrapper {
|
||||
* @param values The map of values.
|
||||
*/
|
||||
public JSONTransientConfig(@NotNull final Map<String, Object> values) {
|
||||
super(Eco.getHandler().getConfigFactory().createJSONConfig(values));
|
||||
super((JSONConfig) Eco.getHandler().getConfigFactory().createConfig(values));
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty JSON config.
|
||||
*/
|
||||
public JSONTransientConfig() {
|
||||
super((JSONConfig) Eco.getHandler().getConfigFactory().createConfig(new HashMap<>()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,12 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper to handle the backend JSON config implementations.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class JSONConfigWrapper extends ConfigWrapper<JSONConfig> implements JSONConfig {
|
||||
/**
|
||||
* Create a config wrapper.
|
||||
|
||||
@@ -3,14 +3,21 @@ package com.willfp.eco.core.config.json.wrapper;
|
||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
||||
import com.willfp.eco.core.config.interfaces.LoadableConfig;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Wrapper to handle the backend loadable JSON config implementations.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class LoadableJSONConfigWrapper extends JSONConfigWrapper implements LoadableConfig {
|
||||
/**
|
||||
* Create a config wrapper.
|
||||
@@ -48,4 +55,9 @@ public abstract class LoadableJSONConfigWrapper extends JSONConfigWrapper implem
|
||||
public String getName() {
|
||||
return ((LoadableConfig) this.getHandle()).getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable YamlConfiguration getBukkitHandle() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,10 +23,14 @@ import java.lang.annotation.Target;
|
||||
* <p>
|
||||
* The second:
|
||||
* <pre>{@code
|
||||
* public static void update(EcoPlugin plugin) {}
|
||||
* public static void update(EcoPlugin plugin) {
|
||||
* // Update code
|
||||
* }
|
||||
* }</pre>
|
||||
* <p>
|
||||
* If using kotlin, you have to annotate the method with {@code @JvmStatic}
|
||||
* in order to prevent null pointer exceptions.
|
||||
* <p>
|
||||
* Config update methods in all classes in a plugin jar will be called
|
||||
* on reload.
|
||||
* <p>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package com.willfp.eco.core.config.wrapper;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
||||
import com.willfp.eco.core.config.interfaces.LoadableConfig;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -11,6 +14,8 @@ import java.util.Map;
|
||||
/**
|
||||
* Internal component to create backend config implementations.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
public interface ConfigFactory {
|
||||
/**
|
||||
* Updatable config.
|
||||
@@ -20,75 +25,57 @@ public interface ConfigFactory {
|
||||
* @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 type The config type.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
Config createUpdatableYamlConfig(@NotNull String configName,
|
||||
@NotNull PluginLike plugin,
|
||||
@NotNull String subDirectoryPath,
|
||||
@NotNull Class<?> source,
|
||||
boolean removeUnused,
|
||||
@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,
|
||||
LoadableConfig createUpdatableConfig(@NotNull String configName,
|
||||
@NotNull PluginLike plugin,
|
||||
@NotNull String subDirectoryPath,
|
||||
@NotNull Class<?> source,
|
||||
boolean removeUnused,
|
||||
@NotNull ConfigType type,
|
||||
@NotNull String... updateBlacklist);
|
||||
|
||||
/**
|
||||
* JSON loadable config.
|
||||
* Loadable 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 type The config type.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
JSONConfig createLoadableJSONConfig(@NotNull String configName,
|
||||
LoadableConfig createLoadableConfig(@NotNull String configName,
|
||||
@NotNull PluginLike plugin,
|
||||
@NotNull String subDirectoryPath,
|
||||
@NotNull Class<?> source);
|
||||
@NotNull Class<?> source,
|
||||
@NotNull ConfigType type);
|
||||
|
||||
/**
|
||||
* Yaml loadable 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.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
Config createLoadableYamlConfig(@NotNull String configName,
|
||||
@NotNull PluginLike plugin,
|
||||
@NotNull String subDirectoryPath,
|
||||
@NotNull Class<?> source);
|
||||
|
||||
/**
|
||||
* Yaml config.
|
||||
* Create config.
|
||||
*
|
||||
* @param config The handle.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
Config createYamlConfig(@NotNull YamlConfiguration config);
|
||||
Config createConfig(@NotNull YamlConfiguration config);
|
||||
|
||||
/**
|
||||
* JSON config.
|
||||
* Create config.
|
||||
*
|
||||
* @param values The values.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
JSONConfig createJSONConfig(@NotNull Map<String, Object> values);
|
||||
Config createConfig(@NotNull Map<String, Object> values);
|
||||
|
||||
/**
|
||||
* Create config.
|
||||
*
|
||||
* @param contents The file contents.
|
||||
* @param type The type.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
Config createConfig(@NotNull String contents,
|
||||
@NotNull ConfigType type);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.willfp.eco.core.config.wrapper;
|
||||
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import com.willfp.eco.util.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -15,6 +16,7 @@ import java.util.List;
|
||||
*
|
||||
* @param <T> The type of the handle.
|
||||
*/
|
||||
@SuppressWarnings("MethodDoesntCallSuperMethod")
|
||||
public abstract class ConfigWrapper<T extends Config> implements Config {
|
||||
/**
|
||||
* Configs from eco have an internal implementation,
|
||||
@@ -68,70 +70,31 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
||||
handle.set(path, object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Config getSubsection(@NotNull final String path) {
|
||||
return handle.getSubsection(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Config getSubsectionOrNull(@NotNull final String path) {
|
||||
return handle.getSubsectionOrNull(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(@NotNull final String path) {
|
||||
return handle.getInt(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Integer getIntOrNull(@NotNull final String path) {
|
||||
return handle.getIntOrNull(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(@NotNull final String path,
|
||||
final int def) {
|
||||
return handle.getInt(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<Integer> getInts(@NotNull final String path) {
|
||||
return handle.getInts(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<Integer> getIntsOrNull(@NotNull final String path) {
|
||||
return handle.getIntsOrNull(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBool(@NotNull final String path) {
|
||||
return handle.getBool(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Boolean getBoolOrNull(@NotNull final String path) {
|
||||
return handle.getBoolOrNull(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<Boolean> getBools(@NotNull final String path) {
|
||||
return handle.getBools(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<Boolean> getBoolsOrNull(@NotNull final String path) {
|
||||
return handle.getBoolsOrNull(path);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull String getString(@NotNull final String path,
|
||||
final boolean format,
|
||||
@NotNull final StringUtils.FormatOption option) {
|
||||
return handle.getString(path, format, option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getStringOrNull(@NotNull final String path,
|
||||
final boolean format,
|
||||
@@ -139,13 +102,6 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
||||
return handle.getStringOrNull(path, format, option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<String> getStrings(@NotNull final String path,
|
||||
final boolean format,
|
||||
@NotNull final StringUtils.FormatOption option) {
|
||||
return handle.getStrings(path, format, option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<String> getStringsOrNull(@NotNull final String path,
|
||||
final boolean format,
|
||||
@@ -153,31 +109,31 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
||||
return handle.getStringsOrNull(path, format, option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(@NotNull final String path) {
|
||||
return handle.getDouble(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Double getDoubleOrNull(@NotNull final String path) {
|
||||
return handle.getDoubleOrNull(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<Double> getDoubles(@NotNull final String path) {
|
||||
return handle.getDoubles(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<Double> getDoublesOrNull(@NotNull final String path) {
|
||||
return handle.getDoublesOrNull(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<? extends Config> getSubsectionsOrNull(@NotNull final String path) {
|
||||
return handle.getSubsectionsOrNull(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Config clone() {
|
||||
return handle.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ConfigType getType() {
|
||||
return handle.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the handle.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.willfp.eco.core.config.wrapper;
|
||||
|
||||
import com.willfp.eco.core.config.interfaces.LoadableConfig;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Wrapper to handle the backend loadable yaml config implementations.
|
||||
*/
|
||||
public abstract class LoadableConfigWrapper extends ConfigWrapper<LoadableConfig> implements LoadableConfig {
|
||||
/**
|
||||
* Create a config wrapper.
|
||||
*
|
||||
* @param handle The handle.
|
||||
*/
|
||||
protected LoadableConfigWrapper(@NotNull final LoadableConfig handle) {
|
||||
super(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createFile() {
|
||||
this.getHandle().createFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResourcePath() {
|
||||
return this.getHandle().getResourcePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() throws IOException {
|
||||
this.getHandle().save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getConfigFile() {
|
||||
return this.getHandle().getConfigFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.getHandle().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable YamlConfiguration getBukkitHandle() {
|
||||
return this.getHandle().getBukkitHandle();
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.willfp.eco.core.config.yaml;
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -10,7 +11,12 @@ import org.jetbrains.annotations.NotNull;
|
||||
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
|
||||
* <p>
|
||||
* Automatically updates.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
@@ -23,12 +29,14 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
|
||||
@NotNull final PluginLike plugin,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
removeUnused, updateBlacklist
|
||||
removeUnused,
|
||||
ConfigType.YAML,
|
||||
updateBlacklist
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -42,12 +50,13 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
|
||||
final boolean removeUnused,
|
||||
@NotNull final PluginLike plugin) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
removeUnused
|
||||
removeUnused,
|
||||
ConfigType.YAML
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.willfp.eco.core.config.yaml;
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -14,7 +15,12 @@ import org.jetbrains.annotations.NotNull;
|
||||
* </ul>
|
||||
* <p>
|
||||
* Automatically updates.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper {
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
@@ -31,16 +37,18 @@ public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper {
|
||||
@NotNull final String subDirectoryPath,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
subDirectoryPath,
|
||||
source,
|
||||
removeUnused,
|
||||
ConfigType.YAML,
|
||||
updateBlacklist
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
|
||||
@@ -3,12 +3,18 @@ package com.willfp.eco.core.config.yaml;
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Non-updatable yaml config that exists within a plugin jar.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class YamlStaticBaseConfig extends LoadableYamlConfigWrapper {
|
||||
/**
|
||||
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
|
||||
@@ -20,7 +26,7 @@ public abstract class YamlStaticBaseConfig extends LoadableYamlConfigWrapper {
|
||||
*/
|
||||
protected YamlStaticBaseConfig(@NotNull final String configName,
|
||||
@NotNull final PluginLike plugin) {
|
||||
super(Eco.getHandler().getConfigFactory().createLoadableYamlConfig(configName, plugin, "", plugin.getClass()));
|
||||
super(Eco.getHandler().getConfigFactory().createLoadableConfig(configName, plugin, "", plugin.getClass(), ConfigType.YAML));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.willfp.eco.core.config.yaml;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.yaml.wrapper.YamlConfigWrapper;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -11,19 +12,31 @@ import java.io.StringReader;
|
||||
* Config implementation for passing YamlConfigurations.
|
||||
* <p>
|
||||
* Does not automatically update.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public class YamlTransientConfig extends YamlConfigWrapper {
|
||||
/**
|
||||
* @param config The YamlConfiguration handle.
|
||||
* @param config The YamlConfiguration handle.
|
||||
*/
|
||||
public YamlTransientConfig(@NotNull final YamlConfiguration config) {
|
||||
super(Eco.getHandler().getConfigFactory().createYamlConfig(config));
|
||||
super(Eco.getHandler().getConfigFactory().createConfig(config));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contents The contents of the config.
|
||||
* @param contents The contents of the config.
|
||||
*/
|
||||
public YamlTransientConfig(@NotNull final String contents) {
|
||||
super(Eco.getHandler().getConfigFactory().createYamlConfig(YamlConfiguration.loadConfiguration(new StringReader(contents))));
|
||||
super(Eco.getHandler().getConfigFactory().createConfig(contents, ConfigType.YAML));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new empty transient config.
|
||||
*/
|
||||
public YamlTransientConfig() {
|
||||
super(Eco.getHandler().getConfigFactory().createConfig(YamlConfiguration.loadConfiguration(new StringReader(""))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,21 @@ package com.willfp.eco.core.config.yaml.wrapper;
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import com.willfp.eco.core.config.interfaces.LoadableConfig;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Wrapper to handle the backend loadable yaml config implementations.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class LoadableYamlConfigWrapper extends YamlConfigWrapper implements LoadableConfig {
|
||||
/**
|
||||
* Create a config wrapper.
|
||||
@@ -48,4 +55,9 @@ public abstract class LoadableYamlConfigWrapper extends YamlConfigWrapper implem
|
||||
public String getName() {
|
||||
return ((LoadableConfig) this.getHandle()).getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable YamlConfiguration getBukkitHandle() {
|
||||
return ((LoadableConfig) this.getHandle()).getBukkitHandle();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,12 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Wrapper to handle the backend yaml config implementations.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class YamlConfigWrapper extends ConfigWrapper<Config> implements WrappedYamlConfiguration {
|
||||
/**
|
||||
* Create a config wrapper.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
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;
|
||||
|
||||
@@ -12,26 +11,7 @@ import java.util.UUID;
|
||||
* <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);
|
||||
|
||||
public interface PlayerProfile extends Profile {
|
||||
/**
|
||||
* Load a player profile.
|
||||
*
|
||||
@@ -51,6 +31,6 @@ public interface PlayerProfile {
|
||||
*/
|
||||
@NotNull
|
||||
static PlayerProfile load(@NotNull final UUID uuid) {
|
||||
return Eco.getHandler().getPlayerProfileHandler().load(uuid);
|
||||
return Eco.getHandler().getProfileHandler().load(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
30
eco-api/src/main/java/com/willfp/eco/core/data/Profile.java
Normal file
30
eco-api/src/main/java/com/willfp/eco/core/data/Profile.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package com.willfp.eco.core.data;
|
||||
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Persistent data storage interface.
|
||||
* <p>
|
||||
* Profiles save automatically, so there is no need to save after changes.
|
||||
*/
|
||||
public interface Profile {
|
||||
/**
|
||||
* Write a key to 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 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);
|
||||
}
|
||||
@@ -1,15 +1,19 @@
|
||||
package com.willfp.eco.core.data;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* API to handle player profiles.
|
||||
* API to handle profiles.
|
||||
*/
|
||||
public interface PlayerProfileHandler {
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
public interface ProfileHandler {
|
||||
/**
|
||||
* Load a player profile.
|
||||
*
|
||||
@@ -18,6 +22,13 @@ public interface PlayerProfileHandler {
|
||||
*/
|
||||
PlayerProfile load(@NotNull UUID uuid);
|
||||
|
||||
/**
|
||||
* Load the server profile.
|
||||
*
|
||||
* @return The profile.
|
||||
*/
|
||||
ServerProfile loadServerProfile();
|
||||
|
||||
/**
|
||||
* Unload a player profile from memory.
|
||||
* <p>
|
||||
@@ -37,7 +48,7 @@ public interface PlayerProfileHandler {
|
||||
*/
|
||||
@Deprecated
|
||||
default void savePlayer(@NotNull UUID uuid) {
|
||||
this.saveKeysForPlayer(uuid, PersistentDataKey.values());
|
||||
this.saveKeysFor(uuid, PersistentDataKey.values());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,8 +59,8 @@ public interface PlayerProfileHandler {
|
||||
* @param uuid The uuid.
|
||||
* @param keys The keys.
|
||||
*/
|
||||
void saveKeysForPlayer(@NotNull UUID uuid,
|
||||
@NotNull Set<PersistentDataKey<?>> keys);
|
||||
void saveKeysFor(@NotNull UUID uuid,
|
||||
@NotNull Set<PersistentDataKey<?>> keys);
|
||||
|
||||
/**
|
||||
* Save all player data.
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.willfp.eco.core.data;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Persistent data storage interface for servers.
|
||||
* <p>
|
||||
* Profiles save automatically, so there is no need to save after changes.
|
||||
*/
|
||||
public interface ServerProfile extends Profile {
|
||||
/**
|
||||
* Load the server profile.
|
||||
*
|
||||
* @return The profile.
|
||||
*/
|
||||
@NotNull
|
||||
static ServerProfile load() {
|
||||
return Eco.getHandler().getProfileHandler().loadServerProfile();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,18 @@
|
||||
package com.willfp.eco.core.data.keys;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* API to register persistent data keys.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
public interface KeyRegistry {
|
||||
/**
|
||||
* Register a persistent data key to be stored.
|
||||
@@ -21,4 +27,37 @@ public interface KeyRegistry {
|
||||
* @return The keys.
|
||||
*/
|
||||
Set<PersistentDataKey<?>> getRegisteredKeys();
|
||||
|
||||
/**
|
||||
* Mark key as category.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param category The category.
|
||||
*/
|
||||
void markKeyAs(@NotNull PersistentDataKey<?> key,
|
||||
@NotNull KeyRegistry.KeyCategory category);
|
||||
|
||||
/**
|
||||
* Get persistent data key from namespaced key.
|
||||
*
|
||||
* @param namespacedKey The key.
|
||||
* @return The key, or null if not found.
|
||||
*/
|
||||
@Nullable
|
||||
PersistentDataKey<?> getKeyFrom(@NotNull NamespacedKey namespacedKey);
|
||||
|
||||
/**
|
||||
* Locations for key categorization.
|
||||
*/
|
||||
enum KeyCategory {
|
||||
/**
|
||||
* Player keys.
|
||||
*/
|
||||
PLAYER,
|
||||
|
||||
/**
|
||||
* Server keys.
|
||||
*/
|
||||
SERVER
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@ package com.willfp.eco.core.data.keys;
|
||||
import com.willfp.eco.core.Eco;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -11,7 +13,7 @@ import java.util.Set;
|
||||
*
|
||||
* @param <T> The type of the data.
|
||||
*/
|
||||
public class PersistentDataKey<T> {
|
||||
public final class PersistentDataKey<T> {
|
||||
/**
|
||||
* The key of the persistent data value.
|
||||
*/
|
||||
@@ -25,7 +27,7 @@ public class PersistentDataKey<T> {
|
||||
/**
|
||||
* The persistent data key type.
|
||||
*/
|
||||
private final PersistentDataKeyType type;
|
||||
private final PersistentDataKeyType<T> type;
|
||||
|
||||
/**
|
||||
* Create a new Persistent Data Key.
|
||||
@@ -35,7 +37,7 @@ public class PersistentDataKey<T> {
|
||||
* @param defaultValue The default value.
|
||||
*/
|
||||
public PersistentDataKey(@NotNull final NamespacedKey key,
|
||||
@NotNull final PersistentDataKeyType type,
|
||||
@NotNull final PersistentDataKeyType<T> type,
|
||||
@NotNull final T defaultValue) {
|
||||
this.key = key;
|
||||
this.defaultValue = defaultValue;
|
||||
@@ -53,15 +55,6 @@ public class PersistentDataKey<T> {
|
||||
+ '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all persistent data keys.
|
||||
*
|
||||
* @return The keys.
|
||||
*/
|
||||
public static Set<PersistentDataKey<?>> values() {
|
||||
return Eco.getHandler().getKeyRegistry().getRegisteredKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key.
|
||||
*
|
||||
@@ -85,7 +78,58 @@ public class PersistentDataKey<T> {
|
||||
*
|
||||
* @return The key type.
|
||||
*/
|
||||
public PersistentDataKeyType getType() {
|
||||
public PersistentDataKeyType<T> getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Categorize key as a server key, will register new column to MySQL
|
||||
* database immediately rather than waiting for auto-categorization.
|
||||
* <p>
|
||||
* This will improve performance.
|
||||
*
|
||||
* @return The key.
|
||||
*/
|
||||
public PersistentDataKey<T> server() {
|
||||
Eco.getHandler().getKeyRegistry().markKeyAs(this, KeyRegistry.KeyCategory.SERVER);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Categorize key as a player key, will register new column to MySQL
|
||||
* database immediately rather than waiting for auto-categorization.
|
||||
* <p>
|
||||
* This will improve performance.
|
||||
*
|
||||
* @return The key.
|
||||
*/
|
||||
public PersistentDataKey<T> player() {
|
||||
Eco.getHandler().getKeyRegistry().markKeyAs(this, KeyRegistry.KeyCategory.PLAYER);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all persistent data keys.
|
||||
*
|
||||
* @return The keys.
|
||||
*/
|
||||
public static Set<PersistentDataKey<?>> values() {
|
||||
return Eco.getHandler().getKeyRegistry().getRegisteredKeys();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof PersistentDataKey that)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(this.getKey(), that.getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,108 @@
|
||||
package com.willfp.eco.core.data.keys;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* All storable data key types.
|
||||
*
|
||||
* @param <T> The type.
|
||||
*/
|
||||
public enum PersistentDataKeyType {
|
||||
public final class PersistentDataKeyType<T> {
|
||||
/**
|
||||
* The registered key types.
|
||||
*/
|
||||
private static final List<PersistentDataKeyType<?>> VALUES = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* String.
|
||||
*/
|
||||
STRING,
|
||||
public static final PersistentDataKeyType<String> STRING = new PersistentDataKeyType<>(String.class, "STRING");
|
||||
|
||||
/**
|
||||
* Boolean.
|
||||
*/
|
||||
BOOLEAN,
|
||||
public static final PersistentDataKeyType<Boolean> BOOLEAN = new PersistentDataKeyType<>(Boolean.class, "BOOLEAN");
|
||||
|
||||
/**
|
||||
* Integer.
|
||||
* Int.
|
||||
*/
|
||||
INT,
|
||||
public static final PersistentDataKeyType<Integer> INT = new PersistentDataKeyType<>(Integer.class, "INT");
|
||||
|
||||
/**
|
||||
* Double.
|
||||
*/
|
||||
DOUBLE
|
||||
public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>(Double.class, "DOUBLE");
|
||||
|
||||
/**
|
||||
* The class of the type.
|
||||
*/
|
||||
private final Class<T> typeClass;
|
||||
|
||||
/**
|
||||
* The name of the key type.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Get the class of the type.
|
||||
*
|
||||
* @return The class.
|
||||
*/
|
||||
public Class<T> getTypeClass() {
|
||||
return typeClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the key type.
|
||||
*
|
||||
* @return The name.
|
||||
*/
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new PersistentDataKeyType.
|
||||
*
|
||||
* @param typeClass The type class.
|
||||
* @param name The name.
|
||||
*/
|
||||
private PersistentDataKeyType(@NotNull final Class<T> typeClass,
|
||||
@NotNull final String name) {
|
||||
VALUES.add(this);
|
||||
|
||||
this.typeClass = typeClass;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all registered {@link PersistentDataKeyType}s.
|
||||
*
|
||||
* @return The registered types.
|
||||
*/
|
||||
@NotNull
|
||||
public static PersistentDataKeyType<?>[] values() {
|
||||
return VALUES.toArray(new PersistentDataKeyType[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a key type from a name.
|
||||
*
|
||||
* @param name The name.
|
||||
* @return The type, or null if not found.
|
||||
*/
|
||||
@Nullable
|
||||
public static PersistentDataKeyType<?> valueOf(@NotNull final String name) {
|
||||
for (PersistentDataKeyType<?> type : VALUES) {
|
||||
if (type.name.equalsIgnoreCase(name)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ public final class Display {
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
public static ItemStack displayAndFinalize(@NotNull final ItemStack itemStack,
|
||||
@Nullable final Player player) {
|
||||
@Nullable final Player player) {
|
||||
return finalize(display(itemStack, player));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
package com.willfp.eco.core.display;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Interface for display implementations.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
public interface DisplayHandler {
|
||||
/**
|
||||
* Register display module.
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package com.willfp.eco.core.drops;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Internal component to create backend DropQueue implementations.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
public interface DropQueueFactory {
|
||||
/**
|
||||
* Create a DropQueue.
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.willfp.eco.core.drops;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -9,6 +11,8 @@ import java.util.Collection;
|
||||
/**
|
||||
* Internal interface for backend DropQueue implementations.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
public interface InternalDropQueue {
|
||||
/**
|
||||
* Add item to queue.
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.willfp.eco.core.entities;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* A custom entity has 3 components.
|
||||
*
|
||||
* <ul>
|
||||
* <li>The key to identify it</li>
|
||||
* <li>The test to check if any entity is this custom entity</li>
|
||||
* <li>The supplier to spawn the custom {@link org.bukkit.entity.Entity}</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class CustomEntity implements TestableEntity {
|
||||
/**
|
||||
* The key.
|
||||
*/
|
||||
private final NamespacedKey key;
|
||||
|
||||
/**
|
||||
* The test for Entities to pass.
|
||||
*/
|
||||
private final Predicate<@NotNull Entity> test;
|
||||
|
||||
/**
|
||||
* The provider to spawn the entity.
|
||||
*/
|
||||
private final Function<Location, Entity> provider;
|
||||
|
||||
/**
|
||||
* Create a new custom entity.
|
||||
*
|
||||
* @param key The entity key.
|
||||
* @param test The test.
|
||||
* @param provider The provider to spawn the entity.
|
||||
*/
|
||||
public CustomEntity(@NotNull final NamespacedKey key,
|
||||
@NotNull final Predicate<@NotNull Entity> test,
|
||||
@NotNull final Function<Location, Entity> provider) {
|
||||
this.key = key;
|
||||
this.test = test;
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(@Nullable final Entity entity) {
|
||||
if (entity == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return test.test(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity spawn(@NotNull final Location location) {
|
||||
Validate.notNull(location.getWorld());
|
||||
|
||||
return provider.apply(location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the entity.
|
||||
*/
|
||||
public void register() {
|
||||
Entities.registerCustomEntity(this.getKey(), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key.
|
||||
*
|
||||
* @return The key.
|
||||
*/
|
||||
public NamespacedKey getKey() {
|
||||
return this.key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.willfp.eco.core.entities;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
/**
|
||||
* Interface for Dummy Entities in order to filter them using instanceof.
|
||||
*/
|
||||
public interface DummyEntity extends Entity {
|
||||
|
||||
}
|
||||
232
eco-api/src/main/java/com/willfp/eco/core/entities/Entities.java
Normal file
232
eco-api/src/main/java/com/willfp/eco/core/entities/Entities.java
Normal file
@@ -0,0 +1,232 @@
|
||||
package com.willfp.eco.core.entities;
|
||||
|
||||
import com.willfp.eco.core.entities.args.EntityArgParseResult;
|
||||
import com.willfp.eco.core.entities.args.EntityArgParser;
|
||||
import com.willfp.eco.core.entities.impl.EmptyTestableEntity;
|
||||
import com.willfp.eco.core.entities.impl.ModifiedTestableEntity;
|
||||
import com.willfp.eco.core.entities.impl.SimpleTestableEntity;
|
||||
import com.willfp.eco.util.NamespacedKeyUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Class to manage all custom and vanilla entities.
|
||||
*/
|
||||
public final class Entities {
|
||||
/**
|
||||
* All entities.
|
||||
*/
|
||||
private static final Map<NamespacedKey, TestableEntity> REGISTRY = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* All entity parsers.
|
||||
*/
|
||||
private static final List<EntityArgParser> ARG_PARSERS = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The lookup handler.
|
||||
*/
|
||||
private static final EntitiesLookupHandler ENTITIES_LOOKUP_HANDLER = new EntitiesLookupHandler(Entities::doParse);
|
||||
|
||||
/**
|
||||
* Register a new custom item.
|
||||
*
|
||||
* @param key The key of the item.
|
||||
* @param item The item.
|
||||
*/
|
||||
public static void registerCustomEntity(@NotNull final NamespacedKey key,
|
||||
@NotNull final TestableEntity item) {
|
||||
REGISTRY.put(key, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new arg parser.
|
||||
*
|
||||
* @param parser The parser.
|
||||
*/
|
||||
public static void registerArgParser(@NotNull final EntityArgParser parser) {
|
||||
ARG_PARSERS.add(parser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an entity.
|
||||
*
|
||||
* @param key The key of the entity.
|
||||
*/
|
||||
public static void removeCustomEntity(@NotNull final NamespacedKey key) {
|
||||
REGISTRY.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the backbone of the entire eco entity system.
|
||||
* <p>
|
||||
* You can look up a TestableEntity for any type or custom entity,
|
||||
* and it will return it with any modifiers passed as parameters.
|
||||
* <p>
|
||||
* If you want to get an Entity instance from this, then just call
|
||||
* {@link TestableEntity#spawn(Location)}.
|
||||
* <p>
|
||||
* The advantages of the testable entity system are that there is the inbuilt
|
||||
* {@link TestableEntity#matches(Entity)} - this allows to check if any entity
|
||||
* is that testable entity; which may sound negligible, but actually it allows for
|
||||
* much more power and flexibility. For example, you can have an entity with an
|
||||
* extra metadata tag, extra lore lines, different display name - and it
|
||||
* will still work as long as the test passes.
|
||||
*
|
||||
* @param key The lookup string.
|
||||
* @return The testable entity, or an empty testable entity if not found.
|
||||
*/
|
||||
@NotNull
|
||||
public static TestableEntity lookup(@NotNull final String key) {
|
||||
return ENTITIES_LOOKUP_HANDLER.parseKey(key);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static TestableEntity doParse(@NotNull final String[] args) {
|
||||
if (args.length == 0) {
|
||||
return new EmptyTestableEntity();
|
||||
}
|
||||
|
||||
TestableEntity entity;
|
||||
|
||||
String[] split = args[0].toLowerCase().split(":");
|
||||
|
||||
if (split.length == 1) {
|
||||
EntityType type;
|
||||
try {
|
||||
type = EntityType.valueOf(args[0].toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return new EmptyTestableEntity();
|
||||
}
|
||||
entity = new SimpleTestableEntity(type);
|
||||
} else {
|
||||
String namespace = split[0];
|
||||
String keyID = split[1];
|
||||
NamespacedKey namespacedKey = NamespacedKeyUtils.create(namespace, keyID);
|
||||
|
||||
TestableEntity part = REGISTRY.get(namespacedKey);
|
||||
|
||||
if (part == null) {
|
||||
return new EmptyTestableEntity();
|
||||
}
|
||||
|
||||
entity = part;
|
||||
}
|
||||
|
||||
String[] modifierArgs = Arrays.copyOfRange(args, 1, args.length);
|
||||
|
||||
List<EntityArgParseResult> parseResults = new ArrayList<>();
|
||||
|
||||
for (EntityArgParser argParser : ARG_PARSERS) {
|
||||
EntityArgParseResult result = argParser.parseArguments(modifierArgs);
|
||||
if (result != null) {
|
||||
parseResults.add(result);
|
||||
}
|
||||
}
|
||||
|
||||
Function<Location, Entity> spawner = entity::spawn;
|
||||
|
||||
if (!parseResults.isEmpty()) {
|
||||
entity = new ModifiedTestableEntity(
|
||||
entity,
|
||||
test -> {
|
||||
for (EntityArgParseResult parseResult : parseResults) {
|
||||
if (!parseResult.test().test(test)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
location -> {
|
||||
Entity spawned = spawner.apply(location);
|
||||
|
||||
for (EntityArgParseResult parseResult : parseResults) {
|
||||
parseResult.modifier().accept(spawned);
|
||||
}
|
||||
|
||||
return spawned;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Testable Entity from an ItemStack.
|
||||
* <p>
|
||||
* Will search for registered entity first. If there are no matches in the registry,
|
||||
* then it will return a {@link com.willfp.eco.core.entities.impl.SimpleTestableEntity} matching the entity type.
|
||||
* <p>
|
||||
* If the entity is not custom and has unknown type, this will return null.
|
||||
*
|
||||
* @param entity The Entity.
|
||||
* @return The found Testable Entity.
|
||||
*/
|
||||
@Nullable
|
||||
public static TestableEntity getEntity(@Nullable final Entity entity) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
TestableEntity customEntity = getEntity(entity);
|
||||
|
||||
if (customEntity != null) {
|
||||
return customEntity;
|
||||
}
|
||||
|
||||
for (TestableEntity known : REGISTRY.values()) {
|
||||
if (known.matches(entity)) {
|
||||
return known;
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.getType() == EntityType.UNKNOWN) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new SimpleTestableEntity(entity.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if entity is a custom entity.
|
||||
*
|
||||
* @param entity The entity to check.
|
||||
* @return If is custom.
|
||||
*/
|
||||
public static boolean isCustomEntity(@NotNull final Entity entity) {
|
||||
for (TestableEntity testable : REGISTRY.values()) {
|
||||
if (testable.matches(entity)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all registered custom items.
|
||||
*
|
||||
* @return A set of all items.
|
||||
*/
|
||||
public static Set<TestableEntity> getCustomEntities() {
|
||||
return new HashSet<>(REGISTRY.values());
|
||||
}
|
||||
|
||||
private Entities() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.willfp.eco.core.entities;
|
||||
|
||||
import com.willfp.eco.core.entities.impl.EmptyTestableEntity;
|
||||
import com.willfp.eco.core.entities.impl.GroupedTestableEntities;
|
||||
import com.willfp.eco.core.lookup.LookupHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Handle item lookup strings.
|
||||
*/
|
||||
public class EntitiesLookupHandler implements LookupHandler<TestableEntity> {
|
||||
/**
|
||||
* The parser.
|
||||
*/
|
||||
private final Function<String[], @NotNull TestableEntity> parser;
|
||||
|
||||
/**
|
||||
* Create new lookup handler.
|
||||
*
|
||||
* @param parser The parser.
|
||||
*/
|
||||
public EntitiesLookupHandler(@NotNull final Function<String[], @NotNull TestableEntity> parser) {
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TestableEntity parse(@NotNull final String[] args) {
|
||||
return parser.apply(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(@NotNull final TestableEntity object) {
|
||||
return !(object instanceof EmptyTestableEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TestableEntity getFailsafe() {
|
||||
return new EmptyTestableEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TestableEntity join(@NotNull final Collection<TestableEntity> options) {
|
||||
return new GroupedTestableEntities(options);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.willfp.eco.core.entities;
|
||||
|
||||
import com.willfp.eco.core.lookup.Testable;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An item with a test to see if any item is that item.
|
||||
*/
|
||||
public interface TestableEntity extends Testable<Entity> {
|
||||
/**
|
||||
* If an Entity matches the test.
|
||||
*
|
||||
* @param entity The entity to test.
|
||||
* @return If the entity matches.
|
||||
*/
|
||||
@Override
|
||||
boolean matches(@Nullable Entity entity);
|
||||
|
||||
/**
|
||||
* Spawn the entity.
|
||||
*
|
||||
* @param location The location.
|
||||
* @return The entity.
|
||||
*/
|
||||
Entity spawn(@NotNull Location location);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.willfp.eco.core.entities.args;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* @param test The test for the entity.
|
||||
* @param modifier The modifier to apply to the entity.
|
||||
* @see EntityArgParser
|
||||
*/
|
||||
public record EntityArgParseResult(@NotNull Predicate<Entity> test,
|
||||
@NotNull Consumer<Entity> modifier) {
|
||||
/**
|
||||
* Kotlin destructuring support.
|
||||
*
|
||||
* @return The test.
|
||||
*/
|
||||
public Predicate<Entity> component1() {
|
||||
return test;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kotlin destructuring support.
|
||||
*
|
||||
* @return The modifier.
|
||||
*/
|
||||
public Consumer<Entity> component2() {
|
||||
return modifier;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.willfp.eco.core.entities.args;
|
||||
|
||||
import com.willfp.eco.core.entities.TestableEntity;
|
||||
import org.bukkit.Location;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An argument parser should generate the predicate as well
|
||||
* as modify the Entity for {@link TestableEntity#spawn(Location)}.
|
||||
*/
|
||||
public interface EntityArgParser {
|
||||
/**
|
||||
* Parse the arguments.
|
||||
*
|
||||
* @param args The arguments.
|
||||
* @return The predicate test to apply to the modified entity.
|
||||
*/
|
||||
@Nullable EntityArgParseResult parseArguments(@NotNull String[] args);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.willfp.eco.core.entities.impl;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.entities.TestableEntity;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Empty entity.
|
||||
*/
|
||||
public class EmptyTestableEntity implements TestableEntity {
|
||||
/**
|
||||
* Create a new empty testable entity.
|
||||
*/
|
||||
public EmptyTestableEntity() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(@Nullable final Entity entity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity spawn(@NotNull final Location location) {
|
||||
Validate.notNull(location.getWorld());
|
||||
|
||||
return Eco.getHandler().createDummyEntity(location);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.willfp.eco.core.entities.impl;
|
||||
|
||||
import com.willfp.eco.core.entities.TestableEntity;
|
||||
import com.willfp.eco.util.NumberUtils;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* A group of testable entities.
|
||||
*
|
||||
* @see com.willfp.eco.core.entities.CustomEntity
|
||||
*/
|
||||
public class GroupedTestableEntities implements TestableEntity {
|
||||
/**
|
||||
* The children.
|
||||
*/
|
||||
private final Collection<TestableEntity> children;
|
||||
|
||||
/**
|
||||
* Create a new group of testable entities.
|
||||
*
|
||||
* @param children The children.
|
||||
*/
|
||||
public GroupedTestableEntities(@NotNull final Collection<TestableEntity> children) {
|
||||
Validate.isTrue(!children.isEmpty(), "Group must have at least one child!");
|
||||
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the item matches any children.
|
||||
*
|
||||
* @param entity The entity to test.
|
||||
* @return If the entity matches the test of any children.
|
||||
*/
|
||||
@Override
|
||||
public boolean matches(@Nullable final Entity entity) {
|
||||
for (TestableEntity child : children) {
|
||||
if (child.matches(entity)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity spawn(@NotNull final Location location) {
|
||||
return new ArrayList<>(children)
|
||||
.get(NumberUtils.randInt(0, children.size() - 1))
|
||||
.spawn(location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the children.
|
||||
*
|
||||
* @return The children.
|
||||
*/
|
||||
public Collection<TestableEntity> getChildren() {
|
||||
return new ArrayList<>(children);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.willfp.eco.core.entities.impl;
|
||||
|
||||
import com.willfp.eco.core.entities.TestableEntity;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Existing testable entity with an extra filter.
|
||||
*
|
||||
* @see com.willfp.eco.core.entities.CustomEntity
|
||||
*/
|
||||
public class ModifiedTestableEntity implements TestableEntity {
|
||||
/**
|
||||
* The item.
|
||||
*/
|
||||
private final TestableEntity handle;
|
||||
|
||||
/**
|
||||
* The amount.
|
||||
*/
|
||||
private final Predicate<Entity> test;
|
||||
|
||||
/**
|
||||
* The provider to spawn the entity.
|
||||
*/
|
||||
private final Function<Location, Entity> provider;
|
||||
|
||||
/**
|
||||
* Create a new modified testable entity.
|
||||
*
|
||||
* @param entity The base entity.
|
||||
* @param test The test.
|
||||
* @param provider The provider to spawn the entity.
|
||||
*/
|
||||
public ModifiedTestableEntity(@NotNull final TestableEntity entity,
|
||||
@NotNull final Predicate<@NotNull Entity> test,
|
||||
@NotNull final Function<Location, Entity> provider) {
|
||||
this.handle = entity;
|
||||
this.test = test;
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(@Nullable final Entity entity) {
|
||||
return entity != null && handle.matches(entity) && test.test(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity spawn(@NotNull final Location location) {
|
||||
Validate.notNull(location.getWorld());
|
||||
|
||||
return provider.apply(location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the handle.
|
||||
*
|
||||
* @return The handle.
|
||||
*/
|
||||
public TestableEntity getHandle() {
|
||||
return this.handle;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.willfp.eco.core.entities.impl;
|
||||
|
||||
import com.willfp.eco.core.entities.TestableEntity;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Default vanilla entities.
|
||||
*/
|
||||
public class SimpleTestableEntity implements TestableEntity {
|
||||
/**
|
||||
* The entity type.
|
||||
*/
|
||||
private final EntityType type;
|
||||
|
||||
/**
|
||||
* Create a new simple testable entity.
|
||||
*
|
||||
* @param type The entity type.
|
||||
*/
|
||||
public SimpleTestableEntity(@NotNull final EntityType type) {
|
||||
this.type = type;
|
||||
|
||||
Validate.notNull(type.getEntityClass(), "Entity cannot be of unknown type!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(@Nullable final Entity entity) {
|
||||
return entity != null && entity.getType() == type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity spawn(@NotNull final Location location) {
|
||||
Validate.notNull(location.getWorld());
|
||||
|
||||
assert type.getEntityClass() != null;
|
||||
|
||||
return location.getWorld().spawn(location, type.getEntityClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type.
|
||||
*
|
||||
* @return The type.
|
||||
*/
|
||||
public EntityType getType() {
|
||||
return this.type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package com.willfp.eco.core.events;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Called on DropQueue push.
|
||||
*/
|
||||
public class DropQueuePushEvent extends PlayerEvent implements Cancellable {
|
||||
/**
|
||||
* Cancel state.
|
||||
*/
|
||||
private boolean cancelled;
|
||||
|
||||
/**
|
||||
* If telekinetic.
|
||||
*/
|
||||
private final boolean isTelekinetic;
|
||||
|
||||
/**
|
||||
* The items.
|
||||
*/
|
||||
private final Collection<? extends ItemStack> items;
|
||||
|
||||
/**
|
||||
* The xp.
|
||||
*/
|
||||
private final int xp;
|
||||
|
||||
/**
|
||||
* The location.
|
||||
*/
|
||||
private final Location location;
|
||||
|
||||
/**
|
||||
* Bukkit parity.
|
||||
*/
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
|
||||
/**
|
||||
* Create a new DropQueuePushEvent.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param items The items.
|
||||
* @param location The location.
|
||||
* @param xp The xp.
|
||||
* @param isTelekinetic If the event is telekinetic.
|
||||
*/
|
||||
public DropQueuePushEvent(@NotNull final Player player,
|
||||
@NotNull final Collection<? extends ItemStack> items,
|
||||
@NotNull final Location location,
|
||||
final int xp,
|
||||
final boolean isTelekinetic) {
|
||||
super(player);
|
||||
this.items = items;
|
||||
this.location = location;
|
||||
this.xp = xp;
|
||||
this.isTelekinetic = isTelekinetic;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 cancel state.
|
||||
*
|
||||
* @return The cancel state.
|
||||
*/
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cancel state.
|
||||
*
|
||||
* @param cancelled If cancelled.
|
||||
*/
|
||||
@Override
|
||||
public void setCancelled(final boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the items to be dropped.
|
||||
*
|
||||
* @return The items.
|
||||
*/
|
||||
public Collection<? extends ItemStack> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the xp to be dropped.
|
||||
*
|
||||
* @return The xp.
|
||||
*/
|
||||
public int getXp() {
|
||||
return xp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the location.
|
||||
*
|
||||
* @return The location.
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get force telekinesis state.
|
||||
*
|
||||
* @return The force telekinesis state.
|
||||
*/
|
||||
public boolean isTelekinetic() {
|
||||
return this.isTelekinetic;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.willfp.eco.core.events;
|
||||
|
||||
import org.bukkit.event.Listener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Manages listeners for a plugin.
|
||||
@@ -11,14 +12,14 @@ public interface EventManager {
|
||||
*
|
||||
* @param listener The listener to register.
|
||||
*/
|
||||
void registerListener(Listener listener);
|
||||
void registerListener(@NotNull Listener listener);
|
||||
|
||||
/**
|
||||
* Unregister a listener with bukkit.
|
||||
*
|
||||
* @param listener The listener to unregister.
|
||||
*/
|
||||
void unregisterListener(Listener listener);
|
||||
void unregisterListener(@NotNull Listener listener);
|
||||
|
||||
/**
|
||||
* Unregister all listeners associated with the plugin.
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.apache.commons.lang.Validate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* An extension is a separate jar file that hooks into the base plugin jar.
|
||||
@@ -143,6 +144,11 @@ public abstract class Extension implements PluginLike {
|
||||
return this.plugin.getConfigHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger getLogger() {
|
||||
return this.plugin.getLogger();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin for the extension.
|
||||
*
|
||||
|
||||
@@ -22,8 +22,30 @@ public interface FastItemStack {
|
||||
*
|
||||
* @param checkStored If stored NBT should also be checked.
|
||||
* @return A map of all enchantments.
|
||||
* @deprecated Poorly named method. Use getEnchants instead.
|
||||
*/
|
||||
Map<Enchantment, Integer> getEnchantmentsOnItem(boolean checkStored);
|
||||
@Deprecated(since = "6.24.0")
|
||||
default Map<Enchantment, Integer> getEnchantmentsOnItem(boolean checkStored) {
|
||||
return getEnchants(checkStored);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all enchantments on an item.
|
||||
* Does not account for stored enchants.
|
||||
*
|
||||
* @return A map of all enchantments.
|
||||
*/
|
||||
default Map<Enchantment, Integer> getEnchants() {
|
||||
return getEnchants(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all enchantments on an item.
|
||||
*
|
||||
* @param checkStored If stored enchantments should be accounted for.
|
||||
* @return A map of all enchantments.
|
||||
*/
|
||||
Map<Enchantment, Integer> getEnchants(boolean checkStored);
|
||||
|
||||
/**
|
||||
* Get the level of an enchantment on an item.
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
package com.willfp.eco.core.gui;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.gui.menu.MenuBuilder;
|
||||
import com.willfp.eco.core.gui.slot.SlotBuilder;
|
||||
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
public interface GUIFactory {
|
||||
/**
|
||||
* Create slot builder.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.willfp.eco.core.gui.slot;
|
||||
|
||||
import com.willfp.eco.core.items.builder.ItemStackBuilder;
|
||||
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
|
||||
import com.willfp.eco.core.recipe.parts.MaterialTestableItem;
|
||||
import com.willfp.eco.util.ListUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -38,7 +40,7 @@ public class FillerMask {
|
||||
*/
|
||||
public FillerMask(@NotNull final Material material,
|
||||
@NotNull final String... pattern) {
|
||||
this(new MaskMaterials(material), pattern);
|
||||
this(new MaskItems(new MaterialTestableItem(material)), pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,17 +48,33 @@ public class FillerMask {
|
||||
*
|
||||
* @param materials The mask materials.
|
||||
* @param pattern The pattern.
|
||||
* @deprecated Use {@link MaskItems} instead.
|
||||
*/
|
||||
@Deprecated(since = "6.24.0")
|
||||
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!");
|
||||
this(
|
||||
materials.toMaskItems(),
|
||||
pattern
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new filler mask.
|
||||
*
|
||||
* @param items The mask items.
|
||||
* @param pattern The pattern.
|
||||
*/
|
||||
public FillerMask(@NotNull final MaskItems items,
|
||||
@NotNull final String... pattern) {
|
||||
if (Arrays.stream(items.items()).anyMatch(item -> item instanceof EmptyTestableItem)) {
|
||||
throw new IllegalArgumentException("Items cannot be empty!");
|
||||
}
|
||||
|
||||
mask = ListUtils.create2DList(6, 9);
|
||||
|
||||
for (int i = 0; i < materials.materials().length; i++) {
|
||||
ItemStack itemStack = new ItemStackBuilder(materials.materials()[i])
|
||||
for (int i = 0; i < items.items().length; i++) {
|
||||
ItemStack itemStack = new ItemStackBuilder(items.items()[i])
|
||||
.setDisplayName("&r")
|
||||
.build();
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.willfp.eco.core.gui.slot;
|
||||
|
||||
import com.willfp.eco.core.items.Items;
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
|
||||
import com.willfp.eco.core.recipe.parts.MaterialTestableItem;
|
||||
import org.bukkit.Material;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Mask materials store a set of items which can be accessed by
|
||||
* a filler mask.
|
||||
*
|
||||
* @param items The items.
|
||||
*/
|
||||
public record MaskItems(@NotNull TestableItem... items) {
|
||||
/**
|
||||
* Create MaskItems from a list of item names.
|
||||
*
|
||||
* @param names The names.
|
||||
* @return The mask items.
|
||||
*/
|
||||
public static MaskItems fromItemNames(@NotNull final Iterable<String> names) {
|
||||
List<TestableItem> items = new ArrayList<>();
|
||||
|
||||
for (String name : names) {
|
||||
TestableItem item = Items.lookup(name);
|
||||
|
||||
if (item instanceof EmptyTestableItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
items.add(item);
|
||||
}
|
||||
|
||||
if (items.isEmpty()) {
|
||||
return new MaskItems(new MaterialTestableItem(Material.BLACK_STAINED_GLASS_PANE));
|
||||
}
|
||||
|
||||
return new MaskItems(items.toArray(new TestableItem[0]));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.willfp.eco.core.gui.slot;
|
||||
|
||||
import com.willfp.eco.core.items.Items;
|
||||
import org.bukkit.Material;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -8,7 +9,16 @@ import org.jetbrains.annotations.NotNull;
|
||||
* a filler mask.
|
||||
*
|
||||
* @param materials The materials.
|
||||
* @deprecated Use {@link MaskItems} instead.
|
||||
*/
|
||||
@Deprecated(since = "6.24.0")
|
||||
public record MaskMaterials(@NotNull Material... materials) {
|
||||
|
||||
/**
|
||||
* Convert MaskMaterials to MaskItems.
|
||||
*
|
||||
* @return The MaskItems.
|
||||
*/
|
||||
public MaskItems toMaskItems() {
|
||||
return new MaskItems(Items.fromMaterials(this.materials()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ 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 com.willfp.eco.core.gui.slot.functional.SlotUpdater;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -106,8 +107,23 @@ public interface SlotBuilder {
|
||||
*
|
||||
* @param modifier The modifier.
|
||||
* @return The builder.
|
||||
* @deprecated Use {@link SlotBuilder#setUpdater(SlotUpdater)} instead.
|
||||
*/
|
||||
SlotBuilder setModifier(@NotNull SlotModifier modifier);
|
||||
@Deprecated
|
||||
default SlotBuilder setModifier(@NotNull SlotModifier modifier) {
|
||||
return setUpdater((player, menu, previous) -> {
|
||||
modifier.modify(player, menu, previous);
|
||||
return previous;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ItemStack updater.
|
||||
*
|
||||
* @param updater The updater.
|
||||
* @return The builder.
|
||||
*/
|
||||
SlotBuilder setUpdater(@NotNull SlotUpdater updater);
|
||||
|
||||
/**
|
||||
* Set slot to be a captive slot.
|
||||
|
||||
@@ -7,8 +7,11 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Interface to run on slot modify.
|
||||
*
|
||||
* @deprecated Use {@link SlotUpdater} instead.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
@Deprecated
|
||||
public interface SlotModifier {
|
||||
/**
|
||||
* Performs this operation on the given arguments.
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
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 update.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface SlotUpdater {
|
||||
/**
|
||||
* Performs this operation on the given arguments.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param menu The menu.
|
||||
* @param previous The previous ItemStack.
|
||||
* @return The new ItemStack.
|
||||
*/
|
||||
ItemStack update(@NotNull Player player,
|
||||
@NotNull Menu menu,
|
||||
@NotNull ItemStack previous);
|
||||
}
|
||||
@@ -1,7 +1,13 @@
|
||||
package com.willfp.eco.core.integrations;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* An integration loader runs a runnable only if a specific plugin is present on the server.
|
||||
* <p>
|
||||
@@ -9,7 +15,15 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public class IntegrationLoader {
|
||||
/**
|
||||
* The lambda to be ran if the plugin is present.
|
||||
* All loaded plugins on the server.
|
||||
*/
|
||||
private static final Set<String> LOADED_PLUGINS = Arrays.stream(Bukkit.getPluginManager().getPlugins())
|
||||
.map(Plugin::getName)
|
||||
.map(String::toLowerCase)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
/**
|
||||
* The lambda to be run if the plugin is present.
|
||||
*/
|
||||
private final Runnable runnable;
|
||||
|
||||
@@ -22,7 +36,7 @@ public class IntegrationLoader {
|
||||
* Create a new Integration Loader.
|
||||
*
|
||||
* @param pluginName The plugin to require.
|
||||
* @param onLoad The lambda to be ran if the plugin is present.
|
||||
* @param onLoad The lambda to be run if the plugin is present.
|
||||
*/
|
||||
public IntegrationLoader(@NotNull final String pluginName,
|
||||
@NotNull final Runnable onLoad) {
|
||||
@@ -30,6 +44,15 @@ public class IntegrationLoader {
|
||||
this.pluginName = pluginName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the integration if the specified plugin is present on the server.
|
||||
*/
|
||||
public void loadIfPresent() {
|
||||
if (LOADED_PLUGINS.contains(this.pluginName.toLowerCase())) {
|
||||
this.load();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the integration.
|
||||
*/
|
||||
|
||||
@@ -24,7 +24,7 @@ public final class AnticheatManager {
|
||||
* @param anticheat The anticheat to register.
|
||||
*/
|
||||
public static void register(@NotNull final EcoPlugin plugin,
|
||||
@NotNull final AnticheatWrapper anticheat) {
|
||||
@NotNull final AnticheatWrapper anticheat) {
|
||||
if (anticheat instanceof Listener) {
|
||||
plugin.getEventManager().registerListener((Listener) anticheat);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,18 @@ public final class AntigriefManager {
|
||||
REGISTERED.remove(antigrief);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can player pickup item.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param location The location.
|
||||
* @return If player can pick up item.
|
||||
*/
|
||||
public static boolean canPickupItem(@NotNull final Player player,
|
||||
@NotNull final Location location) {
|
||||
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canPickupItem(player, location));
|
||||
}
|
||||
|
||||
/**
|
||||
* Can player break block.
|
||||
*
|
||||
@@ -45,7 +57,7 @@ public final class AntigriefManager {
|
||||
* @return If player can break block.
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -57,7 +69,7 @@ public final class AntigriefManager {
|
||||
* @return If player can create explosion.
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -69,7 +81,7 @@ public final class AntigriefManager {
|
||||
* @return If player can place block.
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -81,7 +93,7 @@ public final class AntigriefManager {
|
||||
* @return If player can injure.
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Wrapper class for antigrief integrations.
|
||||
@@ -17,7 +18,7 @@ public interface AntigriefWrapper extends Integration {
|
||||
* @param block The block.
|
||||
* @return If player can break block.
|
||||
*/
|
||||
boolean canBreakBlock(Player player, Block block);
|
||||
boolean canBreakBlock(@NotNull Player player, @NotNull Block block);
|
||||
|
||||
/**
|
||||
* Can player create explosion at location.
|
||||
@@ -26,7 +27,7 @@ public interface AntigriefWrapper extends Integration {
|
||||
* @param location The location.
|
||||
* @return If player can create explosion.
|
||||
*/
|
||||
boolean canCreateExplosion(Player player, Location location);
|
||||
boolean canCreateExplosion(@NotNull Player player, @NotNull Location location);
|
||||
|
||||
/**
|
||||
* Can player place block.
|
||||
@@ -35,7 +36,7 @@ public interface AntigriefWrapper extends Integration {
|
||||
* @param block The block.
|
||||
* @return If player can place block.
|
||||
*/
|
||||
boolean canPlaceBlock(Player player, Block block);
|
||||
boolean canPlaceBlock(@NotNull Player player, @NotNull Block block);
|
||||
|
||||
/**
|
||||
* Can player injure living entity.
|
||||
@@ -44,5 +45,16 @@ public interface AntigriefWrapper extends Integration {
|
||||
* @param victim The victim.
|
||||
* @return If player can injure.
|
||||
*/
|
||||
boolean canInjure(Player player, LivingEntity victim);
|
||||
boolean canInjure(@NotNull Player player, @NotNull LivingEntity victim);
|
||||
|
||||
/**
|
||||
* Can player pick up item.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param location The location.
|
||||
* @return If player can pick up item.
|
||||
*/
|
||||
default boolean canPickupItem(@NotNull Player player, @NotNull Location location) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.willfp.eco.core.integrations.customentities;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Class to handle custom entity integrations.
|
||||
*/
|
||||
public final class CustomEntitiesManager {
|
||||
/**
|
||||
* A set of all registered integrations.
|
||||
*/
|
||||
private static final Set<CustomEntitiesWrapper> REGISTERED = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Register a new integration.
|
||||
*
|
||||
* @param integration The integration to register.
|
||||
*/
|
||||
public static void register(@NotNull final CustomEntitiesWrapper integration) {
|
||||
REGISTERED.add(integration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register all the custom entities for a specific plugin into eco.
|
||||
*
|
||||
* @see com.willfp.eco.core.entities.Entities
|
||||
*/
|
||||
public static void registerAllEntities() {
|
||||
for (CustomEntitiesWrapper wrapper : REGISTERED) {
|
||||
wrapper.registerAllEntities();
|
||||
}
|
||||
}
|
||||
|
||||
private CustomEntitiesManager() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.willfp.eco.core.integrations.customentities;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
|
||||
/**
|
||||
* Wrapper class for custom item integrations.
|
||||
*/
|
||||
public interface CustomEntitiesWrapper extends Integration {
|
||||
/**
|
||||
* Register all the custom entities for a specific plugin into eco.
|
||||
*
|
||||
* @see com.willfp.eco.core.entities.Entities
|
||||
*/
|
||||
void registerAllEntities();
|
||||
}
|
||||
@@ -41,7 +41,7 @@ public final class EconomyManager {
|
||||
* @return If the player has the amount.
|
||||
*/
|
||||
public static boolean hasAmount(@NotNull final OfflinePlayer player,
|
||||
final double amount) {
|
||||
final double amount) {
|
||||
for (EconomyWrapper wrapper : REGISTERED) {
|
||||
return wrapper.hasAmount(player, amount);
|
||||
}
|
||||
@@ -57,7 +57,7 @@ public final class EconomyManager {
|
||||
* @return If the transaction was a success.
|
||||
*/
|
||||
public static boolean giveMoney(@NotNull final OfflinePlayer player,
|
||||
final double amount) {
|
||||
final double amount) {
|
||||
for (EconomyWrapper wrapper : REGISTERED) {
|
||||
return wrapper.giveMoney(player, amount);
|
||||
}
|
||||
@@ -73,7 +73,7 @@ public final class EconomyManager {
|
||||
* @return If the transaction was a success.
|
||||
*/
|
||||
public static boolean removeMoney(@NotNull final OfflinePlayer player,
|
||||
final double amount) {
|
||||
final double amount) {
|
||||
for (EconomyWrapper wrapper : REGISTERED) {
|
||||
return wrapper.removeMoney(player, amount);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public final class HologramManager {
|
||||
* @return The hologram.
|
||||
*/
|
||||
public static Hologram createHologram(@NotNull final Location location,
|
||||
@NotNull final List<String> contents) {
|
||||
@NotNull final List<String> contents) {
|
||||
for (HologramWrapper wrapper : REGISTERED) {
|
||||
return wrapper.createHologram(location, contents);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package com.willfp.eco.core.integrations.placeholder;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
@@ -28,12 +30,20 @@ public class PlaceholderEntry {
|
||||
*/
|
||||
private final boolean requiresPlayer;
|
||||
|
||||
/**
|
||||
* The plugin for the placeholder.
|
||||
*/
|
||||
@Nullable
|
||||
private final EcoPlugin plugin;
|
||||
|
||||
/**
|
||||
* Create a placeholder entry that doesn't require a player.
|
||||
*
|
||||
* @param identifier The identifier of the placeholder.
|
||||
* @param function A lambda to get the result of the placeholder given a player.
|
||||
* @deprecated Specify a plugin.
|
||||
*/
|
||||
@Deprecated
|
||||
public PlaceholderEntry(@NotNull final String identifier,
|
||||
@NotNull final Function<Player, String> function) {
|
||||
this(identifier, function, false);
|
||||
@@ -45,10 +55,41 @@ public class PlaceholderEntry {
|
||||
* @param identifier The identifier of the placeholder.
|
||||
* @param function A lambda to get the result of the placeholder.
|
||||
* @param requiresPlayer If the placeholder requires a player.
|
||||
* @deprecated Specify a plugin.
|
||||
*/
|
||||
@Deprecated
|
||||
public PlaceholderEntry(@NotNull final String identifier,
|
||||
@NotNull final Function<Player, String> function,
|
||||
final boolean requiresPlayer) {
|
||||
this(null, identifier, function, requiresPlayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a placeholder entry that doesn't require a player.
|
||||
*
|
||||
* @param plugin The plugin for the placeholder.
|
||||
* @param identifier The identifier of the placeholder.
|
||||
* @param function A lambda to get the result of the placeholder given a player.
|
||||
*/
|
||||
public PlaceholderEntry(@Nullable final EcoPlugin plugin,
|
||||
@NotNull final String identifier,
|
||||
@NotNull final Function<Player, String> function) {
|
||||
this(plugin, identifier, function, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a placeholder entry that may require a player.
|
||||
*
|
||||
* @param plugin The plugin for the placeholder.
|
||||
* @param identifier The identifier of the placeholder.
|
||||
* @param function A lambda to get the result of the placeholder.
|
||||
* @param requiresPlayer If the placeholder requires a player.
|
||||
*/
|
||||
public PlaceholderEntry(@Nullable final EcoPlugin plugin,
|
||||
@NotNull final String identifier,
|
||||
@NotNull final Function<Player, String> function,
|
||||
final boolean requiresPlayer) {
|
||||
this.plugin = plugin;
|
||||
this.identifier = identifier;
|
||||
this.function = function;
|
||||
this.requiresPlayer = requiresPlayer;
|
||||
@@ -85,10 +126,37 @@ public class PlaceholderEntry {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin.
|
||||
*
|
||||
* @return The plugin.
|
||||
*/
|
||||
@Nullable
|
||||
public EcoPlugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the placeholder.
|
||||
*/
|
||||
public void register() {
|
||||
PlaceholderManager.registerPlaceholder(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof PlaceholderEntry entry)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(this.getIdentifier(), entry.getIdentifier())
|
||||
&& Objects.equals(this.getPlugin(), entry.getPlugin());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.getIdentifier(), this.getPlugin());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper class for placeholder integrations.
|
||||
*/
|
||||
@@ -24,4 +27,14 @@ public interface PlaceholderIntegration extends Integration {
|
||||
*/
|
||||
String translate(@NotNull String text,
|
||||
@Nullable Player player);
|
||||
|
||||
/**
|
||||
* Find all placeholders in a given text.
|
||||
*
|
||||
* @param text The text.
|
||||
* @return The placeholders.
|
||||
*/
|
||||
default List<String> findPlaceholdersIn(@NotNull String text) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
package com.willfp.eco.core.integrations.placeholder;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Class to handle placeholder integrations.
|
||||
@@ -16,17 +23,24 @@ public final class PlaceholderManager {
|
||||
/**
|
||||
* All registered placeholders.
|
||||
*/
|
||||
private static final Map<String, PlaceholderEntry> REGISTERED_PLACEHOLDERS = new HashMap<>();
|
||||
private static final Map<EcoPlugin, Map<String, PlaceholderEntry>> REGISTERED_PLACEHOLDERS = new HashMap<>();
|
||||
|
||||
/**
|
||||
* All registered placeholder integrations.
|
||||
*/
|
||||
private static final Set<PlaceholderIntegration> REGISTERED_INTEGRATIONS = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Placeholder Cache.
|
||||
*/
|
||||
private static final LoadingCache<EntryWithPlayer, String> PLACEHOLDER_CACHE = Caffeine.newBuilder()
|
||||
.expireAfterWrite(50, TimeUnit.MILLISECONDS)
|
||||
.build(key -> key.entry.getResult(key.player));
|
||||
|
||||
/**
|
||||
* Register a new placeholder integration.
|
||||
*
|
||||
* @param integration The {@link PlaceholderIntegration} to register.
|
||||
* @param integration The {@link com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration} to register.
|
||||
*/
|
||||
public static void addIntegration(@NotNull final PlaceholderIntegration integration) {
|
||||
integration.registerIntegration();
|
||||
@@ -36,11 +50,14 @@ public final class PlaceholderManager {
|
||||
/**
|
||||
* Register a placeholder.
|
||||
*
|
||||
* @param expansion The {@link PlaceholderEntry} to register.
|
||||
* @param expansion The {@link com.willfp.eco.core.integrations.placeholder.PlaceholderEntry} to register.
|
||||
*/
|
||||
public static void registerPlaceholder(@NotNull final PlaceholderEntry expansion) {
|
||||
REGISTERED_PLACEHOLDERS.remove(expansion.getIdentifier());
|
||||
REGISTERED_PLACEHOLDERS.put(expansion.getIdentifier(), expansion);
|
||||
EcoPlugin plugin = expansion.getPlugin() == null ? Eco.getHandler().getEcoPlugin() : expansion.getPlugin();
|
||||
Map<String, PlaceholderEntry> pluginPlaceholders = REGISTERED_PLACEHOLDERS
|
||||
.getOrDefault(plugin, new HashMap<>());
|
||||
pluginPlaceholders.put(expansion.getIdentifier(), expansion);
|
||||
REGISTERED_PLACEHOLDERS.put(plugin, pluginPlaceholders);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,10 +66,36 @@ public final class PlaceholderManager {
|
||||
* @param player The player to get the result from.
|
||||
* @param identifier The placeholder identifier.
|
||||
* @return The value of the placeholder.
|
||||
* @deprecated Specify a plugin to get the result from.
|
||||
*/
|
||||
@Deprecated
|
||||
public static String getResult(@Nullable final Player player,
|
||||
@NotNull final String identifier) {
|
||||
PlaceholderEntry entry = REGISTERED_PLACEHOLDERS.get(identifier.toLowerCase());
|
||||
return getResult(player, identifier, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the result of a placeholder with respect to a player.
|
||||
*
|
||||
* @param player The player to get the result from.
|
||||
* @param identifier The placeholder identifier.
|
||||
* @param plugin The plugin for the placeholder.
|
||||
* @return The value of the placeholder.
|
||||
*/
|
||||
public static String getResult(@Nullable final Player player,
|
||||
@NotNull final String identifier,
|
||||
@Nullable final EcoPlugin plugin) {
|
||||
EcoPlugin owner = plugin == null ? Eco.getHandler().getEcoPlugin() : plugin;
|
||||
PlaceholderEntry entry = REGISTERED_PLACEHOLDERS.getOrDefault(owner, new HashMap<>()).get(identifier.toLowerCase());
|
||||
|
||||
if (entry == null && plugin != null) {
|
||||
PlaceholderEntry alternate = REGISTERED_PLACEHOLDERS.getOrDefault(Eco.getHandler().getEcoPlugin(), new HashMap<>())
|
||||
.get(identifier.toLowerCase());
|
||||
if (alternate != null) {
|
||||
entry = alternate;
|
||||
}
|
||||
}
|
||||
|
||||
if (entry == null) {
|
||||
return "";
|
||||
}
|
||||
@@ -61,7 +104,7 @@ public final class PlaceholderManager {
|
||||
return "";
|
||||
}
|
||||
|
||||
return entry.getResult(player);
|
||||
return PLACEHOLDER_CACHE.get(new EntryWithPlayer(entry, player));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,6 +123,26 @@ public final class PlaceholderManager {
|
||||
return processed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all placeholders in a given text.
|
||||
*
|
||||
* @param text The text.
|
||||
* @return The placeholders.
|
||||
*/
|
||||
public static List<String> findPlaceholdersIn(@NotNull final String text) {
|
||||
List<String> found = new ArrayList<>();
|
||||
for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
|
||||
found.addAll(integration.findPlaceholdersIn(text));
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private static record EntryWithPlayer(@NotNull PlaceholderEntry entry,
|
||||
@Nullable Player player) {
|
||||
|
||||
}
|
||||
|
||||
private PlaceholderManager() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public class CustomItem implements TestableItem {
|
||||
|
||||
@Override
|
||||
public ItemStack getItem() {
|
||||
return item;
|
||||
return item.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
103
eco-api/src/main/java/com/willfp/eco/core/items/HashedItem.java
Normal file
103
eco-api/src/main/java/com/willfp/eco/core/items/HashedItem.java
Normal file
@@ -0,0 +1,103 @@
|
||||
package com.willfp.eco.core.items;
|
||||
|
||||
import com.willfp.eco.core.fast.FastItemStack;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An item and its {@link com.willfp.eco.core.fast.FastItemStack} hash.
|
||||
*/
|
||||
public final class HashedItem {
|
||||
/**
|
||||
* The item.
|
||||
*/
|
||||
private final ItemStack item;
|
||||
|
||||
/**
|
||||
* The hash.
|
||||
*/
|
||||
private final int hash;
|
||||
|
||||
/**
|
||||
* Create new hashed item.
|
||||
*
|
||||
* @param item The item.
|
||||
* @param hash The hash.
|
||||
*/
|
||||
private HashedItem(@NotNull final ItemStack item,
|
||||
final int hash) {
|
||||
this.item = item;
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item.
|
||||
*
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
public ItemStack getItem() {
|
||||
return this.item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hash.
|
||||
*
|
||||
* @return The hash.
|
||||
*/
|
||||
public int getHash() {
|
||||
return this.hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kotlin destructuring support.
|
||||
*
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
public ItemStack component1() {
|
||||
return this.getItem();
|
||||
}
|
||||
|
||||
/**
|
||||
* Kotlin destructuring support.
|
||||
*
|
||||
* @return The hash.
|
||||
*/
|
||||
public int component2() {
|
||||
return this.getHash();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable final Object other) {
|
||||
if (!(other instanceof HashedItem o)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return o.hash == this.hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashed item from an item.
|
||||
*
|
||||
* @param item The item.
|
||||
* @return The hashed item.
|
||||
*/
|
||||
public static HashedItem of(@NotNull final ItemStack item) {
|
||||
return new HashedItem(item, FastItemStack.wrap(item).hashCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashed item from a fast item stack.
|
||||
*
|
||||
* @param item The item.
|
||||
* @return The hashed item.
|
||||
*/
|
||||
public static HashedItem of(@NotNull final FastItemStack item) {
|
||||
return new HashedItem(item.unwrap(), item.hashCode());
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.willfp.eco.core.items;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
import com.willfp.eco.core.items.args.LookupArgParser;
|
||||
import com.willfp.eco.core.items.provider.ItemProvider;
|
||||
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
|
||||
@@ -17,10 +19,13 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -33,6 +38,25 @@ public final class Items {
|
||||
*/
|
||||
private static final Map<NamespacedKey, TestableItem> REGISTRY = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Cached custom item lookups, using {@link HashedItem}.
|
||||
*/
|
||||
private static final LoadingCache<HashedItem, Optional<TestableItem>> CACHE = Caffeine.newBuilder()
|
||||
.expireAfterAccess(5, TimeUnit.MINUTES)
|
||||
.build(
|
||||
key -> {
|
||||
TestableItem match = null;
|
||||
for (TestableItem item : REGISTRY.values()) {
|
||||
if (item.matches(key.getItem())) {
|
||||
match = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.ofNullable(match);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* All item providers.
|
||||
*/
|
||||
@@ -43,6 +67,11 @@ public final class Items {
|
||||
*/
|
||||
private static final List<LookupArgParser> ARG_PARSERS = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The handler.
|
||||
*/
|
||||
private static final ItemsLookupHandler ITEMS_LOOKUP_HANDLER = new ItemsLookupHandler(Items::doParse);
|
||||
|
||||
/**
|
||||
* Register a new custom item.
|
||||
*
|
||||
@@ -50,7 +79,7 @@ public final class Items {
|
||||
* @param item The item.
|
||||
*/
|
||||
public static void registerCustomItem(@NotNull final NamespacedKey key,
|
||||
@NotNull final TestableItem item) {
|
||||
@NotNull final TestableItem item) {
|
||||
REGISTRY.put(key, item);
|
||||
}
|
||||
|
||||
@@ -84,7 +113,7 @@ public final class Items {
|
||||
/**
|
||||
* This is the backbone of the entire eco item system.
|
||||
* <p>
|
||||
* You can lookup a TestableItem for any material, custom item,
|
||||
* You can look up 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.
|
||||
@@ -94,8 +123,8 @@ public final class Items {
|
||||
* <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
|
||||
* is that testable item; which may sound negligible, but actually it allows for
|
||||
* much more power and 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
|
||||
@@ -104,20 +133,13 @@ public final class Items {
|
||||
* @param key The lookup string.
|
||||
* @return The testable item, or an {@link EmptyTestableItem}.
|
||||
*/
|
||||
@NotNull
|
||||
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 ITEMS_LOOKUP_HANDLER.parseKey(key);
|
||||
}
|
||||
|
||||
return new EmptyTestableItem();
|
||||
}
|
||||
|
||||
String[] args = key.split(" ");
|
||||
@NotNull
|
||||
private static TestableItem doParse(@NotNull final String[] args) {
|
||||
if (args.length == 0) {
|
||||
return new EmptyTestableItem();
|
||||
}
|
||||
@@ -191,7 +213,7 @@ public final class Items {
|
||||
}
|
||||
}
|
||||
|
||||
// Marked as redundant but i am covering all bases here
|
||||
// Marked as redundant but I am covering all bases here
|
||||
if (item == null || item instanceof EmptyTestableItem) {
|
||||
return new EmptyTestableItem();
|
||||
}
|
||||
@@ -235,6 +257,37 @@ public final class Items {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Testable Item from an ItemStack.
|
||||
* <p>
|
||||
* Will search for registered items first. If there are no matches in the registry,
|
||||
* then it will return a {@link MaterialTestableItem} matching the item type.
|
||||
* <p>
|
||||
* Does not account for modifiers (arg parser data).
|
||||
*
|
||||
* @param item The ItemStack.
|
||||
* @return The found Testable Item.
|
||||
*/
|
||||
@NotNull
|
||||
public static TestableItem getItem(@Nullable final ItemStack item) {
|
||||
if (item == null || item.getType().isAir()) {
|
||||
return new EmptyTestableItem();
|
||||
}
|
||||
|
||||
CustomItem customItem = getCustomItem(item);
|
||||
|
||||
if (customItem != null) {
|
||||
return customItem;
|
||||
}
|
||||
|
||||
for (TestableItem known : REGISTRY.values()) {
|
||||
if (known.matches(item)) {
|
||||
return known;
|
||||
}
|
||||
}
|
||||
return new MaterialTestableItem(item.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if itemStack is a custom item.
|
||||
*
|
||||
@@ -242,12 +295,7 @@ public final class Items {
|
||||
* @return If is recipe.
|
||||
*/
|
||||
public static boolean isCustomItem(@NotNull final ItemStack itemStack) {
|
||||
for (TestableItem item : REGISTRY.values()) {
|
||||
if (item.matches(itemStack)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return getCustomItem(itemStack) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -258,12 +306,7 @@ public final class Items {
|
||||
*/
|
||||
@Nullable
|
||||
public static CustomItem getCustomItem(@NotNull final ItemStack itemStack) {
|
||||
for (TestableItem item : REGISTRY.values()) {
|
||||
if (item.matches(itemStack)) {
|
||||
return getOrWrap(item);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return CACHE.get(HashedItem.of(itemStack)).map(Items::getOrWrap).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -284,6 +327,7 @@ public final class Items {
|
||||
* @param item The item.
|
||||
* @return The CustomItem.
|
||||
*/
|
||||
@NotNull
|
||||
public static CustomItem getOrWrap(@NotNull final TestableItem item) {
|
||||
if (item instanceof CustomItem) {
|
||||
return (CustomItem) item;
|
||||
@@ -296,6 +340,35 @@ public final class Items {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an array of materials to an array of testable items.
|
||||
*
|
||||
* @param materials The materials.
|
||||
* @return An array of functionally identical testable items.
|
||||
*/
|
||||
@NotNull
|
||||
public static TestableItem[] fromMaterials(@NotNull final Material... materials) {
|
||||
return Arrays.stream(materials)
|
||||
.map(MaterialTestableItem::new)
|
||||
.toArray(MaterialTestableItem[]::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a collection of materials into a collection of testable items.
|
||||
*
|
||||
* @param materials The materials.
|
||||
* @return A collection of functionally identical testable items.
|
||||
*/
|
||||
@NotNull
|
||||
public static Collection<TestableItem> fromMaterials(@NotNull final Iterable<Material> materials) {
|
||||
List<TestableItem> items = new ArrayList<>();
|
||||
for (Material material : materials) {
|
||||
items.add(new MaterialTestableItem(material));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
private Items() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.willfp.eco.core.items;
|
||||
|
||||
import com.willfp.eco.core.lookup.LookupHandler;
|
||||
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
|
||||
import com.willfp.eco.core.recipe.parts.GroupedTestableItems;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Handle item lookup strings.
|
||||
*/
|
||||
public class ItemsLookupHandler implements LookupHandler<TestableItem> {
|
||||
/**
|
||||
* The parser.
|
||||
*/
|
||||
private final Function<String[], @NotNull TestableItem> parser;
|
||||
|
||||
/**
|
||||
* Create new lookup handler.
|
||||
*
|
||||
* @param parser The parser.
|
||||
*/
|
||||
public ItemsLookupHandler(@NotNull final Function<String[], @NotNull TestableItem> parser) {
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TestableItem parse(@NotNull final String[] args) {
|
||||
return parser.apply(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(@NotNull final TestableItem object) {
|
||||
return !(object instanceof EmptyTestableItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TestableItem getFailsafe() {
|
||||
return new EmptyTestableItem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TestableItem join(@NotNull final Collection<TestableItem> options) {
|
||||
return new GroupedTestableItems(options);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,20 @@
|
||||
package com.willfp.eco.core.items;
|
||||
|
||||
import com.willfp.eco.core.lookup.Testable;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An item with a test to see if any item is that item.
|
||||
*/
|
||||
public interface TestableItem {
|
||||
public interface TestableItem extends Testable<ItemStack> {
|
||||
/**
|
||||
* If an ItemStack matches the recipe part.
|
||||
*
|
||||
* @param itemStack The item to test.
|
||||
* @return If the item matches.
|
||||
*/
|
||||
@Override
|
||||
boolean matches(@Nullable ItemStack itemStack);
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user