Compare commits
192 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
c0547a7c34 |
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.1.0"
|
||||
id("com.github.johnrengelman.shadow") version "7.1.2"
|
||||
id("maven-publish")
|
||||
id("java")
|
||||
kotlin("jvm") version "1.6.10"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -10,7 +21,6 @@ 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(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf"))
|
||||
}
|
||||
@@ -20,6 +30,7 @@ allprojects {
|
||||
apply(plugin = "java-library")
|
||||
apply(plugin = "maven-publish")
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
apply(plugin = "kotlin")
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
@@ -64,19 +75,30 @@ allprojects {
|
||||
|
||||
// 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")
|
||||
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> {
|
||||
@@ -94,6 +116,14 @@ allprojects {
|
||||
}
|
||||
|
||||
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'
|
||||
@@ -15,13 +8,10 @@ dependencies {
|
||||
compileOnly 'org.apache.maven:maven-artifact:3.8.1'
|
||||
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.1-SNAPSHOT'
|
||||
compileOnly 'com.google.code.gson:gson:2.8.8'
|
||||
compileOnly 'org.apache.commons:commons-lang3:3.0'
|
||||
}
|
||||
|
||||
java {
|
||||
withJavadocJar()
|
||||
}
|
||||
|
||||
group 'com.willfp'
|
||||
version rootProject.version
|
||||
|
||||
build.dependsOn publishToMavenLocal
|
||||
|
||||
|
||||
@@ -4,6 +4,12 @@ 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;
|
||||
|
||||
/**
|
||||
* Holds the instance of the eco handler for bridging between the frontend
|
||||
* and backend.
|
||||
@@ -52,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");
|
||||
}
|
||||
|
||||
@@ -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,7 +353,7 @@ 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.getLogger().warning("&c " + this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
|
||||
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!");
|
||||
}
|
||||
@@ -534,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.
|
||||
*
|
||||
@@ -635,7 +676,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
* @return The proxy.
|
||||
*/
|
||||
public final <T> T getProxy(@NotNull final Class<T> proxyClass) {
|
||||
Validate.notNull(proxyFactory, "Plugin does not support proxy!");
|
||||
Validate.notNull(proxyFactory, "Plugin does not support proxies!");
|
||||
|
||||
return proxyFactory.getProxy(proxyClass);
|
||||
}
|
||||
|
||||
@@ -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,10 +15,10 @@ 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;
|
||||
@@ -32,6 +32,7 @@ import java.util.logging.Logger;
|
||||
* @see Eco#getHandler()
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@SuppressWarnings("removal")
|
||||
public interface Handler {
|
||||
/**
|
||||
* Create a scheduler.
|
||||
@@ -209,7 +210,8 @@ public interface Handler {
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
RequirementFactory getRequirementFactory();
|
||||
@Deprecated(forRemoval = true)
|
||||
com.willfp.eco.core.requirement.RequirementFactory getRequirementFactory();
|
||||
|
||||
/**
|
||||
* Get Adventure audiences.
|
||||
@@ -233,7 +235,7 @@ public interface Handler {
|
||||
* @return The handler.
|
||||
*/
|
||||
@NotNull
|
||||
PlayerProfileHandler getPlayerProfileHandler();
|
||||
ProfileHandler getProfileHandler();
|
||||
|
||||
/**
|
||||
* Create dummy entity - never spawned, exists purely in code.
|
||||
@@ -243,4 +245,30 @@ public interface Handler {
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
|
||||
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,5 +1,6 @@
|
||||
package com.willfp.eco.core.command;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -66,6 +67,13 @@ public interface CommandBase {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin.
|
||||
*
|
||||
* @return The plugin.
|
||||
*/
|
||||
EcoPlugin getPlugin();
|
||||
|
||||
/**
|
||||
* Get the handler.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
@@ -25,7 +24,12 @@ import java.util.stream.Collectors;
|
||||
* layer, hence why it's a package-private class.
|
||||
*/
|
||||
@SuppressWarnings({"DeprecatedIsStillUsed"})
|
||||
abstract class HandledCommand extends PluginDependent<EcoPlugin> implements CommandBase {
|
||||
abstract class HandledCommand implements CommandBase {
|
||||
/**
|
||||
* The plugin.
|
||||
*/
|
||||
private final EcoPlugin plugin;
|
||||
|
||||
/**
|
||||
* The name of the command.
|
||||
*/
|
||||
@@ -78,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;
|
||||
@@ -98,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.
|
||||
*
|
||||
@@ -124,6 +138,11 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -193,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;
|
||||
|
||||
@@ -5,7 +5,10 @@ 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;
|
||||
|
||||
/**
|
||||
@@ -21,6 +24,15 @@ public class TransientConfig extends ConfigWrapper<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.
|
||||
*
|
||||
|
||||
@@ -2,7 +2,9 @@ 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;
|
||||
|
||||
@@ -108,6 +110,29 @@ public interface Config extends Cloneable {
|
||||
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.
|
||||
*
|
||||
@@ -210,7 +235,7 @@ public interface Config extends Cloneable {
|
||||
*/
|
||||
@NotNull
|
||||
default String getString(@NotNull String path) {
|
||||
return getString(path, false);
|
||||
return getString(path, false, StringUtils.FormatOption.WITHOUT_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -519,6 +544,28 @@ public interface Config extends Cloneable {
|
||||
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.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
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;
|
||||
@@ -14,6 +15,7 @@ import java.util.Map;
|
||||
* Internal component to create backend config implementations.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
public interface ConfigFactory {
|
||||
/**
|
||||
* Updatable config.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.willfp.eco.core.entities;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.willfp.eco.core.entities.impl;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.entities.TestableEntity;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.willfp.eco.core.entities.impl;
|
||||
|
||||
import com.willfp.eco.core.entities.TestableEntity;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.willfp.eco.core.entities.impl;
|
||||
|
||||
import com.willfp.eco.core.entities.TestableEntity;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
@@ -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,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");
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -18,10 +20,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;
|
||||
|
||||
@@ -34,6 +39,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.
|
||||
*/
|
||||
@@ -194,7 +218,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();
|
||||
}
|
||||
@@ -276,12 +300,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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,12 +311,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -331,6 +345,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");
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
package com.willfp.eco.core.items.args;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Parse leather armor colors.
|
||||
*
|
||||
* @deprecated Moved to internals.
|
||||
*/
|
||||
@Deprecated(since = "6.16.0", forRemoval = true)
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "6.18.2")
|
||||
public class ColorArgParser implements LookupArgParser {
|
||||
/**
|
||||
* Instantiate arg parser.
|
||||
*/
|
||||
public ColorArgParser() {
|
||||
Bukkit.getLogger().severe("Instantiation of class marked for removal! (" + this.getClass().getName() + "), this will throw an error in a future release!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
||||
@NotNull final ItemMeta meta) {
|
||||
return null;
|
||||
}
|
||||
|
||||
static {
|
||||
Bukkit.getLogger().severe("Referencing a class marked for removal! (" + ColorArgParser.class.getName() + "), this will throw an error in the next release!");
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package com.willfp.eco.core.items.args;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Parse custom model data.
|
||||
*
|
||||
* @deprecated Moved to internals.
|
||||
*/
|
||||
@Deprecated(since = "6.16.0", forRemoval = true)
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "6.18.2")
|
||||
public class CustomModelDataArgParser implements LookupArgParser {
|
||||
/**
|
||||
* Instantiate arg parser.
|
||||
*/
|
||||
public CustomModelDataArgParser() {
|
||||
Bukkit.getLogger().severe("Instantiation of class marked for removal! (" + this.getClass().getName() + "), this will throw an error in a future release!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
||||
@NotNull final ItemMeta meta) {
|
||||
return null;
|
||||
}
|
||||
|
||||
static {
|
||||
Bukkit.getLogger().severe("Referencing a class marked for removal! (" + CustomModelDataArgParser.class.getName() + "), this will throw an error in the next release!");
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package com.willfp.eco.core.items.args;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Parses enchantment arguments.
|
||||
*
|
||||
* @deprecated Moved to internals.
|
||||
*/
|
||||
@Deprecated(since = "6.16.0", forRemoval = true)
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "6.18.2")
|
||||
public class EnchantmentArgParser implements LookupArgParser {
|
||||
/**
|
||||
* Instantiate arg parser.
|
||||
*/
|
||||
public EnchantmentArgParser() {
|
||||
Bukkit.getLogger().severe("Instantiation of class marked for removal! (" + this.getClass().getName() + "), this will throw an error in a future release!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
||||
@NotNull final ItemMeta meta) {
|
||||
return null;
|
||||
}
|
||||
|
||||
static {
|
||||
Bukkit.getLogger().severe("Referencing a class marked for removal! (" + EnchantmentArgParser.class.getName() + "), this will throw an error in the next release!");
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package com.willfp.eco.core.items.args;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Parse skull textures.
|
||||
*
|
||||
* @deprecated Moved to internals.
|
||||
*/
|
||||
@Deprecated(since = "6.16.0", forRemoval = true)
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "6.18.2")
|
||||
public class TextureArgParser implements LookupArgParser {
|
||||
/**
|
||||
* Instantiate arg parser.
|
||||
*/
|
||||
public TextureArgParser() {
|
||||
Bukkit.getLogger().severe("Instantiation of class marked for removal! (" + this.getClass().getName() + "), this will throw an error in a future release!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
||||
@NotNull final ItemMeta meta) {
|
||||
return null;
|
||||
}
|
||||
|
||||
static {
|
||||
Bukkit.getLogger().severe("Referencing a class marked for removal! (" + TextureArgParser.class.getName() + "), this will throw an error in the next release!");
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,25 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* Generic error with proxy loading.
|
||||
*/
|
||||
public class ProxyError extends RuntimeException {
|
||||
public class ProxyError extends Error {
|
||||
/**
|
||||
* Thrown if there is an error getting a proxy.
|
||||
*
|
||||
* @param message The message to send.
|
||||
* @param cause The cause.
|
||||
*/
|
||||
public ProxyError(@NotNull final String message,
|
||||
@NotNull final Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown if there is an error getting a proxy.
|
||||
*
|
||||
* @param message The message to send.
|
||||
* @deprecated Proxy Errors should include a cause.
|
||||
*/
|
||||
@Deprecated
|
||||
public ProxyError(@NotNull final String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.willfp.eco.core.proxy.exceptions;
|
||||
|
||||
import com.willfp.eco.core.proxy.ProxyConstants;
|
||||
|
||||
/**
|
||||
* Server running an unsupported version.
|
||||
*/
|
||||
public class UnsupportedVersionError extends Error {
|
||||
/**
|
||||
* Thrown if the server is running an unsupported version.
|
||||
*/
|
||||
public UnsupportedVersionError() {
|
||||
super("You're running an unsupported server version: " + ProxyConstants.NMS_VERSION);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,30 @@
|
||||
package com.willfp.eco.core.proxy.exceptions;
|
||||
|
||||
import com.willfp.eco.core.proxy.ProxyConstants;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Error if the server is running an unsupported version.
|
||||
*
|
||||
* @deprecated Poorly named, exception when it's actually an error, contains doubly nested errors.
|
||||
*/
|
||||
@Deprecated(since = "6.24.0", forRemoval = true)
|
||||
public class UnsupportedVersionException extends ProxyError {
|
||||
/**
|
||||
* Thrown if the server is running an unsupported NMS version.
|
||||
*
|
||||
* @param message The message to send.
|
||||
* @deprecated Use the default constructor.
|
||||
*/
|
||||
@Deprecated(since = "6.24.0")
|
||||
public UnsupportedVersionException(@NotNull final String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown if the server is running an unsupported NMS version.
|
||||
*/
|
||||
public UnsupportedVersionException() {
|
||||
super("You're running an unsupported server version: " + ProxyConstants.NMS_VERSION, new IllegalStateException());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.items.Items;
|
||||
import com.willfp.eco.core.recipe.recipes.CraftingRecipe;
|
||||
import com.willfp.eco.core.recipe.recipes.ShapedCraftingRecipe;
|
||||
import com.willfp.eco.util.NamespacedKeyUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -16,7 +18,6 @@ import java.util.List;
|
||||
/**
|
||||
* Utility class to manage and register crafting recipes.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public final class Recipes {
|
||||
/**
|
||||
* Registry of all recipes.
|
||||
@@ -58,7 +59,10 @@ public final class Recipes {
|
||||
}
|
||||
|
||||
if (key.getKey().contains("_displayed")) {
|
||||
NamespacedKey otherKey = new NamespacedKey(key.getNamespace(), key.getKey().replace("_displayed", ""));
|
||||
NamespacedKey otherKey = NamespacedKeyUtils.create(
|
||||
key.getNamespace(),
|
||||
key.getKey().replace("_displayed", "")
|
||||
);
|
||||
|
||||
return RECIPES.get(otherKey);
|
||||
}
|
||||
@@ -92,6 +96,7 @@ public final class Recipes {
|
||||
* @param permission The permission.
|
||||
* @return The recipe.
|
||||
*/
|
||||
@Nullable
|
||||
public static CraftingRecipe createAndRegisterRecipe(@NotNull final EcoPlugin plugin,
|
||||
@NotNull final String key,
|
||||
@NotNull final ItemStack output,
|
||||
@@ -105,6 +110,12 @@ public final class Recipes {
|
||||
builder.setRecipePart(i, Items.lookup(recipeStrings.get(i)));
|
||||
}
|
||||
|
||||
if (builder.isAir()) {
|
||||
Bukkit.getLogger().warning("RECIPE ERROR! " + plugin.getName() + ":" + key + " consists only");
|
||||
Bukkit.getLogger().warning("of air or invalid items! Please change that or disable this recipe.");
|
||||
return null;
|
||||
}
|
||||
|
||||
ShapedCraftingRecipe recipe = builder.build();
|
||||
recipe.register();
|
||||
|
||||
|
||||
@@ -287,6 +287,20 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if recipe parts are all air.
|
||||
*
|
||||
* @return If recipe parts are all air.
|
||||
*/
|
||||
public boolean isAir() {
|
||||
for (TestableItem recipePart : this.recipeParts) {
|
||||
if (recipePart != null && !(recipePart instanceof EmptyTestableItem)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the recipe.
|
||||
*
|
||||
|
||||
@@ -7,7 +7,11 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* A requirement is a defined goal that a player must meet.
|
||||
*
|
||||
* @deprecated No typing, weak definitions, and not an API component. Shouldn't be in eco.
|
||||
*/
|
||||
@Deprecated(since = "6.24.0", forRemoval = true)
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
public abstract class Requirement {
|
||||
/**
|
||||
* Create a new requirement.
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
package com.willfp.eco.core.requirement;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Interface for internal requirement factory implementations.
|
||||
*
|
||||
* @deprecated See {@link Requirement}.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
@Deprecated(since = "6.24.0", forRemoval = true)
|
||||
@SuppressWarnings({"removal", "DeprecatedIsStillUsed"})
|
||||
public interface RequirementFactory {
|
||||
/**
|
||||
* Create a requirement.
|
||||
|
||||
@@ -5,7 +5,11 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Contains methods and fields pertaining to requirements.
|
||||
*
|
||||
* @deprecated See {@link Requirement}.
|
||||
*/
|
||||
@Deprecated(since = "6.24.0", forRemoval = true)
|
||||
@SuppressWarnings("removal")
|
||||
public final class Requirements {
|
||||
/**
|
||||
* Requires a player to have a permission.
|
||||
|
||||
@@ -26,11 +26,26 @@ public final class DurabilityUtils {
|
||||
* @param item The item to damage.
|
||||
* @param damage The amount of damage to deal.
|
||||
* @param slot The slot in the inventory of the item.
|
||||
* @deprecated The slot is not required.
|
||||
*/
|
||||
@Deprecated(since = "6.24.0")
|
||||
public static void damageItem(@NotNull final Player player,
|
||||
@NotNull final ItemStack item,
|
||||
final int damage,
|
||||
final int slot) {
|
||||
damageItem(player, item, damage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Damage an item in a player's inventory.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param item The item to damage.
|
||||
* @param damage The amount of damage to deal.
|
||||
*/
|
||||
public static void damageItem(@NotNull final Player player,
|
||||
@NotNull final ItemStack item,
|
||||
final int damage) {
|
||||
if (item.getItemMeta() == null) {
|
||||
return;
|
||||
}
|
||||
@@ -61,7 +76,7 @@ public final class DurabilityUtils {
|
||||
item.setItemMeta((ItemMeta) meta);
|
||||
PlayerItemBreakEvent event = new PlayerItemBreakEvent(player, item);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
player.getInventory().clear(slot);
|
||||
item.setType(Material.AIR);
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, SoundCategory.BLOCKS, 1, 1);
|
||||
} else {
|
||||
item.setItemMeta((ItemMeta) meta);
|
||||
@@ -69,6 +84,44 @@ public final class DurabilityUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Damage an item.
|
||||
*
|
||||
* @param item The item to damage.
|
||||
* @param damage The amount of damage to deal.
|
||||
*/
|
||||
public static void damageItem(@NotNull final ItemStack item,
|
||||
final int damage) {
|
||||
if (item.getItemMeta() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.getItemMeta().isUnbreakable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(item.getItemMeta() instanceof Damageable)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Special edge case
|
||||
if (item.getType() == Material.CARVED_PUMPKIN || item.getType() == Material.PLAYER_HEAD) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Damageable meta = (Damageable) item.getItemMeta();
|
||||
meta.setDamage(meta.getDamage() + damage);
|
||||
|
||||
if (meta.getDamage() >= item.getType().getMaxDurability()) {
|
||||
meta.setDamage(item.getType().getMaxDurability());
|
||||
item.setItemMeta((ItemMeta) meta);
|
||||
item.setType(Material.AIR);
|
||||
} else {
|
||||
item.setItemMeta((ItemMeta) meta);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Damage an item in a player's inventory without breaking it.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -17,7 +19,7 @@ public final class NamespacedKeyUtils {
|
||||
*/
|
||||
@NotNull
|
||||
public static NamespacedKey createEcoKey(@NotNull final String string) {
|
||||
return Objects.requireNonNull(NamespacedKey.fromString("eco:" + string));
|
||||
return NamespacedKeyUtils.create("eco", string);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,7 +32,45 @@ public final class NamespacedKeyUtils {
|
||||
@NotNull
|
||||
public static NamespacedKey create(@NotNull final String namespace,
|
||||
@NotNull final String key) {
|
||||
return Objects.requireNonNull(NamespacedKey.fromString(namespace + ":" + key));
|
||||
return Eco.getHandler().createNamespacedKey(
|
||||
namespace,
|
||||
key
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a NamespacedKey from a string.
|
||||
* <p>
|
||||
* Preferred over {@link NamespacedKey#fromString(String)} for performance reasons.
|
||||
*
|
||||
* @param string The string.
|
||||
* @return The key.
|
||||
*/
|
||||
@NotNull
|
||||
public static NamespacedKey fromString(@NotNull final String string) {
|
||||
return Objects.requireNonNull(NamespacedKeyUtils.fromStringOrNull(string));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a NamespacedKey from a string.
|
||||
* <p>
|
||||
* Preferred over {@link NamespacedKey#fromString(String)} for performance reasons.
|
||||
*
|
||||
* @param string The string.
|
||||
* @return The key, or null if not a key.
|
||||
*/
|
||||
@Nullable
|
||||
public static NamespacedKey fromStringOrNull(@NotNull final String string) {
|
||||
int index = string.indexOf(":");
|
||||
|
||||
if (index < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return NamespacedKeyUtils.create(
|
||||
string.substring(0, index),
|
||||
string.substring(index + 1)
|
||||
);
|
||||
}
|
||||
|
||||
private NamespacedKeyUtils() {
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
* Utilities / API methods for numbers.
|
||||
@@ -16,6 +21,11 @@ public final class NumberUtils {
|
||||
*/
|
||||
private static final double[] SIN_LOOKUP = new double[65536];
|
||||
|
||||
/**
|
||||
* Crunch handler.
|
||||
*/
|
||||
private static BiFunction<String, Player, Double> crunch = null;
|
||||
|
||||
/**
|
||||
* Set of roman numerals to look up.
|
||||
*/
|
||||
@@ -83,7 +93,9 @@ public final class NumberUtils {
|
||||
* @param toChange The value to test.
|
||||
* @param limit The maximum.
|
||||
* @return The new value.
|
||||
* @deprecated Pointless method.
|
||||
*/
|
||||
@Deprecated(since = "6.19.0")
|
||||
public static int equalIfOver(final int toChange,
|
||||
final int limit) {
|
||||
return Math.min(toChange, limit);
|
||||
@@ -95,7 +107,9 @@ public final class NumberUtils {
|
||||
* @param toChange The value to test.
|
||||
* @param limit The maximum.
|
||||
* @return The new value.
|
||||
* @deprecated Pointless method.
|
||||
*/
|
||||
@Deprecated(since = "6.19.0")
|
||||
public static double equalIfOver(final double toChange,
|
||||
final double limit) {
|
||||
return Math.min(toChange, limit);
|
||||
@@ -218,6 +232,39 @@ public final class NumberUtils {
|
||||
return formatted.endsWith("00") ? String.valueOf((int) toFormat) : formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate an expression.
|
||||
*
|
||||
* @param expression The expression.
|
||||
* @return The value of the expression, or zero if invalid.
|
||||
*/
|
||||
public static double evaluateExpression(@NotNull final String expression) {
|
||||
return evaluateExpression(expression, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate an expression with respect to a player (for placeholders).
|
||||
*
|
||||
* @param expression The expression.
|
||||
* @param player The player.
|
||||
* @return The value of the expression, or zero if invalid.
|
||||
*/
|
||||
public static double evaluateExpression(@NotNull final String expression,
|
||||
@Nullable final Player player) {
|
||||
return crunch.apply(expression, player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init crunch handler.
|
||||
*
|
||||
* @param handler The handler.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static void initCrunch(@NotNull final BiFunction<String, Player, Double> handler) {
|
||||
Validate.isTrue(crunch == null, "Already initialized!");
|
||||
crunch = handler;
|
||||
}
|
||||
|
||||
private NumberUtils() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.willfp.eco.core.Prerequisite;
|
||||
import com.willfp.eco.core.data.PlayerProfile;
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey;
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKeyType;
|
||||
import com.willfp.eco.core.integrations.anticheat.AnticheatManager;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
@@ -12,6 +13,8 @@ import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Utilities / API methods for players.
|
||||
*/
|
||||
@@ -107,6 +110,38 @@ public final class PlayerUtils {
|
||||
profile.write(PLAYER_NAME_KEY, player.getDisplayName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Run something with the player exempted.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param action The action.
|
||||
*/
|
||||
public static void runExempted(@NotNull final Player player,
|
||||
@NotNull final Consumer<Player> action) {
|
||||
try {
|
||||
AnticheatManager.exemptPlayer(player);
|
||||
action.accept(player);
|
||||
} finally {
|
||||
AnticheatManager.unexemptPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run something with the player exempted.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param action The action.
|
||||
*/
|
||||
public static void runExempted(@NotNull final Player player,
|
||||
@NotNull final Runnable action) {
|
||||
try {
|
||||
AnticheatManager.exemptPlayer(player);
|
||||
action.run();
|
||||
} finally {
|
||||
AnticheatManager.unexemptPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
private PlayerUtils() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
@@ -20,6 +22,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -66,6 +69,42 @@ public final class StringUtils {
|
||||
.emitLegacyHoverEvent()
|
||||
.build();
|
||||
|
||||
/**
|
||||
* String format cache.
|
||||
*/
|
||||
private static final LoadingCache<String, String> STRING_FORMAT_CACHE = Caffeine.newBuilder()
|
||||
.expireAfterAccess(10, TimeUnit.SECONDS)
|
||||
.build(StringUtils::processFormatting);
|
||||
|
||||
/**
|
||||
* Json -> Legacy Cache.
|
||||
*/
|
||||
private static final LoadingCache<String, String> JSON_TO_LEGACY = Caffeine.newBuilder()
|
||||
.expireAfterAccess(10, TimeUnit.SECONDS)
|
||||
.build(
|
||||
json -> {
|
||||
try {
|
||||
Component component = GSON_COMPONENT_SERIALIZER.deserialize(json);
|
||||
return LEGACY_COMPONENT_SERIALIZER.serialize(component);
|
||||
} catch (JsonSyntaxException e) {
|
||||
return json;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Legacy -> Json Cache.
|
||||
*/
|
||||
private static final LoadingCache<String, String> LEGACY_TO_JSON = Caffeine.newBuilder()
|
||||
.expireAfterAccess(10, TimeUnit.SECONDS)
|
||||
.build(
|
||||
legacy -> GSON_COMPONENT_SERIALIZER.serialize(
|
||||
Component.empty().decoration(TextDecoration.ITALIC, false).append(
|
||||
LEGACY_COMPONENT_SERIALIZER.deserialize(legacy)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Color map.
|
||||
*/
|
||||
@@ -272,6 +311,11 @@ public final class StringUtils {
|
||||
if (option == FormatOption.WITH_PLACEHOLDERS) {
|
||||
processedMessage = PlaceholderManager.translatePlaceholders(processedMessage, player);
|
||||
}
|
||||
return STRING_FORMAT_CACHE.get(processedMessage);
|
||||
}
|
||||
|
||||
private static String processFormatting(@NotNull final String message) {
|
||||
String processedMessage = message;
|
||||
processedMessage = ChatColor.translateAlternateColorCodes('&', processedMessage);
|
||||
processedMessage = translateGradients(processedMessage);
|
||||
processedMessage = translateHexColorCodes(processedMessage);
|
||||
@@ -423,11 +467,8 @@ public final class StringUtils {
|
||||
if (legacy == null) {
|
||||
processed = "";
|
||||
}
|
||||
return GSON_COMPONENT_SERIALIZER.serialize(
|
||||
Component.empty().decoration(TextDecoration.ITALIC, false).append(
|
||||
LEGACY_COMPONENT_SERIALIZER.deserialize(processed)
|
||||
)
|
||||
);
|
||||
|
||||
return LEGACY_TO_JSON.get(processed);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -442,12 +483,7 @@ public final class StringUtils {
|
||||
return "";
|
||||
}
|
||||
|
||||
try {
|
||||
Component component = GSON_COMPONENT_SERIALIZER.deserialize(json);
|
||||
return LEGACY_COMPONENT_SERIALIZER.serialize(component);
|
||||
} catch (JsonSyntaxException e) {
|
||||
return json;
|
||||
}
|
||||
return JSON_TO_LEGACY.get(json);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.willfp.eco.util;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.willfp.eco.core.Prerequisite;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
@@ -69,8 +68,10 @@ public final class TeamUtils {
|
||||
*
|
||||
* @param material The material to find the team from.
|
||||
* @return The team.
|
||||
* @deprecated Stupid method.
|
||||
*/
|
||||
@NotNull
|
||||
@Deprecated(since = "6.24.0")
|
||||
public static Team getMaterialColorTeam(@NotNull final Material material) {
|
||||
return fromChatColor(MATERIAL_COLORS.getOrDefault(material, ChatColor.WHITE));
|
||||
}
|
||||
@@ -89,17 +90,15 @@ public final class TeamUtils {
|
||||
MATERIAL_COLORS.put(Material.EMERALD_ORE, ChatColor.GREEN);
|
||||
MATERIAL_COLORS.put(Material.ANCIENT_DEBRIS, ChatColor.DARK_RED);
|
||||
|
||||
if (Prerequisite.HAS_1_17.isMet()) {
|
||||
MATERIAL_COLORS.put(Material.COPPER_ORE, ChatColor.GOLD);
|
||||
MATERIAL_COLORS.put(Material.DEEPSLATE_COPPER_ORE, ChatColor.GOLD);
|
||||
MATERIAL_COLORS.put(Material.DEEPSLATE_COAL_ORE, ChatColor.BLACK);
|
||||
MATERIAL_COLORS.put(Material.DEEPSLATE_IRON_ORE, ChatColor.GRAY);
|
||||
MATERIAL_COLORS.put(Material.DEEPSLATE_GOLD_ORE, ChatColor.YELLOW);
|
||||
MATERIAL_COLORS.put(Material.DEEPSLATE_LAPIS_ORE, ChatColor.BLUE);
|
||||
MATERIAL_COLORS.put(Material.DEEPSLATE_REDSTONE_ORE, ChatColor.RED);
|
||||
MATERIAL_COLORS.put(Material.DEEPSLATE_DIAMOND_ORE, ChatColor.AQUA);
|
||||
MATERIAL_COLORS.put(Material.DEEPSLATE_EMERALD_ORE, ChatColor.GREEN);
|
||||
}
|
||||
MATERIAL_COLORS.put(Material.COPPER_ORE, ChatColor.GOLD);
|
||||
MATERIAL_COLORS.put(Material.DEEPSLATE_COPPER_ORE, ChatColor.GOLD);
|
||||
MATERIAL_COLORS.put(Material.DEEPSLATE_COAL_ORE, ChatColor.BLACK);
|
||||
MATERIAL_COLORS.put(Material.DEEPSLATE_IRON_ORE, ChatColor.GRAY);
|
||||
MATERIAL_COLORS.put(Material.DEEPSLATE_GOLD_ORE, ChatColor.YELLOW);
|
||||
MATERIAL_COLORS.put(Material.DEEPSLATE_LAPIS_ORE, ChatColor.BLUE);
|
||||
MATERIAL_COLORS.put(Material.DEEPSLATE_REDSTONE_ORE, ChatColor.RED);
|
||||
MATERIAL_COLORS.put(Material.DEEPSLATE_DIAMOND_ORE, ChatColor.AQUA);
|
||||
MATERIAL_COLORS.put(Material.DEEPSLATE_EMERALD_ORE, ChatColor.GREEN);
|
||||
}
|
||||
|
||||
private TeamUtils() {
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
@file:JvmName("CommandHelperExtensions")
|
||||
|
||||
package com.willfp.eco.core.commands
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.command.CommandBase
|
||||
import com.willfp.eco.core.command.impl.PluginCommand
|
||||
import com.willfp.eco.core.command.impl.Subcommand
|
||||
import org.bukkit.command.CommandSender
|
||||
|
||||
/**
|
||||
* Helper class for creating commands with builders.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @param name The command name.
|
||||
* @param permission The permission.
|
||||
* @param playersOnly If only players should run the command.
|
||||
* @param executor The command executor.
|
||||
* @param tabCompleter The tab completer.
|
||||
*/
|
||||
class BuiltPluginCommand internal constructor(
|
||||
plugin: EcoPlugin,
|
||||
name: String,
|
||||
permission: String,
|
||||
playersOnly: Boolean = false,
|
||||
var executor: (CommandSender, List<String>) -> Unit,
|
||||
var tabCompleter: (CommandSender, List<String>) -> List<String>,
|
||||
) : PluginCommand(plugin, name, permission, playersOnly) {
|
||||
override fun onExecute(sender: CommandSender, args: List<String>) =
|
||||
executor(sender, args)
|
||||
|
||||
override fun tabComplete(sender: CommandSender, args: List<String>): List<String> =
|
||||
tabCompleter(sender, args)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper class for creating commands with builders.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @param name The command name.
|
||||
* @param permission The permission.
|
||||
* @param playersOnly If only players should run the command.
|
||||
* @param executor The command executor.
|
||||
* @param tabCompleter The tab completer.
|
||||
*/
|
||||
class BuiltSubcommand internal constructor(
|
||||
plugin: EcoPlugin,
|
||||
name: String,
|
||||
permission: String,
|
||||
playersOnly: Boolean = false,
|
||||
var executor: (CommandSender, List<String>) -> Unit,
|
||||
var tabCompleter: (CommandSender, List<String>) -> List<String>,
|
||||
) : Subcommand(plugin, name, permission, playersOnly) {
|
||||
internal constructor(
|
||||
parent: CommandBase,
|
||||
name: String,
|
||||
executor: (CommandSender, List<String>) -> Unit,
|
||||
tabCompleter: (CommandSender, List<String>) -> List<String>,
|
||||
) : this(parent.plugin, name, parent.permission, parent.isPlayersOnly, executor, tabCompleter)
|
||||
|
||||
override fun onExecute(sender: CommandSender, args: List<String>) =
|
||||
executor(sender, args)
|
||||
|
||||
override fun tabComplete(sender: CommandSender, args: List<String>): List<String> =
|
||||
tabCompleter(sender, args)
|
||||
}
|
||||
|
||||
/**
|
||||
* Kotlin builder for commands.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @param name The command name.
|
||||
* @param permission The permission.
|
||||
* @param playersOnly If only players should execute the command.
|
||||
* @param init The builder.
|
||||
*/
|
||||
fun command(
|
||||
plugin: EcoPlugin,
|
||||
name: String,
|
||||
permission: String,
|
||||
playersOnly: Boolean = false,
|
||||
init: BuiltPluginCommand.() -> Unit
|
||||
): PluginCommand {
|
||||
val command = BuiltPluginCommand(
|
||||
plugin,
|
||||
name,
|
||||
permission,
|
||||
playersOnly,
|
||||
{ _, _ -> },
|
||||
{ _, _ -> emptyList() }
|
||||
)
|
||||
init(command)
|
||||
return command
|
||||
}
|
||||
|
||||
/**
|
||||
* Kotlin builder for commands.
|
||||
*
|
||||
* @param name The command name.
|
||||
* @param permission The permission.
|
||||
* @param playersOnly If only players should execute the command.
|
||||
* @param init The builder.
|
||||
*/
|
||||
fun CommandBase.addSubcommand(
|
||||
name: String,
|
||||
permission: String,
|
||||
playersOnly: Boolean = false,
|
||||
init: BuiltSubcommand.() -> Unit
|
||||
): Subcommand {
|
||||
val command = BuiltSubcommand(
|
||||
this.plugin,
|
||||
name,
|
||||
permission,
|
||||
playersOnly,
|
||||
{ _, _ -> },
|
||||
{ _, _ -> emptyList() }
|
||||
)
|
||||
init(command)
|
||||
return command
|
||||
}
|
||||
|
||||
/**
|
||||
* Kotlin builder for commands.
|
||||
* Inherits plugin, permission, players only.
|
||||
*
|
||||
* @param name The command name.
|
||||
* @param init The builder.
|
||||
*/
|
||||
fun CommandBase.addSubcommand(
|
||||
name: String,
|
||||
init: BuiltSubcommand.() -> Unit
|
||||
): Subcommand {
|
||||
val command = BuiltSubcommand(
|
||||
this,
|
||||
name,
|
||||
{ _, _ -> },
|
||||
{ _, _ -> emptyList() }
|
||||
)
|
||||
init(command)
|
||||
return command
|
||||
}
|
||||
18
eco-api/src/main/kotlin/com/willfp/eco/core/data/Profiles.kt
Normal file
18
eco-api/src/main/kotlin/com/willfp/eco/core/data/Profiles.kt
Normal file
@@ -0,0 +1,18 @@
|
||||
@file:JvmName("ProfileExtensions")
|
||||
|
||||
package com.willfp.eco.core.data
|
||||
|
||||
import org.bukkit.OfflinePlayer
|
||||
import org.bukkit.Server
|
||||
|
||||
/**
|
||||
* @see PlayerProfile.load
|
||||
*/
|
||||
val OfflinePlayer.profile: PlayerProfile
|
||||
get() = PlayerProfile.load(this)
|
||||
|
||||
/**
|
||||
* @see ServerProfile.load
|
||||
*/
|
||||
val Server.profile: ServerProfile
|
||||
get() = ServerProfile.load()
|
||||
@@ -0,0 +1,11 @@
|
||||
@file:JvmName("FastItemStackExtensions")
|
||||
|
||||
package com.willfp.eco.core.fast
|
||||
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
/**
|
||||
* @see FastItemStack.wrap
|
||||
*/
|
||||
fun ItemStack.fast(): FastItemStack =
|
||||
FastItemStack.wrap(this)
|
||||
105
eco-api/src/main/kotlin/com/willfp/eco/core/gui/GUIHelpers.kt
Normal file
105
eco-api/src/main/kotlin/com/willfp/eco/core/gui/GUIHelpers.kt
Normal file
@@ -0,0 +1,105 @@
|
||||
@file:JvmName("GUIHelperExtensions")
|
||||
|
||||
package com.willfp.eco.core.gui
|
||||
|
||||
import com.willfp.eco.core.gui.menu.Menu
|
||||
import com.willfp.eco.core.gui.menu.MenuBuilder
|
||||
import com.willfp.eco.core.gui.slot.Slot
|
||||
import com.willfp.eco.core.gui.slot.SlotBuilder
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.inventory.InventoryClickEvent
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
/**
|
||||
* @see SlotBuilder.onLeftClick
|
||||
*/
|
||||
fun SlotBuilder.onLeftClick(action: (InventoryClickEvent, Slot, Menu) -> Unit): SlotBuilder =
|
||||
this.onLeftClick { a, b, c -> action(a, b, c) }
|
||||
|
||||
/**
|
||||
* @see SlotBuilder.onRightClick
|
||||
*/
|
||||
fun SlotBuilder.onRightClick(action: (InventoryClickEvent, Slot, Menu) -> Unit): SlotBuilder =
|
||||
this.onRightClick { a, b, c -> action(a, b, c) }
|
||||
|
||||
/**
|
||||
* @see SlotBuilder.onShiftLeftClick
|
||||
*/
|
||||
fun SlotBuilder.onShiftLeftClick(action: (InventoryClickEvent, Slot, Menu) -> Unit): SlotBuilder =
|
||||
this.onShiftLeftClick { a, b, c -> action(a, b, c) }
|
||||
|
||||
/**
|
||||
* @see SlotBuilder.onShiftRightClick
|
||||
*/
|
||||
fun SlotBuilder.onShiftRightClick(action: (InventoryClickEvent, Slot, Menu) -> Unit): SlotBuilder =
|
||||
this.onShiftRightClick { a, b, c -> action(a, b, c) }
|
||||
|
||||
/**
|
||||
* @see SlotBuilder.onShiftRightClick
|
||||
*/
|
||||
fun SlotBuilder.onMiddleClick(action: (InventoryClickEvent, Slot, Menu) -> Unit): SlotBuilder =
|
||||
this.onMiddleClick { a, b, c -> action(a, b, c) }
|
||||
|
||||
/**
|
||||
* @see SlotBuilder.setModifier
|
||||
* @deprecated Use SlotUpdater instead.
|
||||
*/
|
||||
@Deprecated("Use SlotUpdater instead")
|
||||
@Suppress("DEPRECATION")
|
||||
fun SlotBuilder.setModifier(action: (Player, Menu, ItemStack) -> Unit): SlotBuilder =
|
||||
this.setUpdater { a, b, c -> c.apply { action(a, b, c) } }
|
||||
|
||||
/**
|
||||
* @see SlotBuilder.setUpdater
|
||||
*/
|
||||
fun SlotBuilder.setUpdater(action: (Player, Menu, ItemStack) -> ItemStack): SlotBuilder =
|
||||
this.setUpdater { a, b, c -> action(a, b, c) }
|
||||
|
||||
/**
|
||||
* Kotlin builder for slots.
|
||||
*/
|
||||
fun slot(
|
||||
item: ItemStack,
|
||||
init: SlotBuilder.() -> Unit
|
||||
): Slot {
|
||||
val builder = Slot.builder(item)
|
||||
init(builder)
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
/**
|
||||
* Kotlin builder for slots.
|
||||
*/
|
||||
fun slot(
|
||||
provider: (Player, Menu) -> ItemStack,
|
||||
init: SlotBuilder.() -> Unit
|
||||
): Slot {
|
||||
val builder = Slot.builder { a, b -> provider(a, b) }
|
||||
init(builder)
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
/**
|
||||
* @see MenuBuilder.onClose
|
||||
*/
|
||||
fun MenuBuilder.onClose(action: (InventoryCloseEvent, Menu) -> Unit): MenuBuilder =
|
||||
this.onClose { a, b -> action(a, b) }
|
||||
|
||||
/**
|
||||
* @see MenuBuilder.modify
|
||||
*/
|
||||
fun MenuBuilder.modify(modifier: (MenuBuilder) -> Unit): MenuBuilder =
|
||||
this.modfiy { modifier(it) }
|
||||
|
||||
/**
|
||||
* Kotlin builder for menus.
|
||||
*/
|
||||
fun menu(
|
||||
rows: Int,
|
||||
init: MenuBuilder.() -> Unit
|
||||
): Menu {
|
||||
val builder = Menu.builder(rows)
|
||||
init(builder)
|
||||
return builder.build()
|
||||
}
|
||||
12
eco-api/src/main/kotlin/com/willfp/eco/util/ArrowUtils.kt
Normal file
12
eco-api/src/main/kotlin/com/willfp/eco/util/ArrowUtils.kt
Normal file
@@ -0,0 +1,12 @@
|
||||
@file:JvmName("ArrowUtilsExtensions")
|
||||
|
||||
package com.willfp.eco.util
|
||||
|
||||
import org.bukkit.entity.Arrow
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
/**
|
||||
* @see ArrowUtils.getBow
|
||||
*/
|
||||
val Arrow.bow: ItemStack?
|
||||
get() = ArrowUtils.getBow(this)
|
||||
11
eco-api/src/main/kotlin/com/willfp/eco/util/BlockUtils.kt
Normal file
11
eco-api/src/main/kotlin/com/willfp/eco/util/BlockUtils.kt
Normal file
@@ -0,0 +1,11 @@
|
||||
@file:JvmName("BlockUtilsExtensions")
|
||||
|
||||
package com.willfp.eco.util
|
||||
|
||||
import org.bukkit.block.Block
|
||||
|
||||
/**
|
||||
* @see ArrowUtils.getBow
|
||||
*/
|
||||
val Block.isPlayerPlaced: Boolean
|
||||
get() = BlockUtils.isPlayerPlaced(this)
|
||||
@@ -0,0 +1,18 @@
|
||||
@file:JvmName("DurabilityUtilsExtensions")
|
||||
|
||||
package com.willfp.eco.util
|
||||
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
/**
|
||||
* @see DurabilityUtils.damageItem
|
||||
*/
|
||||
fun ItemStack.damage(damage: Int) =
|
||||
DurabilityUtils.damageItem(this, damage)
|
||||
|
||||
/**
|
||||
* @see DurabilityUtils.damageItem
|
||||
*/
|
||||
fun ItemStack.damage(damage: Int, player: Player) =
|
||||
DurabilityUtils.damageItem(player, this, damage)
|
||||
21
eco-api/src/main/kotlin/com/willfp/eco/util/ListUtils.kt
Normal file
21
eco-api/src/main/kotlin/com/willfp/eco/util/ListUtils.kt
Normal file
@@ -0,0 +1,21 @@
|
||||
@file:JvmName("ListUtilsExtensions")
|
||||
|
||||
package com.willfp.eco.util
|
||||
|
||||
/**
|
||||
* @see ListUtils.listToFrequencyMap
|
||||
*/
|
||||
fun <T> List<T>.toFrequencyMap(): Map<T, Int> =
|
||||
ListUtils.listToFrequencyMap(this)
|
||||
|
||||
/**
|
||||
* @see ListUtils.containsIgnoreCase
|
||||
*/
|
||||
fun Iterable<String>.containsIgnoreCase(element: String): Boolean =
|
||||
ListUtils.containsIgnoreCase(this, element)
|
||||
|
||||
/**
|
||||
* @see ListUtils.create2DList
|
||||
*/
|
||||
fun <T> create2DList(rows: Int, columns: Int): MutableList<MutableList<T>> =
|
||||
ListUtils.create2DList(rows, columns)
|
||||
@@ -0,0 +1,29 @@
|
||||
@file:JvmName("NamespacedKeyUtilsExtensions")
|
||||
|
||||
package com.willfp.eco.util
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
|
||||
/**
|
||||
* @see NamespacedKeyUtils.fromString
|
||||
*/
|
||||
fun namespacedKeyOf(string: String) =
|
||||
NamespacedKeyUtils.fromString(string)
|
||||
|
||||
/**
|
||||
* @see NamespacedKeyUtils.fromString
|
||||
*/
|
||||
fun safeNamespacedKeyOf(string: String) =
|
||||
NamespacedKeyUtils.fromStringOrNull(string)
|
||||
|
||||
/**
|
||||
* @see NamespacedKeyUtils.create
|
||||
*/
|
||||
fun namespacedKeyOf(namespace: String, key: String) =
|
||||
NamespacedKeyUtils.create(namespace, key)
|
||||
|
||||
/**
|
||||
* @see EcoPlugin.namespacedKeyFactory
|
||||
*/
|
||||
fun namespacedKeyOf(plugin: EcoPlugin, key: String) =
|
||||
plugin.namespacedKeyFactory.create(key)
|
||||
@@ -0,0 +1,9 @@
|
||||
@file:JvmName("NumberUtilsExtensions")
|
||||
|
||||
package com.willfp.eco.util
|
||||
|
||||
/**
|
||||
* @see NumberUtils.toNumeral
|
||||
*/
|
||||
fun Number.toNumeral(): String =
|
||||
NumberUtils.toNumeral(this.toInt())
|
||||
32
eco-api/src/main/kotlin/com/willfp/eco/util/PlayerUtils.kt
Normal file
32
eco-api/src/main/kotlin/com/willfp/eco/util/PlayerUtils.kt
Normal file
@@ -0,0 +1,32 @@
|
||||
@file:JvmName("PlayerUtilsExtensions")
|
||||
|
||||
package com.willfp.eco.util
|
||||
|
||||
import net.kyori.adventure.audience.Audience
|
||||
import org.bukkit.OfflinePlayer
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
/**
|
||||
* @see PlayerUtils.getSavedDisplayName
|
||||
*/
|
||||
val OfflinePlayer.savedDisplayName: String
|
||||
get() = PlayerUtils.getSavedDisplayName(this)
|
||||
|
||||
/**
|
||||
* @see PlayerUtils.getAudience
|
||||
*/
|
||||
fun Player.asAudience(): Audience =
|
||||
PlayerUtils.getAudience(this)
|
||||
|
||||
/**
|
||||
* @see PlayerUtils.getAudience
|
||||
*/
|
||||
fun CommandSender.asAudience(): Audience =
|
||||
PlayerUtils.getAudience(this)
|
||||
|
||||
/**
|
||||
* @see PlayerUtils.runExempted
|
||||
*/
|
||||
fun Player.runExempted(action: () -> Unit) =
|
||||
PlayerUtils.runExempted(this, action)
|
||||
11
eco-api/src/main/kotlin/com/willfp/eco/util/PotionUtils.kt
Normal file
11
eco-api/src/main/kotlin/com/willfp/eco/util/PotionUtils.kt
Normal file
@@ -0,0 +1,11 @@
|
||||
@file:JvmName("PotionUtilsExtensions")
|
||||
|
||||
package com.willfp.eco.util
|
||||
|
||||
import org.bukkit.potion.PotionData
|
||||
|
||||
/**
|
||||
* @see PotionData.duration
|
||||
*/
|
||||
val PotionData.duration: Int
|
||||
get() = PotionUtils.getDuration(this)
|
||||
11
eco-api/src/main/kotlin/com/willfp/eco/util/ServerUtils.kt
Normal file
11
eco-api/src/main/kotlin/com/willfp/eco/util/ServerUtils.kt
Normal file
@@ -0,0 +1,11 @@
|
||||
@file:JvmName("ServerUtilsExtensions")
|
||||
|
||||
package com.willfp.eco.util
|
||||
|
||||
import org.bukkit.Server
|
||||
|
||||
/**
|
||||
* @see ServerUtils.getTps
|
||||
*/
|
||||
val Server.tps: Double
|
||||
get() = ServerUtils.getTps()
|
||||
17
eco-api/src/main/kotlin/com/willfp/eco/util/SkullUtils.kt
Normal file
17
eco-api/src/main/kotlin/com/willfp/eco/util/SkullUtils.kt
Normal file
@@ -0,0 +1,17 @@
|
||||
@file:JvmName("SkullUtilsExtensions")
|
||||
|
||||
package com.willfp.eco.util
|
||||
|
||||
import org.bukkit.inventory.meta.SkullMeta
|
||||
|
||||
/**
|
||||
* @see SkullUtils.getSkullTexture
|
||||
* @see SkullUtils.setSkullTexture
|
||||
*/
|
||||
var SkullMeta.texture: String?
|
||||
get() = SkullUtils.getSkullTexture(this)
|
||||
set(value) {
|
||||
if (value != null) {
|
||||
SkullUtils.setSkullTexture(this, value)
|
||||
}
|
||||
}
|
||||
42
eco-api/src/main/kotlin/com/willfp/eco/util/StringUtils.kt
Normal file
42
eco-api/src/main/kotlin/com/willfp/eco/util/StringUtils.kt
Normal file
@@ -0,0 +1,42 @@
|
||||
@file:JvmName("StringUtilsExtensions")
|
||||
|
||||
package com.willfp.eco.util
|
||||
|
||||
import net.kyori.adventure.text.Component
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
/**
|
||||
* @see StringUtils.toComponent
|
||||
*/
|
||||
fun String.toComponent(): Component =
|
||||
StringUtils.toComponent(this)
|
||||
|
||||
/**
|
||||
* @see StringUtils.toLegacy
|
||||
*/
|
||||
fun Component.toLegacy(): String =
|
||||
StringUtils.toLegacy(this)
|
||||
|
||||
/**
|
||||
* @see StringUtils.format
|
||||
*/
|
||||
fun String.formatEco(
|
||||
player: Player? = null,
|
||||
formatPlaceholders: Boolean = false
|
||||
) = StringUtils.format(
|
||||
this,
|
||||
player,
|
||||
if (formatPlaceholders) StringUtils.FormatOption.WITH_PLACEHOLDERS else StringUtils.FormatOption.WITHOUT_PLACEHOLDERS
|
||||
)
|
||||
|
||||
/**
|
||||
* @see StringUtils.formatList
|
||||
*/
|
||||
fun List<String>.formatEco(
|
||||
player: Player? = null,
|
||||
formatPlaceholders: Boolean = false
|
||||
): List<String> = StringUtils.formatList(
|
||||
this,
|
||||
player,
|
||||
if (formatPlaceholders) StringUtils.FormatOption.WITH_PLACEHOLDERS else StringUtils.FormatOption.WITHOUT_PLACEHOLDERS
|
||||
)
|
||||
17
eco-api/src/main/kotlin/com/willfp/eco/util/VectorUtils.kt
Normal file
17
eco-api/src/main/kotlin/com/willfp/eco/util/VectorUtils.kt
Normal file
@@ -0,0 +1,17 @@
|
||||
@file:JvmName("VectorUtilsExtensions")
|
||||
|
||||
package com.willfp.eco.util
|
||||
|
||||
import org.bukkit.util.Vector
|
||||
|
||||
/**
|
||||
* @see VectorUtils.isFinite
|
||||
*/
|
||||
val Vector.isFinite: Boolean
|
||||
get() = VectorUtils.isFinite(this)
|
||||
|
||||
/**
|
||||
* @see VectorUtils.simplifyVector
|
||||
*/
|
||||
fun Vector.simplify(): Vector =
|
||||
VectorUtils.simplifyVector(this)
|
||||
@@ -1,29 +1,8 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0"
|
||||
}
|
||||
}
|
||||
|
||||
group 'com.willfp'
|
||||
version rootProject.version
|
||||
|
||||
subprojects {
|
||||
apply plugin: "kotlin"
|
||||
|
||||
dependencies {
|
||||
compileOnly project(":eco-api")
|
||||
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.6.0'
|
||||
}
|
||||
|
||||
compileKotlin {
|
||||
kotlinOptions {
|
||||
jvmTarget = "17"
|
||||
}
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,5 +7,5 @@ dependencies {
|
||||
compileOnly 'org.reflections:reflections:0.9.12'
|
||||
compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
|
||||
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
||||
compileOnly 'com.google.guava:guava:31.0.1-jre'
|
||||
compileOnly 'org.objenesis:objenesis:3.2'
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.willfp.eco.internal
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.PluginProps
|
||||
import com.willfp.eco.core.config.TransientConfig
|
||||
import com.willfp.eco.core.config.interfaces.Config
|
||||
|
||||
object EcoPropsParser : PluginProps.PropsParser<Config> {
|
||||
override fun parseFrom(config: Config): PluginProps {
|
||||
val resourceId = config.getIntOrNull("resource-id") ?: 0
|
||||
val bStatsId = config.getIntOrNull("bstats-id") ?: 0
|
||||
val proxyPackage = config.getStringOrNull("proxy-package") ?: ""
|
||||
val color = config.getStringOrNull("color") ?: "&f"
|
||||
val supportsExtensions = config.getBoolOrNull("supports-extensions") ?: false
|
||||
|
||||
return blankProps.apply {
|
||||
this.resourceId = resourceId
|
||||
this.bStatsId = bStatsId
|
||||
this.proxyPackage = proxyPackage
|
||||
this.color = color
|
||||
this.isSupportingExtensions = supportsExtensions
|
||||
}
|
||||
}
|
||||
|
||||
fun parseForPlugin(plugin: Class<out EcoPlugin>): PluginProps {
|
||||
if (!PluginProps.hasParserFor(Config::class.java)) {
|
||||
PluginProps.registerParser(Config::class.java, this)
|
||||
}
|
||||
|
||||
return PluginProps.parse(
|
||||
TransientConfig(plugin.getResourceAsStream("/eco.yml")),
|
||||
Config::class.java
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import com.willfp.eco.internal.config.yaml.EcoYamlConfigSection
|
||||
import org.bukkit.configuration.file.YamlConfiguration
|
||||
import java.io.StringReader
|
||||
|
||||
class EcoConfigFactory : ConfigFactory {
|
||||
object EcoConfigFactory : ConfigFactory {
|
||||
override fun createConfig(config: YamlConfiguration): Config {
|
||||
return EcoYamlConfigSection(config)
|
||||
}
|
||||
|
||||
@@ -24,11 +24,7 @@ open class EcoLoadableJSONConfig(
|
||||
private val name: String = "$configName.json"
|
||||
|
||||
fun reloadFromFile() {
|
||||
try {
|
||||
init(configFile)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
runCatching { init(configFile) }.onFailure { it.printStackTrace() }
|
||||
}
|
||||
|
||||
final override fun createFile() {
|
||||
@@ -94,11 +90,7 @@ open class EcoLoadableJSONConfig(
|
||||
createFile()
|
||||
}
|
||||
configFile = File(directory, name)
|
||||
try {
|
||||
init(configFile)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
init(configFile)
|
||||
plugin.configHandler.addConfig(this)
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
package com.willfp.eco.internal.config.json
|
||||
|
||||
import com.willfp.eco.core.PluginLike
|
||||
import org.bukkit.configuration.InvalidConfigurationException
|
||||
import org.bukkit.configuration.file.YamlConfiguration
|
||||
import java.io.BufferedReader
|
||||
import java.io.IOException
|
||||
import java.io.InputStreamReader
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
@@ -21,48 +19,36 @@ open class EcoUpdatableJSONConfig(
|
||||
|
||||
fun update() {
|
||||
super.clearCache()
|
||||
try {
|
||||
this.init(configFile)
|
||||
val newConfig = configInJar
|
||||
if (newConfig.getKeys(true) == this.getKeys(true)) {
|
||||
return
|
||||
}
|
||||
newConfig.getKeys(true).forEach { key: String ->
|
||||
if (!this.getKeys(true).contains(key)) {
|
||||
if (updateBlacklist.stream().noneMatch { s: String -> key.contains(s) }) {
|
||||
this.set(key, newConfig[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removeUnused) {
|
||||
this.getKeys(true).forEach { s ->
|
||||
if (!newConfig.getKeys(true).contains(s)) {
|
||||
if (updateBlacklist.stream().noneMatch(s::contains)) {
|
||||
this.set(s, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.save()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: InvalidConfigurationException) {
|
||||
e.printStackTrace()
|
||||
this.init(configFile)
|
||||
val newConfig = configInJar ?: return
|
||||
if (newConfig.getKeys(true) == this.getKeys(true)) {
|
||||
return
|
||||
}
|
||||
newConfig.getKeys(true).forEach { key: String ->
|
||||
if (!this.getKeys(true).contains(key)) {
|
||||
if (updateBlacklist.stream().noneMatch { s: String -> key.contains(s) }) {
|
||||
this.set(key, newConfig[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removeUnused) {
|
||||
this.getKeys(true).forEach { s ->
|
||||
if (!newConfig.getKeys(true).contains(s)) {
|
||||
if (updateBlacklist.stream().noneMatch(s::contains)) {
|
||||
this.set(s, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.save()
|
||||
}
|
||||
|
||||
private val configInJar: YamlConfiguration
|
||||
private val configInJar: YamlConfiguration?
|
||||
get() {
|
||||
val newIn = this.source.getResourceAsStream(resourcePath) ?: throw NullPointerException("$name is null?")
|
||||
val newIn = this.source.getResourceAsStream(resourcePath) ?: return null
|
||||
val reader = BufferedReader(InputStreamReader(newIn, StandardCharsets.UTF_8))
|
||||
val newConfig = YamlConfiguration()
|
||||
try {
|
||||
newConfig.load(reader)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: InvalidConfigurationException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
newConfig.load(reader)
|
||||
return newConfig
|
||||
}
|
||||
|
||||
|
||||
@@ -24,15 +24,15 @@ class EcoConfigHandler(
|
||||
|
||||
override fun callUpdate() {
|
||||
for (method in reflections.getMethodsAnnotatedWith(ConfigUpdater::class.java)) {
|
||||
try {
|
||||
kotlin.runCatching {
|
||||
when (method.parameterCount) {
|
||||
0 -> method.invoke(null)
|
||||
1 -> method.invoke(null, this.plugin)
|
||||
else -> throw InvalidUpdateMethodException("Update method must have 0 parameters or a plugin parameter.")
|
||||
}
|
||||
} catch (e: ReflectiveOperationException) {
|
||||
e.printStackTrace()
|
||||
throw InvalidUpdateMethodException("Update method generated an exception")
|
||||
}.onFailure {
|
||||
it.printStackTrace()
|
||||
plugin.logger.severe("Update method ${method.toGenericString()} generated an exception")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ package com.willfp.eco.internal.config.yaml
|
||||
import com.willfp.eco.core.PluginLike
|
||||
import com.willfp.eco.core.config.interfaces.LoadableConfig
|
||||
import com.willfp.eco.core.config.interfaces.WrappedYamlConfiguration
|
||||
import org.bukkit.configuration.InvalidConfigurationException
|
||||
import org.bukkit.configuration.file.YamlConfiguration
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
@@ -23,13 +22,7 @@ open class EcoLoadableYamlConfig(
|
||||
private val name: String = "$configName.yml"
|
||||
|
||||
fun reloadFromFile() {
|
||||
try {
|
||||
handle.load(getConfigFile())
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: InvalidConfigurationException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
handle.load(getConfigFile())
|
||||
}
|
||||
|
||||
final override fun createFile() {
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package com.willfp.eco.internal.config.yaml
|
||||
|
||||
import com.willfp.eco.core.PluginLike
|
||||
import org.bukkit.configuration.InvalidConfigurationException
|
||||
import org.bukkit.configuration.file.YamlConfiguration
|
||||
import java.io.BufferedReader
|
||||
import java.io.IOException
|
||||
import java.io.InputStreamReader
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
@@ -21,48 +19,36 @@ class EcoUpdatableYamlConfig(
|
||||
|
||||
fun update() {
|
||||
super.clearCache()
|
||||
try {
|
||||
this.handle.load(configFile)
|
||||
val newConfig = configInJar
|
||||
if (newConfig.getKeys(true) == this.handle.getKeys(true)) {
|
||||
return
|
||||
}
|
||||
newConfig.getKeys(true).forEach { key ->
|
||||
if (!this.handle.getKeys(true).contains(key)) {
|
||||
if (updateBlacklist.stream().noneMatch { key.contains(it) }) {
|
||||
this.handle.set(key, newConfig[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removeUnused) {
|
||||
this.handle.getKeys(true).forEach { s ->
|
||||
if (!newConfig.getKeys(true).contains(s)) {
|
||||
if (updateBlacklist.stream().noneMatch(s::contains)) {
|
||||
this.handle.set(s, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.handle.save(configFile)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: InvalidConfigurationException) {
|
||||
e.printStackTrace()
|
||||
this.handle.load(configFile)
|
||||
val newConfig = configInJar ?: return
|
||||
if (newConfig.getKeys(true) == this.handle.getKeys(true)) {
|
||||
return
|
||||
}
|
||||
newConfig.getKeys(true).forEach { key ->
|
||||
if (!this.handle.getKeys(true).contains(key)) {
|
||||
if (updateBlacklist.stream().noneMatch { key.contains(it) }) {
|
||||
this.handle.set(key, newConfig[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removeUnused) {
|
||||
this.handle.getKeys(true).forEach { s ->
|
||||
if (!newConfig.getKeys(true).contains(s)) {
|
||||
if (updateBlacklist.stream().noneMatch(s::contains)) {
|
||||
this.handle.set(s, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.handle.save(configFile)
|
||||
}
|
||||
|
||||
private val configInJar: YamlConfiguration
|
||||
private val configInJar: YamlConfiguration?
|
||||
get() {
|
||||
val newIn = source.getResourceAsStream(resourcePath) ?: throw NullPointerException("$name is null?")
|
||||
val newIn = source.getResourceAsStream(resourcePath) ?: return null
|
||||
val reader = BufferedReader(InputStreamReader(newIn, StandardCharsets.UTF_8))
|
||||
val newConfig = YamlConfiguration()
|
||||
try {
|
||||
newConfig.load(reader)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: InvalidConfigurationException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
newConfig.load(reader)
|
||||
return newConfig
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.willfp.eco.core.display.Display
|
||||
import com.willfp.eco.core.display.DisplayHandler
|
||||
import com.willfp.eco.core.display.DisplayModule
|
||||
import com.willfp.eco.core.display.DisplayPriority
|
||||
import com.willfp.eco.core.fast.FastItemStack
|
||||
import com.willfp.eco.core.fast.fast
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.inventory.ItemStack
|
||||
@@ -60,7 +60,7 @@ class EcoDisplayHandler(plugin: EcoPlugin) : DisplayHandler {
|
||||
Display.unfinalize(itemStack)
|
||||
}
|
||||
|
||||
val fast = FastItemStack.wrap(itemStack)
|
||||
val fast = itemStack.fast()
|
||||
val lore = fast.lore
|
||||
|
||||
if (lore.isNotEmpty() && lore.removeIf { line: String ->
|
||||
|
||||
@@ -10,7 +10,6 @@ import org.bukkit.Material
|
||||
import org.bukkit.entity.EntityType
|
||||
import org.bukkit.entity.ExperienceOrb
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.player.PlayerExpChangeEvent
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.util.Vector
|
||||
|
||||
@@ -73,12 +72,10 @@ open class EcoDropQueue(val player: Player) : InternalDropQueue {
|
||||
world.dropItem(location, drop!!).velocity = Vector()
|
||||
}
|
||||
if (xp > 0) {
|
||||
val event = PlayerExpChangeEvent(player, xp)
|
||||
Bukkit.getPluginManager().callEvent(event)
|
||||
val orb =
|
||||
world.spawnEntity(player.location.add(0.0, 0.2, 0.0), EntityType.EXPERIENCE_ORB) as ExperienceOrb
|
||||
orb.velocity = Vector(0, 0, 0)
|
||||
orb.experience = event.amount
|
||||
orb.experience = xp
|
||||
}
|
||||
} else {
|
||||
for (drop in items) {
|
||||
@@ -94,4 +91,4 @@ open class EcoDropQueue(val player: Player) : InternalDropQueue {
|
||||
init {
|
||||
location = player.location
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.willfp.eco.internal.entities
|
||||
|
||||
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||
import org.bukkit.entity.Animals
|
||||
import org.bukkit.entity.Ageable
|
||||
|
||||
class EntityArgParserAdult : EntityArgParser {
|
||||
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||
@@ -20,14 +20,14 @@ class EntityArgParserAdult : EntityArgParser {
|
||||
|
||||
return EntityArgParseResult(
|
||||
{
|
||||
if (it !is Animals) {
|
||||
if (it !is Ageable) {
|
||||
return@EntityArgParseResult false
|
||||
}
|
||||
|
||||
it.isAdult
|
||||
},
|
||||
{
|
||||
(it as? Animals)?.setAdult()
|
||||
(it as? Ageable)?.setAdult()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.willfp.eco.internal.entities
|
||||
|
||||
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||
import org.bukkit.entity.Animals
|
||||
import org.bukkit.entity.Ageable
|
||||
|
||||
class EntityArgParserBaby : EntityArgParser {
|
||||
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||
@@ -20,14 +20,14 @@ class EntityArgParserBaby : EntityArgParser {
|
||||
|
||||
return EntityArgParseResult(
|
||||
{
|
||||
if (it !is Animals) {
|
||||
if (it !is Ageable) {
|
||||
return@EntityArgParseResult false
|
||||
}
|
||||
|
||||
!it.isAdult
|
||||
},
|
||||
{
|
||||
(it as? Animals)?.setBaby()
|
||||
(it as? Ageable)?.setBaby()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.willfp.eco.internal.entities
|
||||
|
||||
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||
import com.willfp.eco.core.items.Items
|
||||
import com.willfp.eco.core.items.TestableItem
|
||||
import org.bukkit.entity.LivingEntity
|
||||
import org.bukkit.inventory.EquipmentSlot
|
||||
|
||||
class EntityArgParserEquipment : EntityArgParser {
|
||||
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||
val equipment = mutableMapOf<EquipmentSlot, TestableItem>()
|
||||
|
||||
for (arg in args) {
|
||||
val argSplit = arg.split(":")
|
||||
for (slot in EquipmentSlot.values()) {
|
||||
if (!argSplit[0].equals(slot.name, ignoreCase = true)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (argSplit.size < 2) {
|
||||
continue
|
||||
}
|
||||
|
||||
equipment[slot] = Items.lookup(argSplit[1])
|
||||
}
|
||||
}
|
||||
|
||||
if (equipment.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
|
||||
return EntityArgParseResult(
|
||||
{
|
||||
if (it !is LivingEntity) {
|
||||
return@EntityArgParseResult false
|
||||
}
|
||||
|
||||
val entityEquipment = it.equipment ?: return@EntityArgParseResult false
|
||||
|
||||
for ((slot, item) in equipment) {
|
||||
if (!item.matches(entityEquipment.getItem(slot))) {
|
||||
return@EntityArgParseResult false
|
||||
}
|
||||
}
|
||||
|
||||
return@EntityArgParseResult true
|
||||
},
|
||||
{
|
||||
if (it !is LivingEntity) {
|
||||
return@EntityArgParseResult
|
||||
}
|
||||
|
||||
val entityEquipment = it.equipment ?: return@EntityArgParseResult
|
||||
|
||||
for ((slot, item) in equipment) {
|
||||
entityEquipment.setItem(slot, item.item, false)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.willfp.eco.internal.entities
|
||||
|
||||
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||
|
||||
class EntityArgParserSilent : EntityArgParser {
|
||||
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||
var silent = false
|
||||
|
||||
for (arg in args) {
|
||||
if (arg.equals("silent", true)) {
|
||||
silent = true
|
||||
}
|
||||
}
|
||||
|
||||
if (!silent) {
|
||||
return null
|
||||
}
|
||||
|
||||
return EntityArgParseResult(
|
||||
{
|
||||
it.isSilent
|
||||
},
|
||||
{
|
||||
it.isSilent = true
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.willfp.eco.internal.extensions
|
||||
|
||||
import com.google.common.collect.ImmutableSet
|
||||
import com.willfp.eco.core.Eco
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.config.TransientConfig
|
||||
import com.willfp.eco.core.extensions.Extension
|
||||
@@ -10,8 +11,6 @@ import com.willfp.eco.core.extensions.MalformedExtensionException
|
||||
import org.bukkit.configuration.file.YamlConfiguration
|
||||
import java.io.File
|
||||
import java.io.InputStreamReader
|
||||
import java.net.MalformedURLException
|
||||
import java.net.URL
|
||||
import java.net.URLClassLoader
|
||||
|
||||
class EcoExtensionLoader(
|
||||
@@ -32,23 +31,18 @@ class EcoExtensionLoader(
|
||||
continue
|
||||
}
|
||||
|
||||
try {
|
||||
loadExtension(extensionJar)
|
||||
} catch (e: MalformedExtensionException) {
|
||||
runCatching { loadExtension(extensionJar) }.onFailure {
|
||||
this.plugin.logger.warning(extensionJar.name + " caused an error!")
|
||||
if (Eco.getHandler().ecoPlugin.configYml.getBool("log-full-extension-errors")) {
|
||||
it.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(MalformedExtensionException::class)
|
||||
private fun loadExtension(extensionJar: File) {
|
||||
lateinit var url: URL
|
||||
|
||||
try {
|
||||
url = extensionJar.toURI().toURL()
|
||||
} catch (e: MalformedURLException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
val url = extensionJar.toURI().toURL()
|
||||
|
||||
val classLoader = URLClassLoader(arrayOf(url), this.plugin::class.java.classLoader)
|
||||
val ymlIn = classLoader.getResourceAsStream("extension.yml")
|
||||
|
||||
@@ -2,10 +2,11 @@ package com.willfp.eco.internal.factory
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.factory.NamespacedKeyFactory
|
||||
import com.willfp.eco.util.NamespacedKeyUtils
|
||||
import org.bukkit.NamespacedKey
|
||||
|
||||
class EcoNamespacedKeyFactory(private val plugin: EcoPlugin) : NamespacedKeyFactory {
|
||||
override fun create(key: String): NamespacedKey {
|
||||
return NamespacedKey(plugin, key)
|
||||
return NamespacedKeyUtils.create(plugin.name, key)
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user